some fixes to ensure we display the correct task data for the diagram elements w/ burnettk

This commit is contained in:
jasquat 2022-12-13 14:16:28 -05:00
parent f6462d83af
commit 620d054586
10 changed files with 77 additions and 43 deletions

View File

@ -1,4 +1,3 @@
"""Spiff_step_details."""
from dataclasses import dataclass
from flask_bpmn.models.db import db

View File

@ -108,7 +108,7 @@ class Task:
multi_instance_type: Union[MultiInstanceType, None] = None,
multi_instance_count: str = "",
multi_instance_index: str = "",
process_name: str = "",
process_identifier: str = "",
properties: Union[dict, None] = None,
process_instance_id: Union[int, None] = None,
process_instance_status: Union[str, None] = None,
@ -153,7 +153,7 @@ class Task:
self.multi_instance_index = (
multi_instance_index # And the index of the currently repeating task.
)
self.process_name = process_name
self.process_identifier = process_identifier
self.properties = properties # Arbitrary extension properties from BPMN editor.
if self.properties is None:
@ -179,7 +179,7 @@ class Task:
"multi_instance_type": multi_instance_type,
"multi_instance_count": self.multi_instance_count,
"multi_instance_index": self.multi_instance_index,
"process_name": self.process_name,
"process_identifier": self.process_identifier,
"properties": self.properties,
"process_instance_id": self.process_instance_id,
"process_instance_status": self.process_instance_status,
@ -285,7 +285,7 @@ class TaskSchema(Schema):
"multi_instance_type",
"multi_instance_count",
"multi_instance_index",
"process_name",
"process_identifier",
"properties",
"process_instance_id",
"form_schema",
@ -296,7 +296,7 @@ class TaskSchema(Schema):
documentation = marshmallow.fields.String(required=False, allow_none=True)
# form = marshmallow.fields.Nested(FormSchema, required=False, allow_none=True)
title = marshmallow.fields.String(required=False, allow_none=True)
process_name = marshmallow.fields.String(required=False, allow_none=True)
process_identifier = marshmallow.fields.String(required=False, allow_none=True)
lane = marshmallow.fields.String(required=False, allow_none=True)
@marshmallow.post_load

View File

@ -321,7 +321,7 @@ class ProcessInstanceService:
multi_instance_type=mi_type,
multi_instance_count=info["mi_count"],
multi_instance_index=info["mi_index"],
process_name=spiff_task.task_spec._wf_spec.description,
process_identifier=spiff_task.task_spec._wf_spec.name,
properties=props,
parent=parent_id,
call_activity_process_identifier=call_activity_process_identifier,

View File

