1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix: restore "all namespaces" on page reload

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-05-10 21:11:22 +03:00
parent 5c67bb7ae2
commit 749eb4a42b
2 changed files with 28 additions and 31 deletions

View File

@ -6,13 +6,7 @@ import { apiManager } from "../../api/api-manager";
export class NamespaceStore extends KubeObjectStore<Namespace> { export class NamespaceStore extends KubeObjectStore<Namespace> {
api = namespacesApi; api = namespacesApi;
private storage = createStorage<string[] | undefined>("selected_namespaces", undefined);
private defaultNamespaces: string[] = [];
private storage = createStorage<string[]>("selected_namespaces", this.defaultNamespaces);
@computed get selectedNamespaces(): string[] {
return this.storage.get();
}
constructor() { constructor() {
super(); super();
@ -26,12 +20,12 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
await this.contextReady; await this.contextReady;
await this.storage.whenReady; await this.storage.whenReady;
this.setContext(this.initialNamespaces); this.selectNamespaces(this.initialNamespaces);
this.autoLoadAllowedNamespaces(); this.autoLoadAllowedNamespaces();
} }
public onContextChange(callback: (namespaces: string[]) => void, opts: IReactionOptions = {}): IReactionDisposer { 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, equals: comparer.shallow,
...opts, ...opts,
}); });
@ -45,10 +39,11 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
} }
private get initialNamespaces(): string[] { 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) // return previously saved namespaces from local-storage (if any)
if (selectedNamespaces !== defaultNamespaces) { if (Array.isArray(selectedNamespaces)) {
return selectedNamespaces.filter(namespace => allowedNamespaces.includes(namespace)); return selectedNamespaces.filter(namespace => allowedNamespaces.includes(namespace));
} }
@ -62,6 +57,10 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
return []; return [];
} }
@computed get selectedNamespaces(): string[] {
return this.storage.get() ?? [];
}
@computed get allowedNamespaces(): string[] { @computed get allowedNamespaces(): string[] {
return Array.from(new Set([ return Array.from(new Set([
...(this.context?.allNamespaces ?? []), // allowed namespaces from cluster (main), updating every 30s ...(this.context?.allNamespaces ?? []), // allowed namespaces from cluster (main), updating every 30s
@ -101,14 +100,14 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
} }
@action @action
setContext(namespace: string | string[]) { selectNamespaces(namespace: string | string[]) {
const namespaces = Array.from(new Set([namespace].flat())); const namespaces = Array.from(new Set([namespace].flat()));
this.storage.set(namespaces); this.storage.set(namespaces);
} }
@action @action
resetContext(namespaces?: string | string[]) { clearSelected(namespaces?: string | string[]) {
if (namespaces) { if (namespaces) {
const resettingNamespaces = [namespaces].flat(); const resettingNamespaces = [namespaces].flat();
const newNamespaces = this.storage.get().filter(ns => !resettingNamespaces.includes(ns)); const newNamespaces = this.storage.get().filter(ns => !resettingNamespaces.includes(ns));
@ -132,9 +131,9 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
@action @action
toggleContext(namespaces: string | string[]) { toggleContext(namespaces: string | string[]) {
if (this.hasContext(namespaces)) { if (this.hasContext(namespaces)) {
this.resetContext(namespaces); this.clearSelected(namespaces);
} else { } else {
this.setContext([this.selectedNamespaces, namespaces].flat()); this.selectNamespaces([this.selectedNamespaces, namespaces].flat());
} }
} }
@ -142,9 +141,9 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
toggleAll(showAll?: boolean) { toggleAll(showAll?: boolean) {
if (typeof showAll === "boolean") { if (typeof showAll === "boolean") {
if (showAll) { if (showAll) {
this.setContext(this.allowedNamespaces); this.selectNamespaces(this.allowedNamespaces);
} else { } else {
this.resetContext(); // empty context considered as "All namespaces" this.selectNamespaces([]); // empty context considered as "All namespaces"
} }
} else { } else {
this.toggleAll(!this.hasAllContexts); this.toggleAll(!this.hasAllContexts);
@ -154,7 +153,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
@action @action
async remove(item: Namespace) { async remove(item: Namespace) {
await super.remove(item); await super.remove(item);
this.resetContext(item.getName()); this.clearSelected(item.getName());
} }
} }

View File

@ -1,6 +1,6 @@
// Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.) // 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 produce, { Draft } from "immer";
import { isEqual, isFunction, isPlainObject } from "lodash"; import { isEqual, isFunction, isPlainObject } from "lodash";
import logger from "../../main/logger"; import logger from "../../main/logger";
@ -23,8 +23,7 @@ export class StorageHelper<T> {
static logPrefix = "[StorageHelper]:"; static logPrefix = "[StorageHelper]:";
readonly storage: StorageAdapter<T>; readonly storage: StorageAdapter<T>;
private data: IObservableValue<T>; private data = observable.box<T>();
@observable initialized = false; @observable initialized = false;
get whenReady() { get whenReady() {
@ -37,12 +36,11 @@ export class StorageHelper<T> {
} }
constructor(readonly key: string, private options: StorageHelperOptions<T>) { constructor(readonly key: string, private options: StorageHelperOptions<T>) {
const { storage, defaultValue, autoInit = true } = options;
makeObservable(this); makeObservable(this);
const { storage, autoInit = true } = options;
this.storage = storage; this.storage = storage;
this.data = observable.box<T>(defaultValue);
this.data.observe_(({ newValue, oldValue }) => { this.data.observe_(({ newValue, oldValue }) => {
this.onChange(newValue as T, oldValue as T); this.onChange(newValue as T, oldValue as T);
}); });
@ -107,21 +105,21 @@ export class StorageHelper<T> {
} }
get(): T { get(): T {
const value = this.data.get(); return this.data.get() ?? this.defaultValue;
// 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;
} }
@action @action
set(value: T) { set(value: T) {
this.data.set(value); if (this.isDefaultValue(value)) {
this.reset();
} else {
this.data.set(value);
}
} }
@action @action
reset() { reset() {
this.data.set(this.defaultValue); this.data.set(undefined);
} }
@action @action