stop at call activity as well when getting calling subprocesses by child id w/ burnettk

This commit is contained in:
jasquat 2023-01-13 10:43:25 -05:00
parent ecfea3f605
commit 189dbc2712
3 changed files with 67 additions and 21 deletions

View File

@ -556,9 +556,11 @@ def process_instance_task_list(
else: else:
spiff_tasks = processor.get_all_user_tasks() spiff_tasks = processor.get_all_user_tasks()
subprocesses_by_child_task_ids = processor.get_subprocesses_by_child_task_ids() subprocesses_by_child_task_ids, task_typename_by_task_id = (
processor.get_highest_level_subprocesses_by_child_task_ids( processor.get_subprocesses_by_child_task_ids()
subprocesses_by_child_task_ids )
processor.get_highest_level_calling_subprocesses_by_child_task_ids(
subprocesses_by_child_task_ids, task_typename_by_task_id
) )
tasks = [] tasks = []

View File

@ -625,7 +625,25 @@ class ProcessInstanceProcessor:
db.session.add(pim) db.session.add(pim)
db.session.commit() db.session.commit()
def get_subprocesses_by_child_task_ids(self) -> dict: def get_all_task_specs(self) -> dict[str, dict]:
"""This looks both at top level task_specs and subprocess_specs in the serialized data.
It returns a dict of all task specs based on the task name like it is in the serialized form.
NOTE: this may not fully work for tasks that are NOT call activities since their task_name may no be unique
but in our current use case we only care about the call activities here.
"""
serialized_data = json.loads(self.serialize())
spiff_task_json = serialized_data["spec"]["task_specs"] or {}
if "subprocess_specs" in serialized_data:
for _subprocess_task_name, subprocess_details in serialized_data[
"subprocess_specs"
].items():
if "task_specs" in subprocess_details:
spiff_task_json = spiff_task_json | subprocess_details["task_specs"]
return spiff_task_json
def get_subprocesses_by_child_task_ids(self) -> Tuple[dict, dict]:
"""Get all subprocess ids based on the child task ids. """Get all subprocess ids based on the child task ids.
This is useful when trying to link the child task of a call activity back to This is useful when trying to link the child task of a call activity back to
@ -641,27 +659,45 @@ class ProcessInstanceProcessor:
call activities like subprocesses in terms of the serialization. call activities like subprocesses in terms of the serialization.
""" """
bpmn_json = json.loads(self.serialize()) bpmn_json = json.loads(self.serialize())
spiff_task_json = self.get_all_task_specs()
subprocesses_by_child_task_ids = {} subprocesses_by_child_task_ids = {}
task_typename_by_task_id = {}
if "subprocesses" in bpmn_json: if "subprocesses" in bpmn_json:
for subprocess_id, subprocess_details in bpmn_json["subprocesses"].items(): for subprocess_id, subprocess_details in bpmn_json["subprocesses"].items():
for task_id in subprocess_details["tasks"]: for task_id, task_details in subprocess_details["tasks"].items():
subprocesses_by_child_task_ids[task_id] = subprocess_id subprocesses_by_child_task_ids[task_id] = subprocess_id
return subprocesses_by_child_task_ids task_name = task_details["task_spec"]
if task_name in spiff_task_json:
task_typename_by_task_id[task_id] = spiff_task_json[task_name][
"typename"
]
return (subprocesses_by_child_task_ids, task_typename_by_task_id)
def get_highest_level_subprocesses_by_child_task_ids( def get_highest_level_calling_subprocesses_by_child_task_ids(
self, subprocesses_by_child_task_ids: dict self, subprocesses_by_child_task_ids: dict, task_typename_by_task_id: dict
) -> dict: ) -> dict:
"""Ensure task ids point to the top level subprocess id. """Ensure task ids point to the top level subprocess id.
This is done by checking if a subprocess is also a task until the subprocess is no longer a task. This is done by checking if a subprocess is also a task until the subprocess is no longer a task or a Call Activity.
""" """
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:
current_subprocess_id_for_task = subprocesses_by_child_task_ids[task_id]
if current_subprocess_id_for_task in task_typename_by_task_id:
# a call activity is like the top-level subprocess since it is the calling subprocess
# according to spiff and the top-level calling subprocess is really what we care about
if (
task_typename_by_task_id[current_subprocess_id_for_task]
== "CallActivity"
):
continue
subprocesses_by_child_task_ids[task_id] = ( subprocesses_by_child_task_ids[task_id] = (
subprocesses_by_child_task_ids[subprocess_id] subprocesses_by_child_task_ids[subprocess_id]
) )
self.get_highest_level_subprocesses_by_child_task_ids( self.get_highest_level_calling_subprocesses_by_child_task_ids(
subprocesses_by_child_task_ids subprocesses_by_child_task_ids, task_typename_by_task_id
) )
return subprocesses_by_child_task_ids return subprocesses_by_child_task_ids

View File

@ -200,19 +200,21 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
const getTaskIds = () => { const getTaskIds = () => {
const taskIds = { completed: [], readyOrWaiting: [] }; const taskIds = { completed: [], readyOrWaiting: [] };
if (tasks) { if (tasks) {
const callingSubprocessId = searchParams.get('call_activity_task_id');
tasks.forEach(function getUserTasksElement(task: ProcessInstanceTask) { tasks.forEach(function getUserTasksElement(task: ProcessInstanceTask) {
const callingSubprocessId = searchParams.get('call_activity_task_id');
if ( if (
!callingSubprocessId || callingSubprocessId &&
callingSubprocessId === task.calling_subprocess_task_id callingSubprocessId !== task.calling_subprocess_task_id
) { ) {
if (task.state === 'COMPLETED') { return null;
(taskIds.completed as any).push(task);
}
if (task.state === 'READY' || task.state === 'WAITING') {
(taskIds.readyOrWaiting as any).push(task);
}
} }
if (task.state === 'COMPLETED') {
(taskIds.completed as any).push(task);
}
if (task.state === 'READY' || task.state === 'WAITING') {
(taskIds.readyOrWaiting as any).push(task);
}
return null;
}); });
} }
return taskIds; return taskIds;
@ -904,6 +906,10 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay }; const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay };
const candidateEvents: any = getEvents(taskToUse); const candidateEvents: any = getEvents(taskToUse);
if (taskToDisplay) { if (taskToDisplay) {
let taskTitleText = taskToUse.id;
if (taskToUse.title) {
taskTitleText += ` (${taskToUse.title})`;
}
return ( return (
<Modal <Modal
open={!!taskToUse} open={!!taskToUse}
@ -911,7 +917,9 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
onRequestClose={handleTaskDataDisplayClose} onRequestClose={handleTaskDataDisplayClose}
> >
<Stack orientation="horizontal" gap={2}> <Stack orientation="horizontal" gap={2}>
{taskToUse.name} ({taskToUse.type}): {taskToUse.state} <span title={taskTitleText}>{taskToUse.name}</span> (
{taskToUse.type}
): {taskToUse.state}
{taskDisplayButtons(taskToUse)} {taskDisplayButtons(taskToUse)}
</Stack> </Stack>
{selectingEvent {selectingEvent