From 1247189bf87746724b837fdcac7462e00778d313 Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 3 Feb 2023 15:40:14 -0500 Subject: [PATCH] make form schema and form ui schema both dicts, add support for hiding fields based on task data --- .../realm_exports/spiffworkflow-realm.json | 2 +- .../src/spiffworkflow_backend/models/task.py | 4 +- .../routes/tasks_controller.py | 57 ++++++++++++------- .../color_question.json | 4 ++ .../dynamic_enums_ask_for_color.bpmn | 4 +- .../integration/test_process_api.py | 3 + .../src/routes/TaskShow.tsx | 2 +- 7 files changed, 51 insertions(+), 25 deletions(-) diff --git a/spiffworkflow-backend/keycloak/realm_exports/spiffworkflow-realm.json b/spiffworkflow-backend/keycloak/realm_exports/spiffworkflow-realm.json index 722f1276..eab3bd96 100644 --- a/spiffworkflow-backend/keycloak/realm_exports/spiffworkflow-realm.json +++ b/spiffworkflow-backend/keycloak/realm_exports/spiffworkflow-realm.json @@ -3554,4 +3554,4 @@ "clientPolicies" : { "policies" : [ ] } -} \ No newline at end of file +} diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/task.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/task.py index 5c924196..e1851773 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/task.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/task.py @@ -115,8 +115,8 @@ class Task: process_model_display_name: Union[str, None] = None, process_group_identifier: Union[str, None] = None, process_model_identifier: Union[str, None] = None, - form_schema: Union[str, None] = None, - form_ui_schema: Union[str, None] = None, + form_schema: Union[dict, None] = None, + form_ui_schema: Union[dict, None] = None, parent: Optional[str] = None, event_definition: Union[dict[str, Any], None] = None, call_activity_process_identifier: Optional[str] = None, diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py index 2879c120..086f7a45 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py @@ -253,31 +253,16 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response ) ) - form_contents = _prepare_form_data( + form_dict = _prepare_form_data( form_schema_file_name, spiff_task, process_model_with_form, ) - try: - # form_contents is a str - form_dict = json.loads(form_contents) - except Exception as exception: - raise ( - ApiError( - error_code="error_loading_form", - message=( - f"Could not load form schema from: {form_schema_file_name}." - f" Error was: {str(exception)}" - ), - status_code=400, - ) - ) from exception - if task.data: _update_form_schema_with_task_data_as_needed(form_dict, task) - if form_contents: + if form_dict: task.form_schema = form_dict if form_ui_schema_file_name: @@ -289,6 +274,23 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response if ui_form_contents: task.form_ui_schema = ui_form_contents + if task.form_ui_schema is None: + task.form_ui_schema = {} + + if task.data and "form_ui_hidden_fields" in task.data: + hidden_fields = task.data["form_ui_hidden_fields"] + for hidden_field in hidden_fields: + hidden_field_parts = hidden_field.split(".") + relevant_depth_of_ui_schema = task.form_ui_schema + for ii, hidden_field_part in enumerate(hidden_field_parts): + if hidden_field_part not in relevant_depth_of_ui_schema: + relevant_depth_of_ui_schema[hidden_field_part] = {} + relevant_depth_of_ui_schema = relevant_depth_of_ui_schema[ + hidden_field_part + ] + if len(hidden_field_parts) == ii + 1: + relevant_depth_of_ui_schema["ui:widget"] = "hidden" + if task.properties and task.data and "instructionsForEndUser" in task.properties: if task.properties["instructionsForEndUser"]: try: @@ -525,14 +527,29 @@ def _get_tasks( def _prepare_form_data( form_file: str, spiff_task: SpiffTask, process_model: ProcessModelInfo -) -> str: +) -> dict: """Prepare_form_data.""" if spiff_task.data is None: - return "" + return {} file_contents = SpecFileService.get_data(process_model, form_file).decode("utf-8") try: - return _render_jinja_template(file_contents, spiff_task) + form_contents = _render_jinja_template(file_contents, spiff_task) + try: + # form_contents is a str + hot_dict: dict = json.loads(form_contents) + return hot_dict + except Exception as exception: + raise ( + ApiError( + error_code="error_loading_form", + message=( + f"Could not load form schema from: {form_file}." + f" Error was: {str(exception)}" + ), + status_code=400, + ) + ) from exception except WorkflowTaskException as wfe: wfe.add_note(f"Error in Json Form File '{form_file}'") api_error = ApiError.from_workflow_exception( diff --git a/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/color_question.json b/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/color_question.json index 20ea1c12..a3528138 100644 --- a/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/color_question.json +++ b/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/color_question.json @@ -13,6 +13,10 @@ "selectedColor": { "$ref": "#/definitions/Color", "title": "Select color" + }, + "veryImportantFieldButOnlySometimes": { + "title": "Very important field", + "type": "string" } } } diff --git a/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/dynamic_enums_ask_for_color.bpmn b/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/dynamic_enums_ask_for_color.bpmn index 7d21851b..7ec50272 100644 --- a/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/dynamic_enums_ask_for_color.bpmn +++ b/spiffworkflow-backend/tests/data/dynamic_enum_select_fields/dynamic_enums_ask_for_color.bpmn @@ -13,7 +13,9 @@ Flow_1my9ag5 Flow_0b04rbg - awesome_color_options = [{"value": "blue", "label": "Blue"}, {"value": "green", "label": "Green"}] + awesome_color_options = [{"value": "blue", "label": "Blue"}, {"value": "green", "label": "Green"}] +form_ui_hidden_fields = ["veryImportantFieldButOnlySometimes"] + diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index f52cbc43..91246c31 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -1686,6 +1686,9 @@ class TestProcessApi(BaseTest): response.json["form_schema"]["definitions"]["Color"]["anyOf"][1]["title"] == "Green" ) + assert response.json["form_ui_schema"] == { + "veryImportantFieldButOnlySometimes": {"ui:widget": "hidden"} + } def test_process_instance_list_with_default_list( self, diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 83e5df3f..fc50df7e 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -189,7 +189,7 @@ export default function TaskShow() { }, }; } else if (task.form_ui_schema) { - formUiSchema = JSON.parse(task.form_ui_schema); + formUiSchema = task.form_ui_schema; } if (task.state !== 'READY') { formUiSchema = Object.assign(formUiSchema || {}, {