136 lines
4.8 KiB
JavaScript
136 lines
4.8 KiB
JavaScript
/**
|
|
* Workflow Catalog
|
|
*
|
|
* Single source of truth for every workflow type known to the frontend:
|
|
* what it's called, what category/description/icons it has, how many steps
|
|
* it has and what they're called, what its initial payload looks like, and
|
|
* which Vue component renders it.
|
|
*
|
|
* Each workflow has a fully co-located component + metadata as a static
|
|
* `meta` option on the component (`Component.meta`, right next to
|
|
* `name`/`props`/etc.) in `@/components/workflow/workflows/*.vue` - this
|
|
* file simply imports those components and reads `.meta` off of them to
|
|
* build the catalog below.
|
|
*
|
|
* This replaces the previous design of a parallel `BaseWorkflow` class
|
|
* hierarchy (metadata) plus a separate per-step `ComponentRegistry.js`
|
|
* (components) - both concerns now live in one flat array with each
|
|
* component responsible for its own metadata and UI implementation.
|
|
*/
|
|
import FotoFirstBulkImportWorkflow from '@/components/workflow/workflows/FotoFirstBulkImportWorkflow.vue';
|
|
import BulkItemImportWorkflow from '@/components/workflow/workflows/BulkItemImportWorkflow.vue';
|
|
import InventoryAuditWorkflow from '@/components/workflow/workflows/InventoryAuditWorkflow.vue';
|
|
import StorageOptimizationWorkflow from '@/components/workflow/workflows/StorageOptimizationWorkflow.vue';
|
|
import MaintenanceScheduleWorkflow from '@/components/workflow/workflows/MaintenanceScheduleWorkflow.vue';
|
|
import ExpiryCheckWorkflow from '@/components/workflow/workflows/ExpiryCheckWorkflow.vue';
|
|
import BackupRestoreWorkflow from '@/components/workflow/workflows/BackupRestoreWorkflow.vue';
|
|
|
|
/**
|
|
* Workflows with a fully co-located component + metadata.
|
|
*/
|
|
const workflows = [
|
|
{...FotoFirstBulkImportWorkflow.meta, component: FotoFirstBulkImportWorkflow},
|
|
{...BulkItemImportWorkflow.meta, component: BulkItemImportWorkflow},
|
|
{...InventoryAuditWorkflow.meta, component: InventoryAuditWorkflow},
|
|
{...StorageOptimizationWorkflow.meta, component: StorageOptimizationWorkflow},
|
|
{...MaintenanceScheduleWorkflow.meta, component: MaintenanceScheduleWorkflow},
|
|
{...ExpiryCheckWorkflow.meta, component: ExpiryCheckWorkflow},
|
|
{...BackupRestoreWorkflow.meta, component: BackupRestoreWorkflow},
|
|
];
|
|
|
|
/**
|
|
* Get every workflow in the catalog.
|
|
* @returns {Array<Object>}
|
|
*/
|
|
export function getAllWorkflows() {
|
|
return workflows;
|
|
}
|
|
|
|
/**
|
|
* Get a single workflow definition by id.
|
|
* @param {string} id
|
|
* @returns {Object|undefined}
|
|
*/
|
|
export function getWorkflow(slug) {
|
|
return workflows.find(workflow => workflow.slug === slug);
|
|
}
|
|
|
|
/**
|
|
* Get the Vue component implementing a workflow's UI, if any.
|
|
* @param {string} id
|
|
* @returns {Object|null}
|
|
*/
|
|
export function getWorkflowComponent(id) {
|
|
return getWorkflow(id)?.component || null;
|
|
}
|
|
|
|
/**
|
|
* Get all workflows belonging to a category.
|
|
* @param {string} category
|
|
* @returns {Array<Object>}
|
|
*/
|
|
export function getWorkflowsByCategory(category) {
|
|
return workflows.filter(workflow => workflow.category === category);
|
|
}
|
|
|
|
/**
|
|
* Get all unique categories present in the catalog.
|
|
* @returns {Array<string>}
|
|
*/
|
|
export function getWorkflowCategories() {
|
|
return [...new Set(workflows.map(workflow => workflow.category))];
|
|
}
|
|
|
|
/**
|
|
* Build the payload sent to the backend to start a new instance of a
|
|
* workflow, merging the common `workflow_config` metadata block with the
|
|
* workflow's own initial payload fields.
|
|
* @param {Object} workflow - A workflow definition, e.g. from getWorkflow()
|
|
* @returns {Object}
|
|
*/
|
|
export function buildWorkflowApiPayload(workflow) {
|
|
const ownPayload = workflow.getInitialPayload ? workflow.getInitialPayload() : {};
|
|
return {
|
|
title: workflow.title,
|
|
slug: workflow.slug,
|
|
state: 'running',
|
|
current_step: 1,
|
|
total_steps: workflow.stepDefinitions.length,
|
|
payload: {
|
|
...ownPayload
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The backend stores WorkflowInstance.payload as an opaque string - it never
|
|
* parses or understands it as JSON. The frontend is fully responsible for
|
|
* serializing it before sending and deserializing it after receiving.
|
|
*/
|
|
export function serializeWorkflowPayload(workflow) {
|
|
console.log(workflow);
|
|
if (!workflow || !('payload' in workflow)) return workflow;
|
|
return {...workflow, payload: JSON.stringify(workflow.payload ?? {})};
|
|
}
|
|
|
|
export function deserializeWorkflowPayload(workflow) {
|
|
if (!workflow) return workflow;
|
|
let payload = {};
|
|
try {
|
|
payload = workflow.payload ? JSON.parse(workflow.payload) : {};
|
|
} catch (e) {
|
|
console.error('Failed to parse workflow payload JSON:', e);
|
|
}
|
|
return {...workflow, payload};
|
|
}
|
|
|
|
export default {
|
|
getAllWorkflows,
|
|
getWorkflow,
|
|
getWorkflowComponent,
|
|
getWorkflowsByCategory,
|
|
getWorkflowCategories,
|
|
buildWorkflowApiPayload,
|
|
serializeWorkflowPayload,
|
|
deserializeWorkflowPayload
|
|
};
|