diff --git a/client/src/components/ActivityBar/ActivityBar.test.js b/client/src/components/ActivityBar/ActivityBar.test.js
index 1fbab6c98ca..8d1b7fc8bfb 100644
--- a/client/src/components/ActivityBar/ActivityBar.test.js
+++ b/client/src/components/ActivityBar/ActivityBar.test.js
@@ -45,7 +45,7 @@ describe("ActivityBar", () => {
beforeEach(async () => {
const pinia = createTestingPinia({ stubActions: false });
- activityStore = useActivityStore();
+ activityStore = useActivityStore("default");
eventStore = useEventStore();
wrapper = shallowMount(mountTarget, {
localVue,
diff --git a/client/src/components/ActivityBar/ActivityBar.vue b/client/src/components/ActivityBar/ActivityBar.vue
index cde4d7b190a..af8bacca559 100644
--- a/client/src/components/ActivityBar/ActivityBar.vue
+++ b/client/src/components/ActivityBar/ActivityBar.vue
@@ -1,11 +1,10 @@
@@ -226,6 +230,28 @@ watch(
tooltip="Administer this Galaxy"
variant="danger"
@click="onToggleSidebar('admin')" />
+
+
+
+
@@ -234,8 +260,9 @@ watch(
-
+
+
diff --git a/client/src/components/ActivityBar/ActivitySettings.test.js b/client/src/components/ActivityBar/ActivitySettings.test.js
index 2fd33b00d02..fc80db0b912 100644
--- a/client/src/components/ActivityBar/ActivitySettings.test.js
+++ b/client/src/components/ActivityBar/ActivitySettings.test.js
@@ -40,13 +40,14 @@ describe("ActivitySettings", () => {
beforeEach(async () => {
const pinia = createTestingPinia({ stubActions: false });
- activityStore = useActivityStore();
+ activityStore = useActivityStore("default");
activityStore.sync();
wrapper = mount(mountTarget, {
localVue,
pinia,
props: {
query: "",
+ activityBarScope: "default",
},
stubs: {
icon: { template: "
" },
diff --git a/client/src/components/ActivityBar/ActivitySettings.vue b/client/src/components/ActivityBar/ActivitySettings.vue
index fe2ecce28dd..946c78a1996 100644
--- a/client/src/components/ActivityBar/ActivitySettings.vue
+++ b/client/src/components/ActivityBar/ActivitySettings.vue
@@ -19,10 +19,11 @@ library.add({
});
const props = defineProps<{
+ activityBarScope: string;
query: string;
}>();
-const activityStore = useActivityStore();
+const activityStore = useActivityStore(props.activityBarScope);
const { activities } = storeToRefs(activityStore);
const activityAction = useActivityAction();
diff --git a/client/src/components/Panels/SettingsPanel.vue b/client/src/components/Panels/SettingsPanel.vue
index a30b7329b70..013911c8e9c 100644
--- a/client/src/components/Panels/SettingsPanel.vue
+++ b/client/src/components/Panels/SettingsPanel.vue
@@ -10,7 +10,11 @@ import ActivitySettings from "@/components/ActivityBar/ActivitySettings.vue";
import DelayedInput from "@/components/Common/DelayedInput.vue";
import ActivityPanel from "@/components/Panels/ActivityPanel.vue";
-const activityStore = useActivityStore();
+const props = defineProps<{
+ activityBarScope: string;
+}>();
+
+const activityStore = useActivityStore(props.activityBarScope);
const confirmRestore = ref(false);
const query = ref("");
@@ -37,7 +41,7 @@ function onQuery(newQuery: string) {
-
+
{
});
it("initialize store", () => {
- const activityStore = useActivityStore();
+ const activityStore = useActivityStore("default");
expect(activityStore.getAll().length).toBe(0);
activityStore.sync();
expect(activityStore.getAll().length).toBe(1);
});
it("add activity", () => {
- const activityStore = useActivityStore();
+ const activityStore = useActivityStore("default");
activityStore.sync();
const initialActivities = activityStore.getAll();
expect(initialActivities[0]?.visible).toBeTruthy();
@@ -81,7 +81,7 @@ describe("Activity Store", () => {
});
it("remove activity", () => {
- const activityStore = useActivityStore();
+ const activityStore = useActivityStore("default");
activityStore.sync();
const initialActivities = activityStore.getAll();
expect(initialActivities.length).toEqual(1);
diff --git a/client/src/stores/activityStore.ts b/client/src/stores/activityStore.ts
index 377a68e0896..d9dbce64ec6 100644
--- a/client/src/stores/activityStore.ts
+++ b/client/src/stores/activityStore.ts
@@ -1,13 +1,14 @@
/**
* Stores the Activity Bar state
*/
+import { watchImmediate } from "@vueuse/core";
+import { computed, type Ref, ref } from "vue";
-import { defineStore } from "pinia";
-import { type Ref } from "vue";
-
+import { useHashedUserId } from "@/composables/hashedUserId";
import { useUserLocalStorage } from "@/composables/userLocalStorage";
-import { Activities } from "./activitySetup";
+import { defaultActivities } from "./activitySetup";
+import { defineScopedStore } from "./scopedStore";
export interface Activity {
// determine wether an anonymous user can access this activity
@@ -34,14 +35,36 @@ export interface Activity {
visible: boolean;
}
-export const useActivityStore = defineStore("activityStore", () => {
- const activities: Ref> = useUserLocalStorage("activity-store-activities", []);
+export const useActivityStore = defineScopedStore("activityStore", (scope) => {
+ const activities: Ref> = useUserLocalStorage(`activity-store-activities-${scope}`, []);
+
+ const { hashedUserId } = useHashedUserId();
+
+ watchImmediate(
+ () => hashedUserId.value,
+ () => {
+ sync();
+ }
+ );
+
+ const customDefaultActivities = ref(null);
+ const currentDefaultActivities = computed(() => customDefaultActivities.value ?? defaultActivities);
+
+ function overrideDefaultActivities(activities: Activity[]) {
+ customDefaultActivities.value = activities;
+ sync();
+ }
+
+ function resetDefaultActivities() {
+ customDefaultActivities.value = null;
+ sync();
+ }
/**
* Restores the default activity bar items
*/
function restore() {
- activities.value = Activities.slice();
+ activities.value = currentDefaultActivities.value.slice();
}
/**
@@ -52,12 +75,15 @@ export const useActivityStore = defineStore("activityStore", () => {
function sync() {
// create a map of built-in activities
const activitiesMap: Record = {};
- Activities.forEach((a) => {
+
+ currentDefaultActivities.value.forEach((a) => {
activitiesMap[a.id] = a;
});
+
// create an updated array of activities
const newActivities: Array = [];
const foundActivity = new Set();
+
activities.value.forEach((a: Activity) => {
if (a.mutable) {
// existing custom activity
@@ -66,6 +92,7 @@ export const useActivityStore = defineStore("activityStore", () => {
// update existing built-in activity attributes
// skip legacy built-in activities
const sourceActivity = activitiesMap[a.id];
+
if (sourceActivity) {
foundActivity.add(a.id);
newActivities.push({
@@ -75,12 +102,14 @@ export const useActivityStore = defineStore("activityStore", () => {
}
}
});
+
// add new built-in activities
- Activities.forEach((a) => {
+ currentDefaultActivities.value.forEach((a) => {
if (!foundActivity.has(a.id)) {
newActivities.push({ ...a });
}
});
+
// update activities stored in local cache only if changes were applied
if (JSON.stringify(activities.value) !== JSON.stringify(newActivities)) {
activities.value = newActivities;
@@ -97,6 +126,7 @@ export const useActivityStore = defineStore("activityStore", () => {
function remove(activityId: string) {
const findIndex = activities.value.findIndex((a: Activity) => a.id === activityId);
+
if (findIndex !== -1) {
activities.value.splice(findIndex, 1);
}
@@ -109,5 +139,9 @@ export const useActivityStore = defineStore("activityStore", () => {
setAll,
restore,
sync,
+ customDefaultActivities,
+ currentDefaultActivities,
+ overrideDefaultActivities,
+ resetDefaultActivities,
};
});