@ -300,7 +300,7 @@ export default function ProcessInstanceListTable({
checkFiltersAndRun();
if (autoReload) {
refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, checkFiltersAndRun);
return refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, checkFiltersAndRun);
}
}, [
autoReload,

View File

@ -58,14 +58,14 @@ import HttpService from '../services/HttpService';
import ButtonWithConfirmation from './ButtonWithConfirmation';
import { makeid } from '../helpers';
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
import { PermissionsToCheck } from '../interfaces';
import { PermissionsToCheck, ProcessInstanceTask } from '../interfaces';
import { usePermissionFetcher } from '../hooks/PermissionService';
type OwnProps = {
processModelId: string;
diagramType: string;
readyOrWaitingBpmnTaskIds?: string[] | null;
completedTasksBpmnIds?: string[] | null;
readyOrWaitingProcessInstanceTasks?: ProcessInstanceTask[] | null;
completedProcessInstanceTasks?: ProcessInstanceTask[] | null;
saveDiagram?: (..._args: any[]) => any;
onDeleteFile?: (..._args: any[]) => any;
onSetPrimaryFile?: (..._args: any[]) => any;
@ -88,8 +88,8 @@ type OwnProps = {
export default function ReactDiagramEditor({
processModelId,
diagramType,
readyOrWaitingBpmnTaskIds,
completedTasksBpmnIds,
readyOrWaitingProcessInstanceTasks,
completedProcessInstanceTasks,
saveDiagram,
onDeleteFile,
onSetPrimaryFile,
@ -227,7 +227,9 @@ export default function ReactDiagramEditor({
function handleElementClick(event: any) {
if (onElementClick) {
onElementClick(event.element);
const canvas = diagramModeler.get('canvas');
const rootElement = canvas.getRootElement();
onElementClick(event.element, rootElement);
}
}
@ -350,12 +352,15 @@ export default function ReactDiagramEditor({
function highlightBpmnIoElement(
canvas: any,
taskBpmnId: string,
bpmnIoClassName: string
processInstanceTask: ProcessInstanceTask,
bpmnIoClassName: string,
bpmnRootElementId: string
) {
if (checkTaskCanBeHighlighted(taskBpmnId)) {
if (checkTaskCanBeHighlighted(processInstanceTask.name)) {
try {
canvas.addMarker(taskBpmnId, bpmnIoClassName);
if (bpmnRootElementId === processInstanceTask.process_identifier) {
canvas.addMarker(processInstanceTask.name, bpmnIoClassName);
}
} catch (bpmnIoError: any) {
// the task list also contains task for processes called from call activities which will
// not exist in this diagram so just ignore them for now.
@ -394,21 +399,25 @@ export default function ReactDiagramEditor({
// highlighting a field
// Option 3 at:
// https://github.com/bpmn-io/bpmn-js-examples/tree/master/colors
if (readyOrWaitingBpmnTaskIds) {
readyOrWaitingBpmnTaskIds.forEach((readyOrWaitingBpmnTaskId) => {
if (readyOrWaitingProcessInstanceTasks) {
const rootElement = canvas.getRootElement();
readyOrWaitingProcessInstanceTasks.forEach((readyOrWaitingBpmnTask) => {
highlightBpmnIoElement(
canvas,
readyOrWaitingBpmnTaskId,
'active-task-highlight'
readyOrWaitingBpmnTask,
'active-task-highlight',
rootElement.id
);
});
}
if (completedTasksBpmnIds) {
completedTasksBpmnIds.forEach((completedTaskBpmnId) => {
if (completedProcessInstanceTasks) {
const rootElement = canvas.getRootElement();
completedProcessInstanceTasks.forEach((completedTask) => {
highlightBpmnIoElement(
canvas,
completedTaskBpmnId,
'completed-task-highlight'
completedTask,
'completed-task-highlight',
rootElement.id
);
});
}
@ -484,8 +493,8 @@ export default function ReactDiagramEditor({
diagramType,
diagramXML,
diagramXMLString,
readyOrWaitingBpmnTaskIds,
completedTasksBpmnIds,
readyOrWaitingProcessInstanceTasks,
completedProcessInstanceTasks,
fileName,
performingXmlUpdates,
processModelId,

View File

@ -41,7 +41,7 @@ export default function MyOpenProcesses() {
});
};
getTasks();
refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, getTasks);
return refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, getTasks);
}, [searchParams]);
const buildTable = () => {

View File

@ -41,7 +41,7 @@ export default function TasksWaitingForMyGroups() {
});
};
getTasks();
refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, getTasks);
return refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, getTasks);
}, [searchParams]);
const buildTable = () => {

View File

@ -208,5 +208,8 @@ export const refreshAtInterval = (
() => clearInterval(intervalRef),
timeout * 1000
);
return [intervalRef, timeoutRef];
return () => {
clearInterval(intervalRef);
clearTimeout(timeoutRef);
};
};

View File

@ -11,6 +11,13 @@ export interface RecentProcessModel {
processModelDisplayName: string;
}
export interface ProcessInstanceTask {
id: string;
state: string;
process_identifier: string;
name: string;
}
export interface ProcessReference {
name: string; // The process or decision Display name.
identifier: string; // The unique id of the process
@ -39,6 +46,7 @@ export interface ProcessInstance {
id: number;
process_model_identifier: string;
process_model_display_name: string;
spiff_step?: number;
}
export interface MessageCorrelationProperties {

View File

@ -39,7 +39,11 @@ import {
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
import ErrorContext from '../contexts/ErrorContext';
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
import { PermissionsToCheck } from '../interfaces';
import {
PermissionsToCheck,
ProcessInstance,
ProcessInstanceTask,
} from '../interfaces';
import { usePermissionFetcher } from '../hooks/PermissionService';
export default function ProcessInstanceShow() {
@ -47,8 +51,9 @@ export default function ProcessInstanceShow() {
const params = useParams();
const [searchParams] = useSearchParams();
const [processInstance, setProcessInstance] = useState(null);
const [tasks, setTasks] = useState<Array<object> | null>(null);
const [processInstance, setProcessInstance] =
useState<ProcessInstance | null>(null);
const [tasks, setTasks] = useState<ProcessInstanceTask[] | null>(null);
const [tasksCallHadError, setTasksCallHadError] = useState<boolean>(false);
const [taskToDisplay, setTaskToDisplay] = useState<object | null>(null);
const [taskDataToDisplay, setTaskDataToDisplay] = useState<string>('');
@ -158,12 +163,12 @@ export default function ProcessInstanceShow() {
const getTaskIds = () => {
const taskIds = { completed: [], readyOrWaiting: [] };
if (tasks) {
tasks.forEach(function getUserTasksElement(task: any) {
tasks.forEach(function getUserTasksElement(task: ProcessInstanceTask) {
if (task.state === 'COMPLETED') {
(taskIds.completed as any).push(task.name);
(taskIds.completed as any).push(task);
}
if (task.state === 'READY' || task.state === 'WAITING') {
(taskIds.readyOrWaiting as any).push(task.name);
(taskIds.readyOrWaiting as any).push(task);
}
});
}
@ -193,13 +198,18 @@ export default function ProcessInstanceShow() {
label: any,
distance: number
) => {
const processIdentifier = searchParams.get('process_identifier');
let queryParams = '';
if (processIdentifier) {
queryParams = `?process_identifier=${processIdentifier}`;
}
return (
<Link
reloadDocument
data-qa="process-instance-step-link"
to={`/admin/process-instances/${params.process_model_id}/${
params.process_instance_id
}/${currentSpiffStep(processInstanceToUse) + distance}`}
}/${currentSpiffStep(processInstanceToUse) + distance}${queryParams}`}
>
{label}
</Link>
@ -380,10 +390,15 @@ export default function ProcessInstanceShow() {
}
};
const handleClickedDiagramTask = (shapeElement: any) => {
const handleClickedDiagramTask = (
shapeElement: any,
bpmnRootElement: any
) => {
if (tasks) {
const matchingTask: any = tasks.find(
(task: any) => task.name === shapeElement.id
(task: any) =>
task.name === shapeElement.id &&
task.process_identifier === bpmnRootElement.id
);
if (matchingTask) {
setTaskToDisplay(matchingTask);
@ -491,7 +506,7 @@ export default function ProcessInstanceShow() {
buttons.push(
<Link
data-qa="go-to-call-activity-result"
to={`/admin/process-instances/${params.process_model_id}/${params.process_instance_id}?process_identifier=${task.call_activity_process_identifier}`}
to={`${window.location.pathname}?process_identifier=${task.call_activity_process_identifier}`}
target="_blank"
>
View Call Activity Diagram
@ -647,8 +662,8 @@ export default function ProcessInstanceShow() {
processModelId={processModelId || ''}
diagramXML={processInstanceToUse.bpmn_xml_file_contents || ''}
fileName={processInstanceToUse.bpmn_xml_file_contents || ''}
readyOrWaitingBpmnTaskIds={taskIds.readyOrWaiting}
completedTasksBpmnIds={taskIds.completed}
readyOrWaitingProcessInstanceTasks={taskIds.readyOrWaiting}
completedProcessInstanceTasks={taskIds.completed}
diagramType="readonly"
onElementClick={handleClickedDiagramTask}
/>