diff --git a/spiffworkflow-frontend/src/components/ErrorDisplay.tsx b/spiffworkflow-frontend/src/components/ErrorDisplay.tsx index 40abec5d..67e6e18d 100644 --- a/spiffworkflow-frontend/src/components/ErrorDisplay.tsx +++ b/spiffworkflow-frontend/src/components/ErrorDisplay.tsx @@ -1,6 +1,10 @@ import { Notification } from './Notification'; import useAPIError from '../hooks/UseApiError'; -import { ErrorForDisplay } from '../interfaces'; +import { + ErrorForDisplay, + ProcessInstanceEventErrorDetail, + ProcessInstanceLogEntry, +} from '../interfaces'; function errorDetailDisplay( errorObject: any, @@ -19,6 +23,23 @@ function errorDetailDisplay( return null; } +export const errorForDisplayFromProcessInstanceErrorDetail = ( + processInstanceEvent: ProcessInstanceLogEntry, + processInstanceErrorEventDetail: ProcessInstanceEventErrorDetail +) => { + const errorForDisplay: ErrorForDisplay = { + message: processInstanceErrorEventDetail.message, + messageClassName: 'failure-string', + task_name: processInstanceEvent.task_definition_name, + task_id: processInstanceEvent.task_definition_identifier, + line_number: processInstanceErrorEventDetail.task_line_number, + error_line: processInstanceErrorEventDetail.task_line_contents, + task_trace: processInstanceErrorEventDetail.task_trace, + stacktrace: processInstanceErrorEventDetail.stacktrace, + }; + return errorForDisplay; +}; + export const childrenForErrorObject = (errorObject: ErrorForDisplay) => { let sentryLinkTag = null; if (errorObject.sentry_link) { diff --git a/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx b/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx index 6cf486ed..ad583d92 100644 --- a/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx +++ b/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx @@ -66,10 +66,7 @@ import { usePermissionFetcher } from '../hooks/PermissionService'; type OwnProps = { processModelId: string; diagramType: string; - readyOrWaitingProcessInstanceTasks?: Task[] | null; - completedProcessInstanceTasks?: Task[] | null; - cancelledProcessInstanceTasks?: Task[] | null; - erroredProcessInstanceTasks?: Task[] | null; + tasks?: Task[] | null; saveDiagram?: (..._args: any[]) => any; onDeleteFile?: (..._args: any[]) => any; isPrimaryFile?: boolean; @@ -94,10 +91,7 @@ type OwnProps = { export default function ReactDiagramEditor({ processModelId, diagramType, - readyOrWaitingProcessInstanceTasks, - completedProcessInstanceTasks, - cancelledProcessInstanceTasks, - erroredProcessInstanceTasks, + tasks, saveDiagram, onDeleteFile, isPrimaryFile, @@ -420,56 +414,29 @@ export default function ReactDiagramEditor({ // highlighting a field // Option 3 at: // https://github.com/bpmn-io/bpmn-js-examples/tree/master/colors - if (readyOrWaitingProcessInstanceTasks) { + if (tasks) { const bpmnProcessIdentifiers = getBpmnProcessIdentifiers( canvas.getRootElement() ); - readyOrWaitingProcessInstanceTasks.forEach((readyOrWaitingBpmnTask) => { - highlightBpmnIoElement( - canvas, - readyOrWaitingBpmnTask, - 'active-task-highlight', - bpmnProcessIdentifiers - ); - }); - } - if (completedProcessInstanceTasks) { - const bpmnProcessIdentifiers = getBpmnProcessIdentifiers( - canvas.getRootElement() - ); - completedProcessInstanceTasks.forEach((completedTask) => { - highlightBpmnIoElement( - canvas, - completedTask, - 'completed-task-highlight', - bpmnProcessIdentifiers - ); - }); - } - if (cancelledProcessInstanceTasks) { - const bpmnProcessIdentifiers = getBpmnProcessIdentifiers( - canvas.getRootElement() - ); - cancelledProcessInstanceTasks.forEach((cancelledTask) => { - highlightBpmnIoElement( - canvas, - cancelledTask, - 'cancelled-task-highlight', - bpmnProcessIdentifiers - ); - }); - } - if (erroredProcessInstanceTasks) { - const bpmnProcessIdentifiers = getBpmnProcessIdentifiers( - canvas.getRootElement() - ); - erroredProcessInstanceTasks.forEach((erroredTask) => { - highlightBpmnIoElement( - canvas, - erroredTask, - 'errored-task-highlight', - bpmnProcessIdentifiers - ); + tasks.forEach((task: Task) => { + let className = ''; + if (task.state === 'COMPLETED') { + className = 'completed-task-highlight'; + } else if (task.state === 'READY' || task.state === 'WAITING') { + className = 'active-task-highlight'; + } else if (task.state === 'CANCELLED') { + className = 'cancelled-task-highlight'; + } else if (task.state === 'ERROR') { + className = 'errored-task-highlight'; + } + if (className) { + highlightBpmnIoElement( + canvas, + task, + className, + bpmnProcessIdentifiers + ); + } }); } } @@ -549,10 +516,8 @@ export default function ReactDiagramEditor({ diagramType, diagramXML, diagramXMLString, - readyOrWaitingProcessInstanceTasks, - completedProcessInstanceTasks, - cancelledProcessInstanceTasks, fileName, + tasks, performingXmlUpdates, processModelId, url, diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index 022469e6..bdbc9251 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -37,6 +37,7 @@ export interface EventDefinition { message_var?: string; } +// TODO: merge with ProcessInstanceTask export interface Task { id: number; guid: string; @@ -55,13 +56,6 @@ export interface Task { event_definition?: EventDefinition; } -export interface TaskIds { - completed: Task[]; - readyOrWaiting: Task[]; - cancelled: Task[]; - errored: Task[]; -} - export interface ProcessInstanceTask { id: string; task_id: string; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx index dac849ac..02100e81 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx @@ -32,14 +32,16 @@ import { import HttpService from '../services/HttpService'; import { useUriListForPermissions } from '../hooks/UriListForPermissions'; import { - ErrorForDisplay, PermissionsToCheck, ProcessInstanceEventErrorDetail, ProcessInstanceLogEntry, } from '../interfaces'; import Filters from '../components/Filters'; import { usePermissionFetcher } from '../hooks/PermissionService'; -import { childrenForErrorObject } from '../components/ErrorDisplay'; +import { + childrenForErrorObject, + errorForDisplayFromProcessInstanceErrorDetail, +} from '../components/ErrorDisplay'; type OwnProps = { variant: string; @@ -158,17 +160,12 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) { ); if (eventErrorDetails) { - const errorForDisplay: ErrorForDisplay = { - message: eventErrorDetails.message, - messageClassName: 'failure-string', - task_name: eventForModal.task_definition_name, - task_id: eventForModal.task_definition_identifier, - line_number: eventErrorDetails.task_line_number, - error_line: eventErrorDetails.task_line_contents, - task_trace: eventErrorDetails.task_trace, - stacktrace: eventErrorDetails.stacktrace, - }; + const errorForDisplay = errorForDisplayFromProcessInstanceErrorDetail( + eventForModal, + eventErrorDetails + ); const errorChildren = childrenForErrorObject(errorForDisplay); + // eslint-disable-next-line react/jsx-no-useless-fragment errorMessageTag = <>{errorChildren}; } return ( diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 263631ea..170673bf 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -47,7 +47,6 @@ import { ProcessInstanceMetadata, Task, TaskDefinitionPropertiesJson, - TaskIds, } from '../interfaces'; import { usePermissionFetcher } from '../hooks/PermissionService'; import ProcessInstanceClass from '../classes/ProcessInstanceClass'; @@ -230,30 +229,6 @@ export default function ProcessInstanceShow({ variant }: OwnProps) { }); }; - const getTaskIds = () => { - const taskIds: TaskIds = { - completed: [], - readyOrWaiting: [], - cancelled: [], - errored: [], - }; - if (tasks) { - tasks.forEach(function getUserTasksElement(task: Task) { - if (task.state === 'COMPLETED') { - taskIds.completed.push(task); - } else if (task.state === 'READY' || task.state === 'WAITING') { - taskIds.readyOrWaiting.push(task); - } else if (task.state === 'CANCELLED') { - taskIds.cancelled.push(task); - } else if (task.state === 'ERROR') { - taskIds.errored.push(task); - } - return null; - }); - } - return taskIds; - }; - const currentToTaskGuid = () => { if (taskToTimeTravelTo) { return taskToTimeTravelTo.guid; @@ -1101,7 +1076,6 @@ export default function ProcessInstanceShow({ variant }: OwnProps) { }; if (processInstance && (tasks || tasksCallHadError)) { - const taskIds = getTaskIds(); const processModelId = unModifyProcessIdentifierForPathParam( params.process_model_id ? params.process_model_id : '' ); @@ -1159,10 +1133,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) { processModelId={processModelId || ''} diagramXML={processInstance.bpmn_xml_file_contents || ''} fileName={processInstance.bpmn_xml_file_contents || ''} - readyOrWaitingProcessInstanceTasks={taskIds.readyOrWaiting} - completedProcessInstanceTasks={taskIds.completed} - cancelledProcessInstanceTasks={taskIds.cancelled} - erroredProcessInstanceTasks={taskIds.errored} + tasks={tasks} diagramType="readonly" onElementClick={handleClickedDiagramTask} />