fixed test w/ burnettk

This commit is contained in:
jasquat 2023-04-19 15:52:11 -04:00
parent d73baedcbe
commit b1568fb472
13 changed files with 156 additions and 135 deletions

View File

@ -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(

View File

@ -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"):

View File

@ -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

View File

@ -120,4 +120,4 @@
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
</bpmn:definitions>

View File

@ -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)

View File

@ -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,

View File

@ -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,

View File

@ -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",

View File

@ -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) {

View File

@ -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 (

View File

@ -56,7 +56,10 @@ export default function HomePageRoutes() {
<Route path="my-tasks" element={<MyTasks />} />
<Route path=":process_instance_id/:task_id" element={<TaskShow />} />
<Route path="grouped" element={<InProgressInstances />} />
<Route path="process/:process_instance_id/interstitial" element={<ProcessInterstitial />} />
<Route
path="process/:process_instance_id/interstitial"
element={<ProcessInterstitial />}
/>
<Route path="completed-instances" element={<CompletedInstances />} />
<Route path="create-new-instance" element={<CreateNewInstance />} />
</Routes>

View File

@ -75,7 +75,12 @@ export default function ProcessInterstitial() {
case 'COMPLETED':
return <img src="/interstitial/checkmark.png" alt="Completed" />;
case 'LOCKED':
return <img src="/interstitial/lock.png" alt="Locked, Waiting on someone else." />;
return (
<img
src="/interstitial/lock.png"
alt="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 (
<div>This next task must be completed by a different person.</div>
);
return <div>This next task must be completed by a different person.</div>;
}
return <div><InstructionsForEndUser task={myTask} /></div>;
return (
<div>
<InstructionsForEndUser task={myTask} />
</div>
);
};
if (lastTask) {
@ -116,7 +123,9 @@ export default function ProcessInterstitial() {
<Column md={6} lg={8} sm={4}>
{data &&
data.map((d) => (
<div style={{ display: 'flex', alignItems: 'center', gap: '2em' }}>
<div
style={{ display: 'flex', alignItems: 'center', gap: '2em' }}
>
<div>
Task: <em>{d.title}</em>
</div>

View File

@ -126,7 +126,6 @@ export default function TaskShow() {
);
};
useEffect(() => {
const processResult = (result: ProcessInstanceTask) => {
setTask(result);