Merge branch 'main' of github.com:sartography/spiff-arena
This commit is contained in:
commit
742a73e0cd
|
@ -18,13 +18,13 @@ def setup_database_uri(app: Flask) -> None:
|
|||
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI") is None:
|
||||
database_name = f"spiffworkflow_backend_{app.config['ENV_IDENTIFIER']}"
|
||||
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "sqlite":
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = (
|
||||
f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
|
||||
)
|
||||
app.config[
|
||||
"SQLALCHEMY_DATABASE_URI"
|
||||
] = f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
|
||||
elif app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "postgres":
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = (
|
||||
f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
|
||||
)
|
||||
app.config[
|
||||
"SQLALCHEMY_DATABASE_URI"
|
||||
] = f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
|
||||
else:
|
||||
# use pswd to trick flake8 with hardcoded passwords
|
||||
db_pswd = app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD")
|
||||
|
|
|
@ -129,9 +129,9 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
|
|||
def serialized_with_metadata(self) -> dict[str, Any]:
|
||||
process_instance_attributes = self.serialized
|
||||
process_instance_attributes["process_metadata"] = self.process_metadata
|
||||
process_instance_attributes["process_model_with_diagram_identifier"] = (
|
||||
self.process_model_with_diagram_identifier
|
||||
)
|
||||
process_instance_attributes[
|
||||
"process_model_with_diagram_identifier"
|
||||
] = self.process_model_with_diagram_identifier
|
||||
return process_instance_attributes
|
||||
|
||||
@property
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import enum
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Union
|
||||
|
@ -85,6 +86,7 @@ class TaskModel(SpiffworkflowBaseDBModel):
|
|||
can_complete: Optional[bool] = None
|
||||
extensions: Optional[dict] = None
|
||||
name_for_display: Optional[str] = None
|
||||
signal_buttons: Optional[List[dict]] = None
|
||||
|
||||
def get_data(self) -> dict:
|
||||
return {**self.python_env_data(), **self.json_data()}
|
||||
|
|
|
@ -18,7 +18,6 @@ from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
|||
)
|
||||
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
||||
from spiffworkflow_backend.models.process_instance_file_data import (
|
||||
ProcessInstanceFileDataModel,
|
||||
)
|
||||
|
@ -32,6 +31,7 @@ from spiffworkflow_backend.services.process_caller_service import ProcessCallerS
|
|||
from spiffworkflow_backend.services.process_instance_processor import (
|
||||
ProcessInstanceProcessor,
|
||||
)
|
||||
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
|
||||
|
||||
|
@ -199,16 +199,13 @@ def send_bpmn_event(
|
|||
if process_instance:
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.send_bpmn_event(body)
|
||||
task = ProcessInstanceService.spiff_task_to_api_task(processor, processor.next_task())
|
||||
return make_response(jsonify(task), 200)
|
||||
else:
|
||||
raise ApiError(
|
||||
error_code="send_bpmn_event_error",
|
||||
message=f"Could not send event to Instance: {process_instance_id}",
|
||||
)
|
||||
return Response(
|
||||
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
|
||||
status=200,
|
||||
mimetype="application/json",
|
||||
)
|
||||
|
||||
|
||||
def _commit_and_push_to_git(message: str) -> None:
|
||||
|
|
|
@ -289,6 +289,7 @@ def task_show(process_instance_id: int, task_guid: str = "next") -> flask.wrappe
|
|||
task_model = _get_task_model_from_guid_or_raise(task_guid, process_instance_id)
|
||||
task_definition = task_model.task_definition
|
||||
extensions = TaskService.get_extensions_from_task_model(task_model)
|
||||
task_model.signal_buttons = TaskService.get_ready_signals_with_button_labels(process_instance_id)
|
||||
|
||||
if "properties" in extensions:
|
||||
properties = extensions["properties"]
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
"""Get_process_info."""
|
||||
from typing import Any
|
||||
|
||||
from spiffworkflow_backend.models.script_attributes_context import (
|
||||
ScriptAttributesContext,
|
||||
)
|
||||
from spiffworkflow_backend.scripts.script import Script
|
||||
|
||||
|
||||
# DEPRECATED: please use GetToplevelProcessInfo instead
|
||||
class GetProcessInfo(Script):
|
||||
"""GetProcessInfo."""
|
||||
|
||||
@staticmethod
|
||||
def requires_privileged_permissions() -> bool:
|
||||
"""We have deemed this function safe to run without elevated permissions."""
|
||||
return False
|
||||
|
||||
def get_description(self) -> str:
|
||||
"""Get_description."""
|
||||
return """Returns a dictionary of information about the currently running process."""
|
||||
|
||||
def run(self, script_attributes_context: ScriptAttributesContext, *_args: Any, **kwargs: Any) -> Any:
|
||||
"""Run."""
|
||||
return {
|
||||
"process_instance_id": script_attributes_context.process_instance_id,
|
||||
"process_model_identifier": script_attributes_context.process_model_identifier,
|
||||
}
|
|
@ -423,9 +423,9 @@ class ProcessInstanceProcessor:
|
|||
tld.process_instance_id = process_instance_model.id
|
||||
|
||||
# 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 = (
|
||||
f"{process_instance_model.process_model_identifier}"
|
||||
)
|
||||
current_app.config[
|
||||
"THREAD_LOCAL_DATA"
|
||||
].process_model_identifier = f"{process_instance_model.process_model_identifier}"
|
||||
|
||||
self.process_instance_model = process_instance_model
|
||||
self.process_model_service = ProcessModelService()
|
||||
|
@ -585,9 +585,9 @@ class ProcessInstanceProcessor:
|
|||
bpmn_subprocess_definition.bpmn_identifier
|
||||
] = bpmn_process_definition_dict
|
||||
spiff_bpmn_process_dict["subprocess_specs"][bpmn_subprocess_definition.bpmn_identifier]["task_specs"] = {}
|
||||
bpmn_subprocess_definition_bpmn_identifiers[bpmn_subprocess_definition.id] = (
|
||||
bpmn_subprocess_definition.bpmn_identifier
|
||||
)
|
||||
bpmn_subprocess_definition_bpmn_identifiers[
|
||||
bpmn_subprocess_definition.id
|
||||
] = bpmn_subprocess_definition.bpmn_identifier
|
||||
|
||||
task_definitions = TaskDefinitionModel.query.filter(
|
||||
TaskDefinitionModel.bpmn_process_definition_id.in_( # type: ignore
|
||||
|
|
|
@ -2,6 +2,7 @@ import copy
|
|||
import json
|
||||
import time
|
||||
from hashlib import sha256
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
from typing import TypedDict
|
||||
|
@ -607,6 +608,28 @@ class TaskService:
|
|||
)
|
||||
return extensions
|
||||
|
||||
@classmethod
|
||||
def get_ready_signals_with_button_labels(cls, process_instance_id: int) -> list[dict]:
|
||||
waiting_tasks: List[TaskModel] = TaskModel.query.filter_by(
|
||||
state="WAITING", process_instance_id=process_instance_id
|
||||
).all()
|
||||
result = []
|
||||
for task_model in waiting_tasks:
|
||||
task_definition = task_model.task_definition
|
||||
extensions: dict = (
|
||||
task_definition.properties_json["extensions"]
|
||||
if "extensions" in task_definition.properties_json
|
||||
else {}
|
||||
)
|
||||
event_definition: dict = (
|
||||
task_definition.properties_json["event_definition"]
|
||||
if "event_definition" in task_definition.properties_json
|
||||
else {}
|
||||
)
|
||||
if "signalButtonLabel" in extensions and "name" in event_definition:
|
||||
result.append({"event": event_definition, "label": extensions["signalButtonLabel"]})
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def get_spec_reference_from_bpmn_process(cls, bpmn_process: BpmnProcessModel) -> SpecReferenceCache:
|
||||
"""Get the bpmn file for a given task model.
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||
<bpmn:process id="SpiffCatchEventExtensions" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0elszck</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0elszck" sourceRef="StartEvent_1" targetRef="Activity_0cmmlen" />
|
||||
<bpmn:endEvent id="Event_1mjvim4">
|
||||
<bpmn:incoming>Flow_1akz8b3</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1akz8b3" sourceRef="Activity_0cmmlen" targetRef="Event_1mjvim4" />
|
||||
<bpmn:sequenceFlow id="Flow_0uenxs3" sourceRef="SpamEvent" targetRef="Activity_1u4om4i" />
|
||||
<bpmn:endEvent id="Event_1dvll15">
|
||||
<bpmn:incoming>Flow_16bzuvz</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_16bzuvz" sourceRef="Activity_1u4om4i" targetRef="Event_1dvll15" />
|
||||
<bpmn:manualTask id="Activity_0cmmlen" name="My Manual Task">
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:instructionsForEndUser># Welcome
|
||||
This manual task has Two Buttons! The first is standard submit button that will take you to the end. The second button will fire a signal event and take you to a different manual task.</spiffworkflow:instructionsForEndUser>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0elszck</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1akz8b3</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:manualTask id="Activity_1u4om4i" name="Spam Message">
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:instructionsForEndUser># Spam Eaten!
|
||||
Congratulations! You have selected the Eat Additional Spam option, which opens up new doors to vast previously uncharted culinary eating experiences! Oh the Joy! Oh the Reward! Sweet savory wonderful Spam! </spiffworkflow:instructionsForEndUser>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0uenxs3</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_16bzuvz</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:boundaryEvent id="SpamEvent" name="Spam Event" attachedToRef="Activity_0cmmlen">
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:signalButtonLabel>Eat Spam</spiffworkflow:signalButtonLabel>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:outgoing>Flow_0uenxs3</bpmn:outgoing>
|
||||
<bpmn:signalEventDefinition id="SignalEventDefinition_11tlwya" signalRef="Signal_17t90lm" />
|
||||
</bpmn:boundaryEvent>
|
||||
</bpmn:process>
|
||||
<bpmn:signal id="Signal_17t90lm" name="eat_spam" />
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_z1jgvu5">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1mjvim4_di" bpmnElement="Event_1mjvim4">
|
||||
<dc:Bounds x="432" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1dvll15_di" bpmnElement="Event_1dvll15">
|
||||
<dc:Bounds x="562" y="282" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0zxmtux_di" bpmnElement="Activity_0cmmlen">
|
||||
<dc:Bounds x="270" y="137" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0tll58x_di" bpmnElement="Activity_1u4om4i">
|
||||
<dc:Bounds x="410" y="260" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_0vnraxp_di" bpmnElement="SpamEvent">
|
||||
<dc:Bounds x="322" y="199" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="311" y="242" width="61" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0elszck_di" bpmnElement="Flow_0elszck">
|
||||
<di:waypoint x="215" y="177" />
|
||||
<di:waypoint x="270" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1akz8b3_di" bpmnElement="Flow_1akz8b3">
|
||||
<di:waypoint x="370" y="177" />
|
||||
<di:waypoint x="432" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0uenxs3_di" bpmnElement="Flow_0uenxs3">
|
||||
<di:waypoint x="340" y="235" />
|
||||
<di:waypoint x="340" y="300" />
|
||||
<di:waypoint x="410" y="300" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_16bzuvz_di" bpmnElement="Flow_16bzuvz">
|
||||
<di:waypoint x="510" y="300" />
|
||||
<di:waypoint x="562" y="300" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -2662,7 +2662,8 @@ class TestProcessApi(BaseTest):
|
|||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert response.json["status"] == "complete"
|
||||
assert response.json["type"] == "End Event"
|
||||
assert response.json["state"] == "COMPLETED"
|
||||
|
||||
response = client.get(
|
||||
f"/v1.0/process-instances/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}/task-info?all_tasks=true",
|
||||
|
|
|
@ -156,3 +156,30 @@ class TestTaskService(BaseTest):
|
|||
assert task_model_level_3 is not None
|
||||
bpmn_process = TaskService.bpmn_process_for_called_activity_or_top_level_process(task_model_level_3)
|
||||
assert bpmn_process.bpmn_process_definition.bpmn_identifier == "Level3"
|
||||
|
||||
def test_get_button_labels_for_waiting_signal_event_tasks(
|
||||
self,
|
||||
app: Flask,
|
||||
with_db_and_bpmn_file_cleanup: None,
|
||||
) -> None:
|
||||
process_model = load_test_spec(
|
||||
"test_group/signal_event_extensions",
|
||||
process_model_source_directory="signal_event_extensions",
|
||||
bpmn_file_name="signal_event_extensions",
|
||||
)
|
||||
load_test_spec(
|
||||
"test_group/SpiffCatchEventExtensions",
|
||||
process_model_source_directory="call_activity_nested",
|
||||
bpmn_file_name="SpiffCatchEventExtensions",
|
||||
)
|
||||
process_instance = self.create_process_instance_from_process_model(process_model)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.do_engine_steps(save=True, execution_strategy_name="greedy")
|
||||
events = TaskService.get_ready_signals_with_button_labels(process_instance.id)
|
||||
assert len(events) == 1
|
||||
signal_event = events[0]
|
||||
assert signal_event["event"]["name"] == "eat_spam"
|
||||
assert signal_event["event"]["typename"] == "SignalEventDefinition"
|
||||
assert signal_event["label"] == "Eat Spam"
|
||||
|
||||
print(events)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,14 +31,14 @@
|
|||
"autoprefixer": "10.4.8",
|
||||
"axios": "^0.27.2",
|
||||
"bootstrap": "^5.2.0",
|
||||
"bpmn-js": "^9.3.2",
|
||||
"bpmn-js-properties-panel": "^1.10.0",
|
||||
"bpmn-js": "^13.0.0",
|
||||
"bpmn-js-properties-panel": "^1.22.0",
|
||||
"bpmn-js-spiffworkflow": "github:sartography/bpmn-js-spiffworkflow#main",
|
||||
"cookie": "^0.5.0",
|
||||
"craco": "^0.0.3",
|
||||
"cypress-slow-down": "^1.2.1",
|
||||
"date-fns": "^2.28.0",
|
||||
"diagram-js": "^8.5.0",
|
||||
"diagram-js": "^11.9.1",
|
||||
"dmn-js": "^12.2.0",
|
||||
"dmn-js-properties-panel": "^1.1",
|
||||
"dmn-js-shared": "^12.1.1",
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'bpmn... Remove this comment to see the full error message
|
||||
import BpmnModeler from 'bpmn-js/lib/Modeler';
|
||||
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'bpmn... Remove this comment to see the full error message
|
||||
import BpmnViewer from 'bpmn-js/lib/Viewer';
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
|
@ -144,11 +142,14 @@ export default function ReactDiagramEditor({
|
|||
}
|
||||
|
||||
const temp = document.createElement('template');
|
||||
const panelId: string =
|
||||
diagramType === 'readonly'
|
||||
? 'hidden-properties-panel'
|
||||
: 'js-properties-panel';
|
||||
temp.innerHTML = `
|
||||
<div class="content with-diagram" id="js-drop-zone">
|
||||
<div class="canvas ${canvasClass}" id="canvas"
|
||||
></div>
|
||||
<div class="properties-panel-parent" id="js-properties-panel"></div>
|
||||
<div class="canvas ${canvasClass}" id="canvas"></div>
|
||||
<div class="properties-panel-parent" id="${panelId}"></div>
|
||||
</div>
|
||||
`;
|
||||
const frag = temp.content;
|
||||
|
|
|
@ -37,6 +37,11 @@ export interface EventDefinition {
|
|||
message_var?: string;
|
||||
}
|
||||
|
||||
export interface SignalButton {
|
||||
label: string;
|
||||
event: EventDefinition;
|
||||
}
|
||||
|
||||
// TODO: merge with ProcessInstanceTask
|
||||
export interface Task {
|
||||
id: number;
|
||||
|
@ -60,6 +65,7 @@ export interface Task {
|
|||
can_complete: boolean;
|
||||
form_schema: any;
|
||||
form_ui_schema: any;
|
||||
signal_buttons: SignalButton[];
|
||||
}
|
||||
|
||||
export interface ProcessInstanceTask {
|
||||
|
|
|
@ -58,7 +58,6 @@ export default function ProcessInterstitial() {
|
|||
// Added this seperate use effect so that the timer interval will be cleared if
|
||||
// we end up redirecting back to the TaskShow page.
|
||||
if (shouldRedirect(lastTask)) {
|
||||
setState('REDIRECTING');
|
||||
lastTask.properties.instructionsForEndUser = '';
|
||||
const timerId = setInterval(() => {
|
||||
navigate(`/tasks/${lastTask.process_instance_id}/${lastTask.id}`);
|
||||
|
@ -103,9 +102,9 @@ export default function ProcessInterstitial() {
|
|||
const getReturnHomeButton = (index: number) => {
|
||||
if (
|
||||
index === 0 &&
|
||||
state !== 'REDIRECTING' &&
|
||||
!shouldRedirect(lastTask) &&
|
||||
['WAITING', 'ERROR', 'LOCKED', 'COMPLETED', 'READY'].includes(getStatus())
|
||||
)
|
||||
) {
|
||||
return (
|
||||
<div style={{ padding: '10px 0 0 0' }}>
|
||||
<Button kind="secondary" onClick={() => navigate(`/tasks`)}>
|
||||
|
@ -113,6 +112,7 @@ export default function ProcessInterstitial() {
|
|||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
@ -165,7 +165,7 @@ export default function ProcessInterstitial() {
|
|||
|
||||
/** In the event there is no task information and the connection closed,
|
||||
* redirect to the home page. */
|
||||
if (state === 'closed' && lastTask === null) {
|
||||
if (state === 'CLOSED' && lastTask === null) {
|
||||
navigate(`/tasks`);
|
||||
}
|
||||
if (lastTask) {
|
||||
|
|
|
@ -18,7 +18,7 @@ import Form from '../themes/carbon';
|
|||
import HttpService from '../services/HttpService';
|
||||
import useAPIError from '../hooks/UseApiError';
|
||||
import { modifyProcessIdentifierForPathParam } from '../helpers';
|
||||
import { Task } from '../interfaces';
|
||||
import { EventDefinition, Task } from '../interfaces';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import InstructionsForEndUser from '../components/InstructionsForEndUser';
|
||||
|
||||
|
@ -195,6 +195,23 @@ export default function TaskShow() {
|
|||
});
|
||||
};
|
||||
|
||||
const handleSignalSubmit = (event: EventDefinition) => {
|
||||
if (disabled || !task) {
|
||||
return;
|
||||
}
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/send-event/${modifyProcessIdentifierForPathParam(
|
||||
task.process_model_identifier
|
||||
)}/${params.process_instance_id}`,
|
||||
successCallback: processSubmitResult,
|
||||
failureCallback: (error: any) => {
|
||||
addError(error);
|
||||
},
|
||||
httpMethod: 'POST',
|
||||
postBody: event,
|
||||
});
|
||||
};
|
||||
|
||||
const buildTaskNavigation = () => {
|
||||
let userTasksElement;
|
||||
let selectedTabIndex = 0;
|
||||
|
@ -355,6 +372,17 @@ export default function TaskShow() {
|
|||
{submitButtonText}
|
||||
</Button>
|
||||
{saveAsDraftButton}
|
||||
<>
|
||||
{task.signal_buttons.map((signal) => (
|
||||
<Button
|
||||
name="signal.signal"
|
||||
disabled={disabled}
|
||||
onClick={() => handleSignalSubmit(signal.event)}
|
||||
>
|
||||
{signal.label}
|
||||
</Button>
|
||||
))}
|
||||
</>
|
||||
</ButtonSet>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue