From 70d5f9ad94136b502ab556b911faf544cec70748 Mon Sep 17 00:00:00 2001 From: daeyeon ko Date: Fri, 25 Oct 2024 18:21:18 +0900 Subject: [PATCH 01/15] test : test --- front/src/entities/workflow/api/index.ts | 63 +++- .../workflow/workflowEditor/model/types.ts | 2 + .../model/workflowEditorModel.ts | 30 +- .../designer/editor/model/editorProviders.ts | 2 +- .../designer/editor/ui/BeetleTaskEditor.vue | 26 +- .../designer/model/sequentialDesignerModel.ts | 8 +- .../designer/toolbox/model/toolboxSteps.ts | 2 +- .../designer/ui/SequentialDesigner.vue | 4 +- .../workflowEditor/ui/WorkflowEditor.vue | 318 +++++++----------- .../workflows/ui/WorkflowsPage.vue | 6 +- front/src/widgets/workflow/index.ts | 1 - .../widgets/workflow/workflowTool/index.ts | 3 - .../workflow/workflowTool/ui/WorkflowTool.vue | 40 --- 13 files changed, 228 insertions(+), 277 deletions(-) delete mode 100644 front/src/widgets/workflow/workflowTool/index.ts delete mode 100644 front/src/widgets/workflow/workflowTool/ui/WorkflowTool.vue diff --git a/front/src/entities/workflow/api/index.ts b/front/src/entities/workflow/api/index.ts index ad21d69f..5be87cc6 100644 --- a/front/src/entities/workflow/api/index.ts +++ b/front/src/entities/workflow/api/index.ts @@ -1,6 +1,15 @@ -import { IAxiosResponse, useAxiosPost } from '@/shared/libs'; -import { ITaskComponentResponse, IWorkflowResponse } from '../model/types'; +import { + IAxiosResponse, + RequestBodyWrapper, + useAxiosPost, +} from '@/shared/libs'; +import { + ITaskComponentResponse, + IWorkflow, + IWorkflowResponse, +} from '../model/types'; import { axiosInstance } from '@/shared/libs/api/instance'; +import { IMciRequestParams } from '@/entities/mci/api'; const GET_WORKFLOW_LIST = 'list-workflow'; const GET_WORKFLOW = 'get-workflow'; @@ -53,6 +62,56 @@ export function useUpdateWorkflow( ); } +export function useUpdateWorkflowV2( + wfId: string | null, + workflowData: IWorkflowResponse['data'] | null, + name: string | null, +) { + const requestBodyWrapper: Required< + Pick< + RequestBodyWrapper< + | { + wfId: string | null; + } + | { + data: IWorkflowResponse['data'] | null; + name: string | null; + } + >, + 'pathParams' | 'request' + > + > = { + pathParams: { + wfId: wfId, + }, + request: { + data: workflowData, + name: name, + }, + }; + + return useAxiosPost< + IAxiosResponse, + Required< + Pick< + RequestBodyWrapper< + | { + wfId: string | null; + } + | { + data: IWorkflowResponse['data'] | null; + name: string | null; + } + >, + 'pathParams' | 'request' + > + > + >(UPDATE_WORKFLOW, requestBodyWrapper); +} + +// Required< +// Pick>, 'pathParams'> +// > export function useRunWorkflow(wfId: string) { return useAxiosPost, any>(RUN_WORKFLOW, { pathParams: { diff --git a/front/src/features/workflow/workflowEditor/model/types.ts b/front/src/features/workflow/workflowEditor/model/types.ts index 4bb8a88d..f4ddb2e7 100644 --- a/front/src/features/workflow/workflowEditor/model/types.ts +++ b/front/src/features/workflow/workflowEditor/model/types.ts @@ -1,4 +1,5 @@ import { Step as _Step } from 'sequential-workflow-model'; +import { ITaskResponse } from '@/entities'; export interface Step extends _Step { sequence?: Step[]; @@ -8,6 +9,7 @@ export interface Step extends _Step { properties: { isDeletable: boolean; model?: object; + originalData?: ITaskResponse; }; } diff --git a/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts b/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts index 3793b6d1..53271db0 100644 --- a/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts +++ b/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts @@ -11,26 +11,17 @@ import { import getRandomId from '@/shared/utils/uuid'; import { toolboxSteps } from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts'; import { parseRequestBody } from '@/shared/utils/stringToObject'; -import { Sequence } from 'sequential-workflow-designer'; export function useWorkflowToolModel() { const workflowStore = useWorkflowStore(); const { defineTaskGroupStep, defineBettleTaskStep } = toolboxSteps(); - function getWorkflowToolData( - workflowId: string, - type: 'template' | 'data' = 'data', - ) { - let workflow; - if (type === 'template') { - workflow = workflowStore.getTemplateById(workflowId); - } else { - workflow = workflowStore.getWorkFlowById(workflowId); - } + function getWorkflowData(workflowId: string) { + return workflowStore.getWorkflowById(workflowId); + } - if (workflow) { - convertCicadaToDesignerFormData(workflow); - } + function getWorkflowTemplateData(workflowTemplateId: string) { + return workflowStore.getWorkflowTemplateById(workflowTemplateId); } function convertCicadaToDesignerFormData( @@ -81,9 +72,9 @@ export function useWorkflowToolModel() { function convertToDesignerTask(task: ITaskResponse): Step { const parsedString: object = parseRequestBody(task.request_body); - return defineBettleTaskStep(getRandomId(), task.name, 'task', { model: parsedString, + originalData: task, }); } @@ -146,10 +137,14 @@ export function useWorkflowToolModel() { } function convertToCicadaTask(step: Step) { + console.log(step); if (step.componentType === 'task') { return { name: step.name, - request_body: JSON.stringify(step.properties.model, null, 2), + request_body: JSON.stringify(step.properties.model), + path_params: step.properties.originalData?.path_params, + task_component: step.properties.originalData?.task_component, + dependencies: step.properties.originalData?.dependencies, }; } } @@ -161,7 +156,8 @@ export function useWorkflowToolModel() { } return { - getWorkflowToolData, + getWorkflowTemplateData, + getWorkflowData, convertCicadaToDesignerFormData, convertDesignerSequenceToCicada, }; diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts b/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts index 5d9c9f3b..d81dd6ea 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts +++ b/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts @@ -40,8 +40,8 @@ export function editorProviders() { { step }, { saveContext: e => { - console.log(e); step.properties.model = e; + stepContext.notifyPropertiesChanged(); }, }, editor, diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue b/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue index e4718087..63834806 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue +++ b/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue @@ -14,6 +14,7 @@ import Vue, { import { useInputModel } from '@/shared/hooks/input/useInputModel.ts'; import { useTaskEditorModel } from '@/features/workflow/workflowEditor/sequential/designer/editor/model/beetleTaskEditorModel.ts'; import BAccordion from '@/shared/ui/Input/Accordian/BAccordion.vue'; +import SequentialShortCut from '@/features/workflow/workflowEditor/sequential/designer/shortcut/ui/SequentialShortCut.vue'; interface IProps { step: { @@ -22,6 +23,7 @@ interface IProps { properties: { isDeletable: boolean; model?: object; + originalData: object; }; sequence: []; type: string; @@ -229,18 +231,18 @@ function handleClickOutside(event: MouseEvent) { - - - - - - - - - - - - + diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts b/front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts index a4afdef0..ffeea236 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts +++ b/front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts @@ -10,7 +10,6 @@ import { editorProviders } from '@/features/workflow/workflowEditor/sequential/d export function useSequentialDesignerModel(refs: any) { let designer: Designer | null = null; - const placeholder = refs.placeholder; const designerOptionsState: any = { id: '', @@ -115,6 +114,7 @@ export function useSequentialDesignerModel(refs: any) { getRandomId(), 'TaskGroup', 'taskGroup', + { model: {} }, ), ], }, @@ -174,15 +174,13 @@ export function useSequentialDesignerModel(refs: any) { function draw() { designer = Designer.create(placeholder, definition, configuration); - designer.onDefinitionChanged.subscribe(newDefinition => { - // ... - // console.log(newDefinition); - }); + designer.onDefinitionChanged.subscribe(newDefinition => {}); } function getDesigner() { return designer; } + return { designer, designerOptionsState, diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts b/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts index 7a7ca558..270bcce9 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts +++ b/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts @@ -42,7 +42,7 @@ export function toolboxSteps() { id: string, name: string, type: string, - properties: { model: object }, + properties: { model: object; originalData: any }, ): Step { return { componentType: 'task', diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue b/front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue index dfcbbe22..ab95d699 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue +++ b/front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue @@ -14,6 +14,7 @@ interface Step { properties: { isDeletable: boolean; model?: object; + originalData?: object; }; } @@ -42,7 +43,7 @@ onMounted(function () { }); }); -watch(props, () => { +watch(props.sequence, () => { sequentialDesignerModel.value.setDefaultSequence(props.sequence); sequentialDesignerModel.value.initDesigner(); sequentialDesignerModel.value.draw(); @@ -51,7 +52,6 @@ watch(props, () => { watch( () => props.trigger, nv => { - console.log(nv); if (nv) emit('getDesigner', sequentialDesignerModel.value.getDesigner()); }, { deep: true }, diff --git a/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue b/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue index 9a6de2da..61b30624 100644 --- a/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue +++ b/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue @@ -1,18 +1,20 @@ diff --git a/front/src/pages/workflowManagement/workflows/ui/WorkflowsPage.vue b/front/src/pages/workflowManagement/workflows/ui/WorkflowsPage.vue index f5c66cc4..df5a30db 100644 --- a/front/src/pages/workflowManagement/workflows/ui/WorkflowsPage.vue +++ b/front/src/pages/workflowManagement/workflows/ui/WorkflowsPage.vue @@ -5,11 +5,11 @@ import { WorkflowList, WorkflowDetail, WorkflowJsonViewer, - WorkflowTool, } from '@/widgets/workflow'; import { SimpleEditForm } from '@/widgets/layout'; import { useGetWorkflow, useUpdateWorkflow } from '@/entities'; import { showErrorMessage, showSuccessMessage } from '@/shared/utils'; +import WorkflowEditor from '@/features/workflow/workflowEditor/ui/WorkflowEditor.vue'; const getWorkflow = useGetWorkflow(null); const updateWorkflow = useUpdateWorkflow(null, null); @@ -219,9 +219,11 @@ async function handleUpdateWorkflow(updatedData: object) { @update:close-modal="e => (modalState.workflowJsonModal.open = e)" @update:api="handleUpdateWorkflow" /> - diff --git a/front/src/widgets/workflow/index.ts b/front/src/widgets/workflow/index.ts index 47f0d1b2..bbc8dda1 100644 --- a/front/src/widgets/workflow/index.ts +++ b/front/src/widgets/workflow/index.ts @@ -1,4 +1,3 @@ export * from './workflows'; export * from './workflowTemplates'; export * from './taskComponents'; -export * from './workflowTool'; diff --git a/front/src/widgets/workflow/workflowTool/index.ts b/front/src/widgets/workflow/workflowTool/index.ts deleted file mode 100644 index fa9fd4ba..00000000 --- a/front/src/widgets/workflow/workflowTool/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import WorkflowTool from './ui/WorkflowTool.vue'; - -export { WorkflowTool }; diff --git a/front/src/widgets/workflow/workflowTool/ui/WorkflowTool.vue b/front/src/widgets/workflow/workflowTool/ui/WorkflowTool.vue deleted file mode 100644 index e6480cf5..00000000 --- a/front/src/widgets/workflow/workflowTool/ui/WorkflowTool.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - From a853600b207c75b4efdb18c8f3d7e3eaa89430a2 Mon Sep 17 00:00:00 2001 From: daeyeon ko Date: Mon, 28 Oct 2024 16:18:00 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat=20:=20task=EC=9D=98=20request=5Fbody?= =?UTF-8?q?=EA=B0=80=20=EB=B9=84=EC=97=88=EC=9D=84=EC=8B=9C=20task=20compo?= =?UTF-8?q?nent=EC=9D=98=20request=5Fbody=20=EC=B0=B8=EC=A1=B0=20=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/src/entities/workflow/model/types.ts | 2 +- .../model/workflowEditorModel.ts | 72 +++++++++++++++++++ .../designer/editor/ui/BeetleTaskEditor.vue | 2 +- .../designer/toolbox/model/api/index.ts | 1 + .../designer/toolbox/model/toolboxModel.ts | 1 + .../workflowEditor/ui/WorkflowEditor.vue | 36 ++++++++-- .../layout/createForm/ui/CreateForm.vue | 2 +- 7 files changed, 108 insertions(+), 8 deletions(-) diff --git a/front/src/entities/workflow/model/types.ts b/front/src/entities/workflow/model/types.ts index 294f8751..bfb268af 100644 --- a/front/src/entities/workflow/model/types.ts +++ b/front/src/entities/workflow/model/types.ts @@ -14,7 +14,7 @@ export interface ITaskGroupResponse { task_groups?: Array; } export interface ITaskResponse { - dependencies: any; + dependencies: any[]; name: string; path_params: any; request_body: string; diff --git a/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts b/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts index 53271db0..142a3f8c 100644 --- a/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts +++ b/front/src/features/workflow/workflowEditor/model/workflowEditorModel.ts @@ -4,13 +4,16 @@ import { Step, } from '@/features/workflow/workflowEditor/model/types.ts'; import { + ITaskComponentResponse, ITaskGroupResponse, ITaskResponse, IWorkflow, + IWorkflowResponse, } from '@/entities/workflow/model/types.ts'; import getRandomId from '@/shared/utils/uuid'; import { toolboxSteps } from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts'; import { parseRequestBody } from '@/shared/utils/stringToObject'; +import { ITaskInfoResponse } from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/api'; export function useWorkflowToolModel() { const workflowStore = useWorkflowStore(); @@ -26,6 +29,7 @@ export function useWorkflowToolModel() { function convertCicadaToDesignerFormData( workflow: IWorkflow, + taskComponentList: Array, ): IWorkFlowDesignerFormData { const sequence: Step[] = []; @@ -46,6 +50,7 @@ export function useWorkflowToolModel() { if (currentTaskGroup.tasks) { for (const task of currentTaskGroup.tasks) { + mappingWorkflowTaskComponent(task, taskComponentList); const currentDesignerTask = convertToDesignerTask(task); currentDesignerTaskGroup.sequence!.push(currentDesignerTask); } @@ -155,10 +160,77 @@ export function useWorkflowToolModel() { }); } + function mappingWorkflowTaskComponent( + task: ITaskResponse, + taskComponentList: Array, + ) { + if (task.request_body === '') { + task.request_body = + taskComponentList.find( + taskComponent => task.task_component === taskComponent.name, + )?.data.options.request_body ?? ''; + } + } + + function designerFormDataReordering(sequence: Step[]) { + console.log(sequence); + const newSequence: Step[] = []; + const taskGroupQueue: Step[] = []; + + sequence.forEach(step => { + if (step.componentType === 'container') { + taskGroupQueue.push(step); + } + }); + + while (taskGroupQueue.length > 0) { + const rootTaskGroup = taskGroupQueue.pop()!; + const newTaskGroupSequence: Step[] = []; + const queue: Step[] = []; + + const rootStep = rootTaskGroup.sequence?.find( + step => step.properties.originalData?.dependencies.length === 0, + ); + + if (rootStep) { + queue.push(rootStep); + newTaskGroupSequence.push(rootStep); + } + + while (queue.length > 0) { + const dependencyTask = queue.pop()!; + + const targetTask = rootTaskGroup.sequence?.find( + step => + dependencyTask.name === + step.properties.originalData?.dependencies[0], + ); + + if (targetTask) { + queue.push(targetTask); + newTaskGroupSequence.push(targetTask); + } + + const taskGroup = rootTaskGroup.sequence?.find( + step => step.componentType === 'container', + ); + + if (taskGroup) { + taskGroupQueue.push(taskGroup); + } + } + rootTaskGroup.sequence = newTaskGroupSequence; + newSequence.push(rootTaskGroup); + } + + return newSequence; + } + return { getWorkflowTemplateData, getWorkflowData, convertCicadaToDesignerFormData, convertDesignerSequenceToCicada, + designerFormDataReordering, }; } diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue b/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue index 63834806..9a7f70b1 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue +++ b/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue @@ -33,7 +33,7 @@ interface IProps { const props = defineProps(); const emit = defineEmits(['saveContext']); const taskEditorModel = useTaskEditorModel(); - +console.log(props.step.properties.originalData.task_component); const shortCutModel = ref({ open: false, xPos: 0, diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/api/index.ts b/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/api/index.ts index e3ec274c..ebfa92d1 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/api/index.ts +++ b/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/api/index.ts @@ -9,6 +9,7 @@ export interface ITaskInfoResponse { data: { options: { request_body: string; + path_params: object; }; }; } diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts b/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts index 4506957b..d7cf3f1b 100644 --- a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts +++ b/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts @@ -30,6 +30,7 @@ export function useSequentialToolboxModel() { 'task', { model: parsedString, + originalData: res, }, ), ); diff --git a/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue b/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue index 61b30624..fe069a9f 100644 --- a/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue +++ b/front/src/features/workflow/workflowEditor/ui/WorkflowEditor.vue @@ -10,11 +10,17 @@ import { useWorkflowToolModel } from '@/features/workflow/workflowEditor/model/w import { useInputModel } from '@/shared/hooks/input/useInputModel.ts'; import { onBeforeMount, reactive, ref, Ref } from 'vue'; import { Step } from '@/features/workflow/workflowEditor/model/types.ts'; -import { IWorkflow, useUpdateWorkflow, useUpdateWorkflowV2 } from '@/entities'; +import { + IWorkflow, + useGetWorkflowTemplateList, + useUpdateWorkflow, + useUpdateWorkflowV2, +} from '@/entities'; import { Designer } from 'sequential-workflow-designer'; import SequentialDesigner from '@/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue'; import { showErrorMessage, showSuccessMessage } from '@/shared/utils'; import { Definition } from 'sequential-workflow-model'; +import { getTaskComponentList } from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/api'; interface IProps { wftId: string; @@ -29,11 +35,23 @@ const workflowName = useInputModel(''); const workflowDescription = useInputModel(''); const workflowData = ref(); const sequentialSequence: Ref = ref([]); + +const resWorkflowTemplateData = useGetWorkflowTemplateList(); +const resTaskComponentList = getTaskComponentList(); const resUpdateWorkflow = useUpdateWorkflowV2(null, null, null); +const loading = ref(true); + onBeforeMount(function () { - loadWorkflow(); - loadSequence(); + Promise.all([ + resWorkflowTemplateData.execute(), + resTaskComponentList.execute(), + ]).then(() => { + loadWorkflow(); + loadSequence(); + reorderingSequence(); + loading.value = false; + }); }); function loadWorkflow() { @@ -52,10 +70,17 @@ function loadSequence() { sequentialSequence.value = workflowToolModel.convertCicadaToDesignerFormData( workflowData.value, + resTaskComponentList.data.value?.responseData!, ).sequence; } } +function reorderingSequence() { + sequentialSequence.value = workflowToolModel.designerFormDataReordering( + sequentialSequence.value, + ); +} + const trigger = reactive({ value: false }); function getCicadaData(designer: Designer | null): IWorkflow { @@ -127,10 +152,11 @@ function handleSave() { class="page-modal-layout" title="Workflow Tool" :need-widget-layout="false" + :loading="loading" @update:modal-state="handleCancel" > -