Squashed 'spiffworkflow-frontend/' changes from 647a428c7..8afeb64f1
8afeb64f1 Front end changes to allow editing task data (#4) git-subtree-dir: spiffworkflow-frontend git-subtree-split: 8afeb64f153ed1d721a18113d5196dd9644fa0a2
This commit is contained in:
parent
3a0b6f634c
commit
fb0ad7bfc5
|
@ -1,4 +1,5 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
import Editor from '@monaco-editor/react';
|
||||||
import { useParams, useNavigate, Link } from 'react-router-dom';
|
import { useParams, useNavigate, Link } from 'react-router-dom';
|
||||||
import { Button, Modal, Stack } from 'react-bootstrap';
|
import { Button, Modal, Stack } from 'react-bootstrap';
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
@ -6,6 +7,7 @@ import HttpService from '../services/HttpService';
|
||||||
import ReactDiagramEditor from '../components/ReactDiagramEditor';
|
import ReactDiagramEditor from '../components/ReactDiagramEditor';
|
||||||
import { convertSecondsToFormattedDate } from '../helpers';
|
import { convertSecondsToFormattedDate } from '../helpers';
|
||||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||||
|
import ErrorContext from '../contexts/ErrorContext';
|
||||||
|
|
||||||
export default function ProcessInstanceShow() {
|
export default function ProcessInstanceShow() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -14,6 +16,10 @@ export default function ProcessInstanceShow() {
|
||||||
const [processInstance, setProcessInstance] = useState(null);
|
const [processInstance, setProcessInstance] = useState(null);
|
||||||
const [tasks, setTasks] = useState<Array<object> | null>(null);
|
const [tasks, setTasks] = useState<Array<object> | null>(null);
|
||||||
const [taskToDisplay, setTaskToDisplay] = useState<object | null>(null);
|
const [taskToDisplay, setTaskToDisplay] = useState<object | null>(null);
|
||||||
|
const [taskDataToDisplay, setTaskDataToDisplay] = useState<string>('');
|
||||||
|
const [editingTaskData, setEditingTaskData] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const setErrorMessage = (useContext as any)(ErrorContext)[1];
|
||||||
|
|
||||||
const navigateToProcessInstances = (_result: any) => {
|
const navigateToProcessInstances = (_result: any) => {
|
||||||
navigate(
|
navigate(
|
||||||
|
@ -168,19 +174,29 @@ export default function ProcessInstanceShow() {
|
||||||
return <div />;
|
return <div />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initializeTaskDataToDisplay = (task: any) => {
|
||||||
|
if (task == null) {
|
||||||
|
setTaskDataToDisplay('');
|
||||||
|
} else {
|
||||||
|
setTaskDataToDisplay(JSON.stringify(task.data, null, 2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleClickedDiagramTask = (shapeElement: any) => {
|
const handleClickedDiagramTask = (shapeElement: any) => {
|
||||||
if (tasks) {
|
if (tasks) {
|
||||||
const matchingTask = tasks.find(
|
const matchingTask: any = tasks.find(
|
||||||
(task: any) => task.name === shapeElement.id
|
(task: any) => task.name === shapeElement.id
|
||||||
);
|
);
|
||||||
if (matchingTask) {
|
if (matchingTask) {
|
||||||
setTaskToDisplay(matchingTask);
|
setTaskToDisplay(matchingTask);
|
||||||
|
initializeTaskDataToDisplay(matchingTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTaskDataDisplayClose = () => {
|
const handleTaskDataDisplayClose = () => {
|
||||||
setTaskToDisplay(null);
|
setTaskToDisplay(null);
|
||||||
|
initializeTaskDataToDisplay(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTaskById = (taskId: string) => {
|
const getTaskById = (taskId: string) => {
|
||||||
|
@ -211,12 +227,57 @@ export default function ProcessInstanceShow() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const taskDataDisplayArea = () => {
|
const canEditTaskData = (task: any) => {
|
||||||
const taskToUse: any = taskToDisplay;
|
return task.state === 'READY';
|
||||||
if (taskToDisplay) {
|
};
|
||||||
let createScriptUnitTestElement = null;
|
|
||||||
if (taskToUse.type === 'Script Task') {
|
const cancelEditingTaskData = () => {
|
||||||
createScriptUnitTestElement = (
|
setEditingTaskData(false);
|
||||||
|
initializeTaskDataToDisplay(taskToDisplay);
|
||||||
|
setErrorMessage(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const taskDataStringToObject = (dataString: string) => {
|
||||||
|
return JSON.parse(dataString);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveTaskDataResult = (_: any) => {
|
||||||
|
setEditingTaskData(false);
|
||||||
|
const dataObject = taskDataStringToObject(taskDataToDisplay);
|
||||||
|
const taskToDisplayCopy = { ...taskToDisplay, data: dataObject }; // spread operator
|
||||||
|
setTaskToDisplay(taskToDisplayCopy);
|
||||||
|
refreshPage();
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveTaskDataFailure = (result: any) => {
|
||||||
|
setErrorMessage({ message: result.toString() });
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveTaskData = () => {
|
||||||
|
if (!taskToDisplay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setErrorMessage(null);
|
||||||
|
|
||||||
|
// taskToUse is copy of taskToDisplay, with taskDataToDisplay in data attribute
|
||||||
|
const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay };
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/process-instances/${params.process_instance_id}/task/${taskToUse.id}/update`,
|
||||||
|
httpMethod: 'POST',
|
||||||
|
successCallback: saveTaskDataResult,
|
||||||
|
failureCallback: saveTaskDataFailure,
|
||||||
|
postBody: {
|
||||||
|
new_task_data: taskToUse.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const taskDataButtons = (task: any) => {
|
||||||
|
const buttons = [];
|
||||||
|
|
||||||
|
if (task.type === 'Script Task') {
|
||||||
|
buttons.push(
|
||||||
<Button
|
<Button
|
||||||
data-qa="create-script-unit-test-button"
|
data-qa="create-script-unit-test-button"
|
||||||
onClick={createScriptUnitTest}
|
onClick={createScriptUnitTest}
|
||||||
|
@ -225,15 +286,68 @@ export default function ProcessInstanceShow() {
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (canEditTaskData(task)) {
|
||||||
|
if (editingTaskData) {
|
||||||
|
buttons.push(
|
||||||
|
<Button
|
||||||
|
data-qa="create-script-unit-test-button"
|
||||||
|
onClick={saveTaskData}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
buttons.push(
|
||||||
|
<Button
|
||||||
|
data-qa="create-script-unit-test-button"
|
||||||
|
onClick={cancelEditingTaskData}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
buttons.push(
|
||||||
|
<Button
|
||||||
|
data-qa="create-script-unit-test-button"
|
||||||
|
onClick={() => setEditingTaskData(true)}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
};
|
||||||
|
|
||||||
|
const taskDataContainer = () => {
|
||||||
|
return editingTaskData ? (
|
||||||
|
<Editor
|
||||||
|
height={600}
|
||||||
|
width="auto"
|
||||||
|
defaultLanguage="json"
|
||||||
|
defaultValue={taskDataToDisplay}
|
||||||
|
onChange={(value) => setTaskDataToDisplay(value || '')}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<pre>{taskDataToDisplay}</pre>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const taskDataDisplayArea = () => {
|
||||||
|
const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay };
|
||||||
|
if (taskToDisplay) {
|
||||||
return (
|
return (
|
||||||
<Modal show={!!taskToUse} onHide={handleTaskDataDisplayClose}>
|
<Modal show={!!taskToUse} onHide={handleTaskDataDisplayClose}>
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title>
|
<Modal.Title>
|
||||||
|
<Stack direction="horizontal" gap={2}>
|
||||||
{taskToUse.name} ({taskToUse.type}): {taskToUse.state}
|
{taskToUse.name} ({taskToUse.type}): {taskToUse.state}
|
||||||
{createScriptUnitTestElement}
|
{taskDataButtons(taskToUse)}
|
||||||
|
</Stack>
|
||||||
</Modal.Title>
|
</Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<pre>{JSON.stringify(taskToUse.data, null, 2)}</pre>
|
{taskDataContainer()}
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue