(false);
const navigate = useNavigate();
const navigateToProcessModel = (result: ProcessModel) => {
@@ -64,6 +75,7 @@ export default function ProcessModelForm({
const postBody = {
display_name: processModel.display_name,
description: processModel.description,
+ metadata_extraction_paths: processModel.metadata_extraction_paths,
};
if (mode === 'new') {
Object.assign(postBody, {
@@ -87,6 +99,80 @@ export default function ProcessModelForm({
setProcessModel(processModelToCopy);
};
+ const metadataExtractionPathForm = (
+ index: number,
+ metadataExtractionPath: MetadataExtractionPath
+ ) => {
+ return (
+
+
+
+
+
+
+ {
+ const cep: MetadataExtractionPath[] =
+ processModel.metadata_extraction_paths || [];
+ cep.splice(index, 1);
+ updateProcessModel({ metadata_extraction_paths: cep });
+ }}
+ />
+
+
+ );
+ };
+
+ const metadataExtractionPathFormArea = () => {
+ if (processModel.metadata_extraction_paths) {
+ return processModel.metadata_extraction_paths.map(
+ (metadataExtractionPath: MetadataExtractionPath, index: number) => {
+ return metadataExtractionPathForm(index, metadataExtractionPath);
+ }
+ );
+ }
+ return null;
+ };
+
+ const addBlankMetadataExtractionPath = () => {
+ const cep: MetadataExtractionPath[] =
+ processModel.metadata_extraction_paths || [];
+ cep.push({ key: '', path: '' });
+ updateProcessModel({ metadata_extraction_paths: cep });
+ };
+
const onDisplayNameChanged = (newDisplayName: any) => {
setDisplayNameInvalid(false);
const updateDict = { display_name: newDisplayName };
@@ -108,7 +194,6 @@ export default function ProcessModelForm({
onChange={(event: any) => {
onDisplayNameChanged(event.target.value);
}}
- onBlur={(event: any) => console.log('event', event)}
/>,
];
@@ -145,6 +230,38 @@ export default function ProcessModelForm({
/>
);
+ textInputs.push(Metadata Extractions );
+ textInputs.push(
+
+
+
+ You can provide one or more metadata extractions to pull data from
+ your process instances to provide quick access in searches and
+ perspectives.
+
+
+
+ );
+ textInputs.push(<>{metadataExtractionPathFormArea()}>);
+ textInputs.push(
+
+
+ {
+ addBlankMetadataExtractionPath();
+ }}
+ >
+ Add Metadata Extraction Path
+
+
+
+ );
+
return textInputs;
};
diff --git a/spiffworkflow-frontend/src/components/ProcessModelListTiles.tsx b/spiffworkflow-frontend/src/components/ProcessModelListTiles.tsx
index 4787fe94..1412635c 100644
--- a/spiffworkflow-frontend/src/components/ProcessModelListTiles.tsx
+++ b/spiffworkflow-frontend/src/components/ProcessModelListTiles.tsx
@@ -54,9 +54,9 @@ export default function ProcessModelListTiles({
Process Instance {processInstance.id} kicked off (
view
diff --git a/spiffworkflow-frontend/src/components/TasksForMyOpenProcesses.tsx b/spiffworkflow-frontend/src/components/TasksForMyOpenProcesses.tsx
index a81779c7..deb2030e 100644
--- a/spiffworkflow-frontend/src/components/TasksForMyOpenProcesses.tsx
+++ b/spiffworkflow-frontend/src/components/TasksForMyOpenProcesses.tsx
@@ -55,7 +55,7 @@ export default function MyOpenProcesses() {
{rowToUse.process_instance_id}
diff --git a/spiffworkflow-frontend/src/components/TasksWaitingForMe.tsx b/spiffworkflow-frontend/src/components/TasksWaitingForMe.tsx
index 92420224..7d06b7a3 100644
--- a/spiffworkflow-frontend/src/components/TasksWaitingForMe.tsx
+++ b/spiffworkflow-frontend/src/components/TasksWaitingForMe.tsx
@@ -47,7 +47,7 @@ export default function TasksWaitingForMe() {
{rowToUse.process_instance_id}
diff --git a/spiffworkflow-frontend/src/components/TasksWaitingForMyGroups.tsx b/spiffworkflow-frontend/src/components/TasksWaitingForMyGroups.tsx
index 51c38e94..565cd4a5 100644
--- a/spiffworkflow-frontend/src/components/TasksWaitingForMyGroups.tsx
+++ b/spiffworkflow-frontend/src/components/TasksWaitingForMyGroups.tsx
@@ -55,7 +55,7 @@ export default function TasksWaitingForMyGroups() {
{rowToUse.process_instance_id}
diff --git a/spiffworkflow-frontend/src/config.tsx b/spiffworkflow-frontend/src/config.tsx
index 5e7e96fe..b0816a39 100644
--- a/spiffworkflow-frontend/src/config.tsx
+++ b/spiffworkflow-frontend/src/config.tsx
@@ -14,6 +14,7 @@ export const PROCESS_STATUSES = [
'complete',
'error',
'suspended',
+ 'terminated',
];
// with time: yyyy-MM-dd HH:mm:ss
diff --git a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx
index 80c78987..eff30a82 100644
--- a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx
+++ b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx
@@ -9,10 +9,12 @@ export const useUriListForPermissions = () => {
messageInstanceListPath: '/v1.0/messages',
processGroupListPath: '/v1.0/process-groups',
processGroupShowPath: `/v1.0/process-groups/${params.process_group_id}`,
- processInstanceActionPath: `/v1.0/process-models/${params.process_model_id}/process-instances`,
+ processInstanceCreatePath: `/v1.0/process-instances/${params.process_model_id}`,
+ processInstanceActionPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}`,
processInstanceListPath: '/v1.0/process-instances',
- processInstanceTaskListPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}/tasks`,
+ processInstanceLogListPath: `/v1.0/logs/${params.process_model_id}/${params.process_instance_id}`,
processInstanceReportListPath: '/v1.0/process-instances/reports',
+ processInstanceTaskListPath: `/v1.0/task-data/${params.process_model_id}/${params.process_instance_id}`,
processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`,
processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`,
processModelFileShowPath: `/v1.0/process-models/${params.process_model_id}/files/${params.file_name}`,
diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css
index 4723e557..f4094785 100644
--- a/spiffworkflow-frontend/src/index.css
+++ b/spiffworkflow-frontend/src/index.css
@@ -69,6 +69,24 @@ h2 {
color: black;
}
+/* match normal link colors */
+.cds--btn--ghost.button-link {
+ color: #0062fe;
+ padding-left: 0;
+}
+.cds--btn--ghost.button-link:visited {
+ color: #0062fe;
+ padding-left: 0;
+}
+.cds--btn--ghost.button-link:hover {
+ color: #0062fe;
+ padding-left: 0;
+}
+.cds--btn--ghost.button-link:visited:hover {
+ color: #0062fe;
+ padding-left: 0;
+}
+
.cds--header__global .cds--btn--primary {
background-color: #161616
}
@@ -151,10 +169,22 @@ h1.with-icons {
margin-top: 1em;
}
+.with-extra-top-margin {
+ margin-top: 1.3em;
+}
+
+.with-tiny-top-margin {
+ margin-top: 4px;
+}
+
.with-large-bottom-margin {
margin-bottom: 3em;
}
+.with-tiny-bottom-margin {
+ margin-bottom: 4px;
+}
+
.diagram-viewer-canvas {
border:1px solid #000000;
height:70vh;
@@ -297,3 +327,38 @@ td.actions-cell {
text-align: right;
padding-bottom: 10px;
}
+
+.cds--btn--ghost:not([disabled]) svg.red-icon {
+ fill: red;
+}
+
+.failure-string {
+ color: red;
+}
+
+.cds--btn--ghost.cds--btn--sm.button-tag-icon {
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 0;
+}
+
+/* .no-wrap cds--label cds--label--inline cds--label--inline--md{ */
+.no-wrap .cds--label--inline{
+ word-break: normal;
+}
+
+.combo-box-in-modal {
+ height: 300px;
+}
+
+.cds--btn.narrow-button {
+ max-width: 10rem;
+ min-width: 5rem;
+ word-break: normal;
+
+}
+
+.tag-type-green:hover {
+ background-color: #00FF00;
+}
+
diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts
index 3c3d7c12..079e4cdc 100644
--- a/spiffworkflow-frontend/src/interfaces.ts
+++ b/spiffworkflow-frontend/src/interfaces.ts
@@ -38,11 +38,58 @@ export interface ProcessFile {
export interface ProcessInstance {
id: number;
process_model_identifier: string;
+ process_model_display_name: string;
+}
+
+export interface MessageCorrelationProperties {
+ [key: string]: string;
+}
+
+export interface MessageCorrelations {
+ [key: string]: MessageCorrelationProperties;
+}
+
+export interface MessageInstance {
+ id: number;
+ process_model_identifier: string;
+ process_model_display_name: string;
+ process_instance_id: number;
+ message_identifier: string;
+ message_type: string;
+ failure_cause: string;
+ status: string;
+ created_at_in_seconds: number;
+ message_correlations?: MessageCorrelations;
+}
+
+export interface ReportFilter {
+ field_name: string;
+ field_value: string;
+ operator?: string;
+}
+
+export interface ReportColumn {
+ Header: string;
+ accessor: string;
+ filterable: boolean;
+}
+
+export interface ReportColumnForEditing extends ReportColumn {
+ filter_field_value: string;
+ filter_operator: string;
+}
+
+export interface ReportMetadata {
+ columns: ReportColumn[];
+ filter_by: ReportFilter[];
+ order_by: string[];
}
export interface ProcessInstanceReport {
- id: string;
- display_name: string;
+ id: number;
+ identifier: string;
+ name: string;
+ report_metadata: ReportMetadata;
}
export interface ProcessGroupLite {
@@ -50,6 +97,11 @@ export interface ProcessGroupLite {
display_name: string;
}
+export interface MetadataExtractionPath {
+ key: string;
+ path: string;
+}
+
export interface ProcessModel {
id: string;
description: string;
@@ -57,6 +109,7 @@ export interface ProcessModel {
primary_file_name: string;
files: ProcessFile[];
parent_groups?: ProcessGroupLite[];
+ metadata_extraction_paths?: MetadataExtractionPath[];
}
export interface ProcessGroup {
diff --git a/spiffworkflow-frontend/src/routes/AdminRoutes.tsx b/spiffworkflow-frontend/src/routes/AdminRoutes.tsx
index 91ae7ab0..da6cae35 100644
--- a/spiffworkflow-frontend/src/routes/AdminRoutes.tsx
+++ b/spiffworkflow-frontend/src/routes/AdminRoutes.tsx
@@ -71,11 +71,11 @@ export default function AdminRoutes() {
element={ }
/>
}
/>
}
/>
}
/>
}
/>
} />
diff --git a/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx b/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx
index f1478058..a9ec6b69 100644
--- a/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx
+++ b/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx
@@ -1,15 +1,19 @@
import { useEffect, useState } from 'react';
// @ts-ignore
-import { Table } from '@carbon/react';
+import { ErrorOutline } from '@carbon/icons-react';
+// @ts-ignore
+import { Table, Modal, Button } from '@carbon/react';
import { Link, useParams, useSearchParams } from 'react-router-dom';
import PaginationForTable from '../components/PaginationForTable';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import {
- convertSecondsToFormattedDateString,
+ convertSecondsToFormattedDateTime,
getPageInfoFromSearchParams,
modifyProcessIdentifierForPathParam,
} from '../helpers';
import HttpService from '../services/HttpService';
+import { FormatProcessModelDisplayName } from '../components/MiniComponents';
+import { MessageInstance } from '../interfaces';
export default function MessageInstanceList() {
const params = useParams();
@@ -17,6 +21,9 @@ export default function MessageInstanceList() {
const [messageIntances, setMessageInstances] = useState([]);
const [pagination, setPagination] = useState(null);
+ const [messageInstanceForModal, setMessageInstanceForModal] =
+ useState(null);
+
useEffect(() => {
const setMessageInstanceListFromResult = (result: any) => {
setMessageInstances(result.results);
@@ -35,41 +42,89 @@ export default function MessageInstanceList() {
});
}, [searchParams, params]);
- const buildTable = () => {
- // return null;
- const rows = messageIntances.map((row) => {
- const rowToUse = row as any;
+ const handleCorrelationDisplayClose = () => {
+ setMessageInstanceForModal(null);
+ };
+
+ const correlationsDisplayModal = () => {
+ if (messageInstanceForModal) {
+ let failureCausePre = null;
+ if (messageInstanceForModal.failure_cause) {
+ failureCausePre = (
+ <>
+
+ {messageInstanceForModal.failure_cause}
+
+
+ >
+ );
+ }
return (
-
- {rowToUse.id}
-
-
- {rowToUse.process_model_identifier}
-
-
+
+ {failureCausePre}
+ Correlations:
+
+ {JSON.stringify(
+ messageInstanceForModal.message_correlations,
+ null,
+ 2
+ )}
+
+
+ );
+ }
+ return null;
+ };
+
+ const buildTable = () => {
+ const rows = messageIntances.map((row: MessageInstance) => {
+ let errorIcon = null;
+ let errorTitle = null;
+ if (row.failure_cause) {
+ errorTitle = 'Instance has an error';
+ errorIcon = (
+ <>
+
+
+ >
+ );
+ }
+ return (
+
+ {row.id}
+ {FormatProcessModelDisplayName(row)}
- {rowToUse.process_instance_id}
+ {row.process_instance_id}
- {rowToUse.message_identifier}
- {rowToUse.message_type}
- {rowToUse.failure_cause || '-'}
- {rowToUse.status}
+ {row.message_identifier}
+ {row.message_type}
- {convertSecondsToFormattedDateString(
- rowToUse.created_at_in_seconds
- )}
+ setMessageInstanceForModal(row)}
+ title={errorTitle}
+ >
+ View
+ {errorIcon}
+
+
+ {row.status}
+
+ {convertSecondsToFormattedDateTime(row.created_at_in_seconds)}
);
@@ -78,12 +133,12 @@ export default function MessageInstanceList() {
- Instance Id
- Process Model
+ Id
+ Process
Process Instance
- Message Model
+ Name
Type
- Failure Cause
+ Details
Status
Created At
@@ -108,9 +163,9 @@ export default function MessageInstanceList() {
},
[
`Process Instance: ${searchParams.get('process_instance_id')}`,
- `/admin/process-models/${searchParams.get(
+ `/admin/process-instances/${searchParams.get(
'process_model_id'
- )}/process-instances/${searchParams.get('process_instance_id')}`,
+ )}/${searchParams.get('process_instance_id')}`,
],
['Messages'],
]}
@@ -121,6 +176,7 @@ export default function MessageInstanceList() {
<>
{breadcrumbElement}
Messages
+ {correlationsDisplayModal()}
Process Instance {processInstance.id} kicked off (
view
@@ -95,7 +95,7 @@ export default function MyTasks() {
{rowToUse.process_instance_id}
diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx
index f41caf94..37ef5519 100644
--- a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx
+++ b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
// @ts-ignore
-import { Table } from '@carbon/react';
+import { Table, Tabs, TabList, Tab } from '@carbon/react';
import { useParams, useSearchParams, Link } from 'react-router-dom';
import PaginationForTable from '../components/PaginationForTable';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
@@ -10,15 +10,18 @@ import {
convertSecondsToFormattedDateTime,
} from '../helpers';
import HttpService from '../services/HttpService';
+import { useUriListForPermissions } from '../hooks/UriListForPermissions';
export default function ProcessInstanceLogList() {
const params = useParams();
- const [searchParams] = useSearchParams();
+ const [searchParams, setSearchParams] = useSearchParams();
const [processInstanceLogs, setProcessInstanceLogs] = useState([]);
const [pagination, setPagination] = useState(null);
const modifiedProcessModelId = modifyProcessIdentifierForPathParam(
`${params.process_model_id}`
);
+ const { targetUris } = useUriListForPermissions();
+ const isDetailedView = searchParams.get('detailed') === 'true';
useEffect(() => {
const setProcessInstanceLogListFromResult = (result: any) => {
@@ -27,26 +30,36 @@ export default function ProcessInstanceLogList() {
};
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
HttpService.makeCallToBackend({
- path: `/process-instances/${params.process_instance_id}/logs?per_page=${perPage}&page=${page}`,
+ path: `${targetUris.processInstanceLogListPath}?per_page=${perPage}&page=${page}&detailed=${isDetailedView}`,
successCallback: setProcessInstanceLogListFromResult,
});
- }, [searchParams, params]);
+ }, [
+ searchParams,
+ params,
+ targetUris.processInstanceLogListPath,
+ isDetailedView,
+ ]);
const buildTable = () => {
const rows = processInstanceLogs.map((row) => {
const rowToUse = row as any;
return (
- {rowToUse.bpmn_process_identifier}
+ {rowToUse.id}
{rowToUse.message}
- {rowToUse.bpmn_task_identifier}
{rowToUse.bpmn_task_name}
- {rowToUse.bpmn_task_type}
+ {isDetailedView && (
+ <>
+ {rowToUse.bpmn_task_identifier}
+ {rowToUse.bpmn_task_type}
+ {rowToUse.bpmn_process_identifier}
+ >
+ )}
{rowToUse.username}
{convertSecondsToFormattedDateTime(rowToUse.timestamp)}
@@ -58,11 +71,16 @@ export default function ProcessInstanceLogList() {
- Bpmn Process Identifier
+ Id
Message
- Task Identifier
Task Name
- Task Type
+ {isDetailedView && (
+ <>
+ Task Identifier
+ Task Type
+ Bpmn Process Identifier
+ >
+ )}
User
Timestamp
@@ -71,11 +89,12 @@ export default function ProcessInstanceLogList() {
);
};
+ const selectedTabIndex = isDetailedView ? 1 : 0;
if (pagination) {
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
return (
-
+ <>
+
+
+ {
+ searchParams.set('detailed', 'false');
+ setSearchParams(searchParams);
+ }}
+ >
+ Simple
+
+ {
+ searchParams.set('detailed', 'true');
+ setSearchParams(searchParams);
+ }}
+ >
+ Detailed
+
+
+
+
-
+ >
);
}
return null;
diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx
index c407c771..9a0495d1 100644
--- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx
+++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx
@@ -59,6 +59,11 @@ export default function ProcessInstanceShow() {
const permissionRequestData: PermissionsToCheck = {
[targetUris.messageInstanceListPath]: ['GET'],
[targetUris.processInstanceTaskListPath]: ['GET'],
+ [targetUris.processInstanceActionPath]: ['DELETE'],
+ [targetUris.processInstanceLogListPath]: ['GET'],
+ [`${targetUris.processInstanceActionPath}/suspend`]: ['PUT'],
+ [`${targetUris.processInstanceActionPath}/terminate`]: ['PUT'],
+ [`${targetUris.processInstanceActionPath}/resume`]: ['PUT'],
};
const { ability, permissionsLoaded } = usePermissionFetcher(
permissionRequestData
@@ -76,7 +81,7 @@ export default function ProcessInstanceShow() {
setTasksCallHadError(true);
};
HttpService.makeCallToBackend({
- path: `/process-models/${modifiedProcessModelId}/process-instances/${params.process_instance_id}`,
+ path: `/process-instances/${modifiedProcessModelId}/${params.process_instance_id}`,
successCallback: setProcessInstance,
});
let taskParams = '?all_tasks=true';
@@ -85,7 +90,7 @@ export default function ProcessInstanceShow() {
}
if (ability.can('GET', targetUris.processInstanceTaskListPath)) {
HttpService.makeCallToBackend({
- path: `/process-instances/${modifiedProcessModelId}/${params.process_instance_id}/tasks${taskParams}`,
+ path: `${targetUris.processInstanceTaskListPath}${taskParams}`,
successCallback: setTasks,
failureCallback: processTaskFailure,
});
@@ -97,7 +102,7 @@ export default function ProcessInstanceShow() {
const deleteProcessInstance = () => {
HttpService.makeCallToBackend({
- path: `/process-instances/${params.process_instance_id}`,
+ path: targetUris.processInstanceActionPath,
successCallback: navigateToProcessInstances,
httpMethod: 'DELETE',
});
@@ -110,7 +115,7 @@ export default function ProcessInstanceShow() {
const terminateProcessInstance = () => {
HttpService.makeCallToBackend({
- path: `/process-instances/${params.process_instance_id}/terminate`,
+ path: `${targetUris.processInstanceActionPath}/terminate`,
successCallback: refreshPage,
httpMethod: 'POST',
});
@@ -118,7 +123,7 @@ export default function ProcessInstanceShow() {
const suspendProcessInstance = () => {
HttpService.makeCallToBackend({
- path: `/process-instances/${params.process_instance_id}/suspend`,
+ path: `${targetUris.processInstanceActionPath}/suspend`,
successCallback: refreshPage,
httpMethod: 'POST',
});
@@ -126,7 +131,7 @@ export default function ProcessInstanceShow() {
const resumeProcessInstance = () => {
HttpService.makeCallToBackend({
- path: `/process-instances/${params.process_instance_id}/resume`,
+ path: `${targetUris.processInstanceActionPath}/resume`,
successCallback: refreshPage,
httpMethod: 'POST',
});
@@ -174,7 +179,7 @@ export default function ProcessInstanceShow() {
-
+
Completed:{' '}
@@ -235,7 +240,7 @@ export default function ProcessInstanceShow() {
return (
<>
-
+
Started:{' '}
@@ -246,7 +251,7 @@ export default function ProcessInstanceShow() {
{currentEndDateTag}
-
+
Status:{' '}
@@ -259,14 +264,20 @@ export default function ProcessInstanceShow() {
-
- Logs
-
+
+ Logs
+
+
{
const elements = [];
- elements.push(terminateButton(processInstanceToUse));
- elements.push(suspendButton(processInstanceToUse));
- elements.push(resumeButton(processInstanceToUse));
- elements.push(
-
- );
+ if (
+ ability.can('POST', `${targetUris.processInstanceActionPath}/terminate`)
+ ) {
+ elements.push(terminateButton(processInstanceToUse));
+ }
+ if (
+ ability.can('POST', `${targetUris.processInstanceActionPath}/suspend`)
+ ) {
+ elements.push(suspendButton(processInstanceToUse));
+ }
+ if (ability.can('POST', `${targetUris.processInstanceActionPath}/resume`)) {
+ elements.push(resumeButton(processInstanceToUse));
+ }
+ if (ability.can('DELETE', targetUris.processInstanceActionPath)) {
+ elements.push(
+
+ );
+ }
return elements;
};
diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx
index d117f798..1a5c751f 100644
--- a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx
+++ b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx
@@ -283,7 +283,7 @@ export default function ProcessModelEditDiagram() {
const onServiceTasksRequested = (event: any) => {
HttpService.makeCallToBackend({
- path: `/service_tasks`,
+ path: `/service-tasks`,
successCallback: makeApiHandler(event),
});
};
diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx
index fc1c354f..1b55b007 100644
--- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx
+++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx
@@ -66,7 +66,7 @@ export default function ProcessModelShow() {
const permissionRequestData: PermissionsToCheck = {
[targetUris.processModelShowPath]: ['PUT', 'DELETE'],
[targetUris.processInstanceListPath]: ['GET'],
- [targetUris.processInstanceActionPath]: ['POST'],
+ [targetUris.processInstanceCreatePath]: ['POST'],
[targetUris.processModelFileCreatePath]: ['POST', 'PUT', 'GET', 'DELETE'],
};
const { ability, permissionsLoaded } = usePermissionFetcher(
@@ -95,7 +95,7 @@ export default function ProcessModelShow() {
Process Instance {processInstance.id} kicked off (
view
@@ -564,7 +564,7 @@ export default function ProcessModelShow() {
<>
diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx
index 768043cd..9e0f65c5 100644
--- a/spiffworkflow-frontend/src/routes/TaskShow.tsx
+++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx
@@ -26,6 +26,9 @@ import Form from '../themes/carbon';
import HttpService from '../services/HttpService';
import ErrorContext from '../contexts/ErrorContext';
import { modifyProcessIdentifierForPathParam } from '../helpers';
+import { useUriListForPermissions } from '../hooks/UriListForPermissions';
+import { PermissionsToCheck } from '../interfaces';
+import { usePermissionFetcher } from '../hooks/PermissionService';
export default function TaskShow() {
const [task, setTask] = useState(null);
@@ -35,24 +38,36 @@ export default function TaskShow() {
const setErrorMessage = (useContext as any)(ErrorContext)[1];
- useEffect(() => {
- const processResult = (result: any) => {
- setTask(result);
- HttpService.makeCallToBackend({
- path: `/process-instances/${modifyProcessIdentifierForPathParam(
- result.process_model_identifier
- )}/${params.process_instance_id}/tasks`,
- successCallback: setUserTasks,
- });
- };
+ const { targetUris } = useUriListForPermissions();
+ const permissionRequestData: PermissionsToCheck = {
+ [targetUris.processInstanceTaskListPath]: ['GET'],
+ };
+ const { ability, permissionsLoaded } = usePermissionFetcher(
+ permissionRequestData
+ );
- HttpService.makeCallToBackend({
- path: `/tasks/${params.process_instance_id}/${params.task_id}`,
- successCallback: processResult,
- // This causes the page to continuously reload
- // failureCallback: setErrorMessage,
- });
- }, [params]);
+ useEffect(() => {
+ if (permissionsLoaded) {
+ const processResult = (result: any) => {
+ setTask(result);
+ if (ability.can('GET', targetUris.processInstanceTaskListPath)) {
+ HttpService.makeCallToBackend({
+ path: `/task-data/${modifyProcessIdentifierForPathParam(
+ result.process_model_identifier
+ )}/${params.process_instance_id}`,
+ successCallback: setUserTasks,
+ });
+ }
+ };
+
+ HttpService.makeCallToBackend({
+ path: `/tasks/${params.process_instance_id}/${params.task_id}`,
+ successCallback: processResult,
+ // This causes the page to continuously reload
+ // failureCallback: setErrorMessage,
+ });
+ }
+ }, [params, permissionsLoaded, ability, targetUris]);
const processSubmitResult = (result: any) => {
setErrorMessage(null);
@@ -116,17 +131,18 @@ export default function TaskShow() {
}
return null;
});
+ return (
+
+
+ {userTasksElement}
+
+
+ );
}
- return (
-
-
- {userTasksElement}
-
-
- );
+ return null;
};
const formElement = (taskToUse: any) => {
@@ -207,7 +223,7 @@ export default function TaskShow() {
);
};
- if (task && userTasks) {
+ if (task) {
const taskToUse = task as any;
let statusString = '';
if (taskToUse.state !== 'READY') {