handle subprocesses in navigation
This commit is contained in:
parent
9962629d95
commit
d6e658ab07
|
@ -34,6 +34,8 @@ from SpiffWorkflow.bpmn.serializer.workflow import BpmnWorkflowSerializer # typ
|
||||||
from SpiffWorkflow.bpmn.specs.BpmnProcessSpec import BpmnProcessSpec # type: ignore
|
from SpiffWorkflow.bpmn.specs.BpmnProcessSpec import BpmnProcessSpec # type: ignore
|
||||||
from SpiffWorkflow.bpmn.specs.events.EndEvent import EndEvent # type: ignore
|
from SpiffWorkflow.bpmn.specs.events.EndEvent import EndEvent # type: ignore
|
||||||
from SpiffWorkflow.bpmn.specs.events.event_definitions import CancelEventDefinition # type: ignore
|
from SpiffWorkflow.bpmn.specs.events.event_definitions import CancelEventDefinition # type: ignore
|
||||||
|
from SpiffWorkflow.bpmn.specs.events.StartEvent import StartEvent # type: ignore
|
||||||
|
from SpiffWorkflow.bpmn.specs.SubWorkflowTask import SubWorkflowTask # type: ignore
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow # type: ignore
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow # type: ignore
|
||||||
from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore
|
from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore
|
||||||
from SpiffWorkflow.dmn.serializer.task_spec_converters import BusinessRuleTaskConverter # type: ignore
|
from SpiffWorkflow.dmn.serializer.task_spec_converters import BusinessRuleTaskConverter # type: ignore
|
||||||
|
@ -68,7 +70,6 @@ from SpiffWorkflow.spiff.serializer.task_spec_converters import UserTaskConverte
|
||||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
from SpiffWorkflow.util.deep_merge import DeepMerge # type: ignore
|
from SpiffWorkflow.util.deep_merge import DeepMerge # type: ignore
|
||||||
|
|
||||||
from spiffworkflow_backend.models.file import File
|
from spiffworkflow_backend.models.file import File
|
||||||
from spiffworkflow_backend.models.file import FileType
|
from spiffworkflow_backend.models.file import FileType
|
||||||
from spiffworkflow_backend.models.group import GroupModel
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
@ -301,7 +302,9 @@ class ProcessInstanceProcessor:
|
||||||
tld.spiff_step = process_instance_model.spiff_step
|
tld.spiff_step = process_instance_model.spiff_step
|
||||||
|
|
||||||
# we want this to be the fully qualified path to the process model including all group subcomponents
|
# we want this to be the fully qualified path to the process model including all group subcomponents
|
||||||
current_app.config["THREAD_LOCAL_DATA"].process_model_identifier = (
|
current_app.config[
|
||||||
|
"THREAD_LOCAL_DATA"
|
||||||
|
].process_model_identifier = (
|
||||||
f"{process_instance_model.process_model_identifier}"
|
f"{process_instance_model.process_model_identifier}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -655,9 +658,9 @@ class ProcessInstanceProcessor:
|
||||||
"""
|
"""
|
||||||
for task_id, subprocess_id in subprocesses_by_child_task_ids.items():
|
for task_id, subprocess_id in subprocesses_by_child_task_ids.items():
|
||||||
if subprocess_id in subprocesses_by_child_task_ids:
|
if subprocess_id in subprocesses_by_child_task_ids:
|
||||||
subprocesses_by_child_task_ids[task_id] = (
|
subprocesses_by_child_task_ids[
|
||||||
subprocesses_by_child_task_ids[subprocess_id]
|
task_id
|
||||||
)
|
] = subprocesses_by_child_task_ids[subprocess_id]
|
||||||
self.get_highest_level_subprocesses_by_child_task_ids(
|
self.get_highest_level_subprocesses_by_child_task_ids(
|
||||||
subprocesses_by_child_task_ids
|
subprocesses_by_child_task_ids
|
||||||
)
|
)
|
||||||
|
@ -787,6 +790,15 @@ class ProcessInstanceProcessor:
|
||||||
f"Manually executing Task {spiff_task.task_spec.name} of process"
|
f"Manually executing Task {spiff_task.task_spec.name} of process"
|
||||||
f" instance {self.process_instance_model.id}"
|
f" instance {self.process_instance_model.id}"
|
||||||
)
|
)
|
||||||
|
# Executing a subworkflow manually will restart its subprocess and allow stepping through it
|
||||||
|
if isinstance(spiff_task.task_spec, SubWorkflowTask):
|
||||||
|
subprocess = self.bpmn_process_instance.get_subprocess(spiff_task)
|
||||||
|
# We have to get to the actual start event
|
||||||
|
for task in self.bpmn_process_instance.get_tasks(workflow=subprocess):
|
||||||
|
task.complete()
|
||||||
|
if isinstance(task.task_spec, StartEvent):
|
||||||
|
break
|
||||||
|
else:
|
||||||
spiff_task.complete()
|
spiff_task.complete()
|
||||||
else:
|
else:
|
||||||
spiff_logger = logging.getLogger("spiff")
|
spiff_logger = logging.getLogger("spiff")
|
||||||
|
@ -796,7 +808,20 @@ class ProcessInstanceProcessor:
|
||||||
spiff_task._set_state(TaskState.COMPLETED)
|
spiff_task._set_state(TaskState.COMPLETED)
|
||||||
for child in spiff_task.children:
|
for child in spiff_task.children:
|
||||||
child.task_spec._update(child)
|
child.task_spec._update(child)
|
||||||
self.bpmn_process_instance.last_task = spiff_task
|
spiff_task.workflow.last_task = spiff_task
|
||||||
|
|
||||||
|
if isinstance(spiff_task.task_spec, EndEvent):
|
||||||
|
for task in self.bpmn_process_instance.get_tasks(
|
||||||
|
TaskState.DEFINITE_MASK, workflow=spiff_task.workflow
|
||||||
|
):
|
||||||
|
task.complete()
|
||||||
|
|
||||||
|
# A subworkflow task will become ready when its workflow is complete. Engine steps would normally
|
||||||
|
# then complete it, but we have to do it ourselves here.
|
||||||
|
for task in self.bpmn_process_instance.get_tasks(TaskState.READY):
|
||||||
|
if isinstance(task.task_spec, SubWorkflowTask):
|
||||||
|
task.complete()
|
||||||
|
|
||||||
self.increment_spiff_step()
|
self.increment_spiff_step()
|
||||||
self.add_step()
|
self.add_step()
|
||||||
self.save()
|
self.save()
|
||||||
|
|
|
@ -528,11 +528,24 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isCurrentTask = (task: any) => {
|
||||||
|
const subprocessTypes = [
|
||||||
|
'Subprocess',
|
||||||
|
'Call Activity',
|
||||||
|
'Transactional Subprocess',
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
(task.state === 'WAITING' &&
|
||||||
|
subprocessTypes.filter((t) => t === task.type).length > 0) ||
|
||||||
|
task.state === 'READY'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const canEditTaskData = (task: any) => {
|
const canEditTaskData = (task: any) => {
|
||||||
return (
|
return (
|
||||||
processInstance &&
|
processInstance &&
|
||||||
ability.can('PUT', targetUris.processInstanceTaskListDataPath) &&
|
ability.can('PUT', targetUris.processInstanceTaskListDataPath) &&
|
||||||
task.state === 'READY' &&
|
isCurrentTask(task) &&
|
||||||
processInstance.status === 'suspended' &&
|
processInstance.status === 'suspended' &&
|
||||||
showingLastSpiffStep()
|
showingLastSpiffStep()
|
||||||
);
|
);
|
||||||
|
@ -556,7 +569,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
||||||
processInstance &&
|
processInstance &&
|
||||||
processInstance.status === 'suspended' &&
|
processInstance.status === 'suspended' &&
|
||||||
ability.can('POST', targetUris.processInstanceCompleteTaskPath) &&
|
ability.can('POST', targetUris.processInstanceCompleteTaskPath) &&
|
||||||
task.state === 'READY' &&
|
isCurrentTask(task) &&
|
||||||
showingLastSpiffStep()
|
showingLastSpiffStep()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue