Skip to content

Commit

Permalink
Pages Editor: add Copy Page feature (zooniverse#7102)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
shaunanoordin authored Jun 6, 2024
1 parent d5416cb commit a698f8c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
36 changes: 36 additions & 0 deletions app/pages/lab-pages-editor/components/TasksPage/TasksPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -290,6 +325,7 @@ export default function TasksPage() {
activeDragItem={activeDragItem}
allSteps={workflow.steps}
allTasks={workflow.tasks}
copyStep={copyStep}
deleteStep={deleteStep}
moveStep={moveStep}
isLinearWorkflow={isLinearWorkflow}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -37,6 +38,10 @@ function StepItem({
const isLastItem = stepIndex === allSteps.length - 1;
const taskKeys = stepBody.taskKeys || [];

function doCopy() {
copyStep(stepIndex);
}

function doDelete() {
deleteStep(stepIndex);
}
Expand Down Expand Up @@ -109,7 +114,12 @@ function StepItem({
>
<DeleteIcon />
</button>
<button aria-label={`Copy Page/Step ${stepKey}`} className="disabled plain" type="button">
<button
aria-label={`Copy Page/Step ${stepKey}`}
className="plain"
onClick={doCopy}
type="button"
>
<CopyIcon />
</button>
<button
Expand Down Expand Up @@ -164,6 +174,7 @@ StepItem.propTypes = {
activeDragItem: PropTypes.number,
allSteps: PropTypes.array,
allTasks: PropTypes.object,
copyStep: PropTypes.func,
deleteStep: PropTypes.func,
isLinearWorkflow: PropTypes.bool,
moveStep: PropTypes.func,
Expand Down

0 comments on commit a698f8c

Please sign in to comment.