Merge pull request #224 from sartography/feature/whole_process_line_clikc
Feature/whole process line click PLUS Fix for interstitial
This commit is contained in:
commit
aec779a182
|
@ -18,13 +18,13 @@ def setup_database_uri(app: Flask) -> None:
|
||||||
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI") is None:
|
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI") is None:
|
||||||
database_name = f"spiffworkflow_backend_{app.config['ENV_IDENTIFIER']}"
|
database_name = f"spiffworkflow_backend_{app.config['ENV_IDENTIFIER']}"
|
||||||
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "sqlite":
|
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "sqlite":
|
||||||
app.config[
|
app.config["SQLALCHEMY_DATABASE_URI"] = (
|
||||||
"SQLALCHEMY_DATABASE_URI"
|
f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
|
||||||
] = f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
|
)
|
||||||
elif app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "postgres":
|
elif app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "postgres":
|
||||||
app.config[
|
app.config["SQLALCHEMY_DATABASE_URI"] = (
|
||||||
"SQLALCHEMY_DATABASE_URI"
|
f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
|
||||||
] = f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
|
)
|
||||||
else:
|
else:
|
||||||
# use pswd to trick flake8 with hardcoded passwords
|
# use pswd to trick flake8 with hardcoded passwords
|
||||||
db_pswd = app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD")
|
db_pswd = app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD")
|
||||||
|
|
|
@ -127,9 +127,9 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
|
||||||
def serialized_with_metadata(self) -> dict[str, Any]:
|
def serialized_with_metadata(self) -> dict[str, Any]:
|
||||||
process_instance_attributes = self.serialized
|
process_instance_attributes = self.serialized
|
||||||
process_instance_attributes["process_metadata"] = self.process_metadata
|
process_instance_attributes["process_metadata"] = self.process_metadata
|
||||||
process_instance_attributes[
|
process_instance_attributes["process_model_with_diagram_identifier"] = (
|
||||||
"process_model_with_diagram_identifier"
|
self.process_model_with_diagram_identifier
|
||||||
] = self.process_model_with_diagram_identifier
|
)
|
||||||
return process_instance_attributes
|
return process_instance_attributes
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -406,16 +406,24 @@ def _interstitial_stream(process_instance_id: int) -> Generator[str, Optional[st
|
||||||
yield f"data: {current_app.json.dumps(task)} \n\n"
|
yield f"data: {current_app.json.dumps(task)} \n\n"
|
||||||
last_task = spiff_task
|
last_task = spiff_task
|
||||||
try:
|
try:
|
||||||
processor.do_engine_steps(execution_strategy_name="run_until_user_message")
|
|
||||||
processor.do_engine_steps(execution_strategy_name="one_at_a_time")
|
processor.do_engine_steps(execution_strategy_name="one_at_a_time")
|
||||||
|
processor.do_engine_steps(execution_strategy_name="run_until_user_message")
|
||||||
|
processor.save() # Fixme - maybe find a way not to do this on every loop?
|
||||||
except WorkflowTaskException as wfe:
|
except WorkflowTaskException as wfe:
|
||||||
api_error = ApiError.from_workflow_exception(
|
api_error = ApiError.from_workflow_exception(
|
||||||
"engine_steps_error", "Failed complete an automated task.", exp=wfe
|
"engine_steps_error", "Failed complete an automated task.", exp=wfe
|
||||||
)
|
)
|
||||||
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
||||||
|
except Exception as e:
|
||||||
|
api_error = ApiError(
|
||||||
|
error_code="engine_steps_error",
|
||||||
|
message=f"Failed complete an automated task. Error was: {str(e)}",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
||||||
|
|
||||||
# Note, this has to be done in case someone leaves the page,
|
# Note, this has to be done in case someone leaves the page,
|
||||||
# which can otherwise cancel this function and leave completed tasks un-registered.
|
# which can otherwise cancel this function and leave completed tasks un-registered.
|
||||||
processor.save() # Fixme - maybe find a way not to do this on every loop?
|
|
||||||
spiff_task = processor.next_task()
|
spiff_task = processor.next_task()
|
||||||
|
|
||||||
# Always provide some response, in the event no instructions were provided.
|
# Always provide some response, in the event no instructions were provided.
|
||||||
|
|
|
@ -423,9 +423,9 @@ class ProcessInstanceProcessor:
|
||||||
tld.process_instance_id = process_instance_model.id
|
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
|
# we want this to be the fully qualified path to the process model including all group subcomponents
|
||||||
current_app.config[
|
current_app.config["THREAD_LOCAL_DATA"].process_model_identifier = (
|
||||||
"THREAD_LOCAL_DATA"
|
f"{process_instance_model.process_model_identifier}"
|
||||||
].process_model_identifier = f"{process_instance_model.process_model_identifier}"
|
)
|
||||||
|
|
||||||
self.process_instance_model = process_instance_model
|
self.process_instance_model = process_instance_model
|
||||||
self.process_model_service = ProcessModelService()
|
self.process_model_service = ProcessModelService()
|
||||||
|
@ -585,9 +585,9 @@ class ProcessInstanceProcessor:
|
||||||
bpmn_subprocess_definition.bpmn_identifier
|
bpmn_subprocess_definition.bpmn_identifier
|
||||||
] = bpmn_process_definition_dict
|
] = bpmn_process_definition_dict
|
||||||
spiff_bpmn_process_dict["subprocess_specs"][bpmn_subprocess_definition.bpmn_identifier]["task_specs"] = {}
|
spiff_bpmn_process_dict["subprocess_specs"][bpmn_subprocess_definition.bpmn_identifier]["task_specs"] = {}
|
||||||
bpmn_subprocess_definition_bpmn_identifiers[
|
bpmn_subprocess_definition_bpmn_identifiers[bpmn_subprocess_definition.id] = (
|
||||||
bpmn_subprocess_definition.id
|
bpmn_subprocess_definition.bpmn_identifier
|
||||||
] = bpmn_subprocess_definition.bpmn_identifier
|
)
|
||||||
|
|
||||||
task_definitions = TaskDefinitionModel.query.filter(
|
task_definitions = TaskDefinitionModel.query.filter(
|
||||||
TaskDefinitionModel.bpmn_process_definition_id.in_( # type: ignore
|
TaskDefinitionModel.bpmn_process_definition_id.in_( # type: ignore
|
||||||
|
|
|
@ -1365,68 +1365,30 @@ export default function ProcessInstanceListTable({
|
||||||
const formatter =
|
const formatter =
|
||||||
reportColumnFormatters[column.accessor] ?? defaultFormatter;
|
reportColumnFormatters[column.accessor] ?? defaultFormatter;
|
||||||
const value = row[column.accessor];
|
const value = row[column.accessor];
|
||||||
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
|
||||||
row.process_model_identifier
|
|
||||||
);
|
|
||||||
const navigateToProcessInstance = () => {
|
|
||||||
navigate(`${processInstanceShowPathPrefix}/${modifiedModelId}/${row.id}`);
|
|
||||||
};
|
|
||||||
const navigateToProcessModel = () => {
|
|
||||||
navigate(`/admin/process-models/${modifiedModelId}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (column.accessor === 'status') {
|
if (column.accessor === 'status') {
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
<td data-qa={`process-instance-status-${value}`}>
|
||||||
<td
|
|
||||||
onClick={navigateToProcessInstance}
|
|
||||||
onKeyDown={navigateToProcessInstance}
|
|
||||||
data-qa={`process-instance-status-${value}`}
|
|
||||||
>
|
|
||||||
{formatter(row, value)}
|
{formatter(row, value)}
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (column.accessor === 'process_model_display_name') {
|
if (column.accessor === 'process_model_display_name') {
|
||||||
const pmStyle = { background: 'rgba(0, 0, 0, .02)' };
|
return <td> {formatter(row, value)} </td>;
|
||||||
return (
|
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
||||||
<td
|
|
||||||
style={pmStyle}
|
|
||||||
onClick={navigateToProcessModel}
|
|
||||||
onKeyDown={navigateToProcessModel}
|
|
||||||
>
|
|
||||||
{formatter(row, value)}
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (column.accessor === 'waiting_for') {
|
if (column.accessor === 'waiting_for') {
|
||||||
return (
|
return <td> {getWaitingForTableCellComponent(row)} </td>;
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
||||||
<td
|
|
||||||
onClick={navigateToProcessInstance}
|
|
||||||
onKeyDown={navigateToProcessInstance}
|
|
||||||
>
|
|
||||||
{getWaitingForTableCellComponent(row)}
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (column.accessor === 'updated_at_in_seconds') {
|
if (column.accessor === 'updated_at_in_seconds') {
|
||||||
return (
|
return (
|
||||||
<TableCellWithTimeAgoInWords
|
<TableCellWithTimeAgoInWords
|
||||||
timeInSeconds={row.updated_at_in_seconds}
|
timeInSeconds={row.updated_at_in_seconds}
|
||||||
onClick={navigateToProcessInstance}
|
|
||||||
onKeyDown={navigateToProcessInstance}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||||
<td
|
<td data-qa={`process-instance-show-link-${column.accessor}`}>
|
||||||
data-qa={`process-instance-show-link-${column.accessor}`}
|
|
||||||
onKeyDown={navigateToProcessInstance}
|
|
||||||
onClick={navigateToProcessInstance}
|
|
||||||
>
|
|
||||||
{formatter(row, value)}
|
{formatter(row, value)}
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
|
@ -1484,9 +1446,22 @@ export default function ProcessInstanceListTable({
|
||||||
}
|
}
|
||||||
|
|
||||||
const rowStyle = { cursor: 'pointer' };
|
const rowStyle = { cursor: 'pointer' };
|
||||||
|
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
||||||
|
row.process_model_identifier
|
||||||
|
);
|
||||||
|
const navigateToProcessInstance = () => {
|
||||||
|
navigate(
|
||||||
|
`${processInstanceShowPathPrefix}/${modifiedModelId}/${row.id}`
|
||||||
|
);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<tr style={rowStyle} key={row.id}>
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||||
|
<tr
|
||||||
|
style={rowStyle}
|
||||||
|
key={row.id}
|
||||||
|
onClick={navigateToProcessInstance}
|
||||||
|
onKeyDown={navigateToProcessInstance}
|
||||||
|
>
|
||||||
{currentRow}
|
{currentRow}
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue