diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index 0ee6db3e..1e17e32c 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -744,7 +744,7 @@ export default function ProcessInstanceListTable({ undefined, paginationQueryParamPrefix ); - page = 1; // Reset page back to 0 + page = 1; const newReportMetadata = getNewReportMetadataBasedOnPageWidgets(); setListHasBeenFiltered(true); diff --git a/spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx b/spiffworkflow-frontend/src/components/ProcessInterstitial.tsx similarity index 82% rename from spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx rename to spiffworkflow-frontend/src/components/ProcessInterstitial.tsx index 368c3285..7dcc3326 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInterstitial.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { fetchEventSource } from '@microsoft/fetch-event-source'; // @ts-ignore import { Loading, Grid, Column, Button } from '@carbon/react'; @@ -7,53 +7,59 @@ import { BACKEND_BASE_URL } from '../config'; import { getBasicHeaders } from '../services/HttpService'; // @ts-ignore -import InstructionsForEndUser from '../components/InstructionsForEndUser'; -import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; +import InstructionsForEndUser from './InstructionsForEndUser'; +import ProcessBreadcrumb from './ProcessBreadcrumb'; import { ProcessInstance, ProcessInstanceTask } from '../interfaces'; import useAPIError from '../hooks/UseApiError'; -export default function ProcessInterstitial() { +type OwnProps = { + processInstanceId: number; + modifiedProcessModelIdentifier: string; + allowRedirect: boolean; +}; + +export default function ProcessInterstitial({ + processInstanceId, + modifiedProcessModelIdentifier, + allowRedirect, +}: OwnProps) { const [data, setData] = useState([]); const [lastTask, setLastTask] = useState(null); + const [state, setState] = useState('RUNNING'); const [processInstance, setProcessInstance] = useState(null); - const [state, setState] = useState('RUNNING'); - const params = useParams(); + const processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${modifiedProcessModelIdentifier}`; const navigate = useNavigate(); const userTasks = useMemo(() => { return ['User Task', 'Manual Task']; }, []); const { addError } = useAPIError(); - const processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${params.modified_process_model_identifier}`; - useEffect(() => { - fetchEventSource( - `${BACKEND_BASE_URL}/tasks/${params.process_instance_id}`, - { - headers: getBasicHeaders(), - onmessage(ev) { - const retValue = JSON.parse(ev.data); - if (retValue.type === 'error') { - addError(retValue.error); - } else if (retValue.type === 'task') { - setData((prevData) => [retValue.task, ...prevData]); - setLastTask(retValue.task); - } else if (retValue.type === 'unrunnable_instance') { - setProcessInstance(retValue.unrunnable_instance); - } - }, - onclose() { - setState('CLOSED'); - }, - } - ); + fetchEventSource(`${BACKEND_BASE_URL}/tasks/${processInstanceId}`, { + headers: getBasicHeaders(), + onmessage(ev) { + const retValue = JSON.parse(ev.data); + if (retValue.type === 'error') { + addError(retValue.error); + } else if (retValue.type === 'task') { + setData((prevData) => [retValue.task, ...prevData]); + setLastTask(retValue.task); + } else if (retValue.type === 'unrunnable_instance') { + setProcessInstance(retValue.unrunnable_instance); + } + }, + onclose() { + setState('CLOSED'); + }, + }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // it is critical to only run this once. const shouldRedirect = useCallback( (myTask: ProcessInstanceTask): boolean => { return ( + allowRedirect && !processInstance && myTask && myTask.can_complete && @@ -166,6 +172,9 @@ export default function ProcessInterstitial() { if (shouldRedirect(myTask)) { return
Redirecting you to the next task now ...
; } + if (myTask && myTask.can_complete && userTasks.includes(myTask.type)) { + return `The task ${myTask.title} is ready for you to complete.`; + } if (myTask.error_message) { return
{myTask.error_message}
; } @@ -201,8 +210,8 @@ export default function ProcessInterstitial() { linkLastItem: true, }, [ - `Process Instance: ${params.process_instance_id}`, - `${processInstanceShowPageBaseUrl}/${params.process_instance_id}`, + `Process Instance: ${processInstanceId}`, + `${processInstanceShowPageBaseUrl}/${processInstanceId}`, ], ]} /> diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index ac0980a2..e9c5f0df 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -23,6 +23,7 @@ export interface RecentProcessModel { export interface TaskPropertiesJson { parent: string; + last_state_change: number; } export interface TaskDefinitionPropertiesJson { diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 8650cc00..cfb9a33a 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -53,6 +53,7 @@ import { usePermissionFetcher } from '../hooks/PermissionService'; import ProcessInstanceClass from '../classes/ProcessInstanceClass'; import TaskListTable from '../components/TaskListTable'; import useAPIError from '../hooks/UseApiError'; +import ProcessInterstitial from "../components/ProcessInterstitial"; type OwnProps = { variant: string; @@ -1092,23 +1093,9 @@ export default function ProcessInstanceShow({ variant }: OwnProps) { return ( <> - - -

- Process Instance Id: {processInstance.id} -

- {buttonIcons()} -
+ + {buttonIcons()} +


diff --git a/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx b/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx new file mode 100644 index 00000000..31b59337 --- /dev/null +++ b/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { useParams } from 'react-router-dom'; +// @ts-ignore +import ProcessInterstitial from '../components/ProcessInterstitial'; + +export default function ProcessInterstitialPage() { + const params = useParams(); + // @ts-ignore + return ( + + ); +} diff --git a/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx b/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx index dc8a1d66..001a8ec2 100644 --- a/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx @@ -1,13 +1,13 @@ import { Route, Routes } from 'react-router-dom'; // @ts-ignore -import ProcessInterstitial from './ProcessInterstitial'; +import ProcessInterstitialPage from './ProcessInterstitialPage'; export default function ProcessRoutes() { return ( } + element={} /> );