mirror of https://github.com/go-gitea/gitea.git
improvements
parent
623388cef9
commit
c2419f8c5b
|
|
@ -70,7 +70,6 @@ func (err ErrProjectNotExist) Unwrap() error {
|
|||
type ErrProjectColumnNotExist struct {
|
||||
ColumnID int64
|
||||
ProjectID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrProjectColumnNotExist checks if an error is a ErrProjectColumnNotExist
|
||||
|
|
@ -80,8 +79,8 @@ func IsErrProjectColumnNotExist(err error) bool {
|
|||
}
|
||||
|
||||
func (err ErrProjectColumnNotExist) Error() string {
|
||||
if err.ProjectID > 0 && len(err.Name) > 0 {
|
||||
return fmt.Sprintf("project column does not exist [project_id: %d, name: %s]", err.ProjectID, err.Name)
|
||||
if err.ProjectID > 0 {
|
||||
return fmt.Sprintf("project column does not exist [project_id: %d, column_id: %d]", err.ProjectID, err.ColumnID)
|
||||
}
|
||||
return fmt.Sprintf("project column does not exist [id: %d]", err.ColumnID)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ const (
|
|||
WorkflowActionTypeColumn WorkflowActionType = "column" // add the item to the project's column
|
||||
WorkflowActionTypeAddLabels WorkflowActionType = "add_labels" // choose one or more labels
|
||||
WorkflowActionTypeRemoveLabels WorkflowActionType = "remove_labels" // choose one or more labels
|
||||
WorkflowActionTypeClose WorkflowActionType = "close" // close the issue
|
||||
WorkflowActionTypeIssueState WorkflowActionType = "issue_state" // change the issue state (reopen/close)
|
||||
)
|
||||
|
||||
type WorkflowAction struct {
|
||||
|
|
@ -141,7 +141,7 @@ func GetWorkflowEventCapabilities() map[WorkflowEvent]WorkflowEventCapabilities
|
|||
},
|
||||
WorkflowEventItemColumnChanged: {
|
||||
AvailableFilters: []WorkflowFilterType{WorkflowFilterTypeIssueType, WorkflowFilterTypeColumn, WorkflowFilterTypeLabels},
|
||||
AvailableActions: []WorkflowActionType{WorkflowActionTypeAddLabels, WorkflowActionTypeRemoveLabels, WorkflowActionTypeClose},
|
||||
AvailableActions: []WorkflowActionType{WorkflowActionTypeAddLabels, WorkflowActionTypeRemoveLabels, WorkflowActionTypeIssueState},
|
||||
},
|
||||
WorkflowEventCodeChangesRequested: {
|
||||
AvailableFilters: []WorkflowFilterType{WorkflowFilterTypeLabels}, // only applies to pull requests
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
package projects
|
||||
|
||||
import (
|
||||
stdCtx "context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -25,22 +26,56 @@ var (
|
|||
)
|
||||
|
||||
// getFilterSummary returns a human-readable summary of the filters
|
||||
func getFilterSummary(filters []project_model.WorkflowFilter) string {
|
||||
func getFilterSummary(ctx stdCtx.Context, filters []project_model.WorkflowFilter) string {
|
||||
if len(filters) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var summary strings.Builder
|
||||
labelIDs := make([]int64, 0)
|
||||
for _, filter := range filters {
|
||||
if filter.Type == "scope" {
|
||||
switch filter.Type {
|
||||
case project_model.WorkflowFilterTypeIssueType:
|
||||
switch filter.Value {
|
||||
case "issue":
|
||||
return " (Issues only)"
|
||||
summary.WriteString(" (Issues only)")
|
||||
case "pull_request":
|
||||
return " (Pull requests only)"
|
||||
summary.WriteString(" (Pull requests only)")
|
||||
}
|
||||
case project_model.WorkflowFilterTypeColumn:
|
||||
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
|
||||
if columnID <= 0 {
|
||||
continue
|
||||
}
|
||||
col, err := project_model.GetColumn(ctx, columnID)
|
||||
if err != nil {
|
||||
log.Error("GetColumn: %v", err)
|
||||
continue
|
||||
}
|
||||
summary.WriteString(" (Column: " + col.Title + ")")
|
||||
case project_model.WorkflowFilterTypeLabels:
|
||||
labelID, _ := strconv.ParseInt(filter.Value, 10, 64)
|
||||
if labelID > 0 {
|
||||
labelIDs = append(labelIDs, labelID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
if len(labelIDs) > 0 {
|
||||
labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs)
|
||||
if err != nil {
|
||||
log.Error("GetLabelsByIDs: %v", err)
|
||||
} else {
|
||||
summary.WriteString(" (Labels: ")
|
||||
for i, label := range labels {
|
||||
summary.WriteString(label.Name)
|
||||
if i < len(labels)-1 {
|
||||
summary.WriteString(", ")
|
||||
}
|
||||
}
|
||||
summary.WriteString(")")
|
||||
}
|
||||
}
|
||||
return summary.String()
|
||||
}
|
||||
|
||||
// convertFormToFilters converts form filters to WorkflowFilter objects
|
||||
|
|
@ -133,28 +168,16 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
|
|||
}
|
||||
}
|
||||
}
|
||||
case "issueState":
|
||||
case "issue_state":
|
||||
if strValue, ok := value.(string); ok {
|
||||
switch strings.ToLower(strValue) {
|
||||
case "close", "closed", "true":
|
||||
v := strings.ToLower(strValue)
|
||||
if v == "close" || v == "reopen" {
|
||||
actions = append(actions, project_model.WorkflowAction{
|
||||
Type: project_model.WorkflowActionTypeClose,
|
||||
Value: "close",
|
||||
})
|
||||
case "reopen", "open", "false":
|
||||
actions = append(actions, project_model.WorkflowAction{
|
||||
Type: project_model.WorkflowActionTypeClose,
|
||||
Value: "reopen",
|
||||
Type: project_model.WorkflowActionTypeIssueState,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
}
|
||||
case "closeIssue":
|
||||
if boolValue, ok := value.(bool); ok && boolValue {
|
||||
actions = append(actions, project_model.WorkflowAction{
|
||||
Type: project_model.WorkflowActionTypeClose,
|
||||
Value: "close",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +239,7 @@ func WorkflowsEvents(ctx *context.Context) {
|
|||
if len(existingWorkflows) > 0 {
|
||||
// Add all existing workflows for this event
|
||||
for _, wf := range existingWorkflows {
|
||||
filterSummary := getFilterSummary(wf.WorkflowFilters)
|
||||
filterSummary := getFilterSummary(ctx, wf.WorkflowFilters)
|
||||
outputWorkflows = append(outputWorkflows, &WorkflowConfig{
|
||||
ID: wf.ID,
|
||||
EventID: strconv.FormatInt(wf.ID, 10),
|
||||
|
|
@ -485,7 +508,7 @@ func WorkflowsPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
// Return the newly created workflow with filter summary
|
||||
filterSummary := getFilterSummary(wf.WorkflowFilters)
|
||||
filterSummary := getFilterSummary(ctx, wf.WorkflowFilters)
|
||||
ctx.JSON(http.StatusOK, map[string]any{
|
||||
"success": true,
|
||||
"workflow": map[string]any{
|
||||
|
|
@ -518,7 +541,7 @@ func WorkflowsPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
// Return the updated workflow with filter summary
|
||||
filterSummary := getFilterSummary(wf.WorkflowFilters)
|
||||
filterSummary := getFilterSummary(ctx, wf.WorkflowFilters)
|
||||
ctx.JSON(http.StatusOK, map[string]any{
|
||||
"success": true,
|
||||
"workflow": map[string]any{
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ func UpdateIssueProject(ctx *context.Context) {
|
|||
if issue.Project != nil && issue.Project.ID == projectID {
|
||||
continue
|
||||
}
|
||||
if err := issues_servie.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, projectID, 0); err != nil {
|
||||
if err := issues_servie.AssignOrRemoveProject(ctx, issue, ctx.Doer, projectID, 0); err != nil {
|
||||
if errors.Is(err, util.ErrPermissionDenied) {
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/services/notify"
|
||||
)
|
||||
|
||||
func IssueAssignOrRemoveProject(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, projectID int64, position int) error {
|
||||
func AssignOrRemoveProject(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, projectID int64, position int) error {
|
||||
if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, doer, projectID, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,8 +424,8 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
|
|||
}
|
||||
continue
|
||||
}
|
||||
case project_model.WorkflowActionTypeClose:
|
||||
if strings.EqualFold(action.Value, "reopen") || strings.EqualFold(action.Value, "false") {
|
||||
case project_model.WorkflowActionTypeIssueState:
|
||||
if strings.EqualFold(action.Value, "reopen") {
|
||||
if issue.IsClosed {
|
||||
if err := issue_service.ReopenIssue(ctx, issue, user_model.NewProjectWorkflowsUser(), ""); err != nil {
|
||||
log.Error("ReopenIssue: %v", err)
|
||||
|
|
@ -433,7 +433,7 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
|
|||
}
|
||||
issue.IsClosed = false
|
||||
}
|
||||
} else {
|
||||
} else if strings.EqualFold(action.Value, "close") {
|
||||
if !issue.IsClosed {
|
||||
if err := issue_service.CloseIssue(ctx, issue, user_model.NewProjectWorkflowsUser(), ""); err != nil {
|
||||
log.Error("CloseIssue: %v", err)
|
||||
|
|
|
|||
|
|
@ -977,21 +977,21 @@ onUnmounted(() => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" v-if="hasAction('close')">
|
||||
<div class="field" v-if="hasAction('issue_state')">
|
||||
<label for="issue-state-action">Issue state</label>
|
||||
<select
|
||||
v-if="isInEditMode"
|
||||
id="issue-state-action"
|
||||
class="column-select"
|
||||
v-model="store.workflowActions.issueState"
|
||||
v-model="store.workflowActions.issue_state"
|
||||
>
|
||||
<option value="">No change</option>
|
||||
<option value="close">Close issue</option>
|
||||
<option value="reopen">Reopen issue</option>
|
||||
</select>
|
||||
<div v-else class="readonly-value">
|
||||
{{ store.workflowActions.issueState === 'close' ? 'Close issue' :
|
||||
store.workflowActions.issueState === 'reopen' ? 'Reopen issue' : 'No change' }}
|
||||
{{ store.workflowActions.issue_state === 'close' ? 'Close issue' :
|
||||
store.workflowActions.issue_state === 'reopen' ? 'Reopen issue' : 'No change' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue