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

refactoring, more possible branch fixes + lint

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-05-08 15:02:59 +03:00
parent 0c8ff6a1d6
commit 6ee2385d3c
13 changed files with 61 additions and 70 deletions

View File

@ -25,7 +25,7 @@ The following example code creates a store for the `appPreferences` guide exampl
``` typescript ``` typescript
import { Store } from "@k8slens/extensions"; import { Store } from "@k8slens/extensions";
import { observable, toJS, makeObservable } from "mobx"; import { observable, makeObservable } from "mobx";
export type ExamplePreferencesModel = { export type ExamplePreferencesModel = {
enabled: boolean; enabled: boolean;
@ -51,7 +51,7 @@ export class ExamplePreferencesStore extends Store.ExtensionStore<ExamplePrefere
toJSON(): ExamplePreferencesModel { toJSON(): ExamplePreferencesModel {
return { return {
enabled: toJS(this.enabled) enabled: this.enabled
}; };
} }
} }
@ -72,7 +72,6 @@ The `enabled` field of the `ExamplePreferencesStore` is set to the value from th
The `toJSON()` method is complementary to `fromStore()`. The `toJSON()` method is complementary to `fromStore()`.
It is called when the store is being saved. It is called when the store is being saved.
`toJSON()` must provide a JSON serializable object, facilitating its storage in JSON format. `toJSON()` must provide a JSON serializable object, facilitating its storage in JSON format.
The `toJS()` function from [`mobx`](https://mobx.js.org/README.html) is convenient for this purpose, and is used here.
Finally, `ExamplePreferencesStore` is created by calling `ExamplePreferencesStore.getInstanceOrCreate()`, and exported for use by other parts of the extension. Finally, `ExamplePreferencesStore` is created by calling `ExamplePreferencesStore.getInstanceOrCreate()`, and exported for use by other parts of the extension.
Note that `ExamplePreferencesStore` is a singleton. Note that `ExamplePreferencesStore` is a singleton.

View File

@ -1,24 +1,27 @@
import { action, computed, observable, makeObservable } from "mobx"; import { action, computed, makeObservable, observable } from "mobx";
import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "./catalog-entity"; import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "./catalog-entity";
import { toJS } from "../utils";
export class CatalogCategoryRegistry { export class CatalogCategoryRegistry {
@observable protected categories: CatalogCategory[] = []; protected categories = observable.array<CatalogCategory>();
constructor() { constructor() {
makeObservable(this); makeObservable(this);
} }
@action add(category: CatalogCategory) { @action
add(category: CatalogCategory) {
this.categories.push(category); this.categories.push(category);
} }
@action remove(category: CatalogCategory) { @action
this.categories = this.categories.filter((cat) => cat.apiVersion !== category.apiVersion && cat.kind !== category.kind); remove(category: CatalogCategory) {
const categories = this.categories.filter((cat) => cat.apiVersion !== category.apiVersion && cat.kind !== category.kind);
this.categories.replace(categories);
} }
@computed get items() { @computed get items(): CatalogCategory[] {
return toJS(this.categories); return Array.from(this.categories);
} }
getForGroupKind<T extends CatalogCategory>(group: string, kind: string) { getForGroupKind<T extends CatalogCategory>(group: string, kind: string) {

View File

@ -1,27 +1,20 @@
import { import { action, computed, IComputedValue, IObservableArray, makeObservable, observable } from "mobx";
action,
computed,
observable,
IComputedValue,
IObservableArray,
makeObservable,
} from "mobx";
import { CatalogEntity } from "./catalog-entity"; import { CatalogEntity } from "./catalog-entity";
import { iter } from "../utils";
export class CatalogEntityRegistry { export class CatalogEntityRegistry {
protected sources = observable.map<string, IComputedValue<CatalogEntity[]>>([], { deep: true }); protected sources = observable.map<string, IComputedValue<CatalogEntity[]>>();
constructor() { constructor() {
makeObservable(this); makeObservable(this);
} }
@action addObservableSource(id: string, source: IObservableArray<CatalogEntity>) { @action
this.sources.set(id, computed(() => source)); addObservableSource(id: string, source: IObservableArray<CatalogEntity> | IComputedValue<CatalogEntity[]>) {
} if (Array.isArray(source)) {
this.sources.set(id, computed(() => source.toJSON()));
@action addComputedSource(id: string, source: IComputedValue<CatalogEntity[]>) { } else {
this.sources.set(id, source); this.sources.set(id, source);
}
} }
@action removeSource(id: string) { @action removeSource(id: string) {
@ -29,7 +22,9 @@ export class CatalogEntityRegistry {
} }
@computed get items(): CatalogEntity[] { @computed get items(): CatalogEntity[] {
return Array.from(iter.flatMap(this.sources.values(), source => source.get())); return Array.from(this.sources.values())
.map(source => source.get())
.flat();
} }
getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] { getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] {

View File

@ -1,27 +1,28 @@
import { reaction } from "mobx"; import { reaction } from "mobx";
import { broadcastMessage, subscribeToBroadcast, unsubscribeFromBroadcast } from "../common/ipc"; import { broadcastMessage, subscribeToBroadcast, unsubscribeFromBroadcast } from "../common/ipc";
import { CatalogEntityRegistry} from "../common/catalog"; import { CatalogEntityRegistry } from "../common/catalog";
import "../common/catalog-entities/kubernetes-cluster"; import "../common/catalog-entities/kubernetes-cluster";
import { Disposer, toJS } from "../common/utils"; import { Disposer } from "../common/utils";
export class CatalogPusher { export class CatalogPusher {
static init(catalog: CatalogEntityRegistry) { static init(catalog: CatalogEntityRegistry) {
new CatalogPusher(catalog).init(); new CatalogPusher(catalog).init();
} }
private constructor(private catalog: CatalogEntityRegistry) {} private constructor(private catalog: CatalogEntityRegistry) {
}
init() { init() {
const disposers: Disposer[] = []; const disposers: Disposer[] = [
reaction(
disposers.push(reaction(() => toJS(this.catalog.items), (items) => { () => this.catalog.items,
broadcastMessage("catalog:items", items); (items) => broadcastMessage("catalog:items", items),
}, { { fireImmediately: true }
fireImmediately: true, ),
})); ];
const listener = subscribeToBroadcast("catalog:broadcast", () => { const listener = subscribeToBroadcast("catalog:broadcast", () => {
broadcastMessage("catalog:items", toJS(this.catalog.items)); broadcastMessage("catalog:items", this.catalog.items);
}); });
disposers.push(() => unsubscribeFromBroadcast("catalog:broadcast", listener)); disposers.push(() => unsubscribeFromBroadcast("catalog:broadcast", listener));

View File

@ -1,12 +1,4 @@
import { import { action, computed, IComputedValue, makeObservable, observable, ObservableMap, runInAction, } from "mobx";
action,
observable,
IComputedValue,
computed,
ObservableMap,
runInAction,
makeObservable,
} from "mobx";
import { CatalogEntity, catalogEntityRegistry } from "../../common/catalog"; import { CatalogEntity, catalogEntityRegistry } from "../../common/catalog";
import { watch } from "chokidar"; import { watch } from "chokidar";
import fs from "fs"; import fs from "fs";
@ -47,7 +39,7 @@ export class KubeconfigSyncManager extends Singleton {
logger.info(`${logPrefix} starting requested syncs`); logger.info(`${logPrefix} starting requested syncs`);
catalogEntityRegistry.addComputedSource(KubeconfigSyncManager.syncName, computed(() => ( catalogEntityRegistry.addObservableSource(KubeconfigSyncManager.syncName, computed(() => (
Array.from(iter.flatMap( Array.from(iter.flatMap(
this.sources.values(), this.sources.values(),
([entities]) => entities.get() ([entities]) => entities.get()

View File

@ -6,7 +6,7 @@ import { ClusterStore, getClusterIdFromHost } from "../common/cluster-store";
import { Cluster } from "./cluster"; import { Cluster } from "./cluster";
import logger from "./logger"; import logger from "./logger";
import { apiKubePrefix } from "../common/vars"; import { apiKubePrefix } from "../common/vars";
import { Singleton, toJS } from "../common/utils"; import { Singleton } from "../common/utils";
import { catalogEntityRegistry } from "../common/catalog"; import { catalogEntityRegistry } from "../common/catalog";
import { KubernetesCluster } from "../common/catalog-entities/kubernetes-cluster"; import { KubernetesCluster } from "../common/catalog-entities/kubernetes-cluster";

View File

@ -2,7 +2,7 @@ import { randomBytes } from "crypto";
import { SHA256 } from "crypto-js"; import { SHA256 } from "crypto-js";
import { app, remote } from "electron"; import { app, remote } from "electron";
import fse from "fs-extra"; import fse from "fs-extra";
import { action, observable, makeObservable } from "mobx"; import { action, makeObservable, observable } from "mobx";
import path from "path"; import path from "path";
import { BaseStore } from "../common/base-store"; import { BaseStore } from "../common/base-store";
import { LensExtensionId } from "../extensions/lens-extension"; import { LensExtensionId } from "../extensions/lens-extension";
@ -13,7 +13,7 @@ interface FSProvisionModel {
} }
export class FilesystemProvisionerStore extends BaseStore<FSProvisionModel> { export class FilesystemProvisionerStore extends BaseStore<FSProvisionModel> {
@observable registeredExtensions = observable.map<LensExtensionId, string>(); registeredExtensions = observable.map<LensExtensionId, string>();
constructor() { constructor() {
super({ super({

View File

@ -10,7 +10,7 @@ import { Singleton } from "../common/utils";
import { ClusterFrameInfo, clusterFrameMap } from "../common/cluster-frames"; import { ClusterFrameInfo, clusterFrameMap } from "../common/cluster-frames";
import { IpcRendererNavigationEvents } from "../renderer/navigation/events"; import { IpcRendererNavigationEvents } from "../renderer/navigation/events";
import logger from "./logger"; import logger from "./logger";
import { isProduction, productName } from "../common/vars"; import { productName } from "../common/vars";
import { LensProxy } from "./proxy/lens-proxy"; import { LensProxy } from "./proxy/lens-proxy";
export class WindowManager extends Singleton { export class WindowManager extends Singleton {

View File

@ -34,7 +34,7 @@ export class DockTabStore<T> {
this.storage = createStorage(storageKey, {}); this.storage = createStorage(storageKey, {});
this.storage.whenReady.then(() => { this.storage.whenReady.then(() => {
this.data.replace(this.storage.get()); this.data.replace(this.storage.get());
reaction(() => this.getStorableData(), data => this.storage.set(data)); reaction(() => this.toJSON(), data => this.storage.set(data));
}); });
} }
@ -54,14 +54,14 @@ export class DockTabStore<T> {
return data; return data;
} }
protected getStorableData(): DockTabStorageState<T> { protected toJSON(): DockTabStorageState<T> {
const allTabsData = toJS(this.data); const deepCopy = toJS(this.data);
return Object.fromEntries( deepCopy.forEach((tabData, key) => {
Object.entries(allTabsData).map(([tabId, tabData]) => { deepCopy.set(key, this.finalizeDataForSave(tabData));
return [tabId, this.finalizeDataForSave(tabData)]; });
})
); return Object.fromEntries<T>(deepCopy);
} }
isReady(tabId: TabId): boolean { isReady(tabId: TabId): boolean {

View File

@ -7,7 +7,7 @@ import { DockTab, DockTabProps } from "./dock-tab";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { terminalStore } from "./terminal.store"; import { terminalStore } from "./terminal.store";
import { dockStore } from "./dock.store"; import { dockStore } from "./dock.store";
import { reaction, makeObservable } from "mobx"; import { reaction } from "mobx";
interface Props extends DockTabProps { interface Props extends DockTabProps {
} }

View File

@ -5,7 +5,7 @@ import { FitAddon } from "xterm-addon-fit";
import { dockStore, TabId } from "./dock.store"; import { dockStore, TabId } from "./dock.store";
import { TerminalApi } from "../../api/terminal-api"; import { TerminalApi } from "../../api/terminal-api";
import { ThemeStore } from "../../theme.store"; import { ThemeStore } from "../../theme.store";
import { boundMethod, toJS } from "../../utils"; import { boundMethod } from "../../utils";
import { isMac } from "../../../common/vars"; import { isMac } from "../../../common/vars";
import { camelCase } from "lodash"; import { camelCase } from "lodash";
@ -104,7 +104,7 @@ export class Terminal {
window.addEventListener("resize", this.onResize); window.addEventListener("resize", this.onResize);
this.disposers.push( this.disposers.push(
reaction(() => toJS(ThemeStore.getInstance().activeTheme.colors), this.setTheme, { reaction(() => ThemeStore.getInstance().activeTheme.colors, this.setTheme, {
fireImmediately: true fireImmediately: true
}), }),
dockStore.onResize(this.onResize), dockStore.onResize(this.onResize),
@ -132,7 +132,7 @@ export class Terminal {
const { cols, rows } = this.xterm; const { cols, rows } = this.xterm;
this.api.sendTerminalSize(cols, rows); this.api.sendTerminalSize(cols, rows);
} catch(error) { } catch (error) {
console.error(error); console.error(error);
return; // see https://github.com/lensapp/lens/issues/1891 return; // see https://github.com/lensapp/lens/issues/1891
@ -183,12 +183,12 @@ export class Terminal {
// Handle custom hotkey bindings // Handle custom hotkey bindings
if (ctrlKey) { if (ctrlKey) {
switch (code) { switch (code) {
// Ctrl+C: prevent terminal exit on windows / linux (?) // Ctrl+C: prevent terminal exit on windows / linux (?)
case "KeyC": case "KeyC":
if (this.xterm.hasSelection()) return false; if (this.xterm.hasSelection()) return false;
break; break;
// Ctrl+W: prevent unexpected terminal tab closing, e.g. editing file in vim // Ctrl+W: prevent unexpected terminal tab closing, e.g. editing file in vim
case "KeyW": case "KeyW":
evt.preventDefault(); evt.preventDefault();
break; break;

View File

@ -8,7 +8,7 @@ import { StorageHelper } from "./storageHelper";
import { ClusterStore, getHostedClusterId } from "../../common/cluster-store"; import { ClusterStore, getHostedClusterId } from "../../common/cluster-store";
import logger from "../../main/logger"; import logger from "../../main/logger";
const LOG_PREFIX = '[LocalStorageHelper]:'; const LOG_PREFIX = "[LocalStorageHelper]:";
const storage = observable({ const storage = observable({
initialized: false, initialized: false,
@ -56,6 +56,7 @@ export function createStorage<T>(key: string, defaultValue: T) {
async function saveFile(state: Record<string, any> = {}) { async function saveFile(state: Record<string, any> = {}) {
logger.info(`${LOG_PREFIX} saving ${filePath}`); logger.info(`${LOG_PREFIX} saving ${filePath}`);
try { try {
await fse.ensureDir(folder, { mode: 0o755 }); await fse.ensureDir(folder, { mode: 0o755 });
await fse.writeJson(filePath, state, { spaces: 2 }); await fse.writeJson(filePath, state, { spaces: 2 });

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, CreateObservableOptions, IObservableValue, makeObservable, observable, toJS, when, } from "mobx"; import { action, IObservableValue, 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";