diff --git a/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue b/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue index e0ef94bb4992..677761f278aa 100644 --- a/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue +++ b/client/galaxy/scripts/components/Workflow/Run/WorkflowRun.vue @@ -38,9 +38,20 @@ +
+ + + Expand to full workflow form. +
@@ -51,6 +62,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"; @@ -59,10 +71,15 @@ export default { LoadingSpan, WaitButton, WorkflowRunSuccess, - WorkflowRunForm + WorkflowRunForm, + WorkflowRunFormSimple }, props: { - workflowId: { type: String } + workflowId: { type: String }, + preferSimpleForm: { + type: Boolean, + default: false + } }, data() { return { @@ -76,6 +93,7 @@ export default { runButtonWaitText: "", runButtonPercentage: -1, invocations: null, + simpleForm: null, model: null }; }, @@ -83,6 +101,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; @@ -90,6 +135,7 @@ export default { this.loading = false; }) .catch(response => { + console.log(response); this.error = errorMessageAsString(response); }); }, @@ -104,6 +150,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..34b797dee470 --- /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 233373dd6e70..c764053d8ff9 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 b110e99c372d..472751a7be31 100644 --- a/client/galaxy/scripts/entry/analysis/AnalysisRouter.js +++ b/client/galaxy/scripts/entry/analysis/AnalysisRouter.js @@ -408,6 +408,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 969f9abd5fb3..5f6540545e97 100644 --- a/lib/galaxy/managers/configuration.py +++ b/lib/galaxy/managers/configuration.py @@ -75,6 +75,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 bbec7fed676c..2dfac0e87842 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -2337,6 +2337,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 29efbafd487b..e2a872db7c37 100644 --- a/test/functional/tools/samples_tool_conf.xml +++ b/test/functional/tools/samples_tool_conf.xml @@ -189,6 +189,7 @@ +