From a698f8c6a5c8f4aa827763119f2269545ef70d96 Mon Sep 17 00:00:00 2001 From: "Shaun A. Noordin" Date: Thu, 6 Jun 2024 16:00:19 +0100 Subject: [PATCH] Pages Editor: add Copy Page feature (#7102) * pages-editor-pt24: add Copy Step/Page button * TasksPage: copyStep now copies the tasks belonging to the step * TasksPage: Copy Page now fully copys step and its tasks --- .../components/TasksPage/TasksPage.jsx | 36 +++++++++++++++++++ .../components/StepItem/StepItem.jsx | 15 ++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/app/pages/lab-pages-editor/components/TasksPage/TasksPage.jsx b/app/pages/lab-pages-editor/components/TasksPage/TasksPage.jsx index 1704f8760d..1a14818b61 100644 --- a/app/pages/lab-pages-editor/components/TasksPage/TasksPage.jsx +++ b/app/pages/lab-pages-editor/components/TasksPage/TasksPage.jsx @@ -147,6 +147,41 @@ export default function TasksPage() { update({ steps }); } + function copyStep(stepIndex) { + if (!workflow) return; + const { steps, tasks } = workflow; + const [ stepKey, stepBody ] = steps[stepIndex] || []; + + const confirmed = confirm(`Copy Page ${stepKey}?`); + if (!confirmed) return; + + const newSteps = steps.slice(); // Copy Steps. + const newTasks = tasks ? { ...tasks } : {}; // Copy Tasks. + + // Duplicate tasks of the Step we want to copy. + // Each task needs a new task key. + const tasksToCopy = stepBody?.taskKeys || []; + const newTaskKeys = []; + tasksToCopy.forEach(originalKey => { + const newTaskKey = getNewTaskKey(newTasks); + newTaskKeys.push(newTaskKey); + const newTask = structuredClone(tasks[originalKey]); // Copy. + newTasks[newTaskKey] = newTask; + }) + + // Duplicate the Step we want. It needs a new step key. + const newStepKey = getNewStepKey(newSteps); + const newStep = [ newStepKey, { ...stepBody, taskKeys: newTaskKeys } ]; + newSteps.push(newStep); + + // cleanedupTasksAndSteps() will also remove tasks not associated with any step. + const cleanedTasksAndSteps = cleanupTasksAndSteps(newTasks, newSteps); + if (linkStepsInWorkflow) { + cleanedTasksAndSteps.steps = linkStepsInWorkflow(cleanedTasksAndSteps.steps, cleanedTasksAndSteps.tasks); + } + update(cleanedTasksAndSteps); + } + function deleteStep(stepIndex) { if (!workflow) return; const { steps, tasks } = workflow; @@ -290,6 +325,7 @@ export default function TasksPage() { activeDragItem={activeDragItem} allSteps={workflow.steps} allTasks={workflow.tasks} + copyStep={copyStep} deleteStep={deleteStep} moveStep={moveStep} isLinearWorkflow={isLinearWorkflow} diff --git a/app/pages/lab-pages-editor/components/TasksPage/components/StepItem/StepItem.jsx b/app/pages/lab-pages-editor/components/TasksPage/components/StepItem/StepItem.jsx index 7830230713..73542a5f5d 100644 --- a/app/pages/lab-pages-editor/components/TasksPage/components/StepItem/StepItem.jsx +++ b/app/pages/lab-pages-editor/components/TasksPage/components/StepItem/StepItem.jsx @@ -21,10 +21,11 @@ function StepItem({ activeDragItem = -1, allSteps, allTasks, + copyStep = DEFAULT_HANDLER, deleteStep = DEFAULT_HANDLER, + isLinearWorkflow = false, moveStep = DEFAULT_HANDLER, openEditStepDialog = DEFAULT_HANDLER, - isLinearWorkflow = false, setActiveDragItem = DEFAULT_HANDLER, step, stepIndex, @@ -37,6 +38,10 @@ function StepItem({ const isLastItem = stepIndex === allSteps.length - 1; const taskKeys = stepBody.taskKeys || []; + function doCopy() { + copyStep(stepIndex); + } + function doDelete() { deleteStep(stepIndex); } @@ -109,7 +114,12 @@ function StepItem({ > -