From 1707396783c2571633f78666feee36a817dfdbcc Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 5 Dec 2022 14:56:55 -0500 Subject: [PATCH 1/6] updated tasks endpoint to task-data for easier permission setting w/ burnettk --- spiffworkflow-backend/src/spiffworkflow_backend/api.yml | 2 +- .../config/permissions/development.yml | 7 ++++++- .../config/permissions/terraform_deployed_environment.yml | 7 ++++++- .../src/components/ProcessInstanceListTable.tsx | 4 +++- spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx | 2 +- spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx | 2 +- spiffworkflow-frontend/src/routes/TaskShow.tsx | 4 ++-- 7 files changed, 20 insertions(+), 8 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index 5be50b8d..fe783918 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -1101,7 +1101,7 @@ paths: items: $ref: "#/components/schemas/Task" - /process-instances/{modified_process_model_id}/{process_instance_id}/tasks: + /task-data/{modified_process_model_id}/{process_instance_id}: parameters: - name: modified_process_model_id in: path diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml index e17e3f11..b404aa97 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml @@ -12,7 +12,6 @@ groups: mike, jason, j, - amir, jarrad, elizabeth, jon, @@ -98,6 +97,12 @@ permissions: allowed_permissions: [read] uri: /v1.0/processes + task-data-read: + groups: [demo] + users: [] + allowed_permissions: [read] + uri: /v1.0/task-data/* + manage-procurement-admin: groups: ["Project Lead"] diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/terraform_deployed_environment.yml b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/terraform_deployed_environment.yml index e60946b3..ce2e2dba 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/terraform_deployed_environment.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/terraform_deployed_environment.yml @@ -12,7 +12,6 @@ groups: mike, jason, j, - amir, jarrad, elizabeth, jon, @@ -98,6 +97,12 @@ permissions: allowed_permissions: [read] uri: /v1.0/processes + task-data-read: + groups: [demo] + users: [] + allowed_permissions: [read] + uri: /v1.0/task-data/* + manage-procurement-admin: groups: ["Project Lead"] diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index cc5ad75a..621c595c 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -1166,6 +1166,9 @@ export default function ProcessInstanceListTable({ return ( <> + + {reportSearchComponent()} + { processGroupShowPath: `/v1.0/process-groups/${params.process_group_id}`, processInstanceActionPath: `/v1.0/process-models/${params.process_model_id}/process-instances`, processInstanceListPath: '/v1.0/process-instances', - processInstanceTaskListPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}/tasks`, + processInstanceTaskListPath: `/v1.0/task-data/${params.process_model_id}/${params.process_instance_id}`, processInstanceReportListPath: '/v1.0/process-instances/reports', processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`, processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`, diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index c407c771..0b0aca14 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -85,7 +85,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, }); diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 768043cd..88e23de7 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -39,9 +39,9 @@ export default function TaskShow() { const processResult = (result: any) => { setTask(result); HttpService.makeCallToBackend({ - path: `/process-instances/${modifyProcessIdentifierForPathParam( + path: `/task-data/${modifyProcessIdentifierForPathParam( result.process_model_identifier - )}/${params.process_instance_id}/tasks`, + )}/${params.process_instance_id}`, successCallback: setUserTasks, }); }; From 731bf6737d50772baf5963c2b65857b188018905 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 5 Dec 2022 16:06:08 -0500 Subject: [PATCH 2/6] cleaned up more api routes for permissions w/ burnettk --- .../src/spiffworkflow_backend/api.yml | 46 +++++------ .../config/permissions/development.yml | 6 +- .../routes/process_api_blueprint.py | 6 +- .../helpers/base_test.py | 2 +- .../integration/test_logging_service.py | 2 +- .../integration/test_process_api.py | 11 +-- .../src/components/ProcessInstanceRun.tsx | 2 +- .../src/components/ProcessModelForm.tsx | 1 - .../src/hooks/UriListForPermissions.tsx | 5 +- .../src/routes/ProcessInstanceLogList.tsx | 8 +- .../src/routes/ProcessInstanceShow.tsx | 81 ++++++++++++------- .../src/routes/TaskShow.tsx | 72 ++++++++++------- 12 files changed, 139 insertions(+), 103 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index fe783918..a8204d39 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -646,7 +646,7 @@ paths: schema: $ref: "#/components/schemas/Workflow" - /process-models/{modified_process_model_id}/process-instances: + /process-instances/{modified_process_model_id}: parameters: - name: modified_process_model_id in: path @@ -654,7 +654,6 @@ paths: description: The unique id of an existing process model. schema: type: string - # process_instance_create post: operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_create summary: Creates an process instance from a process model and returns the instance @@ -668,28 +667,7 @@ paths: schema: $ref: "#/components/schemas/Workflow" - /process-instances/{process_instance_id}: - parameters: - - name: process_instance_id - in: path - required: true - description: The unique id of an existing process instance. - schema: - type: integer - delete: - operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_delete - summary: Deletes a single process instance - tags: - - Process Instances - responses: - "200": - description: The process instance was deleted. - content: - application/json: - schema: - $ref: "#/components/schemas/OkTrue" - - /process-models/{modified_process_model_identifier}/process-instances/{process_instance_id}: + /process-instances/{modified_process_model_identifier}/{process_instance_id}: parameters: - name: modified_process_model_identifier in: path @@ -715,6 +693,18 @@ paths: application/json: schema: $ref: "#/components/schemas/Workflow" + delete: + operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_delete + summary: Deletes a single process instance + tags: + - Process Instances + responses: + "200": + description: The process instance was deleted. + content: + application/json: + schema: + $ref: "#/components/schemas/OkTrue" /process-instances/{modified_process_model_identifier}/{process_instance_id}/run: parameters: @@ -743,7 +733,7 @@ paths: schema: $ref: "#/components/schemas/Workflow" - /process-instances/{process_instance_id}/terminate: + /process-instances/{modified_process_model_identifier}/{process_instance_id}/terminate: parameters: - name: process_instance_id in: path @@ -764,7 +754,7 @@ paths: schema: $ref: "#/components/schemas/OkTrue" - /process-instances/{process_instance_id}/suspend: + /process-instances/{modified_process_model_identifier}/{process_instance_id}/suspend: parameters: - name: process_instance_id in: path @@ -785,7 +775,7 @@ paths: schema: $ref: "#/components/schemas/OkTrue" - /process-instances/{process_instance_id}/resume: + /process-instances/{modified_process_model_identifier}/{process_instance_id}/resume: parameters: - name: process_instance_id in: path @@ -1326,7 +1316,7 @@ paths: schema: $ref: "#/components/schemas/Workflow" - /process-instances/{process_instance_id}/logs: + /logs/{modified_process_model_identifier}/{process_instance_id}: parameters: - name: process_instance_id in: path diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml index b404aa97..9a2f2284 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml @@ -175,17 +175,17 @@ permissions: uri: /v1.0/process-instances/manage-procurement:vendor-lifecycle-management:* core1-admin-models-instantiate: - groups: ["core-contributor"] + groups: ["core-contributor", "Finance Team"] users: [] allowed_permissions: [create] uri: /v1.0/process-models/misc:category_number_one:process-model-with-form/process-instances core1-admin-instances: - groups: ["core-contributor"] + groups: ["core-contributor", "Finance Team"] users: [] allowed_permissions: [create, read] uri: /v1.0/process-instances/misc:category_number_one:process-model-with-form:* core1-admin-instances-slash: - groups: ["core-contributor"] + groups: ["core-contributor", "Finance Team"] users: [] allowed_permissions: [create, read] uri: /v1.0/process-instances/misc:category_number_one:process-model-with-form/* diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index 6843fb15..77fe594c 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -565,6 +565,7 @@ def process_instance_run( def process_instance_terminate( process_instance_id: int, + modified_process_model_identifier: str, ) -> flask.wrappers.Response: """Process_instance_run.""" process_instance = ProcessInstanceService().get_process_instance( @@ -577,6 +578,7 @@ def process_instance_terminate( def process_instance_suspend( process_instance_id: int, + modified_process_model_identifier: str, ) -> flask.wrappers.Response: """Process_instance_suspend.""" process_instance = ProcessInstanceService().get_process_instance( @@ -589,6 +591,7 @@ def process_instance_suspend( def process_instance_resume( process_instance_id: int, + modified_process_model_identifier: str, ) -> flask.wrappers.Response: """Process_instance_resume.""" process_instance = ProcessInstanceService().get_process_instance( @@ -600,6 +603,7 @@ def process_instance_resume( def process_instance_log_list( + modified_process_model_identifier: str, process_instance_id: int, page: int = 1, per_page: int = 100, @@ -1071,7 +1075,7 @@ def process_instance_show( return make_response(jsonify(process_instance), 200) -def process_instance_delete(process_instance_id: int) -> flask.wrappers.Response: +def process_instance_delete(process_instance_id: int, modified_process_model_identifier: str) -> flask.wrappers.Response: """Create_process_instance.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py b/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py index 8d56853b..48982fc6 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py @@ -265,7 +265,7 @@ class BaseTest: ) modified_process_model_id = test_process_model_id.replace("/", ":") response = client.post( - f"/v1.0/process-models/{modified_process_model_id}/process-instances", + f"/v1.0/process-instances/{modified_process_model_id}", headers=headers, ) assert response.status_code == 201 diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_logging_service.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_logging_service.py index 2f56d1d6..f9dd4452 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_logging_service.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_logging_service.py @@ -57,7 +57,7 @@ class TestLoggingService(BaseTest): assert response.status_code == 200 log_response = client.get( - f"/v1.0/process-instances/{process_instance_id}/logs", + f"/v1.0/logs/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}", headers=headers, ) assert log_response.status_code == 200 diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index cd2d37c6..9d719a23 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -912,7 +912,7 @@ class TestProcessApi(BaseTest): modified_process_model_identifier = process_model_identifier.replace("/", ":") response = client.post( - f"/v1.0/process-models/{modified_process_model_identifier}/process-instances", + f"/v1.0/process-instances/{modified_process_model_identifier}", headers=self.logged_in_headers(with_super_admin_user), ) assert response.status_code == 201 @@ -1154,10 +1154,11 @@ class TestProcessApi(BaseTest): headers=self.logged_in_headers(with_super_admin_user), ) show_response = client.get( - f"/v1.0/process-models/{modified_process_model_identifier}/process-instances/{process_instance_id}", + f"/v1.0/process-instances/{modified_process_model_identifier}/{process_instance_id}", headers=self.logged_in_headers(with_super_admin_user), ) assert show_response.json is not None + assert show_response.status_code == 200 file_system_root = FileSystemService.root_path() file_path = ( f"{file_system_root}/{process_model_identifier}/{process_model_id}.bpmn" @@ -1320,7 +1321,7 @@ class TestProcessApi(BaseTest): assert response.json is not None response = client.post( - f"/v1.0/process-instances/{process_instance_id}/terminate", + f"/v1.0/process-instances/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}/terminate", headers=self.logged_in_headers(with_super_admin_user), ) assert response.status_code == 200 @@ -1367,7 +1368,7 @@ class TestProcessApi(BaseTest): assert response.json is not None delete_response = client.delete( - f"/v1.0/process-instances/{process_instance_id}", + f"/v1.0/process-instances/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}", headers=self.logged_in_headers(with_super_admin_user), ) assert delete_response.status_code == 200 @@ -2366,7 +2367,7 @@ class TestProcessApi(BaseTest): assert process_instance.status == "user_input_required" client.post( - f"/v1.0/process-instances/{process_instance_id}/suspend", + f"/v1.0/process-instances/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}/suspend", headers=self.logged_in_headers(with_super_admin_user), ) process_instance = ProcessInstanceService().get_process_instance( diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx index 87406f80..dafe20d5 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx @@ -83,7 +83,7 @@ export default function ProcessInstanceRun({ processModel.id ); - const processInstanceActionPath = `/v1.0/process-models/${modifiedProcessModelId}/process-instances`; + const processInstanceActionPath = `/v1.0/process-instances/${modifiedProcessModelId}`; let permissionRequestData: PermissionsToCheck = { [processInstanceActionPath]: ['POST'], }; diff --git a/spiffworkflow-frontend/src/components/ProcessModelForm.tsx b/spiffworkflow-frontend/src/components/ProcessModelForm.tsx index 1599aff5..7cfd4d61 100644 --- a/spiffworkflow-frontend/src/components/ProcessModelForm.tsx +++ b/spiffworkflow-frontend/src/components/ProcessModelForm.tsx @@ -194,7 +194,6 @@ export default function ProcessModelForm({ onChange={(event: any) => { onDisplayNameChanged(event.target.value); }} - onBlur={(event: any) => console.log('event', event)} />, ]; diff --git a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx index 9496e9e0..67958723 100644 --- a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx +++ b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx @@ -9,10 +9,11 @@ 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`, + processInstanceActionPath: `/v1.0/process-instances/${params.process_model_id}`, processInstanceListPath: '/v1.0/process-instances', - processInstanceTaskListPath: `/v1.0/task-data/${params.process_model_id}/${params.process_instance_id}`, + 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/routes/ProcessInstanceLogList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx index f41caf94..7b09c89f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx @@ -10,6 +10,7 @@ import { convertSecondsToFormattedDateTime, } from '../helpers'; import HttpService from '../services/HttpService'; +import { useUriListForPermissions } from '../hooks/UriListForPermissions'; export default function ProcessInstanceLogList() { const params = useParams(); @@ -19,6 +20,7 @@ export default function ProcessInstanceLogList() { const modifiedProcessModelId = modifyProcessIdentifierForPathParam( `${params.process_model_id}` ); + const { targetUris } = useUriListForPermissions(); useEffect(() => { const setProcessInstanceLogListFromResult = (result: any) => { @@ -27,7 +29,7 @@ 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}`, successCallback: setProcessInstanceLogListFromResult, }); }, [searchParams, params]); @@ -46,7 +48,7 @@ export default function ProcessInstanceLogList() { {convertSecondsToFormattedDateTime(rowToUse.timestamp)} @@ -86,7 +88,7 @@ export default function ProcessInstanceLogList() { }, [ `Process Instance: ${params.process_instance_id}`, - `/admin/process-models/${params.process_model_id}/process-instances/${params.process_instance_id}`, + `/admin/process-instances/${params.process_model_id}/${params.process_instance_id}`, ], ['Logs'], ]} diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 0b0aca14..481f8d6f 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 @@ -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', }); @@ -209,7 +214,7 @@ export default function ProcessInstanceShow() { if (currentEndDate) { currentEndDateTag = ( - + 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() { - + + { 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/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 88e23de7..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: `/task-data/${modifyProcessIdentifierForPathParam( - result.process_model_identifier - )}/${params.process_instance_id}`, - 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') { From f192ab89a27bed9e1f3dcfdd3829bde0da30b60c Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 5 Dec 2022 16:35:20 -0500 Subject: [PATCH 3/6] more api cleanup w/ burnettk --- .../src/spiffworkflow_backend/api.yml | 80 ++++++++++--------- .../config/permissions/development.yml | 6 ++ .../routes/process_api_blueprint.py | 43 ++++++---- .../src/routes/ProcessInstanceShow.tsx | 8 +- .../src/routes/ProcessModelEditDiagram.tsx | 2 +- 5 files changed, 80 insertions(+), 59 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index a8204d39..e9da26b4 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -338,9 +338,9 @@ paths: schema: $ref: "#/components/schemas/ProcessModel" - /process-models/{modified_process_model_id}/files: + /process-models/{modified_process_model_identifier}/files: parameters: - - name: modified_process_model_id + - name: modified_process_model_identifier in: path required: true description: The process_model_id, modified to replace slashes (/) @@ -565,33 +565,6 @@ paths: items: $ref: "#/components/schemas/Workflow" - /process-instances/{process_instance_id}/task/{task_id}/update: - parameters: - - name: process_instance_id - in: path - required: true - description: The unique id of the process instance - schema: - type: string - - name: task_id - in: path - required: true - description: The unique id of the task - schema: - type: string - post: - operationId: spiffworkflow_backend.routes.process_api_blueprint.update_task_data - summary: Update the task data for requested instance and task - tags: - - Process Instances - responses: - "200": - description: Task Updated Successfully - content: - application/json: - schema: - $ref: "#/components/schemas/Workflow" - /process-models/{process_group_id}/{process_model_id}/script-unit-tests: parameters: - name: process_group_id @@ -646,9 +619,9 @@ paths: schema: $ref: "#/components/schemas/Workflow" - /process-instances/{modified_process_model_id}: + /process-instances/{modified_process_model_identifier}: parameters: - - name: modified_process_model_id + - name: modified_process_model_identifier in: path required: true description: The unique id of an existing process model. @@ -912,9 +885,9 @@ paths: schema: $ref: "#/components/schemas/OkTrue" - /process-models/{modified_process_model_id}/files/{file_name}: + /process-models/{modified_process_model_identifier}/files/{file_name}: parameters: - - name: modified_process_model_id + - name: modified_process_model_identifier in: path required: true description: The modified process model id @@ -1091,9 +1064,9 @@ paths: items: $ref: "#/components/schemas/Task" - /task-data/{modified_process_model_id}/{process_instance_id}: + /task-data/{modified_process_model_identifier}/{process_instance_id}: parameters: - - name: modified_process_model_id + - name: modified_process_model_identifier in: path required: true description: The modified id of an existing process model @@ -1132,11 +1105,44 @@ paths: items: $ref: "#/components/schemas/Task" - /service_tasks: + /task-data/{modified_process_model_identifier}/{process_instance_id}/{task_id}: + parameters: + - name: modified_process_model_identifier + in: path + required: true + description: The modified id of an existing process model + schema: + type: string + - name: process_instance_id + in: path + required: true + description: The unique id of an existing process instance. + schema: + type: integer + - name: task_id + in: path + required: true + description: The unique id of the task. + schema: + type: string + put: + operationId: spiffworkflow_backend.routes.process_api_blueprint.update_task_data + summary: Update the task data for requested instance and task + tags: + - Process Instances + responses: + "200": + description: Task Updated Successfully + content: + application/json: + schema: + $ref: "#/components/schemas/Workflow" + + /service-tasks: get: tags: - Service Tasks - operationId: spiffworkflow_backend.routes.process_api_blueprint.service_tasks_show + operationId: spiffworkflow_backend.routes.process_api_blueprint.service_task_list summary: Gets all available service task connectors responses: "200": diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml index 9a2f2284..4c748fd9 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/permissions/development.yml @@ -69,6 +69,12 @@ permissions: users: [] allowed_permissions: [create, read, update, delete] uri: /v1.0/tasks/* + service-tasks: + groups: [everybody] + users: [] + allowed_permissions: [read] + uri: /v1.0/service-tasks + # read all for everybody read-all-process-groups: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index 77fe594c..f780a97d 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -158,9 +158,9 @@ def modify_process_model_id(process_model_id: str) -> str: return process_model_id.replace("/", ":") -def un_modify_modified_process_model_id(modified_process_model_id: str) -> str: +def un_modify_modified_process_model_id(modified_process_model_identifier: str) -> str: """Un_modify_modified_process_model_id.""" - return modified_process_model_id.replace(":", "/") + return modified_process_model_identifier.replace(":", "/") def process_group_add(body: dict) -> flask.wrappers.Response: @@ -411,9 +411,9 @@ def process_list() -> Any: return SpecReferenceSchema(many=True).dump(references) -def get_file(modified_process_model_id: str, file_name: str) -> Any: +def get_file(modified_process_model_identifier: str, file_name: str) -> Any: """Get_file.""" - process_model_identifier = modified_process_model_id.replace(":", "/") + process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model = get_process_model(process_model_identifier) files = SpecFileService.get_files(process_model, file_name) if len(files) == 0: @@ -433,10 +433,10 @@ def get_file(modified_process_model_id: str, file_name: str) -> Any: def process_model_file_update( - modified_process_model_id: str, file_name: str + modified_process_model_identifier: str, file_name: str ) -> flask.wrappers.Response: """Process_model_file_update.""" - process_model_identifier = modified_process_model_id.replace(":", "/") + process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model = get_process_model(process_model_identifier) request_file = get_file_from_request() @@ -462,10 +462,10 @@ def process_model_file_update( def process_model_file_delete( - modified_process_model_id: str, file_name: str + modified_process_model_identifier: str, file_name: str ) -> flask.wrappers.Response: """Process_model_file_delete.""" - process_model_identifier = modified_process_model_id.replace(":", "/") + process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model = get_process_model(process_model_identifier) try: SpecFileService.delete_file(process_model, file_name) @@ -481,9 +481,9 @@ def process_model_file_delete( return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") -def add_file(modified_process_model_id: str) -> flask.wrappers.Response: +def add_file(modified_process_model_identifier: str) -> flask.wrappers.Response: """Add_file.""" - process_model_identifier = modified_process_model_id.replace(":", "/") + process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model = get_process_model(process_model_identifier) request_file = get_file_from_request() if not request_file.filename: @@ -504,10 +504,12 @@ def add_file(modified_process_model_id: str) -> flask.wrappers.Response: ) -def process_instance_create(modified_process_model_id: str) -> flask.wrappers.Response: +def process_instance_create( + modified_process_model_identifier: str, +) -> flask.wrappers.Response: """Create_process_instance.""" process_model_identifier = un_modify_modified_process_model_id( - modified_process_model_id + modified_process_model_identifier ) process_instance = ( ProcessInstanceService.create_process_instance_from_process_model_identifier( @@ -1075,7 +1077,9 @@ def process_instance_show( return make_response(jsonify(process_instance), 200) -def process_instance_delete(process_instance_id: int, modified_process_model_identifier: str) -> flask.wrappers.Response: +def process_instance_delete( + process_instance_id: int, modified_process_model_identifier: str +) -> flask.wrappers.Response: """Create_process_instance.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) @@ -1157,8 +1161,8 @@ def process_instance_report_delete( return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") -def service_tasks_show() -> flask.wrappers.Response: - """Service_tasks_show.""" +def service_task_list() -> flask.wrappers.Response: + """Service_task_list.""" available_connectors = ServiceTaskService.available_connectors() return Response( json.dumps(available_connectors), status=200, mimetype="application/json" @@ -1365,7 +1369,7 @@ def get_tasks( def process_instance_task_list( - modified_process_model_id: str, + modified_process_model_identifier: str, process_instance_id: int, all_tasks: bool = False, spiff_step: int = 0, @@ -1926,7 +1930,12 @@ def _update_form_schema_with_task_data_as_needed( _update_form_schema_with_task_data_as_needed(o, task_data) -def update_task_data(process_instance_id: str, task_id: str, body: Dict) -> Response: +def update_task_data( + process_instance_id: str, + modified_process_model_identifier: str, + task_id: str, + body: Dict, +) -> Response: """Update task data.""" process_instance = ProcessInstanceModel.query.filter( ProcessInstanceModel.id == int(process_instance_id) diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 481f8d6f..3e17ce81 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -81,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'; @@ -179,7 +179,7 @@ export default function ProcessInstanceShow() { { HttpService.makeCallToBackend({ - path: `/service_tasks`, + path: `/service-tasks`, successCallback: makeApiHandler(event), }); }; From 3a40b07f5e75b51a5b164b608813547e32f6e55b Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 5 Dec 2022 16:49:27 -0500 Subject: [PATCH 4/6] make the frontend uris match the api calls better w/ burnettk --- .../src/components/ProcessInstanceListTable.tsx | 2 +- .../src/components/ProcessInstanceRun.tsx | 8 ++++---- .../src/components/ProcessModelListTiles.tsx | 4 ++-- .../src/components/TasksForMyOpenProcesses.tsx | 2 +- .../src/components/TasksWaitingForMe.tsx | 2 +- .../src/components/TasksWaitingForMyGroups.tsx | 2 +- .../src/hooks/UriListForPermissions.tsx | 3 ++- spiffworkflow-frontend/src/routes/AdminRoutes.tsx | 6 +++--- spiffworkflow-frontend/src/routes/MessageInstanceList.tsx | 8 ++++---- spiffworkflow-frontend/src/routes/MyTasks.tsx | 6 +++--- .../src/routes/ProcessInstanceLogList.tsx | 2 +- spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx | 2 +- spiffworkflow-frontend/src/routes/ProcessModelShow.tsx | 6 +++--- 13 files changed, 27 insertions(+), 26 deletions(-) diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index 621c595c..1bc0fdea 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -1059,7 +1059,7 @@ export default function ProcessInstanceListTable({ return ( {id} diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx index dafe20d5..05b643da 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceRun.tsx @@ -83,9 +83,9 @@ export default function ProcessInstanceRun({ processModel.id ); - const processInstanceActionPath = `/v1.0/process-instances/${modifiedProcessModelId}`; + const processInstanceCreatePath = `/v1.0/process-instances/${modifiedProcessModelId}`; let permissionRequestData: PermissionsToCheck = { - [processInstanceActionPath]: ['POST'], + [processInstanceCreatePath]: ['POST'], }; if (!checkPermissions) { @@ -117,14 +117,14 @@ export default function ProcessInstanceRun({ const processInstanceCreateAndRun = () => { HttpService.makeCallToBackend({ - path: processInstanceActionPath, + path: processInstanceCreatePath, successCallback: processModelRun, httpMethod: 'POST', }); }; if (checkPermissions) { return ( - + 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/hooks/UriListForPermissions.tsx b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx index 67958723..eff30a82 100644 --- a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx +++ b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx @@ -9,7 +9,8 @@ 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-instances/${params.process_model_id}`, + 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', processInstanceLogListPath: `/v1.0/logs/${params.process_model_id}/${params.process_instance_id}`, processInstanceReportListPath: '/v1.0/process-instances/reports', 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 b77b744c..a9ec6b69 100644 --- a/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx @@ -102,9 +102,9 @@ export default function MessageInstanceList() { {row.process_instance_id} @@ -163,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'], ]} diff --git a/spiffworkflow-frontend/src/routes/MyTasks.tsx b/spiffworkflow-frontend/src/routes/MyTasks.tsx index 51f5f3e9..4c1cbc9b 100644 --- a/spiffworkflow-frontend/src/routes/MyTasks.tsx +++ b/spiffworkflow-frontend/src/routes/MyTasks.tsx @@ -55,9 +55,9 @@ export default function MyTasks() {

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 7b09c89f..61420295 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx @@ -32,7 +32,7 @@ export default function ProcessInstanceLogList() { path: `${targetUris.processInstanceLogListPath}?per_page=${perPage}&page=${page}`, successCallback: setProcessInstanceLogListFromResult, }); - }, [searchParams, params]); + }, [searchParams, params, targetUris]); const buildTable = () => { const rows = processInstanceLogs.map((row) => { diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 3e17ce81..9a0495d1 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -273,7 +273,7 @@ export default function ProcessInstanceShow() { size="sm" className="button-white-background" data-qa="process-instance-log-list-link" - href={`/admin/process-models/${modifiedProcessModelId}/process-instances/${params.process_instance_id}/logs`} + href={`/admin/logs/${modifiedProcessModelId}/${params.process_instance_id}`} > Logs diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 2882e183..96a65656 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 @@ -556,7 +556,7 @@ export default function ProcessModelShow() { <> From 3fce0ef413ed11ec7438d8161a952803792dd790 Mon Sep 17 00:00:00 2001 From: jasquat Date: Tue, 6 Dec 2022 09:46:32 -0500 Subject: [PATCH 5/6] get the columsn for the instance list table anytime filter options are displayed if empty --- .../components/ProcessInstanceListTable.tsx | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index 1bc0fdea..eee5a273 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -372,15 +372,18 @@ export default function ProcessInstanceListTable({ titleOperation = 'Created'; } return ( - + <> + +
+ ); } return null; @@ -935,6 +938,15 @@ export default function ProcessInstanceListTable({ if (!showFilterOptions) { return null; } + + // get the columns anytime we display the filter options if they are empty + if (availableReportColumns.length < 1) { + HttpService.makeCallToBackend({ + path: `/process-instances/reports/columns`, + successCallback: setAvailableReportColumns, + }); + } + return ( <> @@ -1134,10 +1146,6 @@ export default function ProcessInstanceListTable({ const toggleShowFilterOptions = () => { setShowFilterOptions(!showFilterOptions); - HttpService.makeCallToBackend({ - path: `/process-instances/reports/columns`, - successCallback: setAvailableReportColumns, - }); }; const reportSearchComponent = () => { From 88ae1df3e59fbd669fe66fbcec5a54849a5b4a20 Mon Sep 17 00:00:00 2001 From: burnettk Date: Tue, 6 Dec 2022 12:38:25 -0500 Subject: [PATCH 6/6] break process instance log list page into two tabs, simple and detailed --- .../src/spiffworkflow_backend/api.yml | 6 ++ .../routes/process_api_blueprint.py | 12 ++-- .../src/routes/ProcessInstanceLogList.tsx | 64 +++++++++++++++---- 3 files changed, 66 insertions(+), 16 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index e9da26b4..6141a861 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -1342,6 +1342,12 @@ paths: description: The number of items to show per page. Defaults to page 10. schema: type: integer + - name: detailed + in: query + required: false + description: Show the detailed view, which includes all log entries + schema: + type: boolean get: tags: - Process Instances diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index f780a97d..549c76f0 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -609,16 +609,20 @@ def process_instance_log_list( process_instance_id: int, page: int = 1, per_page: int = 100, + detailed: bool = False, ) -> flask.wrappers.Response: """Process_instance_log_list.""" # to make sure the process instance exists process_instance = find_process_instance_by_id_or_raise(process_instance_id) + log_query = SpiffLoggingModel.query.filter( + SpiffLoggingModel.process_instance_id == process_instance.id + ) + if not detailed: + log_query = log_query.filter(SpiffLoggingModel.message.in_(["State change to COMPLETED"])) # type: ignore + logs = ( - SpiffLoggingModel.query.filter( - SpiffLoggingModel.process_instance_id == process_instance.id - ) - .order_by(SpiffLoggingModel.timestamp.desc()) # type: ignore + log_query.order_by(SpiffLoggingModel.timestamp.desc()) # type: ignore .join( UserModel, UserModel.id == SpiffLoggingModel.current_user_id, isouter=True ) # isouter since if we don't have a user, we still want the log diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx index 61420295..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'; @@ -14,13 +14,14 @@ 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) => { @@ -29,21 +30,31 @@ export default function ProcessInstanceLogList() { }; const { page, perPage } = getPageInfoFromSearchParams(searchParams); HttpService.makeCallToBackend({ - path: `${targetUris.processInstanceLogListPath}?per_page=${perPage}&page=${page}`, + path: `${targetUris.processInstanceLogListPath}?per_page=${perPage}&page=${page}&detailed=${isDetailedView}`, successCallback: setProcessInstanceLogListFromResult, }); - }, [searchParams, params, targetUris]); + }, [ + 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} - Bpmn Process Identifier + Id Message - Task Identifier Task Name - Task Type + {isDetailedView && ( + <> + Task Identifier + Task Type + Bpmn Process Identifier + + )} User Timestamp @@ -73,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;