mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-14 05:00:02 +02:00
Fix bug
This commit is contained in:
parent
323a24e12c
commit
3d081b300f
@ -33,14 +33,6 @@ func deleteProjectIssuesByProjectID(ctx context.Context, projectID int64) error
|
||||
return err
|
||||
}
|
||||
|
||||
func AddIssueToColumn(ctx context.Context, issueID int64, newColumn *Column) error {
|
||||
return db.Insert(ctx, &ProjectIssue{
|
||||
IssueID: issueID,
|
||||
ProjectID: newColumn.ProjectID,
|
||||
ProjectColumnID: newColumn.ID,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Column) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Column) error {
|
||||
if c.ProjectID != newColumn.ProjectID {
|
||||
return errors.New("columns have to be in the same project")
|
||||
|
||||
@ -41,6 +41,15 @@ func GetWorkflowEvents() []WorkflowEvent {
|
||||
return workflowEvents
|
||||
}
|
||||
|
||||
func IsValidWorkflowEvent(event string) bool {
|
||||
for _, we := range workflowEvents {
|
||||
if we.EventID() == event {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (we WorkflowEvent) LangKey() string {
|
||||
switch we {
|
||||
case WorkflowEventItemOpened:
|
||||
|
||||
@ -5,7 +5,6 @@ package projects
|
||||
|
||||
import (
|
||||
stdCtx "context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -38,9 +37,15 @@ func getFilterSummary(ctx stdCtx.Context, filters []project_model.WorkflowFilter
|
||||
case project_model.WorkflowFilterTypeIssueType:
|
||||
switch filter.Value {
|
||||
case "issue":
|
||||
summary.WriteString(" (Issues only)")
|
||||
if summary.Len() > 0 {
|
||||
summary.WriteString(" ")
|
||||
}
|
||||
summary.WriteString("(Issues only)")
|
||||
case "pull_request":
|
||||
summary.WriteString(" (Pull requests only)")
|
||||
if summary.Len() > 0 {
|
||||
summary.WriteString(" ")
|
||||
}
|
||||
summary.WriteString("(Pull requests only)")
|
||||
}
|
||||
case project_model.WorkflowFilterTypeSourceColumn:
|
||||
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
|
||||
@ -52,7 +57,10 @@ func getFilterSummary(ctx stdCtx.Context, filters []project_model.WorkflowFilter
|
||||
log.Error("GetColumn: %v", err)
|
||||
continue
|
||||
}
|
||||
summary.WriteString(" (Source Column: " + col.Title + ")")
|
||||
if summary.Len() > 0 {
|
||||
summary.WriteString(" ")
|
||||
}
|
||||
summary.WriteString("(Source: " + col.Title + ")")
|
||||
case project_model.WorkflowFilterTypeTargetColumn:
|
||||
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
|
||||
if columnID <= 0 {
|
||||
@ -63,7 +71,10 @@ func getFilterSummary(ctx stdCtx.Context, filters []project_model.WorkflowFilter
|
||||
log.Error("GetColumn: %v", err)
|
||||
continue
|
||||
}
|
||||
summary.WriteString(" (Target Column: " + col.Title + ")")
|
||||
if summary.Len() > 0 {
|
||||
summary.WriteString(" ")
|
||||
}
|
||||
summary.WriteString("(Target: " + col.Title + ")")
|
||||
case project_model.WorkflowFilterTypeLabels:
|
||||
labelID, _ := strconv.ParseInt(filter.Value, 10, 64)
|
||||
if labelID > 0 {
|
||||
@ -76,7 +87,10 @@ func getFilterSummary(ctx stdCtx.Context, filters []project_model.WorkflowFilter
|
||||
if err != nil {
|
||||
log.Error("GetLabelsByIDs: %v", err)
|
||||
} else {
|
||||
summary.WriteString(" (Labels: ")
|
||||
if summary.Len() > 0 {
|
||||
summary.WriteString(" ")
|
||||
}
|
||||
summary.WriteString("(Labels: ")
|
||||
for i, label := range labels {
|
||||
summary.WriteString(label.Name)
|
||||
if i < len(labels)-1 {
|
||||
@ -225,8 +239,7 @@ func WorkflowsEvents(ctx *context.Context) {
|
||||
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
|
||||
WorkflowEvent string `json:"workflow_event"` // The workflow event
|
||||
Capabilities project_model.WorkflowEventCapabilities `json:"capabilities"`
|
||||
Filters []project_model.WorkflowFilter `json:"filters"`
|
||||
Actions []project_model.WorkflowAction `json:"actions"`
|
||||
@ -255,7 +268,6 @@ func WorkflowsEvents(ctx *context.Context) {
|
||||
ID: wf.ID,
|
||||
EventID: strconv.FormatInt(wf.ID, 10),
|
||||
DisplayName: string(ctx.Tr(wf.WorkflowEvent.LangKey())),
|
||||
BaseEventType: string(wf.WorkflowEvent),
|
||||
WorkflowEvent: string(wf.WorkflowEvent),
|
||||
Capabilities: capabilities[event],
|
||||
Filters: wf.WorkflowFilters,
|
||||
@ -271,7 +283,6 @@ func WorkflowsEvents(ctx *context.Context) {
|
||||
ID: 0,
|
||||
EventID: event.EventID(),
|
||||
DisplayName: string(ctx.Tr(event.LangKey())),
|
||||
BaseEventType: string(event),
|
||||
WorkflowEvent: string(event),
|
||||
Capabilities: capabilities[event],
|
||||
FilterSummary: "",
|
||||
@ -460,6 +471,7 @@ type WorkflowsPostForm struct {
|
||||
Actions map[string]any `json:"actions"`
|
||||
}
|
||||
|
||||
// WorkflowsPost handles creating or updating a workflow
|
||||
func WorkflowsPost(ctx *context.Context) {
|
||||
projectID := ctx.PathParamInt64("id")
|
||||
p, err := project_model.GetProjectByID(ctx, projectID)
|
||||
@ -495,7 +507,7 @@ func WorkflowsPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
if form.EventID == "" {
|
||||
ctx.ServerError("InvalidEventID", errors.New("EventID is required"))
|
||||
ctx.JSON(http.StatusBadRequest, map[string]any{"error": "InvalidEventID", "message": "EventID is required"})
|
||||
return
|
||||
}
|
||||
|
||||
@ -505,6 +517,12 @@ func WorkflowsPost(ctx *context.Context) {
|
||||
|
||||
eventID, _ := strconv.ParseInt(form.EventID, 10, 64)
|
||||
if eventID == 0 {
|
||||
// check if workflow event is valid
|
||||
if !project_model.IsValidWorkflowEvent(form.EventID) {
|
||||
ctx.JSON(http.StatusBadRequest, map[string]any{"error": "EventID is invalid"})
|
||||
return
|
||||
}
|
||||
|
||||
// Create a new workflow for the given event
|
||||
wf := &project_model.Workflow{
|
||||
ProjectID: projectID,
|
||||
|
||||
@ -1048,7 +1048,7 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Post("/{workflow_id}", projects.WorkflowsPost)
|
||||
m.Post("/{workflow_id}/status", projects.WorkflowsStatus)
|
||||
m.Post("/{workflow_id}/delete", projects.WorkflowsDelete)
|
||||
}, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead, true))
|
||||
}, reqUnitAccess(unit.TypeProjects, perm.AccessModeWrite, true))
|
||||
m.Group("", func() { //nolint:dupl // duplicates lines 1421-1441
|
||||
m.Get("/new", org.RenderNewProject)
|
||||
m.Post("/new", web.Bind(forms.CreateProjectForm{}), org.NewProjectPost)
|
||||
@ -1437,13 +1437,6 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Group("/{username}/{reponame}/projects", func() {
|
||||
m.Get("", repo.Projects)
|
||||
m.Get("/{id}", repo.ViewProject)
|
||||
m.Group("/{id}/workflows", func() {
|
||||
m.Get("", projects.Workflows)
|
||||
m.Get("/{workflow_id}", projects.Workflows)
|
||||
m.Post("/{workflow_id}", projects.WorkflowsPost)
|
||||
m.Post("/{workflow_id}/status", projects.WorkflowsStatus)
|
||||
m.Post("/{workflow_id}/delete", projects.WorkflowsDelete)
|
||||
})
|
||||
m.Group("", func() { //nolint:dupl // duplicates lines 1034-1054
|
||||
m.Get("/new", repo.RenderNewProject)
|
||||
m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost)
|
||||
@ -1463,6 +1456,14 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Post("/default", repo.SetDefaultProjectColumn)
|
||||
m.Post("/move", repo.MoveIssues)
|
||||
})
|
||||
|
||||
m.Group("/workflows", func() {
|
||||
m.Get("", projects.Workflows)
|
||||
m.Get("/{workflow_id}", projects.Workflows)
|
||||
m.Post("/{workflow_id}", projects.WorkflowsPost)
|
||||
m.Post("/{workflow_id}/status", projects.WorkflowsStatus)
|
||||
m.Post("/{workflow_id}/delete", projects.WorkflowsDelete)
|
||||
})
|
||||
})
|
||||
}, reqRepoProjectsWriter, context.RepoMustNotBeArchived())
|
||||
}, optSignIn, context.RepoAssignment, reqRepoProjectsReader, repo.MustEnableRepoProjects)
|
||||
|
||||
@ -94,8 +94,8 @@ const toggleEditMode = () => {
|
||||
// If we removed a temporary item but have no previous selection, fall back to first workflow
|
||||
const fallback = store.workflowEvents.find((w) => {
|
||||
if (!canceledWorkflow) return false;
|
||||
const baseType = canceledWorkflow.base_event_type || canceledWorkflow.workflow_event;
|
||||
return baseType && (w.base_event_type === baseType || w.workflow_event === baseType || w.event_id === baseType);
|
||||
const baseType = canceledWorkflow.workflow_event;
|
||||
return baseType && (w.workflow_event === baseType || w.event_id === baseType);
|
||||
}) || store.workflowEvents[0];
|
||||
if (fallback) {
|
||||
store.selectedItem = fallback.event_id;
|
||||
@ -132,12 +132,6 @@ const deleteWorkflow = async () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentBaseEventType = store.selectedWorkflow.base_event_type || store.selectedWorkflow.workflow_event || store.selectedWorkflow.event_id;
|
||||
const currentCapabilities = store.selectedWorkflow.capabilities;
|
||||
// Extract base name without any parenthetical descriptions
|
||||
const currentDisplayName = (store.selectedWorkflow.display_name || store.selectedWorkflow.workflow_event || store.selectedWorkflow.event_id)
|
||||
.replace(/\s*\([^)]*\)\s*/g, '');
|
||||
|
||||
// If deleting a temporary workflow (new or cloned, unsaved), just remove from list
|
||||
if (store.selectedWorkflow.id === 0) {
|
||||
const tempIndex = store.workflowEvents.findIndex((w) =>
|
||||
@ -155,7 +149,7 @@ const deleteWorkflow = async () => {
|
||||
|
||||
// Find workflows for the same base event type
|
||||
const sameEventWorkflows = store.workflowEvents.filter((w) =>
|
||||
(w.base_event_type === currentBaseEventType || w.workflow_event === currentBaseEventType)
|
||||
(w.workflow_event === store.selectedWorkflow.workflow_event)
|
||||
);
|
||||
|
||||
let workflowToSelect = null;
|
||||
@ -198,7 +192,7 @@ const cloneWorkflow = (sourceWorkflow) => {
|
||||
if (!sourceWorkflow) return;
|
||||
|
||||
// Generate a unique temporary ID for the cloned workflow
|
||||
const tempId = `clone-${sourceWorkflow.base_event_type || sourceWorkflow.workflow_event}-${Date.now()}`;
|
||||
const tempId = `clone-${sourceWorkflow.workflow_event}-${Date.now()}`;
|
||||
|
||||
// Extract base name without any parenthetical descriptions
|
||||
const baseName = (sourceWorkflow.display_name || sourceWorkflow.workflow_event || sourceWorkflow.event_id)
|
||||
@ -209,8 +203,7 @@ const cloneWorkflow = (sourceWorkflow) => {
|
||||
id: 0, // New workflow
|
||||
event_id: tempId,
|
||||
display_name: `${baseName} (Copy)`,
|
||||
base_event_type: sourceWorkflow.base_event_type || sourceWorkflow.workflow_event || sourceWorkflow.event_id,
|
||||
workflow_event: sourceWorkflow.workflow_event || sourceWorkflow.base_event_type,
|
||||
workflow_event: sourceWorkflow.workflow_event,
|
||||
capabilities: sourceWorkflow.capabilities,
|
||||
filters: JSON.parse(JSON.stringify(sourceWorkflow.filters || [])), // Deep clone
|
||||
actions: JSON.parse(JSON.stringify(sourceWorkflow.actions || [])), // Deep clone
|
||||
@ -325,12 +318,11 @@ const workflowList = computed(() => {
|
||||
return workflows.map((workflow) => ({
|
||||
...workflow,
|
||||
isConfigured: isWorkflowConfigured(workflow),
|
||||
base_event_type: workflow.base_event_type || workflow.workflow_event || workflow.event_id,
|
||||
display_name: workflow.display_name || workflow.workflow_event || workflow.event_id,
|
||||
}));
|
||||
});
|
||||
|
||||
const createNewWorkflow = (baseEventType, capabilities, displayName) => {
|
||||
const createNewWorkflow = (eventType, capabilities, displayName) => {
|
||||
// Store current selection before creating new workflow
|
||||
if (!isInEditMode.value) {
|
||||
previousSelection.value = {
|
||||
@ -339,7 +331,7 @@ const createNewWorkflow = (baseEventType, capabilities, displayName) => {
|
||||
};
|
||||
}
|
||||
|
||||
const tempId = `new-${baseEventType}-${Date.now()}`;
|
||||
const tempId = `new-${eventType}-${Date.now()}`;
|
||||
const newWorkflow = {
|
||||
id: 0,
|
||||
event_id: tempId,
|
||||
@ -348,14 +340,13 @@ const createNewWorkflow = (baseEventType, capabilities, displayName) => {
|
||||
filters: [],
|
||||
actions: [],
|
||||
filter_summary: '',
|
||||
base_event_type: baseEventType,
|
||||
workflow_event: baseEventType,
|
||||
workflow_event: eventType,
|
||||
enabled: true, // Ensure new workflows are enabled by default
|
||||
};
|
||||
|
||||
store.selectedWorkflow = newWorkflow;
|
||||
// For unconfigured events, use the base event type as selected item for UI consistency
|
||||
store.selectedItem = baseEventType;
|
||||
store.selectedItem = eventType;
|
||||
store.resetWorkflowData();
|
||||
// Unconfigured workflows are always in edit mode by default
|
||||
};
|
||||
@ -383,8 +374,7 @@ const selectWorkflowItem = async (item) => {
|
||||
} else {
|
||||
// This is an unconfigured event - check if we already have a workflow object for it
|
||||
const existingWorkflow = store.workflowEvents.find((w) =>
|
||||
w.id === 0 &&
|
||||
(w.base_event_type === item.base_event_type || w.workflow_event === item.base_event_type),
|
||||
w.id === 0 && w.workflow_event === item.workflow_event,
|
||||
);
|
||||
|
||||
if (existingWorkflow) {
|
||||
@ -392,12 +382,12 @@ const selectWorkflowItem = async (item) => {
|
||||
await selectWorkflowEvent(existingWorkflow);
|
||||
} else {
|
||||
// This is truly a new unconfigured event, create new workflow
|
||||
createNewWorkflow(item.base_event_type, item.capabilities, item.display_name);
|
||||
createNewWorkflow(item.workflow_event, item.capabilities, item.display_name);
|
||||
}
|
||||
|
||||
// Update URL for workflow
|
||||
const newUrl = `${props.projectLink}/workflows/${item.base_event_type}`;
|
||||
window.history.pushState({eventId: item.base_event_type}, '', newUrl);
|
||||
const newUrl = `${props.projectLink}/workflows/${item.workflow_event}`;
|
||||
window.history.pushState({eventId: item.workflow_event}, '', newUrl);
|
||||
}
|
||||
};
|
||||
|
||||
@ -433,18 +423,17 @@ const isItemSelected = (item) => {
|
||||
// For configured workflows or temporary workflows (new), match by event_id
|
||||
return store.selectedItem === item.event_id;
|
||||
}
|
||||
// For unconfigured events, match by base_event_type
|
||||
return store.selectedItem === item.base_event_type;
|
||||
// For unconfigured events, match by workflow_event
|
||||
return store.selectedItem === item.workflow_event;
|
||||
};
|
||||
|
||||
// Get display name for workflow with numbering for same types
|
||||
const getWorkflowDisplayName = (item, index) => {
|
||||
const list = workflowList.value;
|
||||
const baseEventType = item.base_event_type || item.workflow_event;
|
||||
|
||||
// Find all workflows of the same type
|
||||
const sameTypeWorkflows = list.filter(w =>
|
||||
(w.base_event_type || w.workflow_event) === baseEventType &&
|
||||
w.workflow_event === item.workflow_event &&
|
||||
(w.isConfigured || w.id === 0) // Only count configured workflows
|
||||
);
|
||||
|
||||
@ -517,7 +506,7 @@ watch(isInEditMode, async (newVal) => {
|
||||
|
||||
const getCurrentDraftKey = () => {
|
||||
if (!store.selectedWorkflow) return null;
|
||||
return store.selectedWorkflow.event_id || store.selectedWorkflow.base_event_type;
|
||||
return store.selectedWorkflow.event_id || store.selectedWorkflow.workflow_event;
|
||||
};
|
||||
|
||||
const persistDraftState = () => {
|
||||
@ -576,11 +565,11 @@ onMounted(async () => {
|
||||
// Check if eventID matches a base event type (unconfigured workflow)
|
||||
const items = workflowList.value;
|
||||
const matchingUnconfigured = items.find((item) =>
|
||||
!item.isConfigured && (item.base_event_type === props.eventID || item.event_id === props.eventID),
|
||||
!item.isConfigured && (item.workflow_event === props.eventID || item.event_id === props.eventID),
|
||||
);
|
||||
if (matchingUnconfigured) {
|
||||
// Create new workflow for this base event type
|
||||
createNewWorkflow(matchingUnconfigured.base_event_type, matchingUnconfigured.capabilities, matchingUnconfigured.display_name);
|
||||
createNewWorkflow(matchingUnconfigured.workflow_event, matchingUnconfigured.capabilities, matchingUnconfigured.display_name);
|
||||
} else {
|
||||
// Fallback: select first available item
|
||||
if (items.length > 0) {
|
||||
@ -626,10 +615,10 @@ const popstateHandler = (e) => {
|
||||
// Check if it's a base event type
|
||||
const items = workflowList.value;
|
||||
const matchingUnconfigured = items.find((item) =>
|
||||
!item.isConfigured && (item.base_event_type === e.state.eventId || item.event_id === e.state.eventId),
|
||||
!item.isConfigured && (item.workflow_event === e.state.eventId || item.event_id === e.state.eventId),
|
||||
);
|
||||
if (matchingUnconfigured) {
|
||||
createNewWorkflow(matchingUnconfigured.base_event_type, matchingUnconfigured.capabilities, matchingUnconfigured.display_name);
|
||||
createNewWorkflow(matchingUnconfigured.workflow_event, matchingUnconfigured.capabilities, matchingUnconfigured.display_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -829,6 +818,23 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" v-if="hasFilter('source_column')">
|
||||
<label>When moved from column</label>
|
||||
<select
|
||||
v-if="isInEditMode"
|
||||
v-model="store.workflowFilters.source_column"
|
||||
class="column-select"
|
||||
>
|
||||
<option value="">Any column</option>
|
||||
<option v-for="column in store.projectColumns" :key="column.id" :value="String(column.id)">
|
||||
{{ column.title }}
|
||||
</option>
|
||||
</select>
|
||||
<div v-else class="readonly-value">
|
||||
{{ store.projectColumns.find(c => String(c.id) === store.workflowFilters.source_column)?.title || 'Any column' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" v-if="hasFilter('target_column')">
|
||||
<label>When moved to column</label>
|
||||
<select
|
||||
|
||||
@ -4,6 +4,7 @@ import {showInfoToast, showErrorToast} from '../../modules/toast.ts';
|
||||
|
||||
type WorkflowFiltersState = {
|
||||
issue_type: string;
|
||||
source_column: string;
|
||||
target_column: string;
|
||||
labels: string[];
|
||||
};
|
||||
@ -22,11 +23,52 @@ type WorkflowDraftState = {
|
||||
actions: WorkflowActionsState;
|
||||
};
|
||||
|
||||
const createDefaultFilters = (): WorkflowFiltersState => ({issue_type: '', target_column: '', labels: []});
|
||||
const createDefaultFilters = (): WorkflowFiltersState => ({issue_type: '', source_column: '',target_column: '', labels: []});
|
||||
const createDefaultActions = (): WorkflowActionsState => ({column: '', add_labels: [], remove_labels: [], issue_state: ''});
|
||||
|
||||
function convertFilters(workflow: any): WorkflowFiltersState {
|
||||
const filters = createDefaultFilters();
|
||||
if (workflow?.filters && Array.isArray(workflow.filters)) {
|
||||
for (const filter of workflow.filters) {
|
||||
if (filter.type === 'issue_type') {
|
||||
filters.issue_type = filter.value;
|
||||
} else if (filter.type === 'source_column') {
|
||||
filters.source_column = filter.value;
|
||||
} else if (filter.type === 'target_column') {
|
||||
filters.target_column = filter.value;
|
||||
} else if (filter.type === 'labels') {
|
||||
filters.labels.push(filter.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
function convertActions(workflow: any): WorkflowActionsState {
|
||||
const actions = createDefaultActions();
|
||||
|
||||
if (workflow?.actions && Array.isArray(workflow.actions)) {
|
||||
for (const action of workflow.actions) {
|
||||
if (action.type === 'column') {
|
||||
// Backend returns string, keep as string to match column.id type
|
||||
actions.column = action.value;
|
||||
} else if (action.type === 'add_labels') {
|
||||
// Backend returns string, keep as string to match label.id type
|
||||
actions.add_labels.push(action.value);
|
||||
} else if (action.type === 'remove_labels') {
|
||||
// Backend returns string, keep as string to match label.id type
|
||||
actions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'issue_state') {
|
||||
actions.issue_state = action.value as WorkflowIssueStateAction;
|
||||
}
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
const cloneFilters = (filters: WorkflowFiltersState): WorkflowFiltersState => ({
|
||||
issue_type: filters.issue_type,
|
||||
source_column: filters.source_column,
|
||||
target_column: filters.target_column,
|
||||
labels: Array.from(filters.labels),
|
||||
});
|
||||
@ -51,7 +93,6 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
||||
selectedEventType: null, // For workflow creation
|
||||
|
||||
workflowFilters: createDefaultFilters(),
|
||||
|
||||
workflowActions: createDefaultActions(),
|
||||
|
||||
workflowDrafts: {} as Record<string, WorkflowDraftState>,
|
||||
@ -108,67 +149,9 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
||||
// Find the workflow from existing workflowEvents
|
||||
const workflow = store.workflowEvents.find((e) => e.event_id === eventId);
|
||||
|
||||
// Load existing configuration from the workflow data
|
||||
// Convert backend filter format to frontend format
|
||||
const frontendFilters = {issue_type: '', target_column: '', labels: []};
|
||||
// Convert backend action format to frontend format
|
||||
const frontendActions: WorkflowActionsState = {column: '', add_labels: [], remove_labels: [], issue_state: ''};
|
||||
|
||||
if (workflow?.filters && Array.isArray(workflow.filters)) {
|
||||
for (const filter of workflow.filters) {
|
||||
if (filter.type === 'issue_type') {
|
||||
frontendFilters.issue_type = filter.value;
|
||||
} else if (filter.type === 'target_column') {
|
||||
frontendFilters.target_column = filter.value;
|
||||
} else if (filter.type === 'labels') {
|
||||
frontendFilters.labels.push(filter.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (workflow.actions && Array.isArray(workflow.actions)) {
|
||||
for (const action of workflow.actions) {
|
||||
if (action.type === 'column') {
|
||||
// Backend returns string, keep as string to match column.id type
|
||||
frontendActions.column = action.value;
|
||||
} else if (action.type === 'add_labels') {
|
||||
// Backend returns string, keep as string to match label.id type
|
||||
frontendActions.add_labels.push(action.value);
|
||||
} else if (action.type === 'remove_labels') {
|
||||
// Backend returns string, keep as string to match label.id type
|
||||
frontendActions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'close') {
|
||||
if (action.value === 'reopen' || action.value === 'false') {
|
||||
frontendActions.issue_state = 'reopen';
|
||||
} else if (action.value === 'true' || action.value === 'close') {
|
||||
frontendActions.issue_state = 'close';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (workflow?.actions && Array.isArray(workflow.actions)) {
|
||||
for (const action of workflow.actions) {
|
||||
if (action.type === 'column') {
|
||||
// Backend returns string, keep as string to match column.id type
|
||||
frontendActions.column = action.value;
|
||||
} else if (action.type === 'add_labels') {
|
||||
// Backend returns string, keep as string to match label.id type
|
||||
frontendActions.add_labels.push(action.value);
|
||||
} else if (action.type === 'remove_labels') {
|
||||
// Backend returns string, keep as string to match label.id type
|
||||
frontendActions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'close') {
|
||||
if (action.value === 'reopen' || action.value === 'false') {
|
||||
frontendActions.issue_state = 'reopen';
|
||||
} else if (action.value === 'true' || action.value === 'close') {
|
||||
frontendActions.issue_state = 'close';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.workflowFilters = frontendFilters;
|
||||
store.workflowActions = frontendActions;
|
||||
store.updateDraft(eventId, frontendFilters, frontendActions);
|
||||
store.workflowFilters = convertFilters(workflow);
|
||||
store.workflowActions = convertActions(workflow);
|
||||
store.updateDraft(eventId, store.workflowFilters, store.workflowActions);
|
||||
} finally {
|
||||
store.loading = false;
|
||||
}
|
||||
@ -188,7 +171,7 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
||||
store.workflowFilters = createDefaultFilters();
|
||||
store.workflowActions = createDefaultActions();
|
||||
|
||||
const currentEventId = store.selectedWorkflow?.event_id || store.selectedWorkflow?.base_event_type;
|
||||
const currentEventId = store.selectedWorkflow?.event_id;
|
||||
if (currentEventId) {
|
||||
store.updateDraft(currentEventId, store.workflowFilters, store.workflowActions);
|
||||
}
|
||||
@ -200,8 +183,7 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
||||
store.saving = true;
|
||||
try {
|
||||
// For new workflows, use the base event type
|
||||
const eventId = store.selectedWorkflow.base_event_type || store.selectedWorkflow.event_id;
|
||||
const previousDraftKey = store.selectedWorkflow.event_id || store.selectedWorkflow.base_event_type;
|
||||
const eventId = store.selectedWorkflow.event_id;
|
||||
|
||||
// Convert frontend data format to backend JSON format
|
||||
const postData = {
|
||||
@ -237,8 +219,8 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
||||
eventKey.startsWith('new-') ||
|
||||
eventKey.startsWith('clone-');
|
||||
|
||||
if (wasNewWorkflow && previousDraftKey) {
|
||||
store.clearDraft(previousDraftKey);
|
||||
if (wasNewWorkflow) {
|
||||
store.clearDraft(store.selectedWorkflow.workflow_event);
|
||||
}
|
||||
|
||||
// Reload events from server to get the correct event structure
|
||||
@ -257,45 +239,10 @@ export function createWorkflowStore(props: {projectLink: string, eventID: string
|
||||
store.selectedItem = result.workflow.event_id;
|
||||
}
|
||||
|
||||
// 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: '', target_column: '', labels: []};
|
||||
const frontendActions: WorkflowActionsState = {column: '', add_labels: [], remove_labels: [], issue_state: ''};
|
||||
|
||||
if (store.selectedWorkflow.filters && Array.isArray(store.selectedWorkflow.filters)) {
|
||||
for (const filter of store.selectedWorkflow.filters) {
|
||||
if (filter.type === 'issue_type') {
|
||||
frontendFilters.issue_type = filter.value;
|
||||
} else if (filter.type === 'target_column') {
|
||||
frontendFilters.target_column = filter.value;
|
||||
} else if (filter.type === 'labels') {
|
||||
frontendFilters.labels.push(filter.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (store.selectedWorkflow.actions && Array.isArray(store.selectedWorkflow.actions)) {
|
||||
for (const action of store.selectedWorkflow.actions) {
|
||||
if (action.type === 'column') {
|
||||
frontendActions.column = action.value;
|
||||
} else if (action.type === 'add_labels') {
|
||||
frontendActions.add_labels.push(action.value);
|
||||
} else if (action.type === 'remove_labels') {
|
||||
frontendActions.remove_labels.push(action.value);
|
||||
} else if (action.type === 'close') {
|
||||
if (action.value === 'reopen' || action.value === 'false') {
|
||||
frontendActions.issue_state = 'reopen';
|
||||
} else if (action.value === 'true' || action.value === 'close') {
|
||||
frontendActions.issue_state = 'close';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.workflowFilters = frontendFilters;
|
||||
store.workflowActions = frontendActions;
|
||||
store.workflowFilters = convertFilters(store.selectedWorkflow);
|
||||
store.workflowActions = convertActions(store.selectedWorkflow);
|
||||
if (store.selectedWorkflow?.event_id) {
|
||||
store.updateDraft(store.selectedWorkflow.event_id, frontendFilters, frontendActions);
|
||||
store.updateDraft(store.selectedWorkflow.event_id, store.workflowFilters, store.workflowActions);
|
||||
}
|
||||
|
||||
// Update URL to use the new workflow ID
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user