diff --git a/src/renderer/components/+namespaces/namespace.store.ts b/src/renderer/components/+namespaces/namespace.store.ts index 7e4b8720d6..6473492202 100644 --- a/src/renderer/components/+namespaces/namespace.store.ts +++ b/src/renderer/components/+namespaces/namespace.store.ts @@ -6,13 +6,7 @@ import { apiManager } from "../../api/api-manager"; export class NamespaceStore extends KubeObjectStore { api = namespacesApi; - - private defaultNamespaces: string[] = []; - private storage = createStorage("selected_namespaces", this.defaultNamespaces); - - @computed get selectedNamespaces(): string[] { - return this.storage.get(); - } + private storage = createStorage("selected_namespaces", undefined); constructor() { super(); @@ -26,12 +20,12 @@ export class NamespaceStore extends KubeObjectStore { await this.contextReady; await this.storage.whenReady; - this.setContext(this.initialNamespaces); + this.selectNamespaces(this.initialNamespaces); this.autoLoadAllowedNamespaces(); } public onContextChange(callback: (namespaces: string[]) => void, opts: IReactionOptions = {}): IReactionDisposer { - return reaction(() => Array.from(this.selectedNamespaces), callback, { + return reaction(() => Array.from(this.contextNamespaces), callback, { equals: comparer.shallow, ...opts, }); @@ -45,10 +39,11 @@ export class NamespaceStore extends KubeObjectStore { } private get initialNamespaces(): string[] { - const { allowedNamespaces, selectedNamespaces, defaultNamespaces } = this; + const { allowedNamespaces } = this; + const selectedNamespaces = this.storage.get(); // raw namespaces, undefined on first load // return previously saved namespaces from local-storage (if any) - if (selectedNamespaces !== defaultNamespaces) { + if (Array.isArray(selectedNamespaces)) { return selectedNamespaces.filter(namespace => allowedNamespaces.includes(namespace)); } @@ -62,6 +57,10 @@ export class NamespaceStore extends KubeObjectStore { return []; } + @computed get selectedNamespaces(): string[] { + return this.storage.get() ?? []; + } + @computed get allowedNamespaces(): string[] { return Array.from(new Set([ ...(this.context?.allNamespaces ?? []), // allowed namespaces from cluster (main), updating every 30s @@ -101,14 +100,14 @@ export class NamespaceStore extends KubeObjectStore { } @action - setContext(namespace: string | string[]) { + selectNamespaces(namespace: string | string[]) { const namespaces = Array.from(new Set([namespace].flat())); this.storage.set(namespaces); } @action - resetContext(namespaces?: string | string[]) { + clearSelected(namespaces?: string | string[]) { if (namespaces) { const resettingNamespaces = [namespaces].flat(); const newNamespaces = this.storage.get().filter(ns => !resettingNamespaces.includes(ns)); @@ -132,9 +131,9 @@ export class NamespaceStore extends KubeObjectStore { @action toggleContext(namespaces: string | string[]) { if (this.hasContext(namespaces)) { - this.resetContext(namespaces); + this.clearSelected(namespaces); } else { - this.setContext([this.selectedNamespaces, namespaces].flat()); + this.selectNamespaces([this.selectedNamespaces, namespaces].flat()); } } @@ -142,9 +141,9 @@ export class NamespaceStore extends KubeObjectStore { toggleAll(showAll?: boolean) { if (typeof showAll === "boolean") { if (showAll) { - this.setContext(this.allowedNamespaces); + this.selectNamespaces(this.allowedNamespaces); } else { - this.resetContext(); // empty context considered as "All namespaces" + this.selectNamespaces([]); // empty context considered as "All namespaces" } } else { this.toggleAll(!this.hasAllContexts); @@ -154,7 +153,7 @@ export class NamespaceStore extends KubeObjectStore { @action async remove(item: Namespace) { await super.remove(item); - this.resetContext(item.getName()); + this.clearSelected(item.getName()); } } diff --git a/src/renderer/utils/storageHelper.ts b/src/renderer/utils/storageHelper.ts index 4e61651364..ba8d8f24ab 100755 --- a/src/renderer/utils/storageHelper.ts +++ b/src/renderer/utils/storageHelper.ts @@ -1,6 +1,6 @@ // Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.) -import { action, IObservableValue, makeObservable, observable, toJS, when, } from "mobx"; +import { action, makeObservable, observable, toJS, when, } from "mobx"; import produce, { Draft } from "immer"; import { isEqual, isFunction, isPlainObject } from "lodash"; import logger from "../../main/logger"; @@ -23,8 +23,7 @@ export class StorageHelper { static logPrefix = "[StorageHelper]:"; readonly storage: StorageAdapter; - private data: IObservableValue; - + private data = observable.box(); @observable initialized = false; get whenReady() { @@ -37,12 +36,11 @@ export class StorageHelper { } constructor(readonly key: string, private options: StorageHelperOptions) { - const { storage, defaultValue, autoInit = true } = options; - makeObservable(this); + const { storage, autoInit = true } = options; this.storage = storage; - this.data = observable.box(defaultValue); + this.data.observe_(({ newValue, oldValue }) => { this.onChange(newValue as T, oldValue as T); }); @@ -107,21 +105,21 @@ export class StorageHelper { } get(): T { - const value = this.data.get(); - - // return real default-value (not a copy from observable when it's an object, e.g. []) - // this will allow to compare values by link with == operator - return this.isDefaultValue(value) ? this.defaultValue : value; + return this.data.get() ?? this.defaultValue; } @action set(value: T) { - this.data.set(value); + if (this.isDefaultValue(value)) { + this.reset(); + } else { + this.data.set(value); + } } @action reset() { - this.data.set(this.defaultValue); + this.data.set(undefined); } @action