Galaxy's workflow engine currently defines input forms server-side for data_input steps, requiring server round-trips and complex translation code (step_state_to_tool_state, _parse_state_into_dict). PR #19313 successfully migrated data_collection_input to client-side rendering. This plan extends that pattern to data_input, which is simpler since it manages only three parameters: optional, format, and tag.
File: lib/galaxy/workflow/modules.py (line ~1124)
Replace the body of InputDataModule.get_inputs() with return {} (matching InputDataCollectionModule.get_inputs() at line 1150):
def get_inputs(self):
# migrated to frontend
return {}File: lib/galaxy/webapps/galaxy/api/workflows.py (line 537)
Change the from_tool_form condition to also exclude data_input:
from_tool_form = True if module_type not in ("data_collection_input", "data_input") else FalseFile: client/src/components/Workflow/Editor/Forms/FormInputDataInput.vue (new)
Follow the pattern of FormInputCollection.vue but simpler — only 3 fields (optional, format, tag). No collection_type, no column definitions, no record field definitions.
The component will:
- Accept
stepanddatatypesprops - Use
useToolState(stepRef)to parse state - Define a
ToolStateinterface with{ optional: boolean; format: string | null; tag: string | null } - Emit
onChangewith flat state dict - Render
FormElementfor optional (boolean) and tag (text), andFormDatatypefor format
Reusable pieces from existing code:
useToolStatecomposable (client/src/components/Workflow/Editor/composables/useToolState.ts)FormElement(client/src/components/Form/FormElement.vue)FormDatatype(client/src/components/Workflow/Editor/Forms/FormDatatype.vue)
File: client/src/components/Workflow/Editor/Forms/FormDefault.vue (line ~46)
Add a new v-if branch for data_input alongside the existing data_collection_input branch:
<FormInputDataInput
v-if="type == 'data_input'"
:step="step"
:datatypes="datatypes"
@onChange="onChange">
</FormInputDataInput>
<FormInputCollection
v-else-if="type == 'data_collection_input'"
...Import the new component at the top.
test/unit/workflows/test_modules.py— unit tests fordata_inputmodule (lines 24-83):test_input_has_no_errors,test_data_input_default_state,test_data_input_modified_state,test_data_input_step_modified_state,test_data_input_compute_runtime_state_default,test_data_input_compute_runtime_state_args,test_data_input_connectionslib/galaxy_test/selenium/test_workflow_editor.py::TestWorkflowEditor::test_data_input(selenium-only, line 241)
File: lib/galaxy_test/selenium/test_workflow_editor.py
Add a new test (NOT @selenium_only) that:
- Creates a new workflow
- Adds a
data_inputstep - Sets label and annotation
- Sets the optional toggle, format(s), and tag filter
- Saves the workflow
- Re-opens and verifies: label, annotation persisted; downloads workflow and verifies
tool_statecontainsoptional,format, andtagwith correct values - Verifies round-trip: the form shows the correct values after reload
This tests the full client-side rendering + persistence roundtrip. Pattern from test_collection_input_sample_sheet_chipseq_example (line 292).
Extract a shared helper _download_current_workflow is already available (line 972). Also consider extracting shared add-input-and-set-label-annotation logic into a helper to keep tests DRY, since test_data_input, test_collection_input, and the new test all repeat the same pattern.
| File | Change |
|---|---|
lib/galaxy/workflow/modules.py |
InputDataModule.get_inputs() → return {} |
lib/galaxy/webapps/galaxy/api/workflows.py |
Add data_input to from_tool_form=False condition |
client/src/components/Workflow/Editor/Forms/FormInputDataInput.vue |
New file — client-side form |
client/src/components/Workflow/Editor/Forms/FormDefault.vue |
Route data_input to new component |
lib/galaxy_test/selenium/test_workflow_editor.py |
Add Playwright-compatible test for data_input roundtrip |
- Unit tests:
pytest test/unit/workflows/test_modules.py— all existing data_input tests must pass - Playwright tests:
./run_tests.sh -playwright lib/galaxy_test/selenium/test_workflow_editor.py::TestWorkflowEditor::test_data_input— both old and new tests - Manual check: The workflow editor should render the data_input form client-side (no
build_moduleround-trip for form inputs), with optional, format, and tag fields working correctly