mirror of https://github.com/go-gitea/gitea.git
fix
parent
60bf918934
commit
6c4160dba0
|
|
@ -8,6 +8,7 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
|
|
@ -132,11 +133,26 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
|
|||
}
|
||||
}
|
||||
}
|
||||
case "issueState":
|
||||
if strValue, ok := value.(string); ok {
|
||||
switch strings.ToLower(strValue) {
|
||||
case "close", "closed", "true":
|
||||
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",
|
||||
})
|
||||
}
|
||||
}
|
||||
case "closeIssue":
|
||||
if boolValue, ok := value.(bool); ok && boolValue {
|
||||
actions = append(actions, project_model.WorkflowAction{
|
||||
Type: project_model.WorkflowActionTypeClose,
|
||||
Value: "true",
|
||||
Value: "close",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -172,17 +188,17 @@ func WorkflowsEvents(ctx *context.Context) {
|
|||
}
|
||||
|
||||
type WorkflowConfig struct {
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
DisplayName string `json:"display_name"`
|
||||
BaseEventType string `json:"base_event_type"` // Base event type for grouping
|
||||
WorkflowEvent string `json:"workflow_event"` // The actual workflow event
|
||||
Capabilities project_model.WorkflowEventCapabilities `json:"capabilities"`
|
||||
Filters []project_model.WorkflowFilter `json:"filters"`
|
||||
Actions []project_model.WorkflowAction `json:"actions"`
|
||||
FilterSummary string `json:"filter_summary"` // Human readable filter description
|
||||
Enabled bool `json:"enabled"`
|
||||
IsConfigured bool `json:"isConfigured"` // Whether this workflow is configured/saved
|
||||
ID int64 `json:"id"`
|
||||
EventID string `json:"event_id"`
|
||||
DisplayName string `json:"display_name"`
|
||||
BaseEventType string `json:"base_event_type"` // Base event type for grouping
|
||||
WorkflowEvent string `json:"workflow_event"` // The actual workflow event
|
||||
Capabilities project_model.WorkflowEventCapabilities `json:"capabilities"`
|
||||
Filters []project_model.WorkflowFilter `json:"filters"`
|
||||
Actions []project_model.WorkflowAction `json:"actions"`
|
||||
FilterSummary string `json:"filter_summary"` // Human readable filter description
|
||||
Enabled bool `json:"enabled"`
|
||||
IsConfigured bool `json:"isConfigured"` // Whether this workflow is configured/saved
|
||||
}
|
||||
|
||||
outputWorkflows := make([]*WorkflowConfig, 0)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package projects
|
|||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
|
|
@ -424,9 +425,22 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
|
|||
continue
|
||||
}
|
||||
case project_model.WorkflowActionTypeClose:
|
||||
if err := issue_service.CloseIssue(ctx, issue, user_model.NewProjectWorkflowsUser(), ""); err != nil {
|
||||
log.Error("CloseIssue: %v", err)
|
||||
continue
|
||||
if strings.EqualFold(action.Value, "reopen") || strings.EqualFold(action.Value, "false") {
|
||||
if issue.IsClosed {
|
||||
if err := issue_service.ReopenIssue(ctx, issue, user_model.NewProjectWorkflowsUser(), ""); err != nil {
|
||||
log.Error("ReopenIssue: %v", err)
|
||||
continue
|
||||
}
|
||||
issue.IsClosed = false
|
||||
}
|
||||
} else {
|
||||
if !issue.IsClosed {
|
||||
if err := issue_service.CloseIssue(ctx, issue, user_model.NewProjectWorkflowsUser(), ""); err != nil {
|
||||
log.Error("CloseIssue: %v", err)
|
||||
continue
|
||||
}
|
||||
issue.IsClosed = true
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Error("Unsupported action type: %s", action.Type)
|
||||
|
|
|
|||
|
|
@ -978,13 +978,20 @@ onUnmounted(() => {
|
|||
</div>
|
||||
|
||||
<div class="field" v-if="hasAction('close')">
|
||||
<div v-if="isInEditMode" class="form-check">
|
||||
<input type="checkbox" v-model="store.workflowActions.closeIssue" id="close-issue">
|
||||
<label for="close-issue">Close issue</label>
|
||||
</div>
|
||||
<label for="issue-state-action">Issue state</label>
|
||||
<select
|
||||
v-if="isInEditMode"
|
||||
id="issue-state-action"
|
||||
class="form-select"
|
||||
v-model="store.workflowActions.issueState"
|
||||
>
|
||||
<option value="">No change</option>
|
||||
<option value="close">Close issue</option>
|
||||
<option value="reopen">Reopen issue</option>
|
||||
</select>
|
||||
<div v-else class="readonly-value">
|
||||
<label>Close issue</label>
|
||||
<div>{{ store.workflowActions.closeIssue ? 'Yes' : 'No' }}</div>
|
||||
{{ store.workflowActions.issueState === 'close' ? 'Close issue' :
|
||||
store.workflowActions.issueState === 'reopen' ? 'Reopen issue' : 'No change' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1024,6 +1031,7 @@ onUnmounted(() => {
|
|||
background: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
|
|
@ -1164,6 +1172,7 @@ onUnmounted(() => {
|
|||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.editor-header {
|
||||
|
|
@ -1202,6 +1211,7 @@ onUnmounted(() => {
|
|||
flex: 1;
|
||||
padding: 1.5rem;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.editor-content .field {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ type WorkflowFiltersState = {
|
|||
labels: string[];
|
||||
};
|
||||
|
||||
type WorkflowIssueStateAction = '' | 'close' | 'reopen';
|
||||
|
||||
type WorkflowActionsState = {
|
||||
column: string;
|
||||
add_labels: string[];
|
||||
remove_labels: string[];
|
||||
closeIssue: boolean;
|
||||
issueState: WorkflowIssueStateAction;
|
||||
};
|
||||
|
||||
type WorkflowDraftState = {
|
||||
|
|
@ -21,7 +23,7 @@ type WorkflowDraftState = {
|
|||
};
|
||||
|
||||
const createDefaultFilters = (): WorkflowFiltersState => ({issue_type: '', column: '', labels: []});
|
||||
const createDefaultActions = (): WorkflowActionsState => ({column: '', add_labels: [], remove_labels: [], closeIssue: false});
|
||||
const createDefaultActions = (): WorkflowActionsState => ({column: '', add_labels: [], remove_labels: [], issueState: ''});
|
||||
|
||||
const cloneFilters = (filters: WorkflowFiltersState): WorkflowFiltersState => ({
|
||||
issue_type: filters.issue_type,
|
||||
|
|
@ -33,7 +35,7 @@ const cloneActions = (actions: WorkflowActionsState): WorkflowActionsState => ({
|
|||
column: actions.column,
|
||||
add_labels: Array.from(actions.add_labels),
|
||||
remove_labels: Array.from(actions.remove_labels),
|
||||
closeIssue: actions.closeIssue,
|
||||
issueState: actions.issueState,
|
||||
});
|
||||
|
||||
export function createWorkflowStore(props: {projectLink: string, eventID: string}) {
|
||||
|
|
@ -112,7 +114,7 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
|||
// Convert backend filter format to frontend format
|
||||
const frontendFilters = {issue_type: '', column: '', labels: []};
|
||||
// Convert backend action format to frontend format
|
||||
const frontendActions = {column: '', add_labels: [], remove_labels: [], closeIssue: false};
|
||||
const frontendActions: WorkflowActionsState = {column: '', add_labels: [], remove_labels: [], issueState: ''};
|
||||
|
||||
if (workflow?.filters && Array.isArray(workflow.filters)) {
|
||||
for (const filter of workflow.filters) {
|
||||
|
|
@ -137,7 +139,11 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
|||
// Backend returns string, keep as string to match label.id type
|
||||
frontendActions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'close') {
|
||||
frontendActions.closeIssue = action.value === 'true';
|
||||
if (action.value === 'reopen' || action.value === 'false') {
|
||||
frontendActions.issueState = 'reopen';
|
||||
} else if (action.value === 'true' || action.value === 'close') {
|
||||
frontendActions.issueState = 'close';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -153,7 +159,11 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
|||
// Backend returns string, keep as string to match label.id type
|
||||
frontendActions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'close') {
|
||||
frontendActions.closeIssue = action.value === 'true';
|
||||
if (action.value === 'reopen' || action.value === 'false') {
|
||||
frontendActions.issueState = 'reopen';
|
||||
} else if (action.value === 'true' || action.value === 'close') {
|
||||
frontendActions.issueState = 'close';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +262,7 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
|||
// Convert backend data to frontend format and update form
|
||||
// Use the selectedWorkflow which now points to the reloaded workflow with complete data
|
||||
const frontendFilters = {issue_type: '', column: '', labels: []};
|
||||
const frontendActions = {column: '', add_labels: [], remove_labels: [], closeIssue: false};
|
||||
const frontendActions: WorkflowActionsState = {column: '', add_labels: [], remove_labels: [], issueState: ''};
|
||||
|
||||
if (store.selectedWorkflow.filters && Array.isArray(store.selectedWorkflow.filters)) {
|
||||
for (const filter of store.selectedWorkflow.filters) {
|
||||
|
|
@ -275,7 +285,11 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
|||
} else if (action.type === 'remove_labels') {
|
||||
frontendActions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'close') {
|
||||
frontendActions.closeIssue = action.value === 'true';
|
||||
if (action.value === 'reopen' || action.value === 'false') {
|
||||
frontendActions.issueState = 'reopen';
|
||||
} else if (action.value === 'true' || action.value === 'close') {
|
||||
frontendActions.issueState = 'close';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue