From f0c83764493e2b4768dbb50ec40b3f8c57529485 Mon Sep 17 00:00:00 2001 From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:02:08 +0100 Subject: [PATCH 1/6] remove double label in form default --- client/src/components/Workflow/Editor/Forms/FormDefault.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/src/components/Workflow/Editor/Forms/FormDefault.vue b/client/src/components/Workflow/Editor/Forms/FormDefault.vue index 8ac56fd941da..3a0f82c0a9d6 100644 --- a/client/src/components/Workflow/Editor/Forms/FormDefault.vue +++ b/client/src/components/Workflow/Editor/Forms/FormDefault.vue @@ -97,9 +97,6 @@ const { stepId, contentId, annotation, label, name, type, configForm } = useStep const { stepStore } = useWorkflowStores(); const uniqueErrorLabel = useUniqueLabelError(stepStore, label.value); const stepTitle = computed(() => { - if (label.value) { - return label.value; - } if (isSubworkflow.value) { return name.value; } else { From cf9b3027a73d912cdede62d12f2233e0ff5c4a92 Mon Sep 17 00:00:00 2001 From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com> Date: Wed, 4 Dec 2024 19:46:17 +0100 Subject: [PATCH 2/6] remove workflows and inputs from editor config --- client/src/components/Panels/ToolBox.vue | 1 - client/src/components/Panels/ToolPanel.vue | 2 - .../src/components/Workflow/Editor/Index.vue | 5 -- .../entry/analysis/modules/WorkflowEditor.vue | 1 - .../webapps/galaxy/controllers/workflow.py | 49 ------------------- lib/galaxy/workflow/modules.py | 17 ------- 6 files changed, 75 deletions(-) diff --git a/client/src/components/Panels/ToolBox.vue b/client/src/components/Panels/ToolBox.vue index 50e5aeb10ac7..7bc882468056 100644 --- a/client/src/components/Panels/ToolBox.vue +++ b/client/src/components/Panels/ToolBox.vue @@ -33,7 +33,6 @@ const props = defineProps({ panelView: { type: String, required: true }, showAdvanced: { type: Boolean, default: false, required: true }, panelQuery: { type: String, required: true }, - editorWorkflows: { type: Array, default: null }, dataManagers: { type: Array, default: null }, moduleSections: { type: Array as PropType>, default: null }, }); diff --git a/client/src/components/Panels/ToolPanel.vue b/client/src/components/Panels/ToolPanel.vue index fc9b9db2aa60..55bc38f28694 100644 --- a/client/src/components/Panels/ToolPanel.vue +++ b/client/src/components/Panels/ToolPanel.vue @@ -17,7 +17,6 @@ import Heading from "@/components/Common/Heading.vue"; const props = defineProps({ workflow: { type: Boolean, default: false }, - editorWorkflows: { type: Array, default: null }, dataManagers: { type: Array, default: null }, moduleSections: { type: Array, default: null }, }); @@ -198,7 +197,6 @@ watch( :panel-query.sync="query" :panel-view="currentPanelView" :show-advanced.sync="showAdvanced" - :editor-workflows="editorWorkflows" :data-managers="dataManagers" :module-sections="moduleSections" @updatePanelView="updatePanelView" diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue index 45225d211533..5994cdaea67d 100644 --- a/client/src/components/Workflow/Editor/Index.vue +++ b/client/src/components/Workflow/Editor/Index.vue @@ -47,7 +47,6 @@ workflow :module-sections="moduleSections" :data-managers="dataManagers" - :editor-workflows="workflows" @onInsertTool="onInsertTool" @onInsertModule="onInsertModule" @onInsertWorkflow="onInsertWorkflow" @@ -265,10 +264,6 @@ export default { type: Array, required: true, }, - workflows: { - type: Array, - required: true, - }, }, setup(props, { emit }) { const { datatypes, datatypesMapper, datatypesMapperLoading } = useDatatypesMapper(); diff --git a/client/src/entry/analysis/modules/WorkflowEditor.vue b/client/src/entry/analysis/modules/WorkflowEditor.vue index fb8ed6eea9d5..67634f4a3842 100644 --- a/client/src/entry/analysis/modules/WorkflowEditor.vue +++ b/client/src/entry/analysis/modules/WorkflowEditor.vue @@ -7,7 +7,6 @@ :initial-version="editorConfig.initialVersion" :module-sections="editorConfig.moduleSections" :workflow-tags="editorConfig.tags" - :workflows="editorConfig.workflows" @update:confirmation="$emit('update:confirmation', $event)" /> + + + + diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue index 5994cdaea67d..7f03c1e3773e 100644 --- a/client/src/components/Workflow/Editor/Index.vue +++ b/client/src/components/Workflow/Editor/Index.vue @@ -51,6 +51,10 @@ @onInsertModule="onInsertModule" @onInsertWorkflow="onInsertWorkflow" @onInsertWorkflowSteps="onInsertWorkflowSteps" /> + { - const updatedStep = { - ...stepData, - tool_state: response.tool_state, - inputs: response.inputs, - outputs: response.outputs, - config_form: response.config_form, - }; + const response = await getModule( + { name, type, content_id: contentId, tool_state: state }, + stepData.id, + this.stateStore.setLoadingState + ); - this.stepStore.updateStep(updatedStep); - action.updateStepData = updatedStep; + const updatedStep = { + ...stepData, + tool_state: response.tool_state, + inputs: response.inputs, + outputs: response.outputs, + config_form: response.config_form, + }; - this.stateStore.activeNodeId = stepData.id; - } - ); + this.stepStore.updateStep(updatedStep); + action.updateStepData = updatedStep; + + this.stateStore.activeNodeId = stepData.id; }, async _loadEditorData(data) { if (data.name !== undefined) { diff --git a/client/src/components/Workflow/Editor/modules/activities.ts b/client/src/components/Workflow/Editor/modules/activities.ts index aed37909dea2..5a5534a4af0e 100644 --- a/client/src/components/Workflow/Editor/modules/activities.ts +++ b/client/src/components/Workflow/Editor/modules/activities.ts @@ -13,6 +13,7 @@ import { faWrench, } from "@fortawesome/free-solid-svg-icons"; import { watchImmediate } from "@vueuse/core"; +import { faDiagramNext } from "font-awesome-6"; import { computed, type Ref } from "vue"; import { type Activity, useActivityStore } from "@/stores/activityStore"; @@ -27,6 +28,15 @@ export const workflowEditorActivities = [ icon: faPencilAlt, visible: true, }, + { + title: "Inputs", + id: "workflow-editor-inputs", + tooltip: "Add input steps to your workflow", + description: "Add input steps to your workflow.", + icon: faDiagramNext, + panel: true, + visible: true, + }, { title: "Tools", id: "workflow-editor-tools", diff --git a/client/src/components/Workflow/Editor/modules/inputs.ts b/client/src/components/Workflow/Editor/modules/inputs.ts new file mode 100644 index 000000000000..1e299c4a5bd4 --- /dev/null +++ b/client/src/components/Workflow/Editor/modules/inputs.ts @@ -0,0 +1,84 @@ +import { faFile, faFolder } from "@fortawesome/free-regular-svg-icons"; +import { faPencilAlt } from "@fortawesome/free-solid-svg-icons"; +import { type IconDefinition } from "font-awesome-6"; + +export interface WorkflowInput { + id: string; + title: string; + description: string; + stateOverwrites?: { + parameter_type?: "text" | "integer" | "boolean" | "color" | "float" | "directory_uri"; + }; + icon: IconDefinition; +} + +export function getWorkflowInputs(): WorkflowInput[] { + return [ + { + id: "data_input", + title: "Input Dataset", + description: "Single dataset input", + icon: faFile, + }, + { + id: "data_collection_input", + title: "Input Dataset Collection", + description: "Input for a collection of datasets", + icon: faFolder, + }, + { + id: "parameter_input", + title: "Text Input", + description: "Text parameter used for workflow logic", + icon: faPencilAlt, + stateOverwrites: { + parameter_type: "text", + }, + }, + { + id: "parameter_input", + title: "Integer Input", + description: "Whole number parameter used for workflow logic", + icon: faPencilAlt, + stateOverwrites: { + parameter_type: "integer", + }, + }, + { + id: "parameter_input", + title: "Float Input", + description: "Imprecise decimal number parameter used for workflow logic", + icon: faPencilAlt, + stateOverwrites: { + parameter_type: "float", + }, + }, + { + id: "parameter_input", + title: "Boolean Input", + description: "True / False parameter used for workflow logic", + icon: faPencilAlt, + stateOverwrites: { + parameter_type: "boolean", + }, + }, + { + id: "parameter_input", + title: "Color Input", + description: "Color parameter used for workflow logic", + icon: faPencilAlt, + stateOverwrites: { + parameter_type: "color", + }, + }, + { + id: "parameter_input", + title: "Directory Input", + description: "Directory parameter used for workflow logic", + icon: faPencilAlt, + stateOverwrites: { + parameter_type: "directory_uri", + }, + }, + ]; +} diff --git a/client/yarn.lock b/client/yarn.lock index 63fb0ca4c55e..cd6c4bf5f55a 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1456,6 +1456,11 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz#411e02a820744d3f7e0d8d9df9d82b471beaa073" integrity sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ== +"@fortawesome/fontawesome-common-types@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.1.tgz#6201640f39fdcf8e41cd9d1a92b2da3a96817fa4" + integrity sha512-gbDz3TwRrIPT3i0cDfujhshnXO9z03IT1UKRIVi/VEjpNHtSBIP2o5XSm+e816FzzCFEzAxPw09Z13n20PaQJQ== + "@fortawesome/fontawesome-common-types@^0.2.36": version "0.2.36" resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz" @@ -6335,6 +6340,13 @@ follow-redirects@^1.0.0, follow-redirects@^1.15.6: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== +"font-awesome-6@npm:@fortawesome/free-solid-svg-icons@6": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.1.tgz#c1f9a6c25562a12c283e87e284f9d82a5b0dbcc0" + integrity sha512-BTKc0b0mgjWZ2UDKVgmwaE0qt0cZs6ITcDgjrti5f/ki7aF5zs+N91V6hitGo3TItCFtnKg6cUVGdTmBFICFRg== + dependencies: + "@fortawesome/fontawesome-common-types" "6.7.1" + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" diff --git a/lib/galaxy/webapps/galaxy/api/workflows.py b/lib/galaxy/webapps/galaxy/api/workflows.py index 9348e25a977b..b52d495d40e6 100644 --- a/lib/galaxy/webapps/galaxy/api/workflows.py +++ b/lib/galaxy/webapps/galaxy/api/workflows.py @@ -531,12 +531,12 @@ def build_module(self, trans: GalaxyWebTransaction, payload=None): inputs = payload.get("inputs", {}) trans.workflow_building_mode = workflow_building_modes.ENABLED module = module_factory.from_dict(trans, payload, from_tool_form=True) - if "tool_state" not in payload: - module_state: Dict[str, Any] = {} - errors: ParameterValidationErrorsT = {} - populate_state(trans, module.get_inputs(), inputs, module_state, errors=errors, check=True) - module.recover_state(module_state, from_tool_form=True) - module.check_and_update_state() + + module_state: Dict[str, Any] = {} + errors: ParameterValidationErrorsT = {} + populate_state(trans, module.get_inputs(), inputs, module_state, errors=errors, check=True) + module.recover_state(module_state, from_tool_form=True) + module.check_and_update_state() step_dict = { "name": module.get_name(), "tool_state": module_state, From fa384b7ed0f10883933494dfc369fdea7b31c855 Mon Sep 17 00:00:00 2001 From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:27:33 +0100 Subject: [PATCH 4/6] add missing required prop to test --- .../src/components/Workflow/Editor/Forms/FormDefault.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/components/Workflow/Editor/Forms/FormDefault.test.js b/client/src/components/Workflow/Editor/Forms/FormDefault.test.js index 2a09dc0d7963..7fb84f507636 100644 --- a/client/src/components/Workflow/Editor/Forms/FormDefault.test.js +++ b/client/src/components/Workflow/Editor/Forms/FormDefault.test.js @@ -24,6 +24,7 @@ describe("FormDefault", () => { contentId: "id", annotation: "annotation", label: "label", + name: "name", type: "subworkflow", configForm: { inputs: [], @@ -42,7 +43,7 @@ describe("FormDefault", () => { it("check initial value and value change", async () => { const title = wrapper.find(".portlet-title-text").text(); - expect(title).toBe("label"); + expect(title).toBe("name"); const inputCount = wrapper.findAll("input").length; expect(inputCount).toBe(4); const outputLabelCount = wrapper.findAll("#__label__output-name").length; From d0da7e75e0fd8727082ddad431738f48eef63d6e Mon Sep 17 00:00:00 2001 From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:51:57 +0100 Subject: [PATCH 5/6] fix parameters inputs function --- client/src/components/Panels/InputPanel.vue | 7 +++--- .../Workflow/Editor/modules/inputs.ts | 24 ++++++++++++------- client/src/utils/navigation/navigation.yml | 5 ++++ lib/galaxy/selenium/navigates_galaxy.py | 9 ++++--- .../selenium/test_workflow_editor.py | 8 +++---- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/client/src/components/Panels/InputPanel.vue b/client/src/components/Panels/InputPanel.vue index f62dd45e5bf3..2150d969050a 100644 --- a/client/src/components/Panels/InputPanel.vue +++ b/client/src/components/Panels/InputPanel.vue @@ -20,11 +20,12 @@ const emit = defineEmits<{ diff --git a/client/src/components/Workflow/Editor/modules/inputs.ts b/client/src/components/Workflow/Editor/modules/inputs.ts index 1e299c4a5bd4..c152058d4360 100644 --- a/client/src/components/Workflow/Editor/modules/inputs.ts +++ b/client/src/components/Workflow/Editor/modules/inputs.ts @@ -3,7 +3,8 @@ import { faPencilAlt } from "@fortawesome/free-solid-svg-icons"; import { type IconDefinition } from "font-awesome-6"; export interface WorkflowInput { - id: string; + id?: string; // unique ID. defaults to module ID + moduleId: string; title: string; description: string; stateOverwrites?: { @@ -15,19 +16,19 @@ export interface WorkflowInput { export function getWorkflowInputs(): WorkflowInput[] { return [ { - id: "data_input", + moduleId: "data_input", title: "Input Dataset", description: "Single dataset input", icon: faFile, }, { - id: "data_collection_input", + moduleId: "data_collection_input", title: "Input Dataset Collection", description: "Input for a collection of datasets", icon: faFolder, }, { - id: "parameter_input", + moduleId: "parameter_input", title: "Text Input", description: "Text parameter used for workflow logic", icon: faPencilAlt, @@ -36,7 +37,8 @@ export function getWorkflowInputs(): WorkflowInput[] { }, }, { - id: "parameter_input", + id: "parameter_input_integer", + moduleId: "parameter_input", title: "Integer Input", description: "Whole number parameter used for workflow logic", icon: faPencilAlt, @@ -45,7 +47,8 @@ export function getWorkflowInputs(): WorkflowInput[] { }, }, { - id: "parameter_input", + id: "parameter_input_float", + moduleId: "parameter_input", title: "Float Input", description: "Imprecise decimal number parameter used for workflow logic", icon: faPencilAlt, @@ -54,7 +57,8 @@ export function getWorkflowInputs(): WorkflowInput[] { }, }, { - id: "parameter_input", + id: "parameter_input_boolean", + moduleId: "parameter_input", title: "Boolean Input", description: "True / False parameter used for workflow logic", icon: faPencilAlt, @@ -63,7 +67,8 @@ export function getWorkflowInputs(): WorkflowInput[] { }, }, { - id: "parameter_input", + id: "parameter_input_color", + moduleId: "parameter_input", title: "Color Input", description: "Color parameter used for workflow logic", icon: faPencilAlt, @@ -72,7 +77,8 @@ export function getWorkflowInputs(): WorkflowInput[] { }, }, { - id: "parameter_input", + id: "parameter_input_directory_uri", + moduleId: "parameter_input", title: "Directory Input", description: "Directory parameter used for workflow logic", icon: faPencilAlt, diff --git a/client/src/utils/navigation/navigation.yml b/client/src/utils/navigation/navigation.yml index 0612bdf75aff..a20d2d82ecac 100644 --- a/client/src/utils/navigation/navigation.yml +++ b/client/src/utils/navigation/navigation.yml @@ -750,6 +750,11 @@ workflow_editor: freehand_comment: ".freehand-workflow-comment" freehand_path: ".freehand-workflow-comment path" delete: "button[title='Delete comment']" + inputs: + selectors: + activity_button: "#activity-workflow-editor-inputs" + activity_panel: ".activity-panel[data-description='Inputs']" + input: ".workflow-input-button[data-id='${id}']" selectors: node_inspector: '.tool-inspector' node_inspector_close: ".tool-inspector [title='close']" diff --git a/lib/galaxy/selenium/navigates_galaxy.py b/lib/galaxy/selenium/navigates_galaxy.py index 141d6e1c28ec..10abaf0ed8d5 100644 --- a/lib/galaxy/selenium/navigates_galaxy.py +++ b/lib/galaxy/selenium/navigates_galaxy.py @@ -1209,12 +1209,11 @@ def workflow_editor_add_input(self, item_name="data_input"): # Make sure we're on the workflow editor and not clicking the main tool panel. editor.canvas_body.wait_for_visible() - self.open_toolbox() - editor.tool_menu_section_link(section_name="inputs").wait_for_and_click() - editor.tool_menu_item_link(item_name=item_name).wait_for_and_click() + if editor.inputs.activity_panel.is_absent: + editor.inputs.activity_button.wait_for_and_click() - def workflow_editor_add_parameter_input(self): - self.workflow_editor_add_input(item_name="parameter_input") + editor.inputs.input(id=item_name).wait_for_and_click() + self.sleep_for(self.wait_types.UX_RENDER) def workflow_editor_set_license(self, license: str) -> None: license_selector = self.components.workflow_editor.license_selector diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py index 229b76634b36..8ad6d81a606f 100644 --- a/lib/galaxy_test/selenium/test_workflow_editor.py +++ b/lib/galaxy_test/selenium/test_workflow_editor.py @@ -102,7 +102,7 @@ def test_parameter_regex_validation(self): parameter_name = "text_param" name = self.create_and_wait_for_new_workflow_in_editor() - self.workflow_editor_add_parameter_input() + self.workflow_editor_add_input("parameter_input_text") editor.label_input.wait_for_and_send_keys(parameter_name) # this really should be parameterized with the repeat name self.components.tool_form.repeat_insert.wait_for_and_click() @@ -131,7 +131,7 @@ def test_int_parameter_minimum_validation(self): parameter_name = "int_param" name = self.create_and_wait_for_new_workflow_in_editor() - self.workflow_editor_add_parameter_input() + self.workflow_editor_add_input("parameter_input_text") editor.label_input.wait_for_and_send_keys(parameter_name) select_field = self.components.tool_form.parameter_select(parameter="parameter_definition|parameter_type") self.select_set_value(select_field, "integer") @@ -157,10 +157,8 @@ def test_float_parameter_maximum_validation(self): parameter_name = "float_param" name = self.create_and_wait_for_new_workflow_in_editor() - self.workflow_editor_add_parameter_input() + self.workflow_editor_add_input("parameter_input_float") editor.label_input.wait_for_and_send_keys(parameter_name) - select_field = self.components.tool_form.parameter_select(parameter="parameter_definition|parameter_type") - self.select_set_value(select_field, "float") self.components.tool_form.parameter_input(parameter="parameter_definition|max").wait_for_and_send_keys("3.14") self.save_after_node_form_changes() From f1e3ba4d82d5b8a6879428b25a55547cbc480765 Mon Sep 17 00:00:00 2001 From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:26:10 +0100 Subject: [PATCH 6/6] fix input id --- lib/galaxy_test/selenium/test_workflow_editor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py index 8ad6d81a606f..5e1f37e2a984 100644 --- a/lib/galaxy_test/selenium/test_workflow_editor.py +++ b/lib/galaxy_test/selenium/test_workflow_editor.py @@ -102,7 +102,7 @@ def test_parameter_regex_validation(self): parameter_name = "text_param" name = self.create_and_wait_for_new_workflow_in_editor() - self.workflow_editor_add_input("parameter_input_text") + self.workflow_editor_add_input("parameter_input") editor.label_input.wait_for_and_send_keys(parameter_name) # this really should be parameterized with the repeat name self.components.tool_form.repeat_insert.wait_for_and_click() @@ -131,7 +131,7 @@ def test_int_parameter_minimum_validation(self): parameter_name = "int_param" name = self.create_and_wait_for_new_workflow_in_editor() - self.workflow_editor_add_input("parameter_input_text") + self.workflow_editor_add_input("parameter_input") editor.label_input.wait_for_and_send_keys(parameter_name) select_field = self.components.tool_form.parameter_select(parameter="parameter_definition|parameter_type") self.select_set_value(select_field, "integer")