mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
replacing toJS({}) to utils/cloneJson where might be necessary
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
f620c09095
commit
4fbefb648a
@ -49,9 +49,9 @@ export class ExamplePreferencesStore extends Store.ExtensionStore<ExamplePrefere
|
||||
}
|
||||
|
||||
toJSON(): ExamplePreferencesModel {
|
||||
return toJS({
|
||||
enabled: this.enabled
|
||||
});
|
||||
return {
|
||||
enabled: toJS(this.enabled),
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -71,7 +71,6 @@ The `enabled` field of the `ExamplePreferencesStore` is set to the value from th
|
||||
The `toJSON()` method is complementary to `fromStore()`.
|
||||
It is called when the store is being saved.
|
||||
`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.
|
||||
Note that `ExamplePreferencesStore` is a singleton.
|
||||
|
||||
@ -25,6 +25,7 @@ export class KubernetesCluster implements CatalogEntity {
|
||||
|
||||
constructor(data: CatalogEntityData) {
|
||||
makeObservable(this);
|
||||
|
||||
this.metadata = data.metadata;
|
||||
this.status = data.status as KubernetesClusterStatus;
|
||||
this.spec = data.spec as KubernetesClusterSpec;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { action, computed, observable, IObservableArray, makeObservable } from "mobx";
|
||||
import { action, computed, IObservableArray, makeObservable, observable, toJS } from "mobx";
|
||||
import { CatalogEntity } from "./catalog-entity";
|
||||
|
||||
export class CatalogEntityRegistry {
|
||||
@ -17,7 +17,7 @@ export class CatalogEntityRegistry {
|
||||
}
|
||||
|
||||
@computed get items(): CatalogEntity[] {
|
||||
return Array.from(this.sources.values()).flat();
|
||||
return Array.from(toJS(this.sources).values()).flat();
|
||||
}
|
||||
|
||||
getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import path from "path";
|
||||
import { app, ipcRenderer, remote, webFrame } from "electron";
|
||||
import { unlink } from "fs-extra";
|
||||
import { action, comparer, computed, observable, reaction, toJS, makeObservable } from "mobx";
|
||||
import { action, comparer, computed, makeObservable, observable, reaction, toJS } from "mobx";
|
||||
import { BaseStore } from "./base-store";
|
||||
import { Cluster, ClusterState } from "../main/cluster";
|
||||
import migrations from "../migrations/cluster-store";
|
||||
@ -12,6 +12,7 @@ import { saveToAppFiles } from "./utils/saveToAppFiles";
|
||||
import { KubeConfig } from "@kubernetes/client-node";
|
||||
import { handleRequest, requestMain, subscribeToBroadcast, unsubscribeAllFromBroadcast } from "./ipc";
|
||||
import { ResourceType } from "../renderer/components/cluster-settings/components/cluster-metrics-setting";
|
||||
import { cloneJson } from "./utils";
|
||||
|
||||
export interface ClusterIconUpload {
|
||||
clusterId: string;
|
||||
@ -47,7 +48,7 @@ export interface ClusterModel {
|
||||
* Workspace id
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
*/
|
||||
workspace?: string;
|
||||
|
||||
/** User context in kubeconfig */
|
||||
@ -330,7 +331,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
}
|
||||
|
||||
toJSON(): ClusterStoreModel {
|
||||
return toJS({
|
||||
return cloneJson({
|
||||
activeCluster: this.activeCluster,
|
||||
clusters: this.clustersList.map(cluster => cluster.toJSON()),
|
||||
});
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { action, comparer, observable, toJS, makeObservable } from "mobx";
|
||||
import { action, comparer, makeObservable, observable } from "mobx";
|
||||
import { BaseStore } from "./base-store";
|
||||
import migrations from "../migrations/hotbar-store";
|
||||
import * as uuid from "uuid";
|
||||
import { cloneJson } from "./utils";
|
||||
|
||||
export interface HotbarItem {
|
||||
entity: {
|
||||
@ -59,7 +60,8 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
||||
return this.hotbars.findIndex((hotbar) => hotbar.id === this.activeHotbarId);
|
||||
}
|
||||
|
||||
@action protected async fromStore(data: Partial<HotbarStoreModel> = {}) {
|
||||
@action
|
||||
protected async fromStore(data: Partial<HotbarStoreModel> = {}) {
|
||||
if (data.hotbars?.length === 0) {
|
||||
this.hotbars = [{
|
||||
id: uuid.v4(),
|
||||
@ -139,11 +141,9 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
||||
}
|
||||
|
||||
toJSON(): HotbarStoreModel {
|
||||
const model: HotbarStoreModel = {
|
||||
return cloneJson({
|
||||
hotbars: this.hotbars,
|
||||
activeHotbarId: this.activeHotbarId
|
||||
};
|
||||
|
||||
return toJS(model);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
// https://www.electronjs.org/docs/api/ipc-main
|
||||
// https://www.electronjs.org/docs/api/ipc-renderer
|
||||
|
||||
import { ipcMain, ipcRenderer, webContents, remote } from "electron";
|
||||
import { ipcMain, ipcRenderer, remote, webContents } from "electron";
|
||||
import { toJS } from "mobx";
|
||||
import logger from "../../main/logger";
|
||||
import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames";
|
||||
import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames";
|
||||
|
||||
const subFramesChannel = "ipc:get-sub-frames";
|
||||
|
||||
@ -18,7 +18,7 @@ export async function requestMain(channel: string, ...args: any[]) {
|
||||
}
|
||||
|
||||
function getSubFrames(): ClusterFrameInfo[] {
|
||||
return toJS(Array.from(clusterFrameMap.values()));
|
||||
return Array.from(toJS(clusterFrameMap).values());
|
||||
}
|
||||
|
||||
export async function broadcastMessage(channel: string, ...args: any[]) {
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
// Global configuration setup for external packages.
|
||||
// Should be imported at the top of app's entry points.
|
||||
import { configure } from "mobx";
|
||||
import { enableMapSet, setAutoFreeze } from "immer";
|
||||
import * as Mobx from "mobx";
|
||||
import * as Immer from "immer";
|
||||
|
||||
// Mobx
|
||||
// Docs: https://mobx.js.org/configuration.html
|
||||
configure({
|
||||
isolateGlobalState: true,
|
||||
Mobx.configure({
|
||||
enforceActions: "never",
|
||||
isolateGlobalState: true,
|
||||
|
||||
// TODO: enable later (read more: https://mobx.js.org/migrating-from-4-or-5.html)
|
||||
// computedRequiresReaction: true,
|
||||
// reactionRequiresObservable: true,
|
||||
// observableRequiresReaction: true,
|
||||
});
|
||||
|
||||
// Immer
|
||||
setAutoFreeze(false); // allow to merge mobx observables, docs: https://immerjs.github.io/immer/freezing
|
||||
enableMapSet(); // allow to merge maps and sets, docs: https://immerjs.github.io/immer/map-set
|
||||
// Docs: https://immerjs.github.io/immer/
|
||||
Immer.setAutoFreeze(false); // allow to merge mobx observables
|
||||
Immer.enableMapSet(); // allow to merge maps and sets
|
||||
|
||||
@ -2,16 +2,15 @@ import type { ThemeId } from "../renderer/theme.store";
|
||||
import { app, remote } from "electron";
|
||||
import semver from "semver";
|
||||
import { readFile } from "fs-extra";
|
||||
import { action, computed, observable, reaction, toJS, makeObservable } from "mobx";
|
||||
import { action, computed, makeObservable, observable, reaction } from "mobx";
|
||||
import moment from "moment-timezone";
|
||||
import { BaseStore } from "./base-store";
|
||||
import migrations from "../migrations/user-store";
|
||||
import { getAppVersion } from "./utils/app-version";
|
||||
import migrations, { fileNameMigration } from "../migrations/user-store";
|
||||
import { cloneJson, getAppVersion } from "./utils";
|
||||
import { kubeConfigDefaultPath, loadConfig } from "./kube-helpers";
|
||||
import { appEventBus } from "./event-bus";
|
||||
import logger from "../main/logger";
|
||||
import path from "path";
|
||||
import { fileNameMigration } from "../migrations/user-store";
|
||||
|
||||
export interface UserStoreModel {
|
||||
kubeConfigPath: string;
|
||||
@ -181,7 +180,7 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
}
|
||||
|
||||
toJSON(): UserStoreModel {
|
||||
return toJS({
|
||||
return cloneJson({
|
||||
kubeConfigPath: this.kubeConfigPath,
|
||||
lastSeenAppVersion: this.lastSeenAppVersion,
|
||||
seenContexts: Array.from(this.seenContexts),
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Clone json-serializable object
|
||||
|
||||
export function cloneJsonObject<T = object>(obj: T): T {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
export function cloneJson<T>(data: T): T {
|
||||
return JSON.parse(JSON.stringify(data));
|
||||
}
|
||||
|
||||
@ -2,30 +2,29 @@ import { watch } from "chokidar";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { EventEmitter } from "events";
|
||||
import fs from "fs-extra";
|
||||
import { observable, reaction, toJS, when, makeObservable } from "mobx";
|
||||
import { makeObservable, observable, reaction, when } from "mobx";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import { broadcastMessage, handleRequest, requestMain, subscribeToBroadcast } from "../common/ipc";
|
||||
import { Singleton } from "../common/utils";
|
||||
import { cloneJson, Singleton } from "../common/utils";
|
||||
import logger from "../main/logger";
|
||||
import { extensionInstaller, PackageJson } from "./extension-installer";
|
||||
import { ExtensionsStore } from "./extensions-store";
|
||||
import type { LensExtensionId, LensExtensionManifest } from "./lens-extension";
|
||||
|
||||
export interface InstalledExtension {
|
||||
id: LensExtensionId;
|
||||
id: LensExtensionId;
|
||||
readonly manifest: LensExtensionManifest;
|
||||
|
||||
readonly manifest: LensExtensionManifest;
|
||||
// Absolute path to the non-symlinked source folder,
|
||||
// e.g. "/Users/user/.k8slens/extensions/helloworld"
|
||||
readonly absolutePath: string;
|
||||
|
||||
// Absolute path to the non-symlinked source folder,
|
||||
// e.g. "/Users/user/.k8slens/extensions/helloworld"
|
||||
readonly absolutePath: string;
|
||||
|
||||
// Absolute to the symlinked package.json file
|
||||
readonly manifestPath: string;
|
||||
readonly isBundled: boolean; // defined in project root's package.json
|
||||
isEnabled: boolean;
|
||||
}
|
||||
// Absolute to the symlinked package.json file
|
||||
readonly manifestPath: string;
|
||||
readonly isBundled: boolean; // defined in project root's package.json
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
const logModule = "[EXTENSION-DISCOVERY]";
|
||||
|
||||
@ -151,7 +150,7 @@ export class ExtensionDiscovery extends Singleton {
|
||||
.on("unlinkDir", this.handleWatchUnlinkDir);
|
||||
}
|
||||
|
||||
handleWatchFileAdd = async (manifestPath: string) => {
|
||||
handleWatchFileAdd = async (manifestPath: string) => {
|
||||
// e.g. "foo/package.json"
|
||||
const relativePath = path.relative(this.localFolderPath, manifestPath);
|
||||
|
||||
@ -262,7 +261,6 @@ export class ExtensionDiscovery extends Singleton {
|
||||
// fs.remove won't throw if path is missing
|
||||
await fs.remove(path.join(extensionInstaller.extensionPackagesRoot, "package-lock.json"));
|
||||
|
||||
|
||||
try {
|
||||
// Verify write access to static/extensions, which is needed for symlinking
|
||||
await fs.access(this.inTreeFolderPath, fs.constants.W_OK);
|
||||
@ -447,7 +445,7 @@ export class ExtensionDiscovery extends Singleton {
|
||||
}
|
||||
|
||||
toJSON(): ExtensionDiscoveryChannelMessage {
|
||||
return toJS({
|
||||
return cloneJson({
|
||||
isLoaded: this.isLoaded
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import type { LensExtensionId } from "./lens-extension";
|
||||
import { BaseStore } from "../common/base-store";
|
||||
import { action, computed, observable, toJS, makeObservable } from "mobx";
|
||||
import { action, computed, makeObservable, observable } from "mobx";
|
||||
import { cloneJson } from "../common/utils";
|
||||
|
||||
export interface LensExtensionsStoreModel {
|
||||
extensions: Record<LensExtensionId, LensExtensionState>;
|
||||
@ -22,8 +23,8 @@ export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
||||
@computed
|
||||
get enabledExtensions() {
|
||||
return Array.from(this.state.values())
|
||||
.filter(({enabled}) => enabled)
|
||||
.map(({name}) => name);
|
||||
.filter(({ enabled }) => enabled)
|
||||
.map(({ name }) => name);
|
||||
}
|
||||
|
||||
protected state = observable.map<LensExtensionId, LensExtensionState>();
|
||||
@ -47,7 +48,7 @@ export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
||||
}
|
||||
|
||||
toJSON(): LensExtensionsStoreModel {
|
||||
return toJS({
|
||||
return cloneJson({
|
||||
extensions: Object.fromEntries(this.state),
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import "../common/cluster-ipc";
|
||||
import type http from "http";
|
||||
import { ipcMain } from "electron";
|
||||
import { action, autorun, observable, reaction, toJS, makeObservable } from "mobx";
|
||||
import { action, autorun, makeObservable, observable, reaction, toJS } from "mobx";
|
||||
import { ClusterStore, getClusterIdFromHost } from "../common/cluster-store";
|
||||
import { Cluster } from "./cluster";
|
||||
import logger from "./logger";
|
||||
import { apiKubePrefix } from "../common/vars";
|
||||
import { Singleton } from "../common/utils";
|
||||
import { CatalogEntity } from "../common/catalog-entity";
|
||||
import { cloneJson, Singleton } from "../common/utils";
|
||||
import { CatalogEntity, CatalogEntityData } from "../common/catalog-entity";
|
||||
import { KubernetesCluster } from "../common/catalog-entities/kubernetes-cluster";
|
||||
import { catalogEntityRegistry } from "../common/catalog-entity-registry";
|
||||
|
||||
@ -41,7 +41,6 @@ export class ClusterManager extends Singleton {
|
||||
this.syncClustersFromCatalog(entities);
|
||||
});
|
||||
|
||||
|
||||
// auto-stop removed clusters
|
||||
autorun(() => {
|
||||
const removedClusters = Array.from(ClusterStore.getInstance().removedClusters.values());
|
||||
@ -57,11 +56,16 @@ export class ClusterManager extends Singleton {
|
||||
delay: 250
|
||||
});
|
||||
|
||||
ipcMain.on("network:offline", () => { this.onNetworkOffline(); });
|
||||
ipcMain.on("network:online", () => { this.onNetworkOnline(); });
|
||||
ipcMain.on("network:offline", () => {
|
||||
this.onNetworkOffline();
|
||||
});
|
||||
ipcMain.on("network:online", () => {
|
||||
this.onNetworkOnline();
|
||||
});
|
||||
}
|
||||
|
||||
@action protected updateCatalogSource(clusters: Cluster[]) {
|
||||
@action
|
||||
protected updateCatalogSource(clusters: Cluster[]) {
|
||||
this.catalogSource.forEach((entity, index) => {
|
||||
const clusterIndex = clusters.findIndex((cluster) => entity.metadata.uid === cluster.id);
|
||||
|
||||
@ -121,7 +125,7 @@ export class ClusterManager extends Singleton {
|
||||
}
|
||||
|
||||
protected catalogEntityFromCluster(cluster: Cluster) {
|
||||
return new KubernetesCluster(toJS({
|
||||
const data: CatalogEntityData = cloneJson({
|
||||
apiVersion: "entity.k8slens.dev/v1alpha1",
|
||||
kind: "KubernetesCluster",
|
||||
metadata: {
|
||||
@ -142,7 +146,9 @@ export class ClusterManager extends Singleton {
|
||||
message: "",
|
||||
active: !cluster.disconnected
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
return new KubernetesCluster(data);
|
||||
}
|
||||
|
||||
protected onNetworkOffline() {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ipcMain } from "electron";
|
||||
import type { ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences } from "../common/cluster-store";
|
||||
import type { IMetricsReqParams } from "../renderer/api/endpoints/metrics.api";
|
||||
import { action, comparer, computed, makeObservable, observable, reaction, toJS, when } from "mobx";
|
||||
import { action, comparer, computed, makeObservable, observable, reaction, when } from "mobx";
|
||||
import { apiKubePrefix } from "../common/vars";
|
||||
import { broadcastMessage, ClusterListNamespaceForbiddenChannel, InvalidKubeconfigChannel } from "../common/ipc";
|
||||
import { ContextHandler } from "./context-handler";
|
||||
@ -15,6 +15,7 @@ import logger from "./logger";
|
||||
import { VersionDetector } from "./cluster-detectors/version-detector";
|
||||
import { detectorRegistry } from "./cluster-detectors/detector-registry";
|
||||
import plimit from "p-limit";
|
||||
import { cloneJson } from "../common/utils";
|
||||
|
||||
export enum ClusterStatus {
|
||||
AccessGranted = 2,
|
||||
@ -240,7 +241,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
@computed get prometheusPreferences(): ClusterPrometheusPreferences {
|
||||
const { prometheus, prometheusProvider } = this.preferences;
|
||||
|
||||
return toJS({ prometheus, prometheusProvider });
|
||||
return cloneJson({ prometheus, prometheusProvider });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -604,7 +605,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
}
|
||||
|
||||
toJSON(): ClusterModel {
|
||||
const model: ClusterModel = {
|
||||
return cloneJson({
|
||||
id: this.id,
|
||||
contextName: this.contextName,
|
||||
kubeConfigPath: this.kubeConfigPath,
|
||||
@ -613,16 +614,14 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
metadata: this.metadata,
|
||||
ownerRef: this.ownerRef,
|
||||
accessibleNamespaces: this.accessibleNamespaces,
|
||||
};
|
||||
|
||||
return toJS(model);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializable cluster-state used for sync btw main <-> renderer
|
||||
*/
|
||||
getState(): ClusterState {
|
||||
const state: ClusterState = {
|
||||
return cloneJson({
|
||||
initialized: this.initialized,
|
||||
enabled: this.enabled,
|
||||
apiUrl: this.apiUrl,
|
||||
@ -635,9 +634,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
allowedNamespaces: this.allowedNamespaces,
|
||||
allowedResources: this.allowedResources,
|
||||
isGlobalWatchEnabled: this.isGlobalWatchEnabled,
|
||||
};
|
||||
|
||||
return toJS(state);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -680,7 +677,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
const api = (await this.getProxyKubeconfig()).makeApiClient(CoreV1Api);
|
||||
|
||||
try {
|
||||
const { body: { items }} = await api.listNamespace();
|
||||
const { body: { items } } = await api.listNamespace();
|
||||
const namespaces = items.map(ns => ns.metadata.name);
|
||||
|
||||
this.getAllowedNamespacesErrorCount = 0; // reset on success
|
||||
|
||||
@ -2,17 +2,18 @@ import { randomBytes } from "crypto";
|
||||
import { SHA256 } from "crypto-js";
|
||||
import { app, remote } from "electron";
|
||||
import fse from "fs-extra";
|
||||
import { action, observable, toJS, makeObservable } from "mobx";
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
import path from "path";
|
||||
import { BaseStore } from "../common/base-store";
|
||||
import { LensExtensionId } from "../extensions/lens-extension";
|
||||
import { cloneJson } from "../common/utils";
|
||||
|
||||
interface FSProvisionModel {
|
||||
extensions: Record<string, string>; // extension names to paths
|
||||
}
|
||||
|
||||
export class FilesystemProvisionerStore extends BaseStore<FSProvisionModel> {
|
||||
@observable registeredExtensions = observable.map<LensExtensionId, string>();
|
||||
registeredExtensions = observable.map<LensExtensionId, string>();
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
@ -50,8 +51,8 @@ export class FilesystemProvisionerStore extends BaseStore<FSProvisionModel> {
|
||||
}
|
||||
|
||||
toJSON(): FSProvisionModel {
|
||||
return toJS({
|
||||
extensions: Object.fromEntries(this.registeredExtensions.toJSON()),
|
||||
return cloneJson({
|
||||
extensions: Object.fromEntries(this.registeredExtensions),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import path from "path";
|
||||
import * as tempy from "tempy";
|
||||
import logger from "./logger";
|
||||
import { appEventBus } from "../common/event-bus";
|
||||
import { cloneJsonObject } from "../common/utils";
|
||||
import { cloneJson } from "../common/utils";
|
||||
|
||||
export class ResourceApplier {
|
||||
constructor(protected cluster: Cluster) {
|
||||
@ -83,7 +83,7 @@ export class ResourceApplier {
|
||||
}
|
||||
|
||||
protected sanitizeObject(resource: KubernetesObject | any) {
|
||||
resource = cloneJsonObject(resource);
|
||||
resource = cloneJson(resource);
|
||||
delete resource.status;
|
||||
delete resource.metadata?.resourceVersion;
|
||||
const annotations = resource.metadata?.annotations;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
import { Select } from "../select";
|
||||
import { computed, observable, toJS, makeObservable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { commandRegistry } from "../../../extensions/registries/command-registry";
|
||||
@ -52,13 +52,11 @@ export class CommandDialog extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const action = toJS(command.action);
|
||||
|
||||
try {
|
||||
CommandOverlay.close();
|
||||
|
||||
if (command.scope === "global") {
|
||||
action({
|
||||
command.action({
|
||||
entity: commandRegistry.activeEntity
|
||||
});
|
||||
} else if(commandRegistry.activeEntity) {
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import debounce from "lodash/debounce";
|
||||
import { reaction, toJS } from "mobx";
|
||||
import { reaction } from "mobx";
|
||||
import { Terminal as XTerm } from "xterm";
|
||||
import { FitAddon } from "xterm-addon-fit";
|
||||
import { dockStore, TabId } from "./dock.store";
|
||||
import { TerminalApi } from "../../api/terminal-api";
|
||||
import { ThemeStore } from "../../theme.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autobind, cloneJson } from "../../utils";
|
||||
import { isMac } from "../../../common/vars";
|
||||
import { camelCase } from "lodash";
|
||||
import { camelCase, debounce } from "lodash";
|
||||
|
||||
export class Terminal {
|
||||
static spawningPool: HTMLElement;
|
||||
@ -104,7 +103,7 @@ export class Terminal {
|
||||
window.addEventListener("resize", this.onResize);
|
||||
|
||||
this.disposers.push(
|
||||
reaction(() => toJS(ThemeStore.getInstance().activeTheme.colors), this.setTheme, {
|
||||
reaction(() => cloneJson(ThemeStore.getInstance().activeTheme.colors), this.setTheme, {
|
||||
fireImmediately: true
|
||||
}),
|
||||
dockStore.onResize(this.onResize),
|
||||
@ -132,7 +131,7 @@ export class Terminal {
|
||||
const { cols, rows } = this.xterm;
|
||||
|
||||
this.api.sendTerminalSize(cols, rows);
|
||||
} catch(error) {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
return; // see https://github.com/lensapp/lens/issues/1891
|
||||
@ -183,12 +182,12 @@ export class Terminal {
|
||||
// Handle custom hotkey bindings
|
||||
if (ctrlKey) {
|
||||
switch (code) {
|
||||
// Ctrl+C: prevent terminal exit on windows / linux (?)
|
||||
// Ctrl+C: prevent terminal exit on windows / linux (?)
|
||||
case "KeyC":
|
||||
if (this.xterm.hasSelection()) return false;
|
||||
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":
|
||||
evt.preventDefault();
|
||||
break;
|
||||
|
||||
@ -175,7 +175,7 @@ describe("renderer/utils/StorageHelper", () => {
|
||||
it("storage.get() is observable", () => {
|
||||
expect(storageHelper.get()).toEqual(defaultValue);
|
||||
|
||||
reaction(() => toJS(storageHelper), change => {
|
||||
reaction(() => toJS(storageHelper.toJS()), change => {
|
||||
observedChanges.push(change);
|
||||
});
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.)
|
||||
|
||||
import { action, comparer, CreateObservableOptions, IObservableValue, makeObservable, observable, reaction, toJS, when } from "mobx";
|
||||
import { action, comparer, CreateObservableOptions, IObservableValue, IReactionDisposer, makeObservable, observable, reaction, toJS, when } from "mobx";
|
||||
import produce, { Draft } from "immer";
|
||||
import { isEqual, isFunction, isPlainObject, merge } from "lodash";
|
||||
import logger from "../../main/logger";
|
||||
@ -30,19 +30,24 @@ export class StorageHelper<T> {
|
||||
};
|
||||
|
||||
private data: IObservableValue<T>;
|
||||
@observable initialized = false;
|
||||
whenReady = when(() => this.initialized);
|
||||
|
||||
protected unwatchChanges: IReactionDisposer;
|
||||
public readonly storage: StorageAdapter<T>;
|
||||
public readonly defaultValue: T;
|
||||
|
||||
@observable initialized = false;
|
||||
whenReady = when(() => this.initialized);
|
||||
|
||||
constructor(readonly key: string, private options: StorageHelperOptions<T>) {
|
||||
makeObservable(this);
|
||||
|
||||
this.options = merge({}, StorageHelper.defaultOptions, options);
|
||||
this.storage = options.storage;
|
||||
this.defaultValue = options.defaultValue;
|
||||
this.observeData();
|
||||
this.data = observable.box(this.defaultValue, this.options.observable);
|
||||
|
||||
this.unwatchChanges = reaction(() => toJS(this.data.get()), (newValue, oldValue) => {
|
||||
this.onChange(newValue, oldValue);
|
||||
}, this.options.observable);
|
||||
|
||||
if (this.options.autoInit) {
|
||||
this.init();
|
||||
@ -93,19 +98,6 @@ export class StorageHelper<T> {
|
||||
return isEqual(value, this.defaultValue);
|
||||
}
|
||||
|
||||
private observeData(value = this.options.defaultValue) {
|
||||
const observableOptions: CreateObservableOptions = {
|
||||
...StorageHelper.defaultOptions.observable, // inherit default observability options
|
||||
...this.options.observable,
|
||||
};
|
||||
|
||||
this.data = observable.box<T>(value, observableOptions);
|
||||
|
||||
return reaction(() => toJS(this.data.get()), (newValue, oldValue) => {
|
||||
this.onChange(newValue, oldValue);
|
||||
}, observableOptions);
|
||||
}
|
||||
|
||||
protected onChange(value: T, oldValue?: T) {
|
||||
if (!this.initialized) return;
|
||||
|
||||
@ -151,6 +143,10 @@ export class StorageHelper<T> {
|
||||
this.set(nextValue as T);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.unwatchChanges();
|
||||
}
|
||||
|
||||
toJS() {
|
||||
return toJS(this.get());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user