diff --git a/client/package.json b/client/package.json
index 0e56c46fbe0..a4a02d84195 100644
--- a/client/package.json
+++ b/client/package.json
@@ -66,6 +66,7 @@
"markdown-it": "^12.3.2",
"markdown-it-regexp": "^0.4.0",
"object-hash": "^3.0.0",
+ "pinia": "^2.0.23",
"popper.js": "^1.16.1",
"pretty-bytes": "^6.0.0",
"pyre-to-regexp": "^0.0.5",
diff --git a/client/src/components/Workflow/Invocations.test.js b/client/src/components/Workflow/InvocationsList.test.js
similarity index 93%
rename from client/src/components/Workflow/Invocations.test.js
rename to client/src/components/Workflow/InvocationsList.test.js
index ebe93e2bdf8..eba495d7806 100644
--- a/client/src/components/Workflow/Invocations.test.js
+++ b/client/src/components/Workflow/InvocationsList.test.js
@@ -1,4 +1,4 @@
-import Invocations from "./Invocations";
+import InvocationsList from "./InvocationsList";
import { mount } from "@vue/test-utils";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
@@ -6,11 +6,14 @@ import { getLocalVue } from "jest/helpers";
import mockInvocationData from "./test/json/invocation.json";
import { parseISO, formatDistanceToNow } from "date-fns";
+import { createPinia } from "pinia";
+
import "jest-location-mock";
const localVue = getLocalVue();
-describe("Invocations.vue", () => {
+const pinia = createPinia();
+describe("InvocationsList.vue", () => {
let axiosMock;
let wrapper;
@@ -28,7 +31,7 @@ describe("Invocations.vue", () => {
const propsData = {
ownerGrid: false,
};
- wrapper = mount(Invocations, {
+ wrapper = mount(InvocationsList, {
propsData,
localVue,
});
@@ -49,9 +52,10 @@ describe("Invocations.vue", () => {
const propsData = {
ownerGrid: false,
};
- wrapper = mount(Invocations, {
+ wrapper = mount(InvocationsList, {
propsData,
localVue,
+ pinia,
});
});
@@ -68,9 +72,10 @@ describe("Invocations.vue", () => {
storedWorkflowName: "My Workflow",
storedWorkflowId: "abcde145678",
};
- wrapper = mount(Invocations, {
+ wrapper = mount(InvocationsList, {
propsData,
localVue,
+ pinia,
});
});
@@ -92,7 +97,7 @@ describe("Invocations.vue", () => {
ownerGrid: false,
loading: false,
};
- wrapper = mount(Invocations, {
+ wrapper = mount(InvocationsList, {
propsData,
computed: {
getWorkflowNameByInstanceId: (state) => (id) => "workflow name",
@@ -113,6 +118,7 @@ describe("Invocations.vue", () => {
},
},
localVue,
+ pinia,
});
});
diff --git a/client/src/components/Workflow/Invocations.vue b/client/src/components/Workflow/InvocationsList.vue
similarity index 95%
rename from client/src/components/Workflow/Invocations.vue
rename to client/src/components/Workflow/InvocationsList.vue
index 6b010de3d4d..ed1cd2fc9ad 100644
--- a/client/src/components/Workflow/Invocations.vue
+++ b/client/src/components/Workflow/InvocationsList.vue
@@ -80,14 +80,17 @@
diff --git a/client/src/components/WorkflowInvocationState/WorkflowInvocationDetails.vue b/client/src/components/WorkflowInvocationState/WorkflowInvocationDetails.vue
index d6af91920ad..fcf9af8baba 100644
--- a/client/src/components/WorkflowInvocationState/WorkflowInvocationDetails.vue
+++ b/client/src/components/WorkflowInvocationState/WorkflowInvocationDetails.vue
@@ -1,3 +1,44 @@
+
@@ -36,49 +77,3 @@
-
diff --git a/client/src/components/WorkflowInvocationState/WorkflowInvocationStep.vue b/client/src/components/WorkflowInvocationState/WorkflowInvocationStep.vue
index 0336f4f9cc1..67f338450cc 100644
--- a/client/src/components/WorkflowInvocationState/WorkflowInvocationStep.vue
+++ b/client/src/components/WorkflowInvocationState/WorkflowInvocationStep.vue
@@ -84,8 +84,10 @@
diff --git a/client/src/components/providers/storeProviders.js b/client/src/components/providers/storeProviders.js
index 441daa77272..f4df9359fd2 100644
--- a/client/src/components/providers/storeProviders.js
+++ b/client/src/components/providers/storeProviders.js
@@ -1,10 +1,13 @@
// Simple dataset provider, looks at api for result, renders to slot prop
import axios from "axios";
import { prependPath } from "utils/redirect";
-import { mapActions, mapGetters } from "vuex";
-import { mapCacheActions } from "vuex-cache";
+import { mapActions as vuexMapActions, mapGetters } from "vuex";
import { HasAttributesMixin } from "./utils";
+import { useDbKeyStore } from "stores/dbKeyStore";
+import { mapActions, mapState } from "pinia";
+import { useDatatypeStore } from "../../stores/datatypeStore";
+
export const SimpleProviderMixin = {
props: {
id: { type: String, required: true },
@@ -57,20 +60,20 @@ export const DbKeyProvider = {
await this.load();
},
methods: {
- ...mapCacheActions(["fetchUploadDbKeys"]),
+ ...mapActions(useDbKeyStore, ["fetchUploadDbKeys"]),
async load() {
this.loading = true;
- let dbKeys = this.getUploadDbKeys();
+ let dbKeys = this.getUploadDbKeys;
if (dbKeys == null || dbKeys.length == 0) {
await this.fetchUploadDbKeys();
- dbKeys = this.getUploadDbKeys();
+ dbKeys = this.getUploadDbKeys;
}
this.item = dbKeys;
this.loading = false;
},
},
computed: {
- ...mapGetters(["getUploadDbKeys"]),
+ ...mapState(useDbKeyStore, ["getUploadDbKeys"]),
},
};
@@ -83,20 +86,20 @@ export const DatatypesProvider = {
await this.load();
},
methods: {
- ...mapCacheActions(["fetchUploadDatatypes"]),
+ ...mapActions(useDatatypeStore, ["fetchUploadDatatypes"]),
async load() {
this.loading = true;
- let datatypes = this.getUploadDatatypes();
+ let datatypes = this.getUploadDatatypes;
if (datatypes == null || datatypes.length == 0) {
await this.fetchUploadDatatypes();
- datatypes = this.getUploadDatatypes();
+ datatypes = this.getUploadDatatypes;
}
this.item = datatypes;
this.loading = false;
},
},
computed: {
- ...mapGetters(["getUploadDatatypes"]),
+ ...mapState(useDatatypeStore, ["getUploadDatatypes"]),
},
};
@@ -171,7 +174,7 @@ export const StoreProvider = (storeAction, storeGetter, storeCountGetter = undef
});
},
methods: {
- ...mapActions([storeAction]),
+ ...vuexMapActions([storeAction]),
async load() {
this.loading = true;
try {
diff --git a/client/src/entry/analysis/App.vue b/client/src/entry/analysis/App.vue
index 98d6ef750e1..e5e37d851e0 100644
--- a/client/src/entry/analysis/App.vue
+++ b/client/src/entry/analysis/App.vue
@@ -68,6 +68,12 @@ export default {
return { toastRef, confirmDialogRef };
},
+ setup() {
+ const toastRef = ref(null);
+ setToastComponentRef(toastRef);
+
+ return { toastRef };
+ },
data() {
return {
config: getGalaxyInstance().config,
diff --git a/client/src/entry/analysis/index.js b/client/src/entry/analysis/index.js
index 6dfb557803d..175a61e15a8 100644
--- a/client/src/entry/analysis/index.js
+++ b/client/src/entry/analysis/index.js
@@ -4,6 +4,10 @@ import Vue, { provide } from "vue";
import App from "./App.vue";
import store from "store";
import { getRouter } from "./router";
+import { createPinia, PiniaVuePlugin } from "pinia";
+
+Vue.use(PiniaVuePlugin);
+const pinia = createPinia();
addInitialization((Galaxy) => {
console.log("App setup");
@@ -16,6 +20,7 @@ addInitialization((Galaxy) => {
render: (h) => h(App),
router: router,
store: store,
+ pinia: pinia,
});
});
diff --git a/client/src/store/datatypeStore.js b/client/src/store/datatypeStore.js
deleted file mode 100644
index 85dadbd4e3d..00000000000
--- a/client/src/store/datatypeStore.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export const state = {
- uploadDatatypes: [],
-};
-import UploadUtils from "mvc/upload/upload-utils";
-
-const getters = {
- getUploadDatatypes: (state) => () => {
- return state.uploadDatatypes;
- },
-};
-
-const actions = {
- fetchUploadDatatypes: async ({ commit }) => {
- try {
- const data = await UploadUtils.getUploadDatatypes(false, UploadUtils.AUTO_EXTENSION);
- commit("saveUploadDatatypes", { datatypes: data });
- } catch (err) {
- console.log("Error: unable to load datatypes", err);
- }
- },
-};
-
-const mutations = {
- saveUploadDatatypes: (state, { datatypes }) => {
- state.uploadDatatypes = datatypes;
- },
-};
-
-export const datatypeStore = {
- state,
- getters,
- actions,
- mutations,
-};
diff --git a/client/src/store/dbKeyStore.js b/client/src/store/dbKeyStore.js
deleted file mode 100644
index b6882ee5b92..00000000000
--- a/client/src/store/dbKeyStore.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export const state = {
- uploadDbKeys: [],
-};
-import UploadUtils from "mvc/upload/upload-utils";
-
-const getters = {
- getUploadDbKeys: (state) => () => {
- return state.uploadDbKeys;
- },
-};
-
-const actions = {
- fetchUploadDbKeys: async ({ commit }) => {
- try {
- const data = await UploadUtils.getUploadDbKeys(UploadUtils.DEFAULT_DBKEY);
- commit("saveUploadDbKeys", { dbKeys: data });
- } catch (err) {
- console.log("Error: unable to load Database/Builds", err);
- }
- },
-};
-
-const mutations = {
- saveUploadDbKeys: (state, { dbKeys }) => {
- state.uploadDbKeys = dbKeys;
- },
-};
-
-export const dbKeyStore = {
- state,
- getters,
- actions,
- mutations,
-};
diff --git a/client/src/store/index.js b/client/src/store/index.js
index bb9dc60f12e..c65b03a90bd 100644
--- a/client/src/store/index.js
+++ b/client/src/store/index.js
@@ -18,14 +18,11 @@ import { invocationStore } from "./invocationStore";
import { collectionElementsStore, datasetStore, historyItemsStore, historyStore } from "./historyStore";
import { userStore, userFlagsStore } from "./userStore";
import { configStore } from "./configStore";
-import { workflowStore } from "./workflowStore";
import { toolStore } from "./toolStore";
import { datasetPathDestinationStore } from "./datasetPathDestinationStore";
import { datasetExtFilesStore } from "./datasetExtFilesStore";
import { jobStore } from "./jobStore";
import { collectionAttributesStore } from "./collectionAttributesStore";
-import { dbKeyStore } from "./dbKeyStore";
-import { datatypeStore } from "./datatypeStore";
import { panelStore } from "./panelStore";
// Syncs vuex to Galaxy store until Galaxy vals to not exist
@@ -65,11 +62,9 @@ export function createStore() {
dataset: datasetStore,
datasetExtFiles: datasetExtFilesStore,
datasetPathDestination: datasetPathDestinationStore,
- datatypeStore: datatypeStore,
informationStore: jobStore,
invocations: invocationStore,
jobMetrics: jobMetricsStore,
- dbkeyStore: dbKeyStore,
gridSearch: gridSearchStore,
history: historyStore,
historyItems: historyItemsStore,
@@ -78,7 +73,6 @@ export function createStore() {
tools: toolStore,
user: userStore,
userFlags: userFlagsStore,
- workflows: workflowStore,
},
};
diff --git a/client/src/store/workflowStore.js b/client/src/store/workflowStore.js
deleted file mode 100644
index 9bec25bf9a1..00000000000
--- a/client/src/store/workflowStore.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export const state = {
- workflowsByInstanceId: {},
-};
-
-import Vue from "vue";
-import { getAppRoot } from "onload/loadConfig";
-import axios from "axios";
-
-const getters = {
- getWorkflowByInstanceId: (state) => (workflowId) => {
- return state.workflowsByInstanceId[workflowId];
- },
- getWorkflowNameByInstanceId: (state) => (workflowId) => {
- const details = state.workflowsByInstanceId[workflowId];
- if (details && details.name) {
- return details.name;
- } else {
- return "...";
- }
- },
- getStoredWorkflowIdByInstanceId: (state) => (workflowId) => {
- const storedWorkflow = state.workflowsByInstanceId[workflowId];
- return storedWorkflow?.id;
- },
-};
-
-const actions = {
- fetchWorkflowForInstanceId: async ({ commit }, workflowId) => {
- const params = { instance: "true" };
- const { data } = await axios.get(`${getAppRoot()}api/workflows/${workflowId}`, { params });
- commit("saveWorkflowForInstanceId", { workflowId, workflowData: data });
- },
-};
-
-const mutations = {
- saveWorkflowForInstanceId: (state, { workflowId, workflowData }) => {
- Vue.set(state.workflowsByInstanceId, workflowId, workflowData);
- },
-};
-
-export const workflowStore = {
- state,
- getters,
- actions,
- mutations,
-};
diff --git a/client/src/stores/datatypeStore.js b/client/src/stores/datatypeStore.js
new file mode 100644
index 00000000000..e785e35f848
--- /dev/null
+++ b/client/src/stores/datatypeStore.js
@@ -0,0 +1,23 @@
+import { defineStore } from "pinia";
+import UploadUtils from "mvc/upload/upload-utils";
+
+export const useDatatypeStore = defineStore("datatypeStore", {
+ state: () => ({
+ uploadDatatypes: [],
+ }),
+ getters: {
+ getUploadDatatypes: (state) => {
+ return state.uploadDatatypes;
+ },
+ },
+ actions: {
+ async fetchUploadDatatypes() {
+ try {
+ const data = await UploadUtils.getUploadDatatypes(false, UploadUtils.AUTO_EXTENSION);
+ this.uploadDatatypes = data;
+ } catch (err) {
+ console.log("Error: unable to load datatypes", err);
+ }
+ },
+ },
+});
diff --git a/client/src/stores/dbKeyStore.js b/client/src/stores/dbKeyStore.js
new file mode 100644
index 00000000000..1dadf6d0c28
--- /dev/null
+++ b/client/src/stores/dbKeyStore.js
@@ -0,0 +1,23 @@
+import { defineStore } from "pinia";
+import UploadUtils from "mvc/upload/upload-utils";
+
+export const useDbKeyStore = defineStore("dbKeyStore", {
+ state: () => ({
+ uploadDbKeys: [],
+ }),
+ getters: {
+ getUploadDbKeys: (state) => {
+ return state.uploadDbKeys;
+ },
+ },
+ actions: {
+ async fetchUploadDbKeys() {
+ try {
+ const data = await UploadUtils.getUploadDbKeys(UploadUtils.DEFAULT_DBKEY);
+ this.uploadDbKeys = data;
+ } catch (err) {
+ console.log("Error: unable to load Database/Builds", err);
+ }
+ },
+ },
+});
diff --git a/client/src/stores/workflowStore.js b/client/src/stores/workflowStore.js
new file mode 100644
index 00000000000..5ba6400e1fe
--- /dev/null
+++ b/client/src/stores/workflowStore.js
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import axios from "axios";
+
+import { getAppRoot } from "onload/loadConfig";
+
+export const useWorkflowStore = defineStore("workflowStore", {
+ state: () => ({
+ workflowsByInstanceId: {},
+ }),
+ getters: {
+ getWorkflowByInstanceId: (state) => {
+ return (workflowId) => {
+ state.workflowsByInstanceId[workflowId];
+ };
+ },
+ getWorkflowNameByInstanceId: (state) => {
+ return (workflowId) => {
+ const details = state.workflowsByInstanceId[workflowId];
+ if (details && details.name) {
+ return details.name;
+ } else {
+ return "...";
+ }
+ };
+ },
+ getStoredWorkflowIdByInstanceId: (state) => {
+ return (workflowId) => {
+ const storedWorkflow = state.workflowsByInstanceId[workflowId];
+ return storedWorkflow?.id;
+ };
+ },
+ },
+ actions: {
+ async fetchWorkflowForInstanceId(workflowId) {
+ console.debug("Fetching workflow details for", workflowId);
+ const params = { instance: "true" };
+ const { data } = await axios.get(`${getAppRoot()}api/workflows/${workflowId}`, { params });
+ this.$patch((state) => {
+ state.workflowsByInstanceId[workflowId] = data;
+ });
+ },
+ },
+});
diff --git a/client/tests/jest/helpers.js b/client/tests/jest/helpers.js
index 27f42d756f4..429f3702e9d 100644
--- a/client/tests/jest/helpers.js
+++ b/client/tests/jest/helpers.js
@@ -11,6 +11,7 @@ import { iconPlugin } from "components/plugins/icons";
import BootstrapVue from "bootstrap-vue";
import Vuex from "vuex";
import _l from "utils/localization";
+import { PiniaVuePlugin } from "pinia";
const defaultComparator = (a, b) => a == b;
@@ -153,6 +154,7 @@ export function getLocalVue(instrumentLocalization = false) {
const mockedDirective = {
bind() {},
};
+ localVue.use(PiniaVuePlugin);
localVue.use(Vuex);
localVue.use(BootstrapVue);
const l = instrumentLocalization ? testLocalize : _l;
diff --git a/client/yarn.lock b/client/yarn.lock
index f93c6060e63..254ae707135 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -2191,6 +2191,11 @@
optionalDependencies:
prettier "^1.18.2 || ^2.0.0"
+"@vue/devtools-api@^6.4.4":
+ version "6.4.4"
+ resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.4.4.tgz#0b024fc8ca91bb4b6035abaf53c5aecc17119b3b"
+ integrity sha512-Ku31WzpOV/8cruFaXaEZKF81WkNnvCSlBY4eOGtz5WMSdJvX1v1WWlSMGZeqUwPtQ27ZZz7B62erEMq8JDjcXw==
+
"@vue/test-utils@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.3.0.tgz#d563decdcd9c68a7bca151d4179a2bfd6d5c3e15"
@@ -8073,6 +8078,14 @@ pikaday@1.5.1:
optionalDependencies:
moment "2.x"
+pinia@^2.0.23:
+ version "2.0.23"
+ resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.0.23.tgz#570f5f82160b656b412602789683faa95502d227"
+ integrity sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==
+ dependencies:
+ "@vue/devtools-api" "^6.4.4"
+ vue-demi "*"
+
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
@@ -10314,6 +10327,11 @@ void-elements@^2.0.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==
+vue-demi@*:
+ version "0.13.6"
+ resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.6.tgz#f9433cbd75e68a970dec066647f4ba6c08ced48f"
+ integrity sha512-02NYpxgyGE2kKGegRPYlNQSL1UWfA/+JqvzhGCOYjhfbLWXU5QQX0+9pAm/R2sCOPKr5NBxVIab7fvFU0B1RxQ==
+
vue-eslint-parser@^9.0.1:
version "9.0.3"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz#0c17a89e0932cc94fa6a79f0726697e13bfe3c96"