Skip to content

Commit

Permalink
Merge pull request #16523 from ElectronicBlueberry/workflow-store-scope
Browse files Browse the repository at this point in the history
Scope Workflow Stores to Workflow ID
  • Loading branch information
mvdbeek authored Aug 8, 2023
2 parents a6dcb82 + 8c241c9 commit 65970c6
Show file tree
Hide file tree
Showing 32 changed files with 638 additions and 403 deletions.
6 changes: 3 additions & 3 deletions client/src/components/Workflow/Editor/ConnectionMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import { computed, type ComputedRef, onMounted, ref, watch } from "vue";
import { useFocusWithin } from "@/composables/useActiveElement";
import { useWorkflowStepStore } from "@/stores/workflowStepStore";
import { useWorkflowStores } from "@/composables/workflowStores";
import { assertDefined } from "@/utils/assertions";
import {
Expand Down Expand Up @@ -62,7 +62,7 @@ watch(focused, (focused) => {
}
});
const stepStore = useWorkflowStepStore();
const { connectionStore, stepStore } = useWorkflowStores();
interface InputObject {
stepId: number;
Expand Down Expand Up @@ -97,7 +97,7 @@ function inputObjectToTerminal(inputObject: InputObject): InputTerminals {
const step = stepStore.getStep(inputObject.stepId);
assertDefined(step);
const inputSource = step.inputs.find((input) => input.name == inputObject.inputName)!;
return terminalFactory(inputObject.stepId, inputSource, props.terminal.datatypesMapper);
return terminalFactory(inputObject.stepId, inputSource, props.terminal.datatypesMapper, connectionStore, stepStore);
}
const validInputs: ComputedRef<InputObject[]> = computed(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ describe("FormDefault", () => {
},
localVue,
pinia: createTestingPinia(),
provide: {
workflowId: "mock-workflow",
},
});
});

Expand Down
5 changes: 3 additions & 2 deletions client/src/components/Workflow/Editor/Forms/FormDefault.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ import { computed, toRef } from "vue";
import type { DatatypesMapperModel } from "@/components/Datatypes/model";
import WorkflowIcons from "@/components/Workflow/icons";
import { type Step, useWorkflowStepStore } from "@/stores/workflowStepStore";
import { useWorkflowStores } from "@/composables/workflowStores";
import type { Step } from "@/stores/workflowStepStore";
import { useStepProps } from "../composables/useStepProps";
import { useUniqueLabelError } from "../composables/useUniqueLabelError";
Expand All @@ -80,7 +81,7 @@ const props = defineProps<{
const emit = defineEmits(["onAnnotation", "onLabel", "onAttemptRefactor", "onEditSubworkflow", "onSetData"]);
const stepRef = toRef(props, "step");
const { stepId, contentId, annotation, label, name, type, configForm } = useStepProps(stepRef);
const stepStore = useWorkflowStepStore();
const { stepStore } = useWorkflowStores();
const uniqueErrorLabel = useUniqueLabelError(stepStore, label.value);
const stepTitle = computed(() => {
if (label.value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ describe("FormOutputLabel", () => {
},
localVue,
pinia,
provide: { workflowId: "mock-workflow" },
});

const stepTwo = { id: 1, outputs: [{ name: "other-name" }], workflow_outputs: outputs };
wrapperOther = mount(FormOutputLabel, {
propsData: {
Expand All @@ -38,8 +40,9 @@ describe("FormOutputLabel", () => {
},
localVue,
pinia,
provide: { workflowId: "mock-workflow" },
});
stepStore = useWorkflowStepStore();
stepStore = useWorkflowStepStore("mock-workflow");
stepStore.addStep(stepOne);
stepStore.addStep(stepTwo);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import type { Ref } from "vue";
import { computed, ref } from "vue";
import { useWorkflowStores } from "@/composables/workflowStores";
import type { Step } from "@/stores/workflowStepStore";
import { useWorkflowStepStore } from "@/stores/workflowStepStore";
import FormElement from "@/components/Form/FormElement.vue";
Expand All @@ -29,7 +29,7 @@ const props = withDefaults(
}
);
const stepStore = useWorkflowStepStore();
const { stepStore } = useWorkflowStores();
const error: Ref<string | undefined> = ref(undefined);
const id = computed(() => `__label__${props.name}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe("FormTool", () => {
ToolFooter: { template: "<div>tool-footer</div>" },
},
pinia: createTestingPinia(),
provide: { workflowId: "mock-workflow" },
});
}

Expand Down
4 changes: 2 additions & 2 deletions client/src/components/Workflow/Editor/Forms/FormTool.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
import Utils from "utils/utils";
import { toRef } from "vue";
import { useWorkflowStepStore } from "@/stores/workflowStepStore";
import { useWorkflowStores } from "@/composables/workflowStores";
import { useStepProps } from "../composables/useStepProps";
import { useUniqueLabelError } from "../composables/useUniqueLabelError";
Expand Down Expand Up @@ -93,7 +93,7 @@ export default {
const { stepId, annotation, label, stepInputs, stepOutputs, configForm, postJobActions } = useStepProps(
toRef(props, "step")
);
const stepStore = useWorkflowStepStore();
const { stepStore } = useWorkflowStores();
const uniqueErrorLabel = useUniqueLabelError(stepStore, label);
return {
Expand Down
26 changes: 12 additions & 14 deletions client/src/components/Workflow/Editor/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,9 @@ import Vue, { computed, onUnmounted, ref } from "vue";
import { getUntypedWorkflowParameters } from "@/components/Workflow/Editor/modules/parameters";
import { ConfirmDialog } from "@/composables/confirmDialog";
import { useDatatypesMapper } from "@/composables/datatypesMapper";
import { provideScopedWorkflowStores } from "@/composables/workflowStores";
import { hide_modal } from "@/layout/modal";
import { getAppRoot } from "@/onload/loadConfig";
import { useConnectionStore } from "@/stores/workflowConnectionStore";
import { useWorkflowStateStore } from "@/stores/workflowEditorStateStore";
import { useWorkflowStepStore } from "@/stores/workflowStepStore";
import { LastQueue } from "@/utils/promise-queue";
import { defaultPosition } from "./composables/useDefaultStepPosition";
Expand Down Expand Up @@ -235,10 +233,10 @@ export default {
},
setup(props, { emit }) {
const { datatypes, datatypesMapper, datatypesMapperLoading } = useDatatypesMapper();
const connectionsStore = useConnectionStore();
const stepStore = useWorkflowStepStore();
const { connectionStore, stepStore, stateStore } = provideScopedWorkflowStores(props.id);
const { getStepIndex, steps } = storeToRefs(stepStore);
const stateStore = useWorkflowStateStore();
const { activeNodeId } = storeToRefs(stateStore);
const activeStep = computed(() => {
if (activeNodeId.value !== null) {
Expand All @@ -248,14 +246,14 @@ export default {
});
const hasChanges = ref(false);
const hasInvalidConnections = computed(() => Object.keys(connectionsStore.invalidConnections).length > 0);
const hasInvalidConnections = computed(() => Object.keys(connectionStore.invalidConnections).length > 0);
stepStore.$subscribe((mutation, state) => {
hasChanges.value = true;
});
function resetStores() {
connectionsStore.$reset();
connectionStore.$reset();
stepStore.$reset();
stateStore.$reset();
}
Expand All @@ -264,7 +262,7 @@ export default {
emit("update:confirmation", false);
});
return {
connectionsStore,
connectionStore,
hasChanges,
hasInvalidConnections,
stepStore,
Expand Down Expand Up @@ -360,7 +358,7 @@ export default {
this.onUpdateStep(step);
},
onConnect(connection) {
this.connectionsStore.addConnection(connection);
this.connectionStore.addConnection(connection);
},
onAttemptRefactor(actions) {
if (this.hasChanges) {
Expand Down Expand Up @@ -406,7 +404,7 @@ export default {
},
async onRefactor(response) {
this.resetStores();
await fromSimple(response.workflow);
await fromSimple(this.id, response.workflow);
this._loadEditorData(response.workflow);
},
onUpdate(step) {
Expand Down Expand Up @@ -471,7 +469,7 @@ export default {
// Load workflow definition
this.onWorkflowMessage("Importing workflow", "progress");
loadWorkflow({ id }).then((data) => {
fromSimple(data, true, defaultPosition(this.graphOffset, this.transform));
fromSimple(this.id, data, true, defaultPosition(this.graphOffset, this.transform));
// Determine if any parameters were 'upgraded' and provide message
const insertedStateMessages = getStateUpgradeMessages(data);
this.onInsertedStateMessages(insertedStateMessages);
Expand Down Expand Up @@ -523,7 +521,7 @@ export default {
},
onLayout() {
return import(/* webpackChunkName: "workflowLayout" */ "./modules/layout.ts").then((layout) => {
layout.autoLayout(this.steps).then((newSteps) => {
layout.autoLayout(this.id, this.steps).then((newSteps) => {
newSteps.map((step) => this.onUpdateStep(step));
});
});
Expand Down Expand Up @@ -691,7 +689,7 @@ export default {
this.lastQueue
.enqueue(loadWorkflow, { id, version })
.then((data) => {
fromSimple(data);
fromSimple(id, data);
this._loadEditorData(data);
})
.catch((response) => {
Expand Down
16 changes: 11 additions & 5 deletions client/src/components/Workflow/Editor/Lint.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createTestingPinia } from "@pinia/testing";
import { mount } from "@vue/test-utils";
import { PiniaVuePlugin } from "pinia";
import { PiniaVuePlugin, setActivePinia } from "pinia";
import { getLocalVue } from "tests/jest/helpers";

import { testDatatypesMapper } from "@/components/Datatypes/test_fixtures";
Expand Down Expand Up @@ -88,6 +88,9 @@ describe("Lint", () => {
let stepStore;

beforeEach(() => {
const pinia = createTestingPinia({ stubActions: false });
setActivePinia(pinia);

wrapper = mount(Lint, {
propsData: {
untypedParameters: getUntypedWorkflowParameters(steps),
Expand All @@ -98,9 +101,11 @@ describe("Lint", () => {
datatypesMapper: testDatatypesMapper,
},
localVue,
pinia: createTestingPinia({ stubActions: false }),
pinia,
provide: { workflowId: "mock-workflow" },
});
stepStore = useWorkflowStepStore();

stepStore = useWorkflowStepStore("mock-workflow");
Object.values(steps).map((step) => stepStore.addStep(step));
});

Expand Down Expand Up @@ -131,17 +136,18 @@ describe("Lint", () => {
});

it("should fire refactor event to extract untyped parameter and remove unlabeled workflows", async () => {
wrapper.vm.onRefactor();
await wrapper.find(".refactor-button").trigger("click");
expect(wrapper.emitted().onRefactor.length).toBe(1);
const actions = wrapper.emitted().onRefactor[0][0];
expect(actions.length).toBe(2);
expect(actions[0].action_type).toBe("extract_untyped_parameter");
expect(actions[0].name).toBe("untyped_parameter");
expect(actions[1].action_type).toBe("remove_unlabeled_workflow_outputs");
});

it("should include connect input action when input disconnected", async () => {
stepStore.removeStep(0);
wrapper.vm.onRefactor();
await wrapper.find(".refactor-button").trigger("click");
expect(wrapper.emitted().onRefactor.length).toBe(1);
const actions = wrapper.emitted().onRefactor[0][0];
expect(actions.length).toBe(3);
Expand Down
19 changes: 13 additions & 6 deletions client/src/components/Workflow/Editor/Lint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Best Practices Review
</div>
<div v-if="showRefactor">
<a href="#" @click="onRefactor"> Try to automatically fix issues. </a>
<a class="refactor-button" href="#" @click="onRefactor"> Try to automatically fix issues. </a>
</div>
</template>
<b-card-body>
Expand Down Expand Up @@ -85,7 +85,7 @@ import { storeToRefs } from "pinia";
import Vue from "vue";
import { DatatypesMapperModel } from "@/components/Datatypes/model";
import { useWorkflowStepStore } from "@/stores/workflowStepStore";
import { useWorkflowStores } from "@/composables/workflowStores";
import {
fixAllIssues,
Expand Down Expand Up @@ -135,8 +135,9 @@ export default {
},
},
setup() {
const { hasActiveOutputs } = storeToRefs(useWorkflowStepStore());
return { hasActiveOutputs };
const { connectionStore, stepStore } = useWorkflowStores();
const { hasActiveOutputs } = storeToRefs(stepStore);
return { connectionStore, stepStore, hasActiveOutputs };
},
computed: {
showRefactor() {
Expand Down Expand Up @@ -170,7 +171,7 @@ export default {
return getUntypedParameters(this.untypedParameters);
},
warningDisconnectedInputs() {
return getDisconnectedInputs(this.steps, this.datatypesMapper);
return getDisconnectedInputs(this.steps, this.datatypesMapper, this.connectionStore, this.stepStore);
},
warningMissingMetadata() {
return getMissingMetadata(this.steps);
Expand Down Expand Up @@ -226,7 +227,13 @@ export default {
this.$emit("onUnhighlight", item.stepId);
},
onRefactor() {
const actions = fixAllIssues(this.steps, this.untypedParameters);
const actions = fixAllIssues(
this.steps,
this.untypedParameters,
this.datatypesMapper,
this.connectionStore,
this.stepStore
);
this.$emit("onRefactor", actions);
},
},
Expand Down
5 changes: 4 additions & 1 deletion client/src/components/Workflow/Editor/Node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("Node", () => {
it("test attributes", async () => {
const testingPinia = createTestingPinia();
setActivePinia(testingPinia);
const wrapper = shallowMount(Node, {
const wrapper = shallowMount(Node as any, {
propsData: {
id: 0,
contentId: "tool name",
Expand All @@ -30,6 +30,9 @@ describe("Node", () => {
},
localVue,
pinia: testingPinia,
provide: {
workflowId: "mock-workflow",
},
});
await flushPromises();
// fa-wrench is the tool icon ...
Expand Down
9 changes: 3 additions & 6 deletions client/src/components/Workflow/Editor/Node.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,9 @@ import { getGalaxyInstance } from "@/app";
import { DatatypesMapperModel } from "@/components/Datatypes/model";
import { useNodePosition } from "@/components/Workflow/Editor/composables/useNodePosition";
import WorkflowIcons from "@/components/Workflow/icons";
import { useConnectionStore } from "@/stores/workflowConnectionStore";
import { type TerminalPosition, useWorkflowStateStore, type XYPosition } from "@/stores/workflowEditorStateStore";
import { useWorkflowStores } from "@/composables/workflowStores";
import type { TerminalPosition, XYPosition } from "@/stores/workflowEditorStateStore";
import type { Step } from "@/stores/workflowStepStore";
import { useWorkflowStepStore } from "@/stores/workflowStepStore";
import type { OutputTerminals } from "./modules/terminals";
Expand Down Expand Up @@ -180,9 +179,7 @@ const elHtml: Ref<HTMLElement | null> = computed(() => (el.value?.$el as HTMLEle
const postJobActions = computed(() => props.step.post_job_actions || {});
const workflowOutputs = computed(() => props.step.workflow_outputs || []);
const connectionStore = useConnectionStore();
const stateStore = useWorkflowStateStore();
const stepStore = useWorkflowStepStore();
const { connectionStore, stateStore, stepStore } = useWorkflowStores();
const isLoading = computed(() => Boolean(stateStore.getStepLoadingState(props.id)?.loading));
useNodePosition(
elHtml,
Expand Down
Loading

0 comments on commit 65970c6

Please sign in to comment.