Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate dataset store to Pinia #16709

Merged
merged 12 commits into from
Sep 20, 2023
2 changes: 1 addition & 1 deletion client/src/components/History/Content/ContentItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
<b-collapse :visible="expandDataset">
<DatasetDetails
v-if="expandDataset"
:dataset="item"
:id="item.id"
:writable="writable"
:show-highlight="(isHistoryItem && filterable) || addHighlightBtn"
:item-urls="itemUrls"
Expand Down
78 changes: 44 additions & 34 deletions client/src/components/History/Content/Dataset/DatasetDetails.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
<script setup lang="ts">
import { BLink } from "bootstrap-vue";
import { computed } from "vue";

import { STATES } from "@/components/History/Content/model/states";
import { useDatasetStore } from "@/stores/datasetStore";

import DatasetActions from "./DatasetActions.vue";

const datasetStore = useDatasetStore();

type ItemUrlsMap = {
[key: string]: string;
};

interface Props {
id: string;
writable?: boolean;
showHighlight?: boolean;
itemUrls: ItemUrlsMap;
}

const props = withDefaults(defineProps<Props>(), {
writable: true,
showHighlight: false,
});

const emit = defineEmits<{
(e: "toggleHighlights"): void;
}>();

const result = computed(() => datasetStore.getDataset(props.id));
const isLoading = computed(() => datasetStore.isLoadingDataset(props.id));

const stateText = computed(() => result.value && STATES[result.value.state] && STATES[result.value.state].text);

function toggleHighlights() {
emit("toggleHighlights");
}
</script>

<template>
<DatasetProvider :id="dataset.id" v-slot="{ loading, result }" auto-refresh>
<div v-if="!loading" class="dataset">
<div>
<div v-if="result && !isLoading" class="dataset">
<div class="p-2 details not-loading">
<div class="summary">
<div v-if="stateText" class="mb-1">{{ stateText }}</div>
Expand Down Expand Up @@ -81,40 +122,9 @@
class="dataset-peek p-1"><table cellspacing="0" cellpadding="3"><tbody><tr><td>Dataset peek loading...</td></tr></tbody></table></pre>
</div>
</div>
</DatasetProvider>
</div>
</template>

<script>
import { BLink } from "bootstrap-vue";
import { STATES } from "components/History/Content/model/states";
import { DatasetProvider } from "components/providers/storeProviders";

import DatasetActions from "./DatasetActions";

export default {
components: {
DatasetActions,
DatasetProvider,
BLink,
},
props: {
dataset: { type: Object, required: true },
writable: { type: Boolean, default: true },
showHighlight: { type: Boolean, default: false },
itemUrls: { type: Object, required: true },
},
computed: {
stateText() {
return STATES[this.dataset.state] && STATES[this.dataset.state].text;
},
},
methods: {
toggleHighlights() {
this.$emit("toggleHighlights");
},
},
};
</script>
<style scoped>
.details .summary div.info {
max-height: 4rem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
/*
Client representation of state and state messages. See: https://github.com/galaxyproject/galaxy/blob/dev/lib/galaxy/model/__init__.py#L3292
for a list of available states.
*/
export const STATES = {
import { components } from "@/schema";

type DatasetState = components["schemas"]["DatasetState"];
// The 'failed' state is for the collection job state summary, not a dataset state.
type State = DatasetState | "failed";

interface StateRepresentation {
status: "success" | "warning" | "info" | "danger";
text?: string;
icon?: string;
spin?: boolean;
}

type StateMap = {
[__ in State]: StateRepresentation;
};

/**
* Client representation of state and state messages.
* See: https://github.com/galaxyproject/galaxy/blob/dev/lib/galaxy/model/__init__.py#L3292 for a list of available states.
*/
export const STATES: StateMap = {
/** has successfully completed running */
ok: {
status: "success",
Expand Down Expand Up @@ -80,9 +97,17 @@ export const STATES = {
status: "danger",
icon: "exclamation-triangle",
},
};
} as const satisfies StateMap;

/** We want to display a single state for a dataset collection whose elements may have mixed states.
* This list is ordered from highest to lowest priority. If any element is in error state the whole collection should be in error.
*/
export const HIERARCHICAL_COLLECTION_JOB_STATES = ["error", "failed", "upload", "paused", "running", "queued", "new"];
export const HIERARCHICAL_COLLECTION_JOB_STATES = [
"error",
"failed",
"upload",
"paused",
"running",
"queued",
"new",
] as const;
18 changes: 5 additions & 13 deletions client/src/components/providers/DatasetProvider.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import axios from "axios";
import { SingleQueryProvider } from "components/providers/SingleQueryProvider";
import { getAppRoot } from "onload/loadConfig";
import { rethrowSimple } from "utils/simple-error";

import { stateIsTerminal } from "./utils";
import { SingleQueryProvider } from "@/components/providers/SingleQueryProvider";
import { fetchDatasetDetails } from "@/stores/services/dataset.service";
import { rethrowSimple } from "@/utils/simple-error";

async function getDataset({ id }) {
const url = `${getAppRoot()}api/datasets/${id}`;
try {
const { data } = await axios.get(url);
return data;
} catch (e) {
rethrowSimple(e);
}
}
import { stateIsTerminal } from "./utils";

async function getDatasetAttributes({ id }) {
const url = `${getAppRoot()}dataset/get_edit?dataset_id=${id}`;
Expand All @@ -26,4 +18,4 @@ async function getDatasetAttributes({ id }) {
}

export const DatasetAttributesProvider = SingleQueryProvider(getDatasetAttributes);
export default SingleQueryProvider(getDataset, stateIsTerminal);
export default SingleQueryProvider(fetchDatasetDetails, stateIsTerminal);
10 changes: 2 additions & 8 deletions client/src/components/providers/storeProviders.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,8 @@ export const DatasetCollectionElementProvider = {
* Provider component interface to the actual stores i.e. history items and collection elements stores.
* @param {String} storeAction The store action is executed when the consuming component e.g. the history panel, changes the provider props.
* @param {String} storeGetter The store getter passes its result to the slot of the corresponding provider.
* @param {String} storeCountGetter The query stats store getter passes its matches counts to the slot of the corresponding provider.
*/
export const StoreProvider = (storeAction, storeGetter, storeCountGetter = undefined) => {
export const StoreProvider = (storeAction, storeGetter) => {
return {
mixins: [HasAttributesMixin],
watch: {
Expand All @@ -167,20 +166,16 @@ export const StoreProvider = (storeAction, storeGetter, storeCountGetter = undef
this.load();
},
computed: {
...mapGetters([storeGetter, storeCountGetter]),
...mapGetters([storeGetter]),
result() {
return this[storeGetter](this.attributes);
},
count() {
return storeCountGetter ? this[storeCountGetter]() : undefined;
},
},
render() {
return this.$scopedSlots.default({
error: this.error,
loading: this.loading,
result: this.result,
count: this.count,
});
},
methods: {
Expand All @@ -200,6 +195,5 @@ export const StoreProvider = (storeAction, storeGetter, storeCountGetter = undef
};
};

export const DatasetProvider = StoreProvider("fetchDataset", "getDataset");
export const CollectionElementsProvider = StoreProvider("fetchCollectionElements", "getCollectionElements");
export const ToolsProvider = StoreProvider("fetchAllTools", "getTools");
58 changes: 0 additions & 58 deletions client/src/store/historyStore/datasetStore.js

This file was deleted.

1 change: 0 additions & 1 deletion client/src/store/historyStore/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { collectionElementsStore } from "./collectionElementsStore";
export { datasetStore } from "./datasetStore";
5 changes: 4 additions & 1 deletion client/src/store/historyStore/model/watchHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { getCurrentHistoryFromServer } from "stores/services/history.services";
import { loadSet } from "utils/setCache";
import { urlData } from "utils/url";

import { useDatasetStore } from "@/stores/datasetStore";

const limit = 1000;

let throttlePeriod = 3000;
Expand Down Expand Up @@ -41,6 +43,7 @@ function setVisibilityThrottle() {
export async function watchHistoryOnce(store) {
const historyStore = useHistoryStore();
const historyItemsStore = useHistoryItemsStore();
const datasetStore = useDatasetStore();
// "Reset" watchTimeout so we don't queue up watchHistory calls in rewatchHistory.
watchTimeout = null;
// get current history
Expand Down Expand Up @@ -77,7 +80,7 @@ export async function watchHistoryOnce(store) {
}
// pass changed items to attached stores
historyStore.setHistory(history);
store.commit("saveDatasets", { payload });
datasetStore.saveDatasets(payload);
historyItemsStore.saveHistoryItems(historyId, payload);
store.commit("saveCollectionObjects", { payload });
// trigger changes in legacy handler
Expand Down
2 changes: 0 additions & 2 deletions client/src/store/historyStore/model/watchHistory.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { createPinia, mapState } from "pinia";
import { collectionElementsStore } from "store/historyStore/collectionElementsStore";
import { datasetStore } from "store/historyStore/datasetStore";
import { useHistoryItemsStore } from "stores/history/historyItemsStore";
import { useHistoryStore } from "stores/historyStore";
import Vuex from "vuex";
Expand Down Expand Up @@ -58,7 +57,6 @@ describe("watchHistory", () => {
store: new Vuex.Store({
modules: {
collectionElements: collectionElementsStore,
dataset: datasetStore,
},
}),
localVue,
Expand Down
3 changes: 1 addition & 2 deletions client/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { collectionAttributesStore } from "./collectionAttributesStore";
import { datasetExtFilesStore } from "./datasetExtFilesStore";
import { datasetPathDestinationStore } from "./datasetPathDestinationStore";
import { gridSearchStore } from "./gridSearchStore";
import { collectionElementsStore, datasetStore } from "./historyStore";
import { collectionElementsStore } from "./historyStore";
import { invocationStore } from "./invocationStore";
import { jobDestinationParametersStore } from "./jobDestinationParametersStore";
import { panelStore } from "./panelStore";
Expand Down Expand Up @@ -49,7 +49,6 @@ export function createStore() {
collectionAttributesStore: collectionAttributesStore,
collectionElements: collectionElementsStore,
destinationParameters: jobDestinationParametersStore,
dataset: datasetStore,
datasetExtFiles: datasetExtFilesStore,
datasetPathDestination: datasetPathDestinationStore,
invocations: invocationStore,
Expand Down
Loading