diff --git a/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue b/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue index a7d509ef30dd..850bc95a56ac 100644 --- a/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue +++ b/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue @@ -44,9 +44,20 @@ +
+ + + Expand to full workflow form. +
@@ -58,6 +69,7 @@ import WaitButton from "components/WaitButton"; import LoadingSpan from "components/LoadingSpan"; import WorkflowRunSuccess from "./WorkflowRunSuccess"; import WorkflowRunForm from "./WorkflowRunForm"; +import WorkflowRunFormSimple from "./WorkflowRunFormSimple"; import { WorkflowRunModel } from "./model.js"; import { errorMessageAsString } from "utils/simple-error"; @@ -67,9 +79,14 @@ export default { WaitButton, WorkflowRunSuccess, WorkflowRunForm, + WorkflowRunFormSimple, }, props: { workflowId: { type: String }, + preferSimpleForm: { + type: Boolean, + default: false, + }, }, data() { return { @@ -83,6 +100,7 @@ export default { runButtonWaitText: "", runButtonPercentage: -1, invocations: null, + simpleForm: null, model: null, }; }, @@ -90,6 +108,33 @@ export default { getRunData(this.workflowId) .then((runData) => { const model = new WorkflowRunModel(runData); + let simpleForm = this.preferSimpleForm; + if (simpleForm) { + // These only work with PJA - the API doesn't evaluate them at + // all outside that context currently. The main workflow form renders + // these dynamically and takes care of all the validation and setup details + // on the frontend. If these are implemented on the backend at some + // point this restriction can be lifted. + if (model.hasReplacementParametersInToolForm) { + console.log("cannot render simple workflow form - has ${} values in tool steps"); + simpleForm = false; + } + // If there are required parameters in a tool form (a disconnected runtime + // input), we have to render the tool form steps and cannot use the + // simplified tool form. + if (model.hasOpenToolSteps) { + console.log( + "cannot render simple workflow form - one or more tools have disconnected runtime inputs" + ); + } + // Just render the whole form for resource request parameters (kind of + // niche - I'm not sure anyone is using these currently anyway). + if (model.hasWorkflowResourceParameters) { + console.log(`Cannot render simple workflow form - workflow resource parameters are configured`); + simpleForm = false; + } + } + this.simpleForm = simpleForm; this.model = model; this.hasUpgradeMessages = model.hasUpgradeMessages; this.hasStepVersionChanges = model.hasStepVersionChanges; @@ -97,6 +142,7 @@ export default { this.loading = false; }) .catch((response) => { + console.log(response); this.error = errorMessageAsString(response); }); }, @@ -112,6 +158,9 @@ export default { handleInvocations(invocations) { this.invocations = invocations; }, + showAdvanced() { + this.simpleForm = false; + }, }, }; diff --git a/client/galaxy/scripts/components/Workflow/Run/WorkflowRunFormSimple.vue b/client/galaxy/scripts/components/Workflow/Run/WorkflowRunFormSimple.vue new file mode 100644 index 000000000000..1e70c2cc4eec --- /dev/null +++ b/client/galaxy/scripts/components/Workflow/Run/WorkflowRunFormSimple.vue @@ -0,0 +1,109 @@ + + + diff --git a/client/galaxy/scripts/components/Workflow/Run/model.js b/client/galaxy/scripts/components/Workflow/Run/model.js index 1e5f2bdba14e..d1bfa3eb5bf5 100644 --- a/client/galaxy/scripts/components/Workflow/Run/model.js +++ b/client/galaxy/scripts/components/Workflow/Run/model.js @@ -10,16 +10,19 @@ export class WorkflowRunModel { this.runData = runData; this.name = runData.name; this.workflowResourceParameters = runData.workflow_resource_parameters; + this.hasWorkflowResourceParameters = !_.isEmpty(this.workflowResourceParameters); this.historyId = runData.history_id; this.workflowId = runData.id; this.hasUpgradeMessages = runData.has_upgrade_messages; - this.hasStepVersionChanges = runData.step_version_changes && runData.step_version_changes.length > 0; + this.hasStepVersionChanges = !_.isEmpty(runData.step_version_changes); this.steps = []; this.links = []; this.parms = []; this.wpInputs = {}; + let hasOpenToolSteps = false; + let hasReplacementParametersInToolForm = false; _.each(runData.steps, (step, i) => { var icon = WorkflowIcons[step.step_type]; @@ -130,6 +133,7 @@ export class WorkflowRunModel { _.each(this.steps, (step, i) => { _.each(this.parms[i], (input, name) => { _handleWorkflowParameter(input.value, (wp_input) => { + hasReplacementParametersInToolForm = true; wp_input.links.push(step); input.wp_linked = true; input.type = "text"; @@ -166,6 +170,7 @@ export class WorkflowRunModel { (input.value && input.value.__class__ == "RuntimeValue" && !input.step_linked) ) { step.collapsed = false; + hasOpenToolSteps = true; } if (is_runtime_value) { input.value = null; @@ -180,6 +185,8 @@ export class WorkflowRunModel { }); } }); + this.hasOpenToolSteps = hasOpenToolSteps; + this.hasReplacementParametersInToolForm = hasReplacementParametersInToolForm; } } diff --git a/client/galaxy/scripts/entry/analysis/AnalysisRouter.js b/client/galaxy/scripts/entry/analysis/AnalysisRouter.js index c4a38eded3a7..0c3abddab952 100644 --- a/client/galaxy/scripts/entry/analysis/AnalysisRouter.js +++ b/client/galaxy/scripts/entry/analysis/AnalysisRouter.js @@ -386,6 +386,9 @@ export const getAnalysisRouter = (Galaxy) => /** load workflow by its url in run mode */ _loadWorkflow: function () { const workflowId = QueryStringParsing.get("id"); - this._display_vue_helper(WorkflowRun, { workflowId: workflowId }, "workflow"); + // const preferSimpleForm = (QueryStringParsing.get("simple") || "false").toLowerCase() == "true"; + const Galaxy = getGalaxyInstance(); + const preferSimpleForm = Galaxy.config.simplified_workflow_run_ui == "prefer"; + this._display_vue_helper(WorkflowRun, { workflowId, preferSimpleForm }, "workflow"); }, }); diff --git a/lib/galaxy/managers/configuration.py b/lib/galaxy/managers/configuration.py index a34c21ccd518..48f3a22b9d51 100644 --- a/lib/galaxy/managers/configuration.py +++ b/lib/galaxy/managers/configuration.py @@ -79,6 +79,7 @@ def _use_config(config, key, **context): 'ga_code' : _use_config, 'enable_unique_workflow_defaults' : _use_config, 'enable_beta_markdown_export' : _use_config, + 'simplified_workflow_run_ui' : _use_config, 'has_user_tool_filters' : _defaults_to(False), # TODO: is there no 'correct' way to get an api url? controller='api', action='tools' is a hack # at any rate: the following works with path_prefix but is still brittle diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index 3e45d43fcbdc..6237096120f3 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -2408,6 +2408,19 @@ mapping: When false, the most recently added compatible item in the history will be used for each "Set at Runtime" input, independent of others in the workflow. + simplified_workflow_run_ui: + type: str + default: 'off' + required: false + desc: | + If set to 'off' by default, always use the traditional workflow form that renders + all steps in the GUI and serializes the tool state of all steps during + invocation. Set to 'prefer' to default to a simplified workflow UI that + only renders the inputs if possible (the workflow must have no disconnected + runtime inputs and not replacement parameters within tool steps). In the + future 'force' may be added an option for Galaskio-style servers that should + only render simplified workflows. + myexperiment_target_url: type: str default: www.myexperiment.org:80 diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml index 43116db3f568..12e08b2a60b7 100644 --- a/test/functional/tools/samples_tool_conf.xml +++ b/test/functional/tools/samples_tool_conf.xml @@ -190,6 +190,7 @@ +