From 0ebab2884b6e11c12abe40a87e79aa29f9046c47 Mon Sep 17 00:00:00 2001 From: danfunk Date: Wed, 24 May 2023 15:24:33 -0400 Subject: [PATCH] ProcessInterstitial is now a component, and a page. The component is included into both the Interstitial PAge and the Process Instance Show page. Fixed routes for interstitial to align with those of the TaskShow page (variants are now accepted and passed through) Removed the View button completely. --- spiffworkflow-frontend/src/App.tsx | 2 - .../components/ProcessInstanceListTable.tsx | 26 ++--- .../src/components/ProcessInstanceRun.tsx | 2 +- .../src/components/ProcessInterstitial.tsx | 105 +++++++----------- .../src/routes/AdminRoutes.tsx | 9 ++ .../src/routes/ProcessInstanceShow.tsx | 27 ++++- .../src/routes/ProcessInterstitialPage.tsx | 41 +++++-- .../src/routes/ProcessRoutes.tsx | 14 --- .../src/routes/TaskShow.tsx | 2 +- 9 files changed, 120 insertions(+), 108 deletions(-) delete mode 100644 spiffworkflow-frontend/src/routes/ProcessRoutes.tsx diff --git a/spiffworkflow-frontend/src/App.tsx b/spiffworkflow-frontend/src/App.tsx index cddc30615..97d14fcc8 100644 --- a/spiffworkflow-frontend/src/App.tsx +++ b/spiffworkflow-frontend/src/App.tsx @@ -10,7 +10,6 @@ import HomePageRoutes from './routes/HomePageRoutes'; import About from './routes/About'; import ErrorBoundary from './components/ErrorBoundary'; import AdminRoutes from './routes/AdminRoutes'; -import ProcessRoutes from './routes/ProcessRoutes'; import { AbilityContext } from './contexts/Can'; import UserService from './services/UserService'; @@ -41,7 +40,6 @@ export default function App() { } /> } /> } /> - } /> } /> diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index f54f7856f..268debabd 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -1590,9 +1590,7 @@ export default function ProcessInstanceListTable({ }); if (showActionsColumn) { let buttonElement = null; - const interstitialUrl = `/process/${modifyProcessIdentifierForPathParam( - processInstance.process_model_identifier - )}/${processInstance.id}/interstitial`; + const taskShowUrl = `/tasks/${processInstance.id}/${processInstance.task_id}`; const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`); let hasAccessToCompleteTask = false; if ( @@ -1601,21 +1599,19 @@ export default function ProcessInstanceListTable({ ) { hasAccessToCompleteTask = true; } - let buttonText = 'View'; + buttonElement = null; if (hasAccessToCompleteTask && processInstance.task_id) { - buttonText = 'Go'; + buttonElement = ( + + ); } - buttonElement = ( - - ); - if ( processInstance.status === 'not_started' || processInstance.status === 'user_input_required' || diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx index 22cd3ac3f..0f61e1287 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx @@ -96,7 +96,7 @@ export default function ProcessInstanceRun({ const onProcessInstanceRun = (processInstance: any) => { const processInstanceId = (processInstance as any).id; navigate( - `/process/${modifyProcessIdentifierForPathParam( + `/admin/process-instances/${modifyProcessIdentifierForPathParam( processModel.id )}/${processInstanceId}/interstitial` ); diff --git a/spiffworkflow-frontend/src/components/ProcessInterstitial.tsx b/spiffworkflow-frontend/src/components/ProcessInterstitial.tsx index 9b26122d4..639b5bb92 100644 --- a/spiffworkflow-frontend/src/components/ProcessInterstitial.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInterstitial.tsx @@ -2,33 +2,32 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { fetchEventSource } from '@microsoft/fetch-event-source'; // @ts-ignore -import { Loading, Button } from '@carbon/react'; +import { Loading } from '@carbon/react'; import { BACKEND_BASE_URL } from '../config'; import { getBasicHeaders } from '../services/HttpService'; // @ts-ignore import InstructionsForEndUser from './InstructionsForEndUser'; -import ProcessBreadcrumb from './ProcessBreadcrumb'; import { ProcessInstance, ProcessInstanceTask } from '../interfaces'; import useAPIError from '../hooks/UseApiError'; type OwnProps = { processInstanceId: number; - modifiedProcessModelIdentifier: string; + processInstanceShowPageUrl: string; allowRedirect: boolean; }; export default function ProcessInterstitial({ processInstanceId, - modifiedProcessModelIdentifier, allowRedirect, + processInstanceShowPageUrl, }: OwnProps) { const [data, setData] = useState([]); const [lastTask, setLastTask] = useState(null); const [state, setState] = useState('RUNNING'); const [processInstance, setProcessInstance] = useState(null); - const processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${modifiedProcessModelIdentifier}`; + const navigate = useNavigate(); const userTasks = useMemo(() => { return ['User Task', 'Manual Task']; @@ -50,13 +49,14 @@ export default function ProcessInterstitial({ } }, onclose() { + console.log('The state is closed.'); setState('CLOSED'); }, }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // it is critical to only run this once. - const shouldRedirect = useCallback( + const shouldRedirectToTask = useCallback( (myTask: ProcessInstanceTask): boolean => { return ( allowRedirect && @@ -66,21 +66,38 @@ export default function ProcessInterstitial({ userTasks.includes(myTask.type) ); }, - [userTasks, processInstance] + [allowRedirect, processInstance, userTasks] ); + const shouldRedirectToProcessInstance = useCallback((): boolean => { + return allowRedirect && state === 'CLOSED'; + }, [allowRedirect, state]); + useEffect(() => { // Added this seperate use effect so that the timer interval will be cleared if // we end up redirecting back to the TaskShow page. - if (shouldRedirect(lastTask)) { + if (shouldRedirectToTask(lastTask)) { lastTask.properties.instructionsForEndUser = ''; const timerId = setInterval(() => { navigate(`/tasks/${lastTask.process_instance_id}/${lastTask.id}`); }, 2000); return () => clearInterval(timerId); } + if (shouldRedirectToProcessInstance()) { + // Navigate without pause as we will be showing the same information. + navigate(processInstanceShowPageUrl); + } return undefined; - }, [lastTask, navigate, userTasks, shouldRedirect]); + }, [ + lastTask, + navigate, + userTasks, + shouldRedirectToTask, + processInstanceId, + processInstanceShowPageUrl, + state, + shouldRedirectToProcessInstance, + ]); const getStatus = (): string => { if (processInstance) { @@ -101,35 +118,13 @@ export default function ProcessInterstitial({ ); } return null; }; - const getReturnHomeButton = (index: number) => { - if ( - index === 0 && - !shouldRedirect(lastTask) && - ['WAITING', 'ERROR', 'LOCKED', 'COMPLETED', 'READY'].includes(getStatus()) - ) { - return ( -
- -
- ); - } - return ''; - }; - const userMessage = (myTask: ProcessInstanceTask) => { if (!processInstance || processInstance.status === 'completed') { if (!myTask.can_complete && userTasks.includes(myTask.type)) { @@ -140,7 +135,7 @@ export default function ProcessInterstitial({

); } - if (shouldRedirect(myTask)) { + if (shouldRedirectToTask(myTask)) { return
Redirecting you to the next task now ...
; } if (myTask && myTask.can_complete && userTasks.includes(myTask.type)) { @@ -170,40 +165,24 @@ export default function ProcessInterstitial({ navigate(`/tasks`); } + let displayableData = data; + if (state === 'CLOSED') { + displayableData = [data[0]]; + } + if (lastTask) { return ( <> - {getLoadingIcon()} -
- {data.map((d, index) => ( - <> -
- {userMessage(d)} -
- {getReturnHomeButton(index)} - - ))} -
+ {displayableData.map((d, index) => ( +
+ {userMessage(d)} +
+ ))} ); } diff --git a/spiffworkflow-frontend/src/routes/AdminRoutes.tsx b/spiffworkflow-frontend/src/routes/AdminRoutes.tsx index 0e9df5d90..12fdac25f 100644 --- a/spiffworkflow-frontend/src/routes/AdminRoutes.tsx +++ b/spiffworkflow-frontend/src/routes/AdminRoutes.tsx @@ -22,6 +22,7 @@ import Configuration from './Configuration'; import JsonSchemaFormBuilder from './JsonSchemaFormBuilder'; import ProcessModelNewExperimental from './ProcessModelNewExperimental'; import ProcessInstanceFindById from './ProcessInstanceFindById'; +import ProcessInterstitialPage from "./ProcessInterstitialPage"; export default function AdminRoutes() { const location = useLocation(); @@ -75,6 +76,14 @@ export default function AdminRoutes() { path="process-instances/for-me/:process_model_id/:process_instance_id/:to_task_guid" element={} /> + } + /> + } + /> } diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index cfb9a33a3..ca7968a2b 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -53,7 +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"; +import ProcessInterstitial from '../components/ProcessInterstitial'; type OwnProps = { variant: string; @@ -1093,9 +1093,28 @@ export default function ProcessInstanceShow({ variant }: OwnProps) { return ( <> - - {buttonIcons()} -
+ + +

+ Process Instance Id: {processInstance.id} +

+ {buttonIcons()} +
+

diff --git a/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx b/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx index 31b59337e..6911c8331 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInterstitialPage.tsx @@ -2,17 +2,42 @@ import React from 'react'; import { useParams } from 'react-router-dom'; // @ts-ignore import ProcessInterstitial from '../components/ProcessInterstitial'; +import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; -export default function ProcessInterstitialPage() { +type OwnProps = { + variant: string; +}; + +export default function ProcessInterstitialPage({ variant }: OwnProps) { const params = useParams(); + let processInstanceShowPageUrl = `/admin/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`; + if (variant === 'all') { + processInstanceShowPageUrl = `/admin/process-instances/${params.process_model_id}/${params.process_instance_id}`; + } + // @ts-ignore + console.log('params', params, processInstanceShowPageUrl); return ( - + <> + + + ); } diff --git a/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx b/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx deleted file mode 100644 index 001a8ec20..000000000 --- a/spiffworkflow-frontend/src/routes/ProcessRoutes.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Route, Routes } from 'react-router-dom'; -// @ts-ignore -import ProcessInterstitialPage from './ProcessInterstitialPage'; - -export default function ProcessRoutes() { - return ( - - } - /> - - ); -} diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 6f1407d5b..bc06dad1a 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -102,7 +102,7 @@ export default function TaskShow() { const navigateToInterstitial = (myTask: Task) => { navigate( - `/process/${modifyProcessIdentifierForPathParam( + `/admin/process-instances/${modifyProcessIdentifierForPathParam( myTask.process_model_identifier )}/${myTask.process_instance_id}/interstitial` );