Merge remote-tracking branch 'origin/main' into feature/home_page_refactor
This commit is contained in:
commit
0aa0698557
|
@ -1916,7 +1916,7 @@ lxml = "*"
|
||||||
type = "git"
|
type = "git"
|
||||||
url = "https://github.com/sartography/SpiffWorkflow"
|
url = "https://github.com/sartography/SpiffWorkflow"
|
||||||
reference = "main"
|
reference = "main"
|
||||||
resolved_reference = "98a1b37e01a00faea60025f517a89867b7261432"
|
resolved_reference = "162a1c5f56cf12fc589a1e368704c0819bfcc0cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlalchemy"
|
name = "sqlalchemy"
|
||||||
|
|
|
@ -18,7 +18,9 @@ from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||||
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
|
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
|
||||||
from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
|
from spiffworkflow_backend.models.bpmn_process_definition import (
|
||||||
|
BpmnProcessDefinitionModel,
|
||||||
|
)
|
||||||
from spiffworkflow_backend.models.db import db
|
from spiffworkflow_backend.models.db import db
|
||||||
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
||||||
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
|
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
|
||||||
|
@ -28,7 +30,9 @@ from spiffworkflow_backend.models.process_instance import (
|
||||||
)
|
)
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
||||||
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventModel
|
from spiffworkflow_backend.models.process_instance_event import (
|
||||||
|
ProcessInstanceEventModel,
|
||||||
|
)
|
||||||
from spiffworkflow_backend.models.process_instance_metadata import (
|
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||||
ProcessInstanceMetadataModel,
|
ProcessInstanceMetadataModel,
|
||||||
)
|
)
|
||||||
|
@ -168,7 +172,10 @@ def process_instance_terminate(
|
||||||
try:
|
try:
|
||||||
with ProcessInstanceQueueService.dequeued(process_instance):
|
with ProcessInstanceQueueService.dequeued(process_instance):
|
||||||
processor.terminate()
|
processor.terminate()
|
||||||
except (ProcessInstanceIsNotEnqueuedError, ProcessInstanceIsAlreadyLockedError) as e:
|
except (
|
||||||
|
ProcessInstanceIsNotEnqueuedError,
|
||||||
|
ProcessInstanceIsAlreadyLockedError,
|
||||||
|
) as e:
|
||||||
ErrorHandlingService().handle_error(processor, e)
|
ErrorHandlingService().handle_error(processor, e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
@ -186,7 +193,10 @@ def process_instance_suspend(
|
||||||
try:
|
try:
|
||||||
with ProcessInstanceQueueService.dequeued(process_instance):
|
with ProcessInstanceQueueService.dequeued(process_instance):
|
||||||
processor.suspend()
|
processor.suspend()
|
||||||
except (ProcessInstanceIsNotEnqueuedError, ProcessInstanceIsAlreadyLockedError) as e:
|
except (
|
||||||
|
ProcessInstanceIsNotEnqueuedError,
|
||||||
|
ProcessInstanceIsAlreadyLockedError,
|
||||||
|
) as e:
|
||||||
ErrorHandlingService().handle_error(processor, e)
|
ErrorHandlingService().handle_error(processor, e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
@ -204,7 +214,10 @@ def process_instance_resume(
|
||||||
try:
|
try:
|
||||||
with ProcessInstanceQueueService.dequeued(process_instance):
|
with ProcessInstanceQueueService.dequeued(process_instance):
|
||||||
processor.resume()
|
processor.resume()
|
||||||
except (ProcessInstanceIsNotEnqueuedError, ProcessInstanceIsAlreadyLockedError) as e:
|
except (
|
||||||
|
ProcessInstanceIsNotEnqueuedError,
|
||||||
|
ProcessInstanceIsAlreadyLockedError,
|
||||||
|
) as e:
|
||||||
ErrorHandlingService().handle_error(processor, e)
|
ErrorHandlingService().handle_error(processor, e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
@ -227,7 +240,8 @@ def process_instance_log_list(
|
||||||
.outerjoin(TaskModel, TaskModel.guid == ProcessInstanceEventModel.task_guid)
|
.outerjoin(TaskModel, TaskModel.guid == ProcessInstanceEventModel.task_guid)
|
||||||
.outerjoin(TaskDefinitionModel, TaskDefinitionModel.id == TaskModel.task_definition_id)
|
.outerjoin(TaskDefinitionModel, TaskDefinitionModel.id == TaskModel.task_definition_id)
|
||||||
.outerjoin(
|
.outerjoin(
|
||||||
BpmnProcessDefinitionModel, BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id
|
BpmnProcessDefinitionModel,
|
||||||
|
BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if not detailed:
|
if not detailed:
|
||||||
|
@ -374,7 +388,9 @@ def process_instance_list(
|
||||||
return make_response(jsonify(response_json), 200)
|
return make_response(jsonify(response_json), 200)
|
||||||
|
|
||||||
|
|
||||||
def process_instance_report_column_list(process_model_identifier: Optional[str] = None) -> flask.wrappers.Response:
|
def process_instance_report_column_list(
|
||||||
|
process_model_identifier: Optional[str] = None,
|
||||||
|
) -> flask.wrappers.Response:
|
||||||
"""Process_instance_report_column_list."""
|
"""Process_instance_report_column_list."""
|
||||||
table_columns = ProcessInstanceReportService.builtin_column_options()
|
table_columns = ProcessInstanceReportService.builtin_column_options()
|
||||||
columns_for_metadata_query = (
|
columns_for_metadata_query = (
|
||||||
|
@ -646,7 +662,8 @@ def process_instance_task_list(
|
||||||
== direct_parent_bpmn_process_alias.bpmn_process_definition_id,
|
== direct_parent_bpmn_process_alias.bpmn_process_definition_id,
|
||||||
)
|
)
|
||||||
.join(
|
.join(
|
||||||
BpmnProcessDefinitionModel, BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id
|
BpmnProcessDefinitionModel,
|
||||||
|
BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id,
|
||||||
)
|
)
|
||||||
.add_columns(
|
.add_columns(
|
||||||
BpmnProcessDefinitionModel.bpmn_identifier.label("bpmn_process_definition_identifier"), # type: ignore
|
BpmnProcessDefinitionModel.bpmn_identifier.label("bpmn_process_definition_identifier"), # type: ignore
|
||||||
|
@ -672,14 +689,22 @@ def process_instance_task_list(
|
||||||
task_model_query = task_model_query.filter(bpmn_process_alias.id.in_(bpmn_process_ids))
|
task_model_query = task_model_query.filter(bpmn_process_alias.id.in_(bpmn_process_ids))
|
||||||
|
|
||||||
task_models = task_model_query.all()
|
task_models = task_model_query.all()
|
||||||
task_model_list = {}
|
|
||||||
if most_recent_tasks_only:
|
if most_recent_tasks_only:
|
||||||
|
most_recent_tasks = {}
|
||||||
|
most_recent_subprocesses = set()
|
||||||
for task_model in task_models:
|
for task_model in task_models:
|
||||||
bpmn_process_guid = task_model.bpmn_process_guid or "TOP"
|
bpmn_process_guid = task_model.bpmn_process_guid or "TOP"
|
||||||
row_key = f"{bpmn_process_guid}:::{task_model.bpmn_identifier}"
|
row_key = f"{bpmn_process_guid}:::{task_model.bpmn_identifier}"
|
||||||
if row_key not in task_model_list:
|
if row_key not in most_recent_tasks:
|
||||||
task_model_list[row_key] = task_model
|
most_recent_tasks[row_key] = task_model
|
||||||
task_models = list(task_model_list.values())
|
if task_model.typename in ["SubWorkflowTask", "CallActivity"]:
|
||||||
|
most_recent_subprocesses.add(task_model.guid)
|
||||||
|
|
||||||
|
task_models = [
|
||||||
|
task_model
|
||||||
|
for task_model in most_recent_tasks.values()
|
||||||
|
if task_model.bpmn_process_guid in most_recent_subprocesses or task_model.bpmn_process_guid is None
|
||||||
|
]
|
||||||
|
|
||||||
if to_task_model is not None:
|
if to_task_model is not None:
|
||||||
task_models_dict = json.loads(current_app.json.dumps(task_models))
|
task_models_dict = json.loads(current_app.json.dumps(task_models))
|
||||||
|
|
|
@ -68,6 +68,7 @@ type OwnProps = {
|
||||||
diagramType: string;
|
diagramType: string;
|
||||||
readyOrWaitingProcessInstanceTasks?: Task[] | null;
|
readyOrWaitingProcessInstanceTasks?: Task[] | null;
|
||||||
completedProcessInstanceTasks?: Task[] | null;
|
completedProcessInstanceTasks?: Task[] | null;
|
||||||
|
cancelledProcessInstanceTasks?: Task[] | null;
|
||||||
saveDiagram?: (..._args: any[]) => any;
|
saveDiagram?: (..._args: any[]) => any;
|
||||||
onDeleteFile?: (..._args: any[]) => any;
|
onDeleteFile?: (..._args: any[]) => any;
|
||||||
isPrimaryFile?: boolean;
|
isPrimaryFile?: boolean;
|
||||||
|
@ -94,6 +95,7 @@ export default function ReactDiagramEditor({
|
||||||
diagramType,
|
diagramType,
|
||||||
readyOrWaitingProcessInstanceTasks,
|
readyOrWaitingProcessInstanceTasks,
|
||||||
completedProcessInstanceTasks,
|
completedProcessInstanceTasks,
|
||||||
|
cancelledProcessInstanceTasks,
|
||||||
saveDiagram,
|
saveDiagram,
|
||||||
onDeleteFile,
|
onDeleteFile,
|
||||||
isPrimaryFile,
|
isPrimaryFile,
|
||||||
|
@ -358,7 +360,8 @@ export default function ReactDiagramEditor({
|
||||||
function checkTaskCanBeHighlighted(taskBpmnId: string) {
|
function checkTaskCanBeHighlighted(taskBpmnId: string) {
|
||||||
return (
|
return (
|
||||||
!taskSpecsThatCannotBeHighlighted.includes(taskBpmnId) &&
|
!taskSpecsThatCannotBeHighlighted.includes(taskBpmnId) &&
|
||||||
!taskBpmnId.match(/EndJoin/)
|
!taskBpmnId.match(/EndJoin/) &&
|
||||||
|
!taskBpmnId.match(/BoundaryEventParent/)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +444,19 @@ export default function ReactDiagramEditor({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (cancelledProcessInstanceTasks) {
|
||||||
|
const bpmnProcessIdentifiers = getBpmnProcessIdentifiers(
|
||||||
|
canvas.getRootElement()
|
||||||
|
);
|
||||||
|
cancelledProcessInstanceTasks.forEach((cancelledTask) => {
|
||||||
|
highlightBpmnIoElement(
|
||||||
|
canvas,
|
||||||
|
cancelledTask,
|
||||||
|
'cancelled-task-highlight',
|
||||||
|
bpmnProcessIdentifiers
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayDiagram(
|
function displayDiagram(
|
||||||
|
@ -518,6 +534,7 @@ export default function ReactDiagramEditor({
|
||||||
diagramXMLString,
|
diagramXMLString,
|
||||||
readyOrWaitingProcessInstanceTasks,
|
readyOrWaitingProcessInstanceTasks,
|
||||||
completedProcessInstanceTasks,
|
completedProcessInstanceTasks,
|
||||||
|
cancelledProcessInstanceTasks,
|
||||||
fileName,
|
fileName,
|
||||||
performingXmlUpdates,
|
performingXmlUpdates,
|
||||||
processModelId,
|
processModelId,
|
||||||
|
|
|
@ -142,6 +142,10 @@ code {
|
||||||
fill: grey !important;
|
fill: grey !important;
|
||||||
opacity: .4;
|
opacity: .4;
|
||||||
}
|
}
|
||||||
|
.cancelled-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
|
||||||
|
fill: blue !important;
|
||||||
|
opacity: .2;
|
||||||
|
}
|
||||||
|
|
||||||
.accordion-item-label {
|
.accordion-item-label {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
|
@ -58,6 +58,7 @@ export interface Task {
|
||||||
export interface TaskIds {
|
export interface TaskIds {
|
||||||
completed: Task[];
|
completed: Task[];
|
||||||
readyOrWaiting: Task[];
|
readyOrWaiting: Task[];
|
||||||
|
cancelled: Task[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProcessInstanceTask {
|
export interface ProcessInstanceTask {
|
||||||
|
|
|
@ -231,13 +231,19 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTaskIds = () => {
|
const getTaskIds = () => {
|
||||||
const taskIds: TaskIds = { completed: [], readyOrWaiting: [] };
|
const taskIds: TaskIds = {
|
||||||
|
completed: [],
|
||||||
|
readyOrWaiting: [],
|
||||||
|
cancelled: [],
|
||||||
|
};
|
||||||
if (tasks) {
|
if (tasks) {
|
||||||
tasks.forEach(function getUserTasksElement(task: Task) {
|
tasks.forEach(function getUserTasksElement(task: Task) {
|
||||||
if (task.state === 'COMPLETED') {
|
if (task.state === 'COMPLETED') {
|
||||||
taskIds.completed.push(task);
|
taskIds.completed.push(task);
|
||||||
} else if (task.state === 'READY' || task.state === 'WAITING') {
|
} else if (task.state === 'READY' || task.state === 'WAITING') {
|
||||||
taskIds.readyOrWaiting.push(task);
|
taskIds.readyOrWaiting.push(task);
|
||||||
|
} else if (task.state === 'CANCELLED') {
|
||||||
|
taskIds.cancelled.push(task);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -1152,6 +1158,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
||||||
fileName={processInstance.bpmn_xml_file_contents || ''}
|
fileName={processInstance.bpmn_xml_file_contents || ''}
|
||||||
readyOrWaitingProcessInstanceTasks={taskIds.readyOrWaiting}
|
readyOrWaitingProcessInstanceTasks={taskIds.readyOrWaiting}
|
||||||
completedProcessInstanceTasks={taskIds.completed}
|
completedProcessInstanceTasks={taskIds.completed}
|
||||||
|
cancelledProcessInstanceTasks={taskIds.cancelled}
|
||||||
diagramType="readonly"
|
diagramType="readonly"
|
||||||
onElementClick={handleClickedDiagramTask}
|
onElementClick={handleClickedDiagramTask}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue