From b1568fb472b2c824181d92c86392a56bf29efc57 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 19 Apr 2023 15:52:11 -0400 Subject: [PATCH] fixed test w/ burnettk --- .../routes/tasks_controller.py | 104 +++++++++--------- .../services/process_instance_service.py | 17 +-- .../services/workflow_execution_service.py | 67 +++++------ .../tests/data/interstitial/interstitial.bpmn | 2 +- .../integration/test_for_good_errors.py | 4 +- .../integration/test_process_api.py | 37 +++---- .../unit/test_process_instance_processor.py | 8 +- spiffworkflow-frontend/package-lock.json | 20 ++-- .../src/components/InstructionsForEndUser.tsx | 2 +- .../components/ProcessInstanceListTable.tsx | 3 +- .../src/routes/HomePageRoutes.tsx | 5 +- .../src/routes/ProcessInterstitial.tsx | 21 +++- .../src/routes/TaskShow.tsx | 1 - 13 files changed, 156 insertions(+), 135 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py index 8576047d..f79e141e 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py @@ -1,9 +1,7 @@ """APIs for dealing with process groups, process models, and process instances.""" import json import os -import time import uuid -from datetime import datetime from sys import exc_info from typing import Any from typing import Dict @@ -14,10 +12,11 @@ from typing import Union import flask.wrappers import jinja2 import sentry_sdk -from flask import current_app, stream_with_context +from flask import current_app from flask import g from flask import jsonify from flask import make_response +from flask import stream_with_context from flask.wrappers import Response from jinja2 import TemplateSyntaxError from SpiffWorkflow.exceptions import WorkflowTaskException # type: ignore @@ -85,7 +84,7 @@ class ReactJsonSchemaSelectOption(TypedDict): def task_list_my_tasks( - process_instance_id: Optional[int] = None, page: int = 1, per_page: int = 100 + process_instance_id: Optional[int] = None, page: int = 1, per_page: int = 100 ) -> flask.wrappers.Response: """Task_list_my_tasks.""" principal = _find_principal_or_raise() @@ -166,7 +165,7 @@ def task_list_for_me(page: int = 1, per_page: int = 100) -> flask.wrappers.Respo def task_list_for_my_groups( - user_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100 + user_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100 ) -> flask.wrappers.Response: """Task_list_for_my_groups.""" return _get_tasks( @@ -178,9 +177,9 @@ def task_list_for_my_groups( def task_data_show( - modified_process_model_identifier: str, - process_instance_id: int, - task_guid: str, + modified_process_model_identifier: str, + process_instance_id: int, + task_guid: str, ) -> flask.wrappers.Response: task_model = _get_task_model_from_guid_or_raise(task_guid, process_instance_id) task_model.data = task_model.json_data() @@ -188,10 +187,10 @@ def task_data_show( def task_data_update( - process_instance_id: str, - modified_process_model_identifier: str, - task_guid: str, - body: Dict, + process_instance_id: str, + modified_process_model_identifier: str, + task_guid: str, + body: Dict, ) -> Response: """Update task data.""" process_instance = ProcessInstanceModel.query.filter(ProcessInstanceModel.id == int(process_instance_id)).first() @@ -241,10 +240,10 @@ def task_data_update( def manual_complete_task( - modified_process_model_identifier: str, - process_instance_id: str, - task_guid: str, - body: Dict, + modified_process_model_identifier: str, + process_instance_id: str, + task_guid: str, + body: Dict, ) -> Response: """Mark a task complete without executing it.""" execute = body.get("execute", True) @@ -359,9 +358,7 @@ def _render_instructions_for_end_user(spiff_task: SpiffTask, task: Task): if task.properties and "instructionsForEndUser" in task.properties: if task.properties["instructionsForEndUser"]: try: - instructions = _render_jinja_template( - task.properties["instructionsForEndUser"], spiff_task - ) + instructions = _render_jinja_template(task.properties["instructionsForEndUser"], spiff_task) task.properties["instructionsForEndUser"] = instructions return instructions except WorkflowTaskException as wfe: @@ -371,9 +368,9 @@ def _render_instructions_for_end_user(spiff_task: SpiffTask, task: Task): def process_data_show( - process_instance_id: int, - process_data_identifier: str, - modified_process_model_identifier: str, + process_instance_id: int, + process_data_identifier: str, + modified_process_model_identifier: str, ) -> flask.wrappers.Response: """Process_data_show.""" process_instance = _find_process_instance_by_id_or_raise(process_instance_id) @@ -408,7 +405,7 @@ def _interstitial_stream(process_instance_id: int): instructions = _render_instructions_for_end_user(spiff_task, task) if instructions and spiff_task.id not in reported_ids: reported_ids.append(spiff_task.id) - yield f'data: {current_app.json.dumps(task)} \n\n' + yield f"data: {current_app.json.dumps(task)} \n\n" last_task = spiff_task processor.do_engine_steps(execution_strategy_name="run_until_user_message") processor.do_engine_steps(execution_strategy_name="one_at_a_time") @@ -420,15 +417,15 @@ def _interstitial_stream(process_instance_id: int): def interstitial(process_instance_id: int): """A Server Side Events Stream for watching the execution of engine tasks in a - process instance. """ - return Response(stream_with_context(_interstitial_stream(process_instance_id)), mimetype='text/event-stream') + process instance.""" + return Response(stream_with_context(_interstitial_stream(process_instance_id)), mimetype="text/event-stream") def _task_submit_shared( - process_instance_id: int, - task_guid: str, - body: Dict[str, Any], - save_as_draft: bool = False, + process_instance_id: int, + task_guid: str, + body: Dict[str, Any], + save_as_draft: bool = False, ) -> flask.wrappers.Response: principal = _find_principal_or_raise() process_instance = _find_process_instance_by_id_or_raise(process_instance_id) @@ -509,18 +506,24 @@ def _task_submit_shared( task = ProcessInstanceService.spiff_task_to_api_task(processor, processor.next_task()) return make_response(jsonify(task), 200) - return Response(json.dumps( - {"ok": True, - "process_model_identifier": process_instance.process_model_identifier, - "process_instance_id": process_instance_id - }), status=202, mimetype="application/json") + return Response( + json.dumps( + { + "ok": True, + "process_model_identifier": process_instance.process_model_identifier, + "process_instance_id": process_instance_id, + } + ), + status=202, + mimetype="application/json", + ) def task_submit( - process_instance_id: int, - task_guid: str, - body: Dict[str, Any], - save_as_draft: bool = False, + process_instance_id: int, + task_guid: str, + body: Dict[str, Any], + save_as_draft: bool = False, ) -> flask.wrappers.Response: """Task_submit_user_data.""" with sentry_sdk.start_span(op="controller_action", description="tasks_controller.task_submit"): @@ -528,11 +531,11 @@ def task_submit( def _get_tasks( - processes_started_by_user: bool = True, - has_lane_assignment_id: bool = True, - page: int = 1, - per_page: int = 100, - user_group_identifier: Optional[str] = None, + processes_started_by_user: bool = True, + has_lane_assignment_id: bool = True, + page: int = 1, + per_page: int = 100, + user_group_identifier: Optional[str] = None, ) -> flask.wrappers.Response: """Get_tasks.""" user_id = g.user.id @@ -679,9 +682,9 @@ def _render_jinja_template(unprocessed_template: str, spiff_task: SpiffTask) -> def _get_spiff_task_from_process_instance( - task_guid: str, - process_instance: ProcessInstanceModel, - processor: Union[ProcessInstanceProcessor, None] = None, + task_guid: str, + process_instance: ProcessInstanceModel, + processor: Union[ProcessInstanceProcessor, None] = None, ) -> SpiffTask: """Get_spiff_task_from_process_instance.""" if processor is None: @@ -737,8 +740,9 @@ def _update_form_schema_with_task_data_as_needed(in_dict: dict, task: Task, spif select_options_from_task_data = task.data.get(task_data_var) if isinstance(select_options_from_task_data, list): if all("value" in d and "label" in d for d in select_options_from_task_data): + def map_function( - task_data_select_option: TaskDataSelectOption, + task_data_select_option: TaskDataSelectOption, ) -> ReactJsonSchemaSelectOption: """Map_function.""" return { @@ -776,9 +780,9 @@ def _get_potential_owner_usernames(assigned_user: AliasedClass) -> Any: def _find_human_task_or_raise( - process_instance_id: int, - task_guid: str, - only_tasks_that_can_be_completed: bool = False, + process_instance_id: int, + task_guid: str, + only_tasks_that_can_be_completed: bool = False, ) -> HumanTaskModel: if only_tasks_that_can_be_completed: human_task_query = HumanTaskModel.query.filter_by( diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_service.py index e0be60c3..a02ed40c 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_service.py @@ -10,7 +10,8 @@ from typing import Tuple from urllib.parse import unquote import sentry_sdk -from flask import current_app, g +from flask import current_app +from flask import g from SpiffWorkflow.bpmn.specs.events.IntermediateEvent import _BoundaryEventParent # type: ignore from SpiffWorkflow.task import Task as SpiffTask # type: ignore @@ -26,8 +27,9 @@ from spiffworkflow_backend.models.process_instance_file_data import ( from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.task import Task from spiffworkflow_backend.models.user import UserModel -from spiffworkflow_backend.services.authorization_service import AuthorizationService, HumanTaskNotFoundError, \ - UserDoesNotHaveAccessToTaskError +from spiffworkflow_backend.services.authorization_service import AuthorizationService +from spiffworkflow_backend.services.authorization_service import HumanTaskNotFoundError +from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError from spiffworkflow_backend.services.git_service import GitCommandError from spiffworkflow_backend.services.git_service import GitService from spiffworkflow_backend.services.process_instance_processor import ( @@ -427,12 +429,13 @@ class ProcessInstanceService: # can complete it. can_complete = False try: - AuthorizationService.assert_user_can_complete_spiff_task(processor.process_instance_model.id, spiff_task, - g.user) + AuthorizationService.assert_user_can_complete_spiff_task( + processor.process_instance_model.id, spiff_task, g.user + ) can_complete = True - except HumanTaskNotFoundError as e: + except HumanTaskNotFoundError: can_complete = False - except UserDoesNotHaveAccessToTaskError as ude: + except UserDoesNotHaveAccessToTaskError: can_complete = False if hasattr(spiff_task.task_spec, "spec"): diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/workflow_execution_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/workflow_execution_service.py index fabdb350..487619b8 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/workflow_execution_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/workflow_execution_service.py @@ -1,6 +1,7 @@ import copy import time -from typing import Callable, List +from typing import Callable +from typing import List from typing import Optional from typing import Set from uuid import UUID @@ -50,11 +51,11 @@ class TaskModelSavingDelegate(EngineStepDelegate): """ def __init__( - self, - serializer: BpmnWorkflowSerializer, - process_instance: ProcessInstanceModel, - bpmn_definition_to_task_definitions_mappings: dict, - secondary_engine_step_delegate: Optional[EngineStepDelegate] = None, + self, + serializer: BpmnWorkflowSerializer, + process_instance: ProcessInstanceModel, + bpmn_definition_to_task_definitions_mappings: dict, + secondary_engine_step_delegate: Optional[EngineStepDelegate] = None, ) -> None: self.secondary_engine_step_delegate = secondary_engine_step_delegate self.process_instance = process_instance @@ -132,12 +133,12 @@ class TaskModelSavingDelegate(EngineStepDelegate): # excludes COMPLETED. the others were required to get PP1 to go to completion. # process FUTURE tasks because Boundary events are not processed otherwise. for waiting_spiff_task in bpmn_process_instance.get_tasks( - TaskState.WAITING - | TaskState.CANCELLED - | TaskState.READY - | TaskState.MAYBE - | TaskState.LIKELY - | TaskState.FUTURE + TaskState.WAITING + | TaskState.CANCELLED + | TaskState.READY + | TaskState.MAYBE + | TaskState.LIKELY + | TaskState.FUTURE ): # these will be removed from the parent and then ignored if waiting_spiff_task._has_state(TaskState.PREDICTED_MASK): @@ -267,17 +268,21 @@ class RunUntilServiceTaskExecutionStrategy(ExecutionStrategy): class RunUntilUserTaskOrMessageExecutionStrategy(ExecutionStrategy): """When you want to run tasks until you hit something to report to the end user, or - until there are no other engine steps to complete.""" + until there are no other engine steps to complete.""" def get_engine_steps(self, bpmn_process_instance: BpmnWorkflow) -> List[SpiffTask]: - return list([t for t in bpmn_process_instance.get_tasks(TaskState.READY) \ - if t.task_spec.spec_type not in ["User Task", "Manual Task"] and - not (hasattr(t.task_spec, "extensions") and - t.task_spec.extensions.get("instructionsForEndUser", None)) - ]) + return list( + [ + t + for t in bpmn_process_instance.get_tasks(TaskState.READY) + if t.task_spec.spec_type not in ["User Task", "Manual Task"] + and not ( + hasattr(t.task_spec, "extensions") and t.task_spec.extensions.get("instructionsForEndUser", None) + ) + ] + ) def spiff_run(self, bpmn_process_instance: BpmnWorkflow, exit_at: None = None) -> None: - engine_steps = self.get_engine_steps(bpmn_process_instance) while engine_steps: for task in engine_steps: @@ -320,12 +325,12 @@ class WorkflowExecutionService: """Provides the driver code for workflow execution.""" def __init__( - self, - bpmn_process_instance: BpmnWorkflow, - process_instance_model: ProcessInstanceModel, - execution_strategy: ExecutionStrategy, - process_instance_completer: ProcessInstanceCompleter, - process_instance_saver: ProcessInstanceSaver, + self, + bpmn_process_instance: BpmnWorkflow, + process_instance_model: ProcessInstanceModel, + execution_strategy: ExecutionStrategy, + process_instance_completer: ProcessInstanceCompleter, + process_instance_saver: ProcessInstanceSaver, ): """__init__.""" self.bpmn_process_instance = bpmn_process_instance @@ -402,12 +407,12 @@ class WorkflowExecutionService: for event in waiting_message_events: # Ensure we are only creating one message instance for each waiting message if ( - MessageInstanceModel.query.filter_by( - process_instance_id=self.process_instance_model.id, - message_type="receive", - name=event["name"], - ).count() - > 0 + MessageInstanceModel.query.filter_by( + process_instance_id=self.process_instance_model.id, + message_type="receive", + name=event["name"], + ).count() + > 0 ): continue diff --git a/spiffworkflow-backend/tests/data/interstitial/interstitial.bpmn b/spiffworkflow-backend/tests/data/interstitial/interstitial.bpmn index ec386e56..576f49e9 100644 --- a/spiffworkflow-backend/tests/data/interstitial/interstitial.bpmn +++ b/spiffworkflow-backend/tests/data/interstitial/interstitial.bpmn @@ -120,4 +120,4 @@ - \ No newline at end of file + diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_for_good_errors.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_for_good_errors.py index 51c27a6d..f0a9e973 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_for_good_errors.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_for_good_errors.py @@ -3,14 +3,13 @@ from typing import Any from flask.app import Flask from flask.testing import FlaskClient - -from spiffworkflow_backend.routes.tasks_controller import _interstitial_stream from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec from spiffworkflow_backend import db from spiffworkflow_backend.models.human_task import HumanTaskModel from spiffworkflow_backend.models.user import UserModel +from spiffworkflow_backend.routes.tasks_controller import _interstitial_stream class TestForGoodErrors(BaseTest): @@ -22,7 +21,6 @@ class TestForGoodErrors(BaseTest): client: FlaskClient, with_super_admin_user: UserModel, ) -> Any: - # Call this to assure all engine-steps are fully processed before we search for human tasks. _interstitial_stream(process_instance_id) 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 7ce70e90..7398d0f4 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -10,8 +10,6 @@ import pytest from flask.app import Flask from flask.testing import FlaskClient from SpiffWorkflow.task import TaskState # type: ignore - -from spiffworkflow_backend.routes.tasks_controller import _interstitial_stream from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec @@ -35,6 +33,7 @@ from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.task import TaskModel # noqa: F401 from spiffworkflow_backend.models.user import UserModel +from spiffworkflow_backend.routes.tasks_controller import _interstitial_stream from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.file_system_service import FileSystemService from spiffworkflow_backend.services.process_instance_processor import ( @@ -1615,13 +1614,12 @@ class TestProcessApi(BaseTest): } def test_interstitial_page( - self, + self, app: Flask, client: FlaskClient, with_db_and_bpmn_file_cleanup: None, with_super_admin_user: UserModel, ) -> None: - process_group_id = "my_process_group" process_model_id = "interstitial" bpmn_file_location = "interstitial" @@ -1649,23 +1647,24 @@ class TestProcessApi(BaseTest): assert response.json is not None assert response.json["next_task"] is not None - assert response.json["next_task"]["state"] == 'READY' - assert response.json["next_task"]["title"] == 'Script Task #2' + assert response.json["next_task"]["state"] == "READY" + assert response.json["next_task"]["title"] == "Script Task #2" # Rather that call the API and deal with the Server Side Events, call the loop directly and covert it to # a list. It tests all of our code. No reason to test Flasks SSE support. results = list(_interstitial_stream(process_instance_id)) - json_results = list(map(lambda x: json.loads(x[5:]), results)) # strip the "data:" prefix and convert remaining string to dict. + # strip the "data:" prefix and convert remaining string to dict. + json_results = list(map(lambda x: json.loads(x[5:]), results)) # There should be 2 results back - # the first script task should not be returned (it contains no end user instructions) # The second script task should produce rendered jinja text # The Manual Task should then return a message as well. assert len(results) == 2 - assert json_results[0]["state"] == 'READY' - assert json_results[0]["title"] == 'Script Task #2' - assert json_results[0]["properties"]["instructionsForEndUser"] == 'I am Script Task 2' - assert json_results[1]["state"] == 'READY' - assert json_results[1]["title"] == 'Manual Task' + assert json_results[0]["state"] == "READY" + assert json_results[0]["title"] == "Script Task #2" + assert json_results[0]["properties"]["instructionsForEndUser"] == "I am Script Task 2" + assert json_results[1]["state"] == "READY" + assert json_results[1]["title"] == "Manual Task" response = client.put( f"/v1.0/tasks/{process_instance_id}/{json_results[1]['id']}", @@ -1678,10 +1677,10 @@ class TestProcessApi(BaseTest): results = list(_interstitial_stream(process_instance_id)) json_results = list(map(lambda x: json.loads(x[5:]), results)) assert len(results) == 1 - assert json_results[0]["state"] == 'READY' + assert json_results[0]["state"] == "READY" assert json_results[0]["can_complete"] == False - assert json_results[0]["title"] == 'Please Approve' - assert json_results[0]["properties"]["instructionsForEndUser"] == 'I am a manual task in another lane' + assert json_results[0]["title"] == "Please Approve" + assert json_results[0]["properties"]["instructionsForEndUser"] == "I am a manual task in another lane" # Complete task as the finance user. response = client.put( @@ -1690,13 +1689,13 @@ class TestProcessApi(BaseTest): ) # We should now be on the end task with a valid message, even after loading it many times. - results_1 = list(_interstitial_stream(process_instance_id)) - results_2 = list(_interstitial_stream(process_instance_id)) + list(_interstitial_stream(process_instance_id)) + list(_interstitial_stream(process_instance_id)) results = list(_interstitial_stream(process_instance_id)) json_results = list(map(lambda x: json.loads(x[5:]), results)) assert len(json_results) == 1 - assert json_results[0]["state"] == 'COMPLETED' - assert json_results[0]["properties"]["instructionsForEndUser"] == 'I am the end task' + assert json_results[0]["state"] == "COMPLETED" + assert json_results[0]["properties"]["instructionsForEndUser"] == "I am the end task" def test_process_instance_list_with_default_list( self, diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py index e9326363..c8a33917 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py @@ -405,7 +405,7 @@ class TestProcessInstanceProcessor(BaseTest): process_model=process_model, user=initiator_user ) processor = ProcessInstanceProcessor(process_instance) - processor.do_engine_steps(save=True) + processor.do_engine_steps(save=True, execution_strategy_name="greedy") assert len(process_instance.active_human_tasks) == 1 initial_human_task_id = process_instance.active_human_tasks[0].id @@ -436,7 +436,8 @@ class TestProcessInstanceProcessor(BaseTest): # recreate variables to ensure all bpmn json was recreated from scratch from the db process_instance_relookup = ProcessInstanceModel.query.filter_by(id=process_instance.id).first() processor_final = ProcessInstanceProcessor(process_instance_relookup) - processor.do_engine_steps(save=True, execution_strategy_name="greedy") + processor_final.do_engine_steps(save=True, execution_strategy_name="greedy") + assert process_instance_relookup.status == "complete" data_set_1 = {"set_in_top_level_script": 1} @@ -548,7 +549,6 @@ class TestProcessInstanceProcessor(BaseTest): # assert task_model.python_env_data() == expected_python_env_data, message assert task_model.json_data() == expected_python_env_data, message - processor_final.do_engine_steps(save=True, execution_strategy_name="greedy") all_spiff_tasks = processor_final.bpmn_process_instance.get_tasks() assert len(all_spiff_tasks) > 1 for spiff_task in all_spiff_tasks: @@ -607,7 +607,7 @@ class TestProcessInstanceProcessor(BaseTest): ) assert task_models_that_are_predicted_count == 0 - assert processor.get_data() == data_set_7 + assert processor_final.get_data() == data_set_7 def test_does_not_recreate_human_tasks_on_multiple_saves( self, diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index 8e027fe1..f8ed3986 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -4477,11 +4477,6 @@ "@lezer/common": "^1.0.0" } }, - "node_modules/@microsoft/fetch-event-source": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", - "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==" - }, "node_modules/@lezer/markdown": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.2.tgz", @@ -4492,6 +4487,11 @@ "@lezer/highlight": "^1.0.0" } }, + "node_modules/@microsoft/fetch-event-source": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", + "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==" + }, "node_modules/@monaco-editor/loader": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz", @@ -35359,11 +35359,6 @@ "@lezer/common": "^1.0.0" } }, - "@microsoft/fetch-event-source": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", - "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==" - }, "@lezer/markdown": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.2.tgz", @@ -35374,6 +35369,11 @@ "@lezer/highlight": "^1.0.0" } }, + "@microsoft/fetch-event-source": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", + "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==" + }, "@monaco-editor/loader": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz", diff --git a/spiffworkflow-frontend/src/components/InstructionsForEndUser.tsx b/spiffworkflow-frontend/src/components/InstructionsForEndUser.tsx index a53f6c55..c779e952 100644 --- a/spiffworkflow-frontend/src/components/InstructionsForEndUser.tsx +++ b/spiffworkflow-frontend/src/components/InstructionsForEndUser.tsx @@ -7,7 +7,7 @@ export default function InstructionsForEndUser({ task }: any) { return null; } let instructions = ''; - console.log("I was passed a task: ", task); + console.log('I was passed a task: ', task); const { properties } = task; const { instructionsForEndUser } = properties; if (instructionsForEndUser) { diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index f76f11c9..939a336e 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -1455,7 +1455,8 @@ export default function ProcessInstanceListTable({ if (showActionsColumn) { let buttonElement = null; const interstitialUrl = `/process/${modifyProcessIdentifierForPathParam( - row.process_model_identifier)}/${row.id}/interstitial` + row.process_model_identifier + )}/${row.id}/interstitial`; const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`); let hasAccessToCompleteTask = false; if ( diff --git a/spiffworkflow-frontend/src/routes/HomePageRoutes.tsx b/spiffworkflow-frontend/src/routes/HomePageRoutes.tsx index 061aa248..eee6ad37 100644 --- a/spiffworkflow-frontend/src/routes/HomePageRoutes.tsx +++ b/spiffworkflow-frontend/src/routes/HomePageRoutes.tsx @@ -56,7 +56,10 @@ export default function HomePageRoutes() { } /> } /> } /> - } /> + } + /> } /> } /> diff --git a/spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx b/spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx index cf591017..3b367b57 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInterstitial.tsx @@ -75,7 +75,12 @@ export default function ProcessInterstitial() { case 'COMPLETED': return Completed; case 'LOCKED': - return Locked, Waiting on someone else.; + return ( + Locked, Waiting on someone else. + ); default: return null; } @@ -86,11 +91,13 @@ export default function ProcessInterstitial() { !myTask.can_complete && ['User Task', 'Manual Task'].includes(myTask.type) ) { - return ( -
This next task must be completed by a different person.
- ); + return
This next task must be completed by a different person.
; } - return
; + return ( +
+ +
+ ); }; if (lastTask) { @@ -116,7 +123,9 @@ export default function ProcessInterstitial() { {data && data.map((d) => ( -
+
Task: {d.title}
diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index aafbe3f8..3986242f 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -126,7 +126,6 @@ export default function TaskShow() { ); }; - useEffect(() => { const processResult = (result: ProcessInstanceTask) => { setTask(result);