Skip to content

Commit

Permalink
Merge pull request #11036 from jmchilton/workflow_message_modal
Browse files Browse the repository at this point in the history
Vue-ify Workflow State Upgrade Message Modal
  • Loading branch information
jmchilton authored Jan 3, 2021
2 parents db386c2 + be3adc8 commit e59ecf0
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 23 deletions.
10 changes: 8 additions & 2 deletions client/src/components/Workflow/Editor/Index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div id="columns" class="workflow-client">
<StateUpgradeModal :stateMessages="stateMessages" />
<MarkdownEditor
v-if="!isCanvas"
:markdown-text="markdownText"
Expand Down Expand Up @@ -144,7 +145,7 @@ import { getDatatypesMapper } from "components/Datatypes";
import { getModule, getVersions, saveWorkflow, loadWorkflow, refactor } from "./modules/services";
import {
showWarnings,
showUpgradeMessage,
getStateUpgradeMessages,
copyIntoWorkflow,
getLegacyWorkflowParameters,
showAttributes,
Expand All @@ -160,6 +161,7 @@ import SidePanel from "components/Panels/SidePanel";
import { getAppRoot } from "onload/loadConfig";
import reportDefault from "./reportDefault";
import WorkflowLint from "./Lint";
import StateUpgradeModal from "./StateUpgradeModal";
import { hide_modal, show_message, show_modal } from "layout/modal";
import WorkflowAttributes from "./Attributes";
import ZoomControl from "./ZoomControl";
Expand All @@ -170,6 +172,7 @@ export default {
components: {
MarkdownEditor,
SidePanel,
StateUpgradeModal,
ToolBoxWorkflow,
WorkflowOptions,
WorkflowAttributes,
Expand Down Expand Up @@ -228,6 +231,7 @@ export default {
creator: null,
annotation: null,
name: null,
stateMessages: [],
};
},
created() {
Expand Down Expand Up @@ -458,7 +462,9 @@ export default {
const markdown = report.markdown || reportDefault;
this.markdownText = markdown;
this.markdownConfig = report;
const has_changes = showUpgradeMessage(data);
hide_modal();
this.stateMessages = getStateUpgradeMessages(data);
const has_changes = this.stateMessages.length > 0;
this.license = data.license;
this.creator = data.creator;
getVersions(this.id).then((versions) => {
Expand Down
74 changes: 74 additions & 0 deletions client/src/components/Workflow/Editor/StateUpgradeModal.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { shallowMount, createLocalVue } from "@vue/test-utils";
import StateUpgradeModal from "./StateUpgradeModal";

const localVue = createLocalVue();

describe("StateUpgradeModal.vue", () => {
let wrapper;

async function mountWith(stateMessages) {
wrapper = shallowMount(StateUpgradeModal, {
propsData: {
stateMessages,
},
localVue,
});
await wrapper.vm.$nextTick();
}

it("should not render if there are no messages", async () => {
const stateMessages = [];
await mountWith(stateMessages);
expect(wrapper.vm.show).toBeFalsy();
});

it("should render if there are messages", async () => {
const stateMessages = [
{
stepIndex: 2,
stepName: "step name",
details: ["my message 1", "my message 2"],
},
];
await mountWith(stateMessages);
expect(wrapper.vm.show).toBeTruthy();
});

async function mountSomeInitialMessagesAndDismiss() {
const stateMessages = [
{
stepIndex: 2,
stepName: "step name",
details: ["my message 1", "my message 2"],
},
];
await mountWith(stateMessages);
wrapper.vm.show = false;
await wrapper.vm.$nextTick();
expect(wrapper.vm.show).toBeFalsy();
}

it("should re-render when passed new messages", async () => {
await mountSomeInitialMessagesAndDismiss();
const stateMessagesNew = [
{
stepIndex: 3,
stepName: "step name",
details: ["my message 1", "my message 2"],
},
];
await wrapper.setProps({
stateMessages: stateMessagesNew,
});
expect(wrapper.vm.show).toBeTruthy();
});

it("should not re-render if sent empty messages", async () => {
await mountSomeInitialMessagesAndDismiss();
const stateMessagesNew = [];
await wrapper.setProps({
stateMessages: stateMessagesNew,
});
expect(wrapper.vm.show).toBeFalsy();
});
});
76 changes: 76 additions & 0 deletions client/src/components/Workflow/Editor/StateUpgradeModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<template>
<b-modal v-model="show" title="Issues loading this workflow" scrollable ok-only ok-title="Continue">
<div class="state-upgrade-modal">
Please review the following issues, possibly resulting from tool upgrades or changes.
<ul class="workflow-state-upgrade-step-summaries">
<li v-for="(stateMessage, index) in stateMessages" :key="index">
<b>
<i :class="iconClass(stateMessage)" />
Step {{ humanIndex(stateMessage) }}: {{ title(stateMessage) }}
</b>
<ul class="workflow-state-upgrade-step-details">
<li v-for="(detail, detailIndex) in stateMessage.details" :key="detailIndex">
- <span v-html="detail" />
</li>
</ul>
</li>
</ul>
</div>
</b-modal>
</template>

<script>
import { BModal } from "bootstrap-vue";
export default {
components: { BModal },
props: {
stateMessages: {
type: Array,
requierd: true,
},
},
data() {
return {
show: this.stateMessages.length > 0,
};
},
methods: {
humanIndex(stateMessage) {
return `${parseInt(stateMessage.stepIndex, 10) + 1}`;
},
title(stateMessage) {
return stateMessage.label ? stateMessage.label : stateMessage.name;
},
iconClass(stateMessage) {
let iconClassStr = "";
if (stateMessage.iconType) {
// stolen from Node.vue.
iconClassStr = `icon fa fa-fw ${stateMessage.iconType}`;
}
return iconClassStr;
},
},
watch: {
stateMessages() {
if (this.stateMessages.length > 0) {
this.show = true;
}
},
},
};
</script>

<style>
/* scoped styles not working because of modal, using long names instead. */
ul.workflow-state-upgrade-step-summaries {
margin-top: 10px;
padding: 10px;
}
ul.workflow-state-upgrade-step-details {
list-style-type: square !important;
}
ul.workflow-state-upgrade-step-details li {
padding-left: 5px;
}
</style>
36 changes: 17 additions & 19 deletions client/src/components/Workflow/Editor/modules/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DefaultForm, ToolForm } from "./forms";
import { loadWorkflow } from "./services";
import { toSimple } from "./model";
import { hide_modal, show_message, show_modal } from "layout/modal";
import WorkflowIcons from "components/Workflow/icons";

export function copyIntoWorkflow(workflow, id = null, stepCount = null) {
const _copy_into_workflow_ajax = () => {
Expand Down Expand Up @@ -103,33 +104,30 @@ export function showForm(workflow, node, datatypes) {
}
}

export function showUpgradeMessage(data) {
export function getStateUpgradeMessages(data) {
// Determine if any parameters were 'upgraded' and provide message
var upgrade_message = "";
let hasToolUpgrade = false;
const messages = [];
_.each(data.steps, (step, step_id) => {
var details = "";
const details = [];
if (step.errors) {
details += `<li>${step.errors}</li>`;
details.push(step.errors);
}
_.each(data.upgrade_messages[step_id], (m) => {
hasToolUpgrade = true;
details += `<li>${m}</li>`;
details.push(m);
});
if (details) {
upgrade_message += `<li>Step ${parseInt(step_id, 10) + 1}: ${step.name}<ul>${details}</ul></li>`;
if (details.length) {
const iconType = WorkflowIcons[step.type];
const message = {
stepIndex: step_id,
name: step.name,
details: details,
iconType: iconType,
label: step.label,
};
messages.push(message);
}
});
if (upgrade_message) {
show_modal(
"Issues loading this workflow",
`Please review the following issues, possibly resulting from tool upgrades or changes.<p><ul>${upgrade_message}</ul></p>`,
{ Continue: hide_modal }
);
} else {
hide_modal();
}
return hasToolUpgrade;
return messages;
}

class LegacyParameterReference {
Expand Down
1 change: 1 addition & 0 deletions lib/galaxy/selenium/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ workflow_editor:

connector_destroy_callout: '.delete-terminal'
save_button: '.editor-button-save'
state_modal_body: '.state-upgrade-modal'

tour:
popover:
Expand Down
79 changes: 78 additions & 1 deletion lib/galaxy_test/base/workflow_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,93 @@
"""


# Throwing a bunch of broken steps in to get a really long modal and sure it
# is scrollable.
WORKFLOW_WITH_INVALID_STATE = """
class: GalaxyWorkflow
inputs:
input1: data
steps:
mul_versions:
mul_versions_1:
tool_id: multiple_versions
tool_version: "0.0.1"
state:
inttest: "moocow"
'another bad step':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step2':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step3':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step4':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step5':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step6':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step7':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step8':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step9':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step10':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step11':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step12':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step13':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
'another bad step14':
tool_id: multiple_versions
tool_version: "0.0.3c"
state:
inttest: "moocow"
"""


Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy_test/selenium/test_workflow_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,6 @@ def assert_wf_annotation_is(self, expected_annotation):

@retry_assertion_during_transitions
def assert_modal_has_text(self, expected_text):
modal_element = self.wait_for_selector_visible(self.modal_body_selector())
modal_element = self.components.workflow_editor.state_modal_body.wait_for_visible()
text = modal_element.text
assert expected_text in text, f"Failed to find expected text [{expected_text}] in modal text [{text}]"

0 comments on commit e59ecf0

Please sign in to comment.