diff --git a/src/common/user-store/preferences-helpers.ts b/src/common/user-store/preferences-helpers.ts index 228b754387..39d1e0938e 100644 --- a/src/common/user-store/preferences-helpers.ts +++ b/src/common/user-store/preferences-helpers.ts @@ -6,7 +6,7 @@ import moment from "moment-timezone"; import path from "path"; import os from "os"; -import { getAppVersion, ObservableToggleSet } from "../utils"; +import { getAppVersion } from "../utils"; import type { editor } from "monaco-editor"; import merge from "lodash/merge"; import { SemVer } from "semver"; @@ -236,10 +236,10 @@ const terminalCopyOnSelect: PreferenceDescription = { }, }; -const hiddenTableColumns: PreferenceDescription<[string, string[]][], Map>> = { +const hiddenTableColumns: PreferenceDescription<[string, string[]][], Map>> = { fromStore(val) { return new Map( - (val ?? []).map(([tableId, columnIds]) => [tableId, new ObservableToggleSet(columnIds)]), + (val ?? []).map(([tableId, columnIds]) => [tableId, new Set(columnIds)]), ); }, toStore(val) { diff --git a/src/common/user-store/user-store.ts b/src/common/user-store/user-store.ts index a1ffe65d66..9d16b2c419 100644 --- a/src/common/user-store/user-store.ts +++ b/src/common/user-store/user-store.ts @@ -11,7 +11,7 @@ import migrations, { fileNameMigration } from "../../migrations/user-store"; import { getAppVersion } from "../utils/app-version"; import { kubeConfigDefaultPath } from "../kube-helpers"; import { appEventBus } from "../app-event-bus/event-bus"; -import { ObservableToggleSet, toJS } from "../../renderer/utils"; +import { getOrInsertSet, toggle, toJS } from "../../renderer/utils"; import { DESCRIPTORS, EditorConfiguration, ExtensionRegistry, KubeconfigSyncValue, UserPreferencesModel, TerminalConfig } from "./preferences-helpers"; import logger from "../../main/logger"; @@ -71,7 +71,7 @@ export class UserStore extends BaseStore /* implements UserStore * The column IDs under each configurable table ID that have been configured * to not be shown */ - hiddenTableColumns = observable.map>(); + hiddenTableColumns = observable.map>(); /** * Monaco editor configs @@ -133,16 +133,11 @@ export class UserStore extends BaseStore /* implements UserStore return columnIds.some(columnId => config.has(columnId)); } - @action /** * Toggles the hidden configuration of a table's column */ toggleTableColumnVisibility(tableId: string, columnId: string) { - if (!this.hiddenTableColumns.get(tableId)) { - this.hiddenTableColumns.set(tableId, new ObservableToggleSet()); - } - - this.hiddenTableColumns.get(tableId).toggle(columnId); + toggle(getOrInsertSet(this.hiddenTableColumns, tableId), columnId); } @action diff --git a/src/common/utils/collection-functions.ts b/src/common/utils/collection-functions.ts index 0d18a41e8a..267668ce81 100644 --- a/src/common/utils/collection-functions.ts +++ b/src/common/utils/collection-functions.ts @@ -3,6 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import { runInAction } from "mobx"; + /** * Get the value behind `key`. If it was not present, first insert `value` * @param map The map to interact with @@ -26,6 +28,14 @@ export function getOrInsertMap(map: Map>, key: K): Map return getOrInsert(map, key, new Map()); } +/** + * Like `getOrInsert` but specifically for when `V` is `Set` so that + * the typings are inferred. + */ +export function getOrInsertSet(map: Map>, key: K): Set { + return getOrInsert(map, key, new Set()); +} + /** * Like `getOrInsert` but with delayed creation of the item */ @@ -36,3 +46,17 @@ export function getOrInsertWith(map: Map, key: K, value: () => V): V return map.get(key); } + +/** + * If `key` is in `set`, remove it otherwise add it. + * @param set The set to manipulate + * @param key The key to toggle the "is in"-ness of + */ +export function toggle(set: Set, key: K): void { + runInAction(() => { + // Returns true if value was already in Set; otherwise false. + if (!set.delete(key)) { + set.add(key); + } + }); +} diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index d349bd3b14..d8a07f31f6 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -38,7 +38,6 @@ export * from "./singleton"; export * from "./sort-compare"; export * from "./splitArray"; export * from "./tar"; -export * from "./toggle-set"; export * from "./toJS"; export * from "./type-narrowing"; export * from "./types"; diff --git a/src/common/utils/toggle-set.ts b/src/common/utils/toggle-set.ts deleted file mode 100644 index 3b3c226f9b..0000000000 --- a/src/common/utils/toggle-set.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import { ObservableSet } from "mobx"; - -export class ToggleSet extends Set { - public toggle(value: T): void { - if (!this.delete(value)) { - // Set.prototype.delete returns false if `value` was not in the set - this.add(value); - } - } -} - -export class ObservableToggleSet extends ObservableSet { - public toggle(value: T): void { - if (!this.delete(value)) { - // Set.prototype.delete returns false if `value` was not in the set - this.add(value); - } - } -} diff --git a/src/renderer/components/+config-secrets/secret-details.tsx b/src/renderer/components/+config-secrets/secret-details.tsx index 55e6d605f5..fce67d0abc 100644 --- a/src/renderer/components/+config-secrets/secret-details.tsx +++ b/src/renderer/components/+config-secrets/secret-details.tsx @@ -12,7 +12,7 @@ import { DrawerItem, DrawerTitle } from "../drawer"; import { Input } from "../input"; import { Button } from "../button"; import { Notifications } from "../notifications"; -import { base64, ObservableToggleSet } from "../../utils"; +import { base64, toggle } from "../../utils"; import { Icon } from "../icon"; import { secretsStore } from "./secrets.store"; import type { KubeObjectDetailsProps } from "../kube-object-details"; @@ -27,7 +27,7 @@ interface Props extends KubeObjectDetailsProps { export class SecretDetails extends React.Component { @observable isSaving = false; @observable data: { [name: string]: string } = {}; - revealSecret = new ObservableToggleSet(); + revealSecret = new Set(); constructor(props: Props) { super(props); @@ -99,7 +99,7 @@ export class SecretDetails extends React.Component { this.revealSecret.toggle(name)} + onClick={() => toggle(this.revealSecret, name)} /> )} diff --git a/src/renderer/components/+namespaces/namespace-store/namespace.store.ts b/src/renderer/components/+namespaces/namespace-store/namespace.store.ts index 00cfd6748a..4066070cc3 100644 --- a/src/renderer/components/+namespaces/namespace-store/namespace.store.ts +++ b/src/renderer/components/+namespaces/namespace-store/namespace.store.ts @@ -4,7 +4,7 @@ */ import { action, comparer, computed, IReactionDisposer, makeObservable, reaction } from "mobx"; -import { autoBind, noop, StorageHelper, ToggleSet } from "../../../utils"; +import { autoBind, noop, StorageHelper, toggle } from "../../../utils"; import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../../../common/k8s-api/kube-object.store"; import { Namespace, namespacesApi } from "../../../../common/k8s-api/endpoints/namespaces.api"; @@ -175,10 +175,10 @@ export class NamespaceStore extends KubeObjectStore { */ @action toggleContext(namespaces: string | string[]) { - const nextState = new ToggleSet(this.contextNamespaces); + const nextState = new Set(this.contextNamespaces); for (const namespace of [namespaces].flat()) { - nextState.toggle(namespace); + toggle(nextState, namespace); } this.dependencies.storage.set([...nextState]); @@ -191,9 +191,9 @@ export class NamespaceStore extends KubeObjectStore { * @param namespace The name of a namespace */ toggleSingle(namespace: string) { - const nextState = new ToggleSet(this.contextNamespaces); + const nextState = new Set(this.contextNamespaces); - nextState.toggle(namespace); + toggle(nextState, namespace); this.dependencies.storage.set([...nextState]); } diff --git a/src/renderer/components/item-object-list/list-layout.tsx b/src/renderer/components/item-object-list/list-layout.tsx index 39211d0a6b..959f814bce 100644 --- a/src/renderer/components/item-object-list/list-layout.tsx +++ b/src/renderer/components/item-object-list/list-layout.tsx @@ -8,31 +8,17 @@ import "./item-list-layout.scss"; import React, { ReactNode } from "react"; import { computed, makeObservable, untracked } from "mobx"; import type { ConfirmDialogParams } from "../confirm-dialog"; -import type { - TableCellProps, - TableProps, - TableRowProps, - TableSortCallbacks, -} from "../table"; -import { - boundMethod, - cssNames, - IClassName, - noop, - ObservableToggleSet, - StorageHelper, -} from "../../utils"; +import type { TableCellProps, TableProps, TableRowProps, TableSortCallbacks } from "../table"; +import { boundMethod, cssNames, IClassName, noop, StorageHelper } from "../../utils"; import type { AddRemoveButtonsProps } from "../add-remove-buttons"; import type { ItemObject, ItemStore } from "../../../common/item.store"; import type { SearchInputUrlProps } from "../input"; import { Filter, FilterType, pageFilters } from "./page-filters.store"; import { PageFiltersList } from "./page-filters-list"; -import { UserStore } from "../../../common/user-store"; import type { NamespaceStore } from "../+namespaces/namespace-store/namespace.store"; import namespaceStoreInjectable from "../+namespaces/namespace-store/namespace-store.injectable"; import { withInjectables } from "@ogre-tools/injectable-react"; -import itemListLayoutStorageInjectable - from "./storage.injectable"; +import itemListLayoutStorageInjectable from "./storage.injectable"; import { ItemListLayoutContent } from "./content"; import { ItemListLayoutHeader } from "./header"; import groupBy from "lodash/groupBy"; @@ -142,10 +128,6 @@ class NonInjectedItemListLayout extends React.Component