From 06d870e44750a86bbdcbd9c8a299227699a36601 Mon Sep 17 00:00:00 2001 From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:25:21 +0200 Subject: [PATCH] generalize activity bar --- .../ActivityBar/ActivityBar.test.js | 2 +- .../components/ActivityBar/ActivityBar.vue | 57 ++++++++++++++----- .../ActivityBar/ActivitySettings.test.js | 3 +- .../ActivityBar/ActivitySettings.vue | 3 +- .../src/components/Panels/SettingsPanel.vue | 8 ++- client/src/stores/activitySetup.ts | 4 +- client/src/stores/activityStore.test.ts | 6 +- client/src/stores/activityStore.ts | 52 ++++++++++++++--- 8 files changed, 101 insertions(+), 34 deletions(-) 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 @@ 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, }; });