Merge pull request #278 from sartography/feature/interstitial_process_instance_show
Feature/interstitial process instance show
This commit is contained in:
commit
01ec63f71a
|
@ -10,7 +10,6 @@ import HomePageRoutes from './routes/HomePageRoutes';
|
||||||
import About from './routes/About';
|
import About from './routes/About';
|
||||||
import ErrorBoundary from './components/ErrorBoundary';
|
import ErrorBoundary from './components/ErrorBoundary';
|
||||||
import AdminRoutes from './routes/AdminRoutes';
|
import AdminRoutes from './routes/AdminRoutes';
|
||||||
import ProcessRoutes from './routes/ProcessRoutes';
|
|
||||||
|
|
||||||
import { AbilityContext } from './contexts/Can';
|
import { AbilityContext } from './contexts/Can';
|
||||||
import UserService from './services/UserService';
|
import UserService from './services/UserService';
|
||||||
|
@ -41,7 +40,6 @@ export default function App() {
|
||||||
<Route path="/*" element={<HomePageRoutes />} />
|
<Route path="/*" element={<HomePageRoutes />} />
|
||||||
<Route path="/about" element={<About />} />
|
<Route path="/about" element={<About />} />
|
||||||
<Route path="/tasks/*" element={<HomePageRoutes />} />
|
<Route path="/tasks/*" element={<HomePageRoutes />} />
|
||||||
<Route path="/process/*" element={<ProcessRoutes />} />
|
|
||||||
<Route path="/admin/*" element={<AdminRoutes />} />
|
<Route path="/admin/*" element={<AdminRoutes />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
|
|
|
@ -782,7 +782,7 @@ export default function ProcessInstanceListTable({
|
||||||
undefined,
|
undefined,
|
||||||
paginationQueryParamPrefix
|
paginationQueryParamPrefix
|
||||||
);
|
);
|
||||||
page = 1; // Reset page back to 0
|
page = 1;
|
||||||
|
|
||||||
const newReportMetadata = getNewReportMetadataBasedOnPageWidgets();
|
const newReportMetadata = getNewReportMetadataBasedOnPageWidgets();
|
||||||
setReportMetadata(newReportMetadata);
|
setReportMetadata(newReportMetadata);
|
||||||
|
@ -1590,9 +1590,7 @@ export default function ProcessInstanceListTable({
|
||||||
});
|
});
|
||||||
if (showActionsColumn) {
|
if (showActionsColumn) {
|
||||||
let buttonElement = null;
|
let buttonElement = null;
|
||||||
const interstitialUrl = `/process/${modifyProcessIdentifierForPathParam(
|
const taskShowUrl = `/tasks/${processInstance.id}/${processInstance.task_id}`;
|
||||||
processInstance.process_model_identifier
|
|
||||||
)}/${processInstance.id}/interstitial`;
|
|
||||||
const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`);
|
const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`);
|
||||||
let hasAccessToCompleteTask = false;
|
let hasAccessToCompleteTask = false;
|
||||||
if (
|
if (
|
||||||
|
@ -1601,21 +1599,19 @@ export default function ProcessInstanceListTable({
|
||||||
) {
|
) {
|
||||||
hasAccessToCompleteTask = true;
|
hasAccessToCompleteTask = true;
|
||||||
}
|
}
|
||||||
let buttonText = 'View';
|
buttonElement = null;
|
||||||
if (hasAccessToCompleteTask && processInstance.task_id) {
|
if (hasAccessToCompleteTask && processInstance.task_id) {
|
||||||
buttonText = 'Go';
|
buttonElement = (
|
||||||
|
<Button
|
||||||
|
kind="secondary"
|
||||||
|
href={taskShowUrl}
|
||||||
|
style={{ width: '60px' }}
|
||||||
|
>
|
||||||
|
Go
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonElement = (
|
|
||||||
<Button
|
|
||||||
kind="secondary"
|
|
||||||
href={interstitialUrl}
|
|
||||||
style={{ width: '60px' }}
|
|
||||||
>
|
|
||||||
{buttonText}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
processInstance.status === 'not_started' ||
|
processInstance.status === 'not_started' ||
|
||||||
processInstance.status === 'user_input_required' ||
|
processInstance.status === 'user_input_required' ||
|
||||||
|
|
|
@ -96,7 +96,7 @@ export default function ProcessInstanceRun({
|
||||||
const onProcessInstanceRun = (processInstance: any) => {
|
const onProcessInstanceRun = (processInstance: any) => {
|
||||||
const processInstanceId = (processInstance as any).id;
|
const processInstanceId = (processInstance as any).id;
|
||||||
navigate(
|
navigate(
|
||||||
`/process/${modifyProcessIdentifierForPathParam(
|
`/admin/process-instances/${modifyProcessIdentifierForPathParam(
|
||||||
processModel.id
|
processModel.id
|
||||||
)}/${processInstanceId}/interstitial`
|
)}/${processInstanceId}/interstitial`
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,80 +1,103 @@
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
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';
|
import { fetchEventSource } from '@microsoft/fetch-event-source';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Loading, Button } from '@carbon/react';
|
import { Loading } from '@carbon/react';
|
||||||
import { BACKEND_BASE_URL } from '../config';
|
import { BACKEND_BASE_URL } from '../config';
|
||||||
import { getBasicHeaders } from '../services/HttpService';
|
import { getBasicHeaders } from '../services/HttpService';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import InstructionsForEndUser from '../components/InstructionsForEndUser';
|
import InstructionsForEndUser from './InstructionsForEndUser';
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
|
||||||
import { ProcessInstance, ProcessInstanceTask } from '../interfaces';
|
import { ProcessInstance, ProcessInstanceTask } from '../interfaces';
|
||||||
import useAPIError from '../hooks/UseApiError';
|
import useAPIError from '../hooks/UseApiError';
|
||||||
|
|
||||||
export default function ProcessInterstitial() {
|
type OwnProps = {
|
||||||
|
processInstanceId: number;
|
||||||
|
processInstanceShowPageUrl: string;
|
||||||
|
allowRedirect: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ProcessInterstitial({
|
||||||
|
processInstanceId,
|
||||||
|
allowRedirect,
|
||||||
|
processInstanceShowPageUrl,
|
||||||
|
}: OwnProps) {
|
||||||
const [data, setData] = useState<any[]>([]);
|
const [data, setData] = useState<any[]>([]);
|
||||||
const [lastTask, setLastTask] = useState<any>(null);
|
const [lastTask, setLastTask] = useState<any>(null);
|
||||||
|
const [state, setState] = useState<string>('RUNNING');
|
||||||
const [processInstance, setProcessInstance] =
|
const [processInstance, setProcessInstance] =
|
||||||
useState<ProcessInstance | null>(null);
|
useState<ProcessInstance | null>(null);
|
||||||
const [state, setState] = useState<string>('RUNNING');
|
|
||||||
const params = useParams();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const userTasks = useMemo(() => {
|
const userTasks = useMemo(() => {
|
||||||
return ['User Task', 'Manual Task'];
|
return ['User Task', 'Manual Task'];
|
||||||
}, []);
|
}, []);
|
||||||
const { addError } = useAPIError();
|
const { addError } = useAPIError();
|
||||||
|
|
||||||
const processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${params.modified_process_model_identifier}`;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchEventSource(
|
fetchEventSource(`${BACKEND_BASE_URL}/tasks/${processInstanceId}`, {
|
||||||
`${BACKEND_BASE_URL}/tasks/${params.process_instance_id}`,
|
headers: getBasicHeaders(),
|
||||||
{
|
onmessage(ev) {
|
||||||
headers: getBasicHeaders(),
|
const retValue = JSON.parse(ev.data);
|
||||||
onmessage(ev) {
|
if (retValue.type === 'error') {
|
||||||
const retValue = JSON.parse(ev.data);
|
addError(retValue.error);
|
||||||
if (retValue.type === 'error') {
|
} else if (retValue.type === 'task') {
|
||||||
addError(retValue.error);
|
setData((prevData) => [retValue.task, ...prevData]);
|
||||||
} else if (retValue.type === 'task') {
|
setLastTask(retValue.task);
|
||||||
setData((prevData) => [retValue.task, ...prevData]);
|
} else if (retValue.type === 'unrunnable_instance') {
|
||||||
setLastTask(retValue.task);
|
setProcessInstance(retValue.unrunnable_instance);
|
||||||
} else if (retValue.type === 'unrunnable_instance') {
|
}
|
||||||
setProcessInstance(retValue.unrunnable_instance);
|
},
|
||||||
}
|
onclose() {
|
||||||
},
|
console.log('The state is closed.');
|
||||||
onclose() {
|
setState('CLOSED');
|
||||||
setState('CLOSED');
|
},
|
||||||
},
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []); // it is critical to only run this once.
|
}, []); // it is critical to only run this once.
|
||||||
|
|
||||||
const shouldRedirect = useCallback(
|
const shouldRedirectToTask = useCallback(
|
||||||
(myTask: ProcessInstanceTask): boolean => {
|
(myTask: ProcessInstanceTask): boolean => {
|
||||||
return (
|
return (
|
||||||
|
allowRedirect &&
|
||||||
!processInstance &&
|
!processInstance &&
|
||||||
myTask &&
|
myTask &&
|
||||||
myTask.can_complete &&
|
myTask.can_complete &&
|
||||||
userTasks.includes(myTask.type)
|
userTasks.includes(myTask.type)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[userTasks, processInstance]
|
[allowRedirect, processInstance, userTasks]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const shouldRedirectToProcessInstance = useCallback((): boolean => {
|
||||||
|
return allowRedirect && state === 'CLOSED';
|
||||||
|
}, [allowRedirect, state]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Added this seperate use effect so that the timer interval will be cleared if
|
// Added this seperate use effect so that the timer interval will be cleared if
|
||||||
// we end up redirecting back to the TaskShow page.
|
// we end up redirecting back to the TaskShow page.
|
||||||
if (shouldRedirect(lastTask)) {
|
if (shouldRedirectToTask(lastTask)) {
|
||||||
lastTask.properties.instructionsForEndUser = '';
|
lastTask.properties.instructionsForEndUser = '';
|
||||||
const timerId = setInterval(() => {
|
const timerId = setInterval(() => {
|
||||||
navigate(`/tasks/${lastTask.process_instance_id}/${lastTask.id}`);
|
navigate(`/tasks/${lastTask.process_instance_id}/${lastTask.id}`);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
return () => clearInterval(timerId);
|
return () => clearInterval(timerId);
|
||||||
}
|
}
|
||||||
|
if (shouldRedirectToProcessInstance()) {
|
||||||
|
// Navigate without pause as we will be showing the same information.
|
||||||
|
navigate(processInstanceShowPageUrl);
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [lastTask, navigate, userTasks, shouldRedirect]);
|
}, [
|
||||||
|
lastTask,
|
||||||
|
navigate,
|
||||||
|
userTasks,
|
||||||
|
shouldRedirectToTask,
|
||||||
|
processInstanceId,
|
||||||
|
processInstanceShowPageUrl,
|
||||||
|
state,
|
||||||
|
shouldRedirectToProcessInstance,
|
||||||
|
]);
|
||||||
|
|
||||||
const getStatus = (): string => {
|
const getStatus = (): string => {
|
||||||
if (processInstance) {
|
if (processInstance) {
|
||||||
|
@ -95,35 +118,13 @@ export default function ProcessInterstitial() {
|
||||||
<Loading
|
<Loading
|
||||||
description="Active loading indicator"
|
description="Active loading indicator"
|
||||||
withOverlay={false}
|
withOverlay={false}
|
||||||
style={{ margin: 'auto' }}
|
style={{ margin: '50px 0 50px 50px' }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getReturnHomeButton = (index: number) => {
|
|
||||||
if (
|
|
||||||
index === 0 &&
|
|
||||||
!shouldRedirect(lastTask) &&
|
|
||||||
['WAITING', 'ERROR', 'LOCKED', 'COMPLETED', 'READY'].includes(getStatus())
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '10px 0 0 0' }}>
|
|
||||||
<Button
|
|
||||||
kind="secondary"
|
|
||||||
data-qa="return-to-home-button"
|
|
||||||
onClick={() => navigate(`/tasks`)}
|
|
||||||
style={{ marginBottom: 30 }}
|
|
||||||
>
|
|
||||||
Return to Home
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
const userMessage = (myTask: ProcessInstanceTask) => {
|
const userMessage = (myTask: ProcessInstanceTask) => {
|
||||||
if (!processInstance || processInstance.status === 'completed') {
|
if (!processInstance || processInstance.status === 'completed') {
|
||||||
if (!myTask.can_complete && userTasks.includes(myTask.type)) {
|
if (!myTask.can_complete && userTasks.includes(myTask.type)) {
|
||||||
|
@ -134,9 +135,12 @@ export default function ProcessInterstitial() {
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (shouldRedirect(myTask)) {
|
if (shouldRedirectToTask(myTask)) {
|
||||||
return <div>Redirecting you to the next task now ...</div>;
|
return <div>Redirecting you to the next task now ...</div>;
|
||||||
}
|
}
|
||||||
|
if (myTask && myTask.can_complete && userTasks.includes(myTask.type)) {
|
||||||
|
return `The task ${myTask.title} is ready for you to complete.`;
|
||||||
|
}
|
||||||
if (myTask.error_message) {
|
if (myTask.error_message) {
|
||||||
return <div>{myTask.error_message}</div>;
|
return <div>{myTask.error_message}</div>;
|
||||||
}
|
}
|
||||||
|
@ -161,40 +165,24 @@ export default function ProcessInterstitial() {
|
||||||
navigate(`/tasks`);
|
navigate(`/tasks`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let displayableData = data;
|
||||||
|
if (state === 'CLOSED') {
|
||||||
|
displayableData = [data[0]];
|
||||||
|
}
|
||||||
|
|
||||||
if (lastTask) {
|
if (lastTask) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ProcessBreadcrumb
|
|
||||||
hotCrumbs={[
|
|
||||||
['Process Groups', '/admin'],
|
|
||||||
{
|
|
||||||
entityToExplode: lastTask.process_model_identifier,
|
|
||||||
entityType: 'process-model-id',
|
|
||||||
linkLastItem: true,
|
|
||||||
},
|
|
||||||
[
|
|
||||||
`Process Instance: ${params.process_instance_id}`,
|
|
||||||
`${processInstanceShowPageBaseUrl}/${params.process_instance_id}`,
|
|
||||||
],
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
{getLoadingIcon()}
|
{getLoadingIcon()}
|
||||||
<div style={{ maxWidth: 800, margin: 'auto', padding: 50 }}>
|
{displayableData.map((d, index) => (
|
||||||
{data.map((d, index) => (
|
<div
|
||||||
<>
|
className={
|
||||||
<div
|
index < 4 ? `user_instructions_${index}` : `user_instructions_4`
|
||||||
className={
|
}
|
||||||
index < 4
|
>
|
||||||
? `user_instructions_${index}`
|
{userMessage(d)}
|
||||||
: `user_instructions_4`
|
</div>
|
||||||
}
|
))}
|
||||||
>
|
|
||||||
{userMessage(d)}
|
|
||||||
</div>
|
|
||||||
{getReturnHomeButton(index)}
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -23,6 +23,7 @@ export interface RecentProcessModel {
|
||||||
|
|
||||||
export interface TaskPropertiesJson {
|
export interface TaskPropertiesJson {
|
||||||
parent: string;
|
parent: string;
|
||||||
|
last_state_change: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskDefinitionPropertiesJson {
|
export interface TaskDefinitionPropertiesJson {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import Configuration from './Configuration';
|
||||||
import JsonSchemaFormBuilder from './JsonSchemaFormBuilder';
|
import JsonSchemaFormBuilder from './JsonSchemaFormBuilder';
|
||||||
import ProcessModelNewExperimental from './ProcessModelNewExperimental';
|
import ProcessModelNewExperimental from './ProcessModelNewExperimental';
|
||||||
import ProcessInstanceFindById from './ProcessInstanceFindById';
|
import ProcessInstanceFindById from './ProcessInstanceFindById';
|
||||||
|
import ProcessInterstitialPage from './ProcessInterstitialPage';
|
||||||
|
|
||||||
export default function AdminRoutes() {
|
export default function AdminRoutes() {
|
||||||
const location = useLocation();
|
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"
|
path="process-instances/for-me/:process_model_id/:process_instance_id/:to_task_guid"
|
||||||
element={<ProcessInstanceShow variant="for-me" />}
|
element={<ProcessInstanceShow variant="for-me" />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="process-instances/for-me/:process_model_id/:process_instance_id/interstitial"
|
||||||
|
element={<ProcessInterstitialPage variant="for-me" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="process-instances/:process_model_id/:process_instance_id/interstitial"
|
||||||
|
element={<ProcessInterstitialPage variant="all" />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="process-instances/:process_model_id/:process_instance_id"
|
path="process-instances/:process_model_id/:process_instance_id"
|
||||||
element={<ProcessInstanceShow variant="all" />}
|
element={<ProcessInstanceShow variant="all" />}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||||
import ProcessInstanceClass from '../classes/ProcessInstanceClass';
|
import ProcessInstanceClass from '../classes/ProcessInstanceClass';
|
||||||
import TaskListTable from '../components/TaskListTable';
|
import TaskListTable from '../components/TaskListTable';
|
||||||
import useAPIError from '../hooks/UseApiError';
|
import useAPIError from '../hooks/UseApiError';
|
||||||
|
import ProcessInterstitial from '../components/ProcessInterstitial';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
variant: string;
|
variant: string;
|
||||||
|
@ -1109,6 +1110,11 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
||||||
</h1>
|
</h1>
|
||||||
{buttonIcons()}
|
{buttonIcons()}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<ProcessInterstitial
|
||||||
|
processInstanceId={processInstance.id}
|
||||||
|
processInstanceShowPageUrl={processInstanceShowPageBaseUrl}
|
||||||
|
allowRedirect={false}
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<Grid condensed fullWidth>
|
<Grid condensed fullWidth>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
// @ts-ignore
|
||||||
|
import ProcessInterstitial from '../components/ProcessInterstitial';
|
||||||
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
|
||||||
|
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}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ProcessBreadcrumb
|
||||||
|
hotCrumbs={[
|
||||||
|
['Process Groups', '/admin'],
|
||||||
|
{
|
||||||
|
entityToExplode: String(params.process_model_id),
|
||||||
|
entityType: 'process-model-id',
|
||||||
|
linkLastItem: true,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
`Process Instance: ${params.process_instance_id}`,
|
||||||
|
`${processInstanceShowPageUrl}`,
|
||||||
|
],
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<ProcessInterstitial
|
||||||
|
processInstanceId={Number(params.process_instance_id)}
|
||||||
|
processInstanceShowPageUrl={processInstanceShowPageUrl}
|
||||||
|
allowRedirect
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
import { Route, Routes } from 'react-router-dom';
|
|
||||||
// @ts-ignore
|
|
||||||
import ProcessInterstitial from './ProcessInterstitial';
|
|
||||||
|
|
||||||
export default function ProcessRoutes() {
|
|
||||||
return (
|
|
||||||
<Routes>
|
|
||||||
<Route
|
|
||||||
path=":modified_process_model_identifier/:process_instance_id/interstitial"
|
|
||||||
element={<ProcessInterstitial />}
|
|
||||||
/>
|
|
||||||
</Routes>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -102,7 +102,7 @@ export default function TaskShow() {
|
||||||
|
|
||||||
const navigateToInterstitial = (myTask: Task) => {
|
const navigateToInterstitial = (myTask: Task) => {
|
||||||
navigate(
|
navigate(
|
||||||
`/process/${modifyProcessIdentifierForPathParam(
|
`/admin/process-instances/${modifyProcessIdentifierForPathParam(
|
||||||
myTask.process_model_identifier
|
myTask.process_model_identifier
|
||||||
)}/${myTask.process_instance_id}/interstitial`
|
)}/${myTask.process_instance_id}/interstitial`
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue