mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-13 00:44:55 +08:00
Rework SelectObjectStore API interaction to pinia stores.
This commit is contained in:
@@ -77,6 +77,8 @@ export type DCObject = components["schemas"]["DCObject"];
|
||||
|
||||
export type DatasetCollectionAttributes = components["schemas"]["DatasetCollectionAttributesResult"];
|
||||
|
||||
export type ConcreteObjectStoreModel = components["schemas"]["ConcreteObjectStoreModel"];
|
||||
|
||||
/**
|
||||
* A SubCollection is a DatasetCollectionElement of type `dataset_collection`
|
||||
* with additional information to simplify its handling.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import { getSelectableObjectStores } from "@/api/objectStores";
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
import { useObjectStoreStore } from "@/stores/objectStoreStore";
|
||||
|
||||
import LoadingSpan from "@/components/LoadingSpan.vue";
|
||||
import DescribeObjectStore from "@/components/ObjectStore/DescribeObjectStore.vue";
|
||||
@@ -22,13 +22,13 @@ const props = withDefaults(defineProps<SelectObjectStoreProps>(), {
|
||||
parentError: null,
|
||||
});
|
||||
|
||||
const loading = ref(true);
|
||||
const error = ref(props.parentError);
|
||||
const popoverProps = {
|
||||
placement: "rightbottom",
|
||||
boundary: "window", // don't warp the popover to squeeze it into this modal
|
||||
};
|
||||
const objectStores = ref<Array<object>>([]);
|
||||
|
||||
const store = useObjectStoreStore();
|
||||
const { isLoading, loadErrorMessage, selectableObjectStores } = storeToRefs(store);
|
||||
|
||||
const loadingObjectStoreInfoMessage = ref("Loading object store information");
|
||||
const whyIsSelectionPreferredText = ref(`
|
||||
@@ -40,28 +40,6 @@ click on the info icon in the history panel to view information about where it i
|
||||
is not stored in the correct place, contact your Galaxy administrator for more information.
|
||||
`);
|
||||
|
||||
watch(
|
||||
() => props.parentError,
|
||||
() => {
|
||||
error.value = props.parentError;
|
||||
}
|
||||
);
|
||||
|
||||
function handleError(e: unknown) {
|
||||
const errorMessage = errorMessageAsString(e);
|
||||
error.value = errorMessage;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await getSelectableObjectStores();
|
||||
objectStores.value = data;
|
||||
loading.value = false;
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
}
|
||||
});
|
||||
|
||||
function variant(objectStoreId: string) {
|
||||
if (props.selectedObjectStoreId == objectStoreId) {
|
||||
return "outline-primary";
|
||||
@@ -74,6 +52,10 @@ const emit = defineEmits<{
|
||||
(e: "onSubmit", id: string | null): void;
|
||||
}>();
|
||||
|
||||
const error = computed(() => {
|
||||
return props.parentError || loadErrorMessage.value;
|
||||
});
|
||||
|
||||
async function handleSubmit(preferredObjectStoreId: string) {
|
||||
emit("onSubmit", preferredObjectStoreId);
|
||||
}
|
||||
@@ -81,7 +63,7 @@ async function handleSubmit(preferredObjectStoreId: string) {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<LoadingSpan v-if="loading" :message="loadingObjectStoreInfoMessage" />
|
||||
<LoadingSpan v-if="isLoading" :message="loadingObjectStoreInfoMessage" />
|
||||
<div v-else>
|
||||
<b-alert v-if="error" variant="danger" class="object-store-selection-error" show>
|
||||
{{ error }}
|
||||
@@ -98,7 +80,7 @@ async function handleSubmit(preferredObjectStoreId: string) {
|
||||
><i>{{ defaultOptionTitle | localize }}</i></b-button
|
||||
>
|
||||
<b-button
|
||||
v-for="object_store in objectStores"
|
||||
v-for="object_store in selectableObjectStores"
|
||||
:id="`preferred-object-store-button-${object_store.object_store_id}`"
|
||||
:key="object_store.object_store_id"
|
||||
:variant="variant(object_store.object_store_id)"
|
||||
@@ -125,7 +107,7 @@ async function handleSubmit(preferredObjectStoreId: string) {
|
||||
<span v-localize>{{ defaultOptionDescription }}</span>
|
||||
</b-popover>
|
||||
<b-popover
|
||||
v-for="object_store in objectStores"
|
||||
v-for="object_store in selectableObjectStores"
|
||||
:key="object_store.object_store_id"
|
||||
:target="`preferred-object-store-button-${object_store.object_store_id}`"
|
||||
triggers="hover"
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
import { createTestingPinia } from "@pinia/testing";
|
||||
|
||||
import { getSelectableObjectStores } from "@/api/objectStores";
|
||||
|
||||
jest.mock("@/api/objectStores");
|
||||
|
||||
const OBJECT_STORES = [
|
||||
{ object_store_id: "object_store_1", badges: [], quota: { enabled: false }, private: false },
|
||||
{ object_store_id: "object_store_2", badges: [], quota: { enabled: false }, private: false },
|
||||
{
|
||||
object_store_id: "object_store_1",
|
||||
badges: [],
|
||||
quota: { enabled: false },
|
||||
private: false,
|
||||
name: "Object Store 1",
|
||||
},
|
||||
{
|
||||
object_store_id: "object_store_2",
|
||||
badges: [],
|
||||
quota: { enabled: false },
|
||||
private: false,
|
||||
name: "Object Store 2",
|
||||
},
|
||||
];
|
||||
|
||||
export function setupSelectableMock() {
|
||||
createTestingPinia();
|
||||
const mockGetObjectStores = getSelectableObjectStores as jest.MockedFunction<typeof getSelectableObjectStores>;
|
||||
mockGetObjectStores.mockResolvedValue(OBJECT_STORES);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import { ConcreteObjectStoreModel } from "@/api";
|
||||
import { getSelectableObjectStores } from "@/api/objectStores";
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
|
||||
export const useObjectStoreStore = defineStore("objectStoreStore", () => {
|
||||
const selectableObjectStores = ref<ConcreteObjectStoreModel[] | null>(null);
|
||||
const loadErrorMessage = ref<string | null>(null);
|
||||
const isLoading = ref(false);
|
||||
const isLoaded = computed(() => selectableObjectStores.value != null);
|
||||
|
||||
async function loadObjectStores() {
|
||||
if (!isLoaded.value && !isLoading.value) {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const data = await getSelectableObjectStores();
|
||||
selectableObjectStores.value = data;
|
||||
} catch (err) {
|
||||
const errorMessage = `Error loading Galaxy object stores: ${errorMessageAsString(err)}`;
|
||||
loadErrorMessage.value = errorMessage;
|
||||
console.error("Error loading Galaxy object stores", err);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadObjectStores();
|
||||
|
||||
return {
|
||||
isLoaded,
|
||||
isLoading,
|
||||
loadErrorMessage,
|
||||
selectableObjectStores,
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user