mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Decompose userLocalStorage, watchHistory, etc... to avoid circular dependencies.
This commit is contained in:
@@ -14,7 +14,7 @@ import { useHistoryStore } from "@/stores/historyStore";
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { type Alias, getOperatorForAlias } from "@/utils/filtering";
|
||||
import { setItemDragstart } from "@/utils/setDrag";
|
||||
import { startWatchingHistory } from "@/watch/watchHistory";
|
||||
import { startWatchingHistory } from "@/watch/watchHistoryProvided";
|
||||
|
||||
import { useHistoryDragDrop } from "../../../composables/historyDragDrop";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import Backbone from "backbone";
|
||||
import { createDatasetCollection } from "components/History/model/queries";
|
||||
import { useHistoryItemsStore } from "stores/historyItemsStore";
|
||||
import { useHistoryStore } from "stores/historyStore";
|
||||
import { startWatchingHistory } from "watch/watchHistory";
|
||||
import { startWatchingHistory } from "watch/watchHistoryProvided";
|
||||
|
||||
import { buildRuleCollectionModal } from "./buildCollectionModal";
|
||||
|
||||
|
||||
@@ -593,7 +593,7 @@ import _l from "utils/localization";
|
||||
import Vue from "vue";
|
||||
|
||||
import { errorMessageAsString } from "@/utils/simple-error";
|
||||
import { startWatchingHistory } from "@/watch/watchHistory";
|
||||
import { startWatchingHistory } from "@/watch/watchHistoryProvided";
|
||||
|
||||
import TooltipOnHover from "components/TooltipOnHover.vue";
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ import { canMutateHistory } from "@/api";
|
||||
import { useConfigStore } from "@/stores/configurationStore";
|
||||
import { useHistoryStore } from "@/stores/historyStore";
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { startWatchingHistory } from "@/watch/watchHistory";
|
||||
import { startWatchingHistory } from "@/watch/watchHistoryProvided";
|
||||
|
||||
import ToolRecommendation from "../ToolRecommendation";
|
||||
import { getToolFormData, submitJob, updateToolFormData } from "./services";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { onMounted } from "vue";
|
||||
import type { WorkflowInvocation } from "@/api/invocations";
|
||||
import { useHistoryStore } from "@/stores/historyStore";
|
||||
import Webhooks from "@/utils/webhooks";
|
||||
import { startWatchingHistory } from "@/watch/watchHistory";
|
||||
import { startWatchingHistory } from "@/watch/watchHistoryProvided";
|
||||
|
||||
import GridInvocation from "@/components/Grid/GridInvocation.vue";
|
||||
import WorkflowInvocationState from "@/components/WorkflowInvocationState/WorkflowInvocationState.vue";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type WatchResourceHandler = () => Promise<void>;
|
||||
export type WatchResourceHandler<T = unknown> = (app?: T) => Promise<void>;
|
||||
|
||||
export interface WatchOptions {
|
||||
/**
|
||||
@@ -29,7 +29,10 @@ const DEFAULT_WATCH_OPTIONS: WatchOptions = {
|
||||
* @param watchHandler The handler function that watches the resource by querying the server.
|
||||
* @param options Options to customize the polling interval.
|
||||
*/
|
||||
export function useResourceWatcher(watchHandler: WatchResourceHandler, options: WatchOptions = DEFAULT_WATCH_OPTIONS) {
|
||||
export function useResourceWatcher<T = unknown>(
|
||||
watchHandler: WatchResourceHandler,
|
||||
options: WatchOptions = DEFAULT_WATCH_OPTIONS
|
||||
) {
|
||||
const { shortPollingInterval, longPollingInterval, enableBackgroundPolling } = {
|
||||
...DEFAULT_WATCH_OPTIONS,
|
||||
...options,
|
||||
@@ -41,9 +44,9 @@ export function useResourceWatcher(watchHandler: WatchResourceHandler, options:
|
||||
/**
|
||||
* Starts watching the resource by polling the server continuously.
|
||||
*/
|
||||
function startWatchingResource() {
|
||||
function startWatchingResource(app?: T) {
|
||||
stopWatcher();
|
||||
tryWatchResource();
|
||||
tryWatchResource(app);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,15 +63,15 @@ export function useResourceWatcher(watchHandler: WatchResourceHandler, options:
|
||||
}
|
||||
}
|
||||
|
||||
async function tryWatchResource() {
|
||||
async function tryWatchResource(app?: T) {
|
||||
try {
|
||||
await watchHandler();
|
||||
await watchHandler(app);
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
} finally {
|
||||
if (currentPollingInterval) {
|
||||
watchTimeout = setTimeout(() => {
|
||||
tryWatchResource();
|
||||
tryWatchResource(app);
|
||||
}, currentPollingInterval);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
import { watchImmediate } from "@vueuse/core";
|
||||
import { type Ref, ref } from "vue";
|
||||
import { type Ref, type UnwrapRef } from "vue";
|
||||
|
||||
import { type AnyUser } from "@/api";
|
||||
|
||||
import { useHashedUserId } from "./hashedUserId";
|
||||
import { useHashedUserId as useHashedUserIdFromStore } from "./hashedUserIdFromUserStore";
|
||||
import { syncRefToLocalStorage } from "./persistentRef";
|
||||
import { useUserLocalStorageFromHashId } from "./userLocalStorageFromHashedId";
|
||||
|
||||
/**
|
||||
* Local storage composable specific to current user.
|
||||
* @param key
|
||||
* @param initialValue
|
||||
*/
|
||||
export function useUserLocalStorage<T>(key: string, initialValue: T, user?: Ref<AnyUser>) {
|
||||
export function useUserLocalStorage<T>(key: string, initialValue: T, user?: Ref<AnyUser>): Ref<UnwrapRef<T>> {
|
||||
let hashedUserId;
|
||||
if (user) {
|
||||
hashedUserId = useHashedUserId(user).hashedUserId;
|
||||
} else {
|
||||
hashedUserId = useHashedUserIdFromStore().hashedUserId;
|
||||
}
|
||||
|
||||
const refToSync = ref(initialValue);
|
||||
let hasSynced = false;
|
||||
|
||||
watchImmediate(
|
||||
() => hashedUserId.value,
|
||||
() => {
|
||||
if (hashedUserId.value && !hasSynced) {
|
||||
syncRefToLocalStorage(`${key}-${hashedUserId.value}`, refToSync);
|
||||
hasSynced = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return refToSync;
|
||||
return useUserLocalStorageFromHashId<T>(key, initialValue, hashedUserId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { watchImmediate } from "@vueuse/core";
|
||||
import { type Ref, ref, type UnwrapRef } from "vue";
|
||||
|
||||
import { syncRefToLocalStorage } from "./persistentRef";
|
||||
|
||||
/**
|
||||
* Local storage composable specific to current user.
|
||||
* @param key
|
||||
* @param initialValue
|
||||
*/
|
||||
export function useUserLocalStorageFromHashId<T>(
|
||||
key: string,
|
||||
initialValue: T,
|
||||
hashedUserId: Ref<string | null>
|
||||
): Ref<UnwrapRef<T>> {
|
||||
const refToSync = ref(initialValue);
|
||||
let hasSynced = false;
|
||||
|
||||
watchImmediate(
|
||||
() => hashedUserId.value,
|
||||
() => {
|
||||
if (hashedUserId.value && !hasSynced) {
|
||||
syncRefToLocalStorage(`${key}-${hashedUserId.value}`, refToSync);
|
||||
hasSynced = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return refToSync;
|
||||
}
|
||||
@@ -2,7 +2,8 @@ import { defineStore } from "pinia";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import { type AnyUser, isAdminUser, isAnonymousUser, isRegisteredUser, type RegisteredUser } from "@/api";
|
||||
import { useUserLocalStorage } from "@/composables/userLocalStorage";
|
||||
import { useHashedUserId } from "@/composables/hashedUserId";
|
||||
import { useUserLocalStorageFromHashId } from "@/composables/userLocalStorageFromHashedId";
|
||||
import { useHistoryStore } from "@/stores/historyStore";
|
||||
import {
|
||||
addFavoriteToolQuery,
|
||||
@@ -28,14 +29,15 @@ type UserListViewPreferences = Record<string, ListViewMode>;
|
||||
export const useUserStore = defineStore("userStore", () => {
|
||||
const currentUser = ref<AnyUser>(null);
|
||||
const currentPreferences = ref<Preferences | null>(null);
|
||||
const { hashedUserId } = useHashedUserId(currentUser);
|
||||
|
||||
const currentListViewPreferences = useUserLocalStorage<UserListViewPreferences>(
|
||||
const currentListViewPreferences = useUserLocalStorageFromHashId<UserListViewPreferences>(
|
||||
"user-store-list-view-preferences",
|
||||
{},
|
||||
currentUser
|
||||
hashedUserId
|
||||
);
|
||||
|
||||
const hasSeenUploadHelp = useUserLocalStorage("user-store-seen-upload-help", false, currentUser);
|
||||
const hasSeenUploadHelp = useUserLocalStorageFromHashId("user-store-seen-upload-help", false, hashedUserId);
|
||||
|
||||
let loadPromise: Promise<void> | null = null;
|
||||
|
||||
|
||||
@@ -89,6 +89,8 @@ function _mountSelectionDialog(clazz, options) {
|
||||
* TODO: This should live somewhere else.
|
||||
*/
|
||||
export function create(options) {
|
||||
const galaxy = getGalaxyInstance();
|
||||
|
||||
async function getHistory() {
|
||||
if (!options.history_id) {
|
||||
return getCurrentGalaxyHistory();
|
||||
@@ -98,7 +100,7 @@ export function create(options) {
|
||||
getHistory().then((history_id) => {
|
||||
uploadSubmit({
|
||||
success: (response) => {
|
||||
startWatchingHistory();
|
||||
startWatchingHistory(galaxy);
|
||||
if (options.success) {
|
||||
options.success(response);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* submitted, delayed only by the throttle period and the request response time.
|
||||
*/
|
||||
|
||||
import { getGalaxyInstance } from "app";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useHistoryItemsStore } from "stores/historyItemsStore";
|
||||
import { useHistoryStore } from "stores/historyStore";
|
||||
@@ -18,8 +17,8 @@ import { useDatasetStore } from "@/stores/datasetStore";
|
||||
|
||||
const limit = 1000;
|
||||
|
||||
const ACTIVE_POLLING_INTERVAL = 3000;
|
||||
const INACTIVE_POLLING_INTERVAL = 60000;
|
||||
export const ACTIVE_POLLING_INTERVAL = 3000;
|
||||
export const INACTIVE_POLLING_INTERVAL = 60000;
|
||||
|
||||
// last time the history has changed
|
||||
let lastUpdateTime = null;
|
||||
@@ -34,11 +33,12 @@ const { startWatchingResource: startWatchingHistory } = useResourceWatcher(watch
|
||||
|
||||
export { startWatchingHistory };
|
||||
|
||||
async function watchHistory() {
|
||||
export async function watchHistory(app) {
|
||||
// GalaxyApp
|
||||
const { isWatching } = storeToRefs(useHistoryItemsStore());
|
||||
try {
|
||||
isWatching.value = true;
|
||||
await watchHistoryOnce();
|
||||
await watchHistoryOnce(app);
|
||||
} catch (error) {
|
||||
// error alerting the user that watch history failed
|
||||
console.warn(error);
|
||||
@@ -46,7 +46,7 @@ async function watchHistory() {
|
||||
}
|
||||
}
|
||||
|
||||
export async function watchHistoryOnce() {
|
||||
export async function watchHistoryOnce(app) {
|
||||
const historyStore = useHistoryStore();
|
||||
const historyItemsStore = useHistoryItemsStore();
|
||||
const datasetStore = useDatasetStore();
|
||||
@@ -91,10 +91,9 @@ export async function watchHistoryOnce() {
|
||||
historyItemsStore.saveHistoryItems(historyId, payload);
|
||||
collectionElementsStore.saveCollections(payload);
|
||||
// trigger changes in legacy handler
|
||||
const Galaxy = getGalaxyInstance();
|
||||
if (Galaxy) {
|
||||
Galaxy.user.fetch({
|
||||
url: `${Galaxy.user.urlRoot()}/${Galaxy.user.id || "current"}`,
|
||||
if (app) {
|
||||
app.user.fetch({
|
||||
url: `${app.user.urlRoot()}/${app.user.id || "current"}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { getGalaxyInstance } from "app";
|
||||
|
||||
import { useResourceWatcher } from "@/composables/resourceWatcher";
|
||||
|
||||
import {
|
||||
ACTIVE_POLLING_INTERVAL,
|
||||
INACTIVE_POLLING_INTERVAL,
|
||||
watchHistory as watchHistorySuppliedApp,
|
||||
} from "./watchHistory";
|
||||
|
||||
function watchHistory() {
|
||||
const app = getGalaxyInstance();
|
||||
return watchHistorySuppliedApp(app);
|
||||
}
|
||||
|
||||
const { startWatchingResource: startWatchingHistory } = useResourceWatcher(watchHistory, {
|
||||
shortPollingInterval: ACTIVE_POLLING_INTERVAL,
|
||||
longPollingInterval: INACTIVE_POLLING_INTERVAL,
|
||||
});
|
||||
|
||||
export { startWatchingHistory };
|
||||
Reference in New Issue
Block a user