mirror of https://github.com/go-gitea/gitea.git
fix
parent
60bf918934
commit
6c4160dba0
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
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":
|
case "closeIssue":
|
||||||
if boolValue, ok := value.(bool); ok && boolValue {
|
if boolValue, ok := value.(bool); ok && boolValue {
|
||||||
actions = append(actions, project_model.WorkflowAction{
|
actions = append(actions, project_model.WorkflowAction{
|
||||||
Type: project_model.WorkflowActionTypeClose,
|
Type: project_model.WorkflowActionTypeClose,
|
||||||
Value: "true",
|
Value: "close",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package projects
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
project_model "code.gitea.io/gitea/models/project"
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
|
|
@ -424,10 +425,23 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case project_model.WorkflowActionTypeClose:
|
case project_model.WorkflowActionTypeClose:
|
||||||
|
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 {
|
if err := issue_service.CloseIssue(ctx, issue, user_model.NewProjectWorkflowsUser(), ""); err != nil {
|
||||||
log.Error("CloseIssue: %v", err)
|
log.Error("CloseIssue: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
issue.IsClosed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
log.Error("Unsupported action type: %s", action.Type)
|
log.Error("Unsupported action type: %s", action.Type)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -978,13 +978,20 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field" v-if="hasAction('close')">
|
<div class="field" v-if="hasAction('close')">
|
||||||
<div v-if="isInEditMode" class="form-check">
|
<label for="issue-state-action">Issue state</label>
|
||||||
<input type="checkbox" v-model="store.workflowActions.closeIssue" id="close-issue">
|
<select
|
||||||
<label for="close-issue">Close issue</label>
|
v-if="isInEditMode"
|
||||||
</div>
|
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">
|
<div v-else class="readonly-value">
|
||||||
<label>Close issue</label>
|
{{ store.workflowActions.issueState === 'close' ? 'Close issue' :
|
||||||
<div>{{ store.workflowActions.closeIssue ? 'Yes' : 'No' }}</div>
|
store.workflowActions.issueState === 'reopen' ? 'Reopen issue' : 'No change' }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1024,6 +1031,7 @@ onUnmounted(() => {
|
||||||
background: white;
|
background: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar */
|
/* Sidebar */
|
||||||
|
|
@ -1164,6 +1172,7 @@ onUnmounted(() => {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-header {
|
.editor-header {
|
||||||
|
|
@ -1202,6 +1211,7 @@ onUnmounted(() => {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-content .field {
|
.editor-content .field {
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,13 @@ type WorkflowFiltersState = {
|
||||||
labels: string[];
|
labels: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type WorkflowIssueStateAction = '' | 'close' | 'reopen';
|
||||||
|
|
||||||
type WorkflowActionsState = {
|
type WorkflowActionsState = {
|
||||||
column: string;
|
column: string;
|
||||||
add_labels: string[];
|
add_labels: string[];
|
||||||
remove_labels: string[];
|
remove_labels: string[];
|
||||||
closeIssue: boolean;
|
issueState: WorkflowIssueStateAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type WorkflowDraftState = {
|
type WorkflowDraftState = {
|
||||||
|
|
@ -21,7 +23,7 @@ type WorkflowDraftState = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const createDefaultFilters = (): WorkflowFiltersState => ({issue_type: '', column: '', labels: []});
|
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 => ({
|
const cloneFilters = (filters: WorkflowFiltersState): WorkflowFiltersState => ({
|
||||||
issue_type: filters.issue_type,
|
issue_type: filters.issue_type,
|
||||||
|
|
@ -33,7 +35,7 @@ const cloneActions = (actions: WorkflowActionsState): WorkflowActionsState => ({
|
||||||
column: actions.column,
|
column: actions.column,
|
||||||
add_labels: Array.from(actions.add_labels),
|
add_labels: Array.from(actions.add_labels),
|
||||||
remove_labels: Array.from(actions.remove_labels),
|
remove_labels: Array.from(actions.remove_labels),
|
||||||
closeIssue: actions.closeIssue,
|
issueState: actions.issueState,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function createWorkflowStore(props: {projectLink: string, eventID: string}) {
|
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
|
// Convert backend filter format to frontend format
|
||||||
const frontendFilters = {issue_type: '', column: '', labels: []};
|
const frontendFilters = {issue_type: '', column: '', labels: []};
|
||||||
// Convert backend action format to frontend format
|
// 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)) {
|
if (workflow?.filters && Array.isArray(workflow.filters)) {
|
||||||
for (const filter of 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
|
// Backend returns string, keep as string to match label.id type
|
||||||
frontendActions.remove_labels.push(action.value);
|
frontendActions.remove_labels.push(action.value);
|
||||||
} else if (action.type === 'close') {
|
} 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
|
// Backend returns string, keep as string to match label.id type
|
||||||
frontendActions.remove_labels.push(action.value);
|
frontendActions.remove_labels.push(action.value);
|
||||||
} else if (action.type === 'close') {
|
} 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
|
// Convert backend data to frontend format and update form
|
||||||
// Use the selectedWorkflow which now points to the reloaded workflow with complete data
|
// Use the selectedWorkflow which now points to the reloaded workflow with complete data
|
||||||
const frontendFilters = {issue_type: '', column: '', labels: []};
|
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)) {
|
if (store.selectedWorkflow.filters && Array.isArray(store.selectedWorkflow.filters)) {
|
||||||
for (const filter of 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') {
|
} else if (action.type === 'remove_labels') {
|
||||||
frontendActions.remove_labels.push(action.value);
|
frontendActions.remove_labels.push(action.value);
|
||||||
} else if (action.type === 'close') {
|
} 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