diff --git a/web_src/js/components/projects/ProjectWorkflow.vue b/web_src/js/components/projects/ProjectWorkflow.vue
index d7ae5a3f6d..1e47b62775 100644
--- a/web_src/js/components/projects/ProjectWorkflow.vue
+++ b/web_src/js/components/projects/ProjectWorkflow.vue
@@ -40,7 +40,7 @@ const setEditMode = (enabled) => {
}
};
- // Store previous selection for cancel functionality
+// Store previous selection for cancel functionality
const toggleEditMode = () => {
if (isInEditMode.value) {
@@ -97,7 +97,7 @@ const deleteWorkflow = async () => {
const currentDisplayName = (store.selectedWorkflow.display_name || store.selectedWorkflow.workflow_event || store.selectedWorkflow.event_id)
.replace(/\s*\([^)]*\)\s*/g, '');
- // If deleting a temporary workflow (clone/new), just remove from list
+ // If deleting a temporary workflow (new), just remove from list
if (store.selectedWorkflow.id === 0) {
const tempIndex = store.workflowEvents.findIndex((w) =>
w.event_id === store.selectedWorkflow.event_id,
@@ -254,51 +254,6 @@ const createNewWorkflow = (baseEventType, capabilities, displayName) => {
// Unconfigured workflows are always in edit mode by default
};
-const cloneWorkflow = (sourceWorkflow) => {
- // Store current selection before cloning
- previousSelection.value = {
- selectedItem: store.selectedItem,
- selectedWorkflow: store.selectedWorkflow ? {...store.selectedWorkflow} : null,
- };
-
- const tempId = `clone-${sourceWorkflow.base_event_type || sourceWorkflow.workflow_event}-${Date.now()}`;
- // Extract base name without filter descriptions
- const baseName = (sourceWorkflow.display_name || sourceWorkflow.workflow_event || sourceWorkflow.event_id)
- .replace(/\s*\([^)]*\)\s*/g, ''); // Remove any parenthetical descriptions
-
- const clonedWorkflow = {
- id: 0,
- event_id: tempId,
- display_name: `${baseName} (Copy)`, // Add copy suffix
- capabilities: sourceWorkflow.capabilities,
- filters: Array.from(sourceWorkflow.filters || []),
- actions: Array.from(sourceWorkflow.actions || []),
- filter_summary: '',
- base_event_type: sourceWorkflow.base_event_type || sourceWorkflow.workflow_event || sourceWorkflow.event_id,
- enabled: true,
- };
-
- // Find the position of source workflow and insert cloned workflow after it
- const sourceIndex = store.workflowEvents.findIndex((w) => w.event_id === sourceWorkflow.event_id);
- if (sourceIndex >= 0) {
- store.workflowEvents.splice(sourceIndex + 1, 0, clonedWorkflow);
- } else {
- store.workflowEvents.push(clonedWorkflow);
- }
-
- // Select the cloned workflow
- store.selectedWorkflow = clonedWorkflow;
- store.selectedItem = tempId;
-
- // Load the source workflow's data into the form
- store.loadWorkflowData(sourceWorkflow.event_id);
- // Cloned workflows (id: 0) are always in edit mode by default
-
- // Update URL for cloned workflow
- const newUrl = `${props.projectLink}/workflows/${tempId}`;
- window.history.pushState({eventId: tempId}, '', newUrl);
-};
-
// Add debounce mechanism
let selectTimeout = null;
@@ -369,7 +324,7 @@ const isItemSelected = (item) => {
if (!store.selectedItem) return false;
if (item.isConfigured || item.id === 0) {
- // For configured workflows or temporary workflows (clones/new), match by event_id
+ // 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
@@ -585,17 +540,6 @@ onUnmounted(() => {
{{ store.selectedWorkflow.enabled ? 'Disable' : 'Enable' }}
-
-
-
diff --git a/web_src/js/components/projects/WorkflowStore.ts b/web_src/js/components/projects/WorkflowStore.ts
index cd70a19180..f7feedfc74 100644
--- a/web_src/js/components/projects/WorkflowStore.ts
+++ b/web_src/js/components/projects/WorkflowStore.ts
@@ -148,14 +148,51 @@ export function createWorkflowStore(props: { projectLink: string, eventID: strin
// Reload events from server to get the correct event structure
await store.loadEvents();
- // Update selected workflow and selectedItem
- store.selectedWorkflow = result.workflow;
- store.selectedItem = result.workflow.event_id;
+ // Find the reloaded workflow which has complete data including capabilities
+ const reloadedWorkflow = store.workflowEvents.find((w) => w.event_id === result.workflow.event_id);
+
+ if (reloadedWorkflow) {
+ // Use the reloaded workflow as it has all the necessary fields
+ store.selectedWorkflow = reloadedWorkflow;
+ store.selectedItem = reloadedWorkflow.event_id;
+ } else {
+ // Fallback: use the result from backend (shouldn't normally happen)
+ store.selectedWorkflow = result.workflow;
+ 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: ''};
+ const frontendActions = {column: '', add_labels: [], closeIssue: false};
+
+ 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;
+ }
+ }
+ }
+
+ 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 === 'close') {
+ frontendActions.closeIssue = action.value === 'true';
+ }
+ }
+ }
+
+ store.workflowFilters = frontendFilters;
+ store.workflowActions = frontendActions;
// Update URL to use the new workflow ID
if (wasNewWorkflow) {
- const newUrl = `${props.projectLink}/workflows/${result.workflow.event_id}`;
- window.history.replaceState({eventId: result.workflow.event_id}, '', newUrl);
+ const newUrl = `${props.projectLink}/workflows/${store.selectedWorkflow.event_id}`;
+ window.history.replaceState({eventId: store.selectedWorkflow.event_id}, '', newUrl);
}
showInfoToast('Workflow saved successfully!');