epic: getting rid of vue -- part 2

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman committed 2020-07-08 12:12:11 +03:00
1 parent 63de5fce3c
commit 1f26f0b3a7
22 files changed
+469 -297

No files matched your search

+7 -6
View File
@@ -21,7 +21,7 @@ export class BaseStore<T = any> extends Singleton {
public whenLoaded = when(() => this.isLoaded);
@observable isLoaded = false;
@observable protected data = {} as T;
@observable protected data: T;
protected constructor(protected params: BaseStoreParams) {
super();
@@ -69,9 +69,9 @@ export class BaseStore<T = any> extends Singleton {
},
...confOptions,
});
const data = this.storeConfig.store;
console.info(`[STORE]: [LOADED] ${this.storeConfig.path}`, data);
this.fromStore(data);
const jsonModel = this.storeConfig.store;
console.info(`[STORE]: [LOADED] ${this.storeConfig.path}`, jsonModel);
this.fromStore(jsonModel);
this.isLoaded = true;
}
@@ -111,8 +111,8 @@ export class BaseStore<T = any> extends Singleton {
}
@action
protected fromStore(data: Partial<T> = {}) {
Object.assign(this.data, data);
protected fromStore(data: T) {
this.data = data;
}
@action
@@ -120,6 +120,7 @@ export class BaseStore<T = any> extends Singleton {
this.data = produce(this.data, updater);
}
// todo: use "serializr" ?
toJSON(): T {
return toJS(this.data, {
recurseEverything: true,
+5 -6
View File
@@ -81,12 +81,11 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
@action
protected fromStore({ clusters = [] }: Partial<ClusterStoreModel> = {}) {
// fixme: handle clusters update + delete
clusters.forEach(model => {
if (!this.clusters.has(model.id)) {
this.clusters.set(model.id, new Cluster(model));
}
})
const clustersMap = new Map<ClusterId, Cluster>();
clusters.forEach(clusterModel => {
clustersMap.set(clusterModel.id, new Cluster(clusterModel));
});
this.clusters.replace(clustersMap);
}
toJSON(): ClusterStoreModel {
+7 -3
View File
@@ -9,12 +9,16 @@ export interface IpcOptions {
timeout?: number;
}
export interface IpcMessageHandler {
(...args: any[]): any;
}
export async function invokeMessage(channel: string, ...args: any[]) {
logger.debug(`[IPC]: invoke channel "${channel}"`, { args });
return ipcRenderer.invoke(channel, ...args);
}
export function onMessage(channel: string, handler: (...args: any[]) => any, options: IpcOptions = {}) {
export function onMessage(channel: string, handler: IpcMessageHandler, options: IpcOptions = {}) {
const { timeout = 0 } = options;
ipcMain.handle(channel, async (event, ...args: any[]) => {
logger.debug(`[IPC]: handle "${channel}"`, { event, args });
@@ -37,8 +41,8 @@ export function onMessage(channel: string, handler: (...args: any[]) => any, opt
})
}
export function onMessages(messages: Record<string, Function>, options?: IpcOptions) {
export function onMessages(messages: Record<string, IpcMessageHandler>, options?: IpcOptions) {
Object.entries(messages).forEach(([channel, handler]) => {
this.onMessage(channel, handler, options);
onMessage(channel, handler, options);
})
}
+17
View File
@@ -0,0 +1,17 @@
// Register custom protocols
import path from "path";
import { protocol } from "electron"
import logger from "../main/logger";
export function registerFileProtocol(name: string, basePath: string) {
protocol.registerFileProtocol(name, (request, callback) => {
const filePath = request.url.replace(name + "://", "");
const absPath = path.resolve(basePath, filePath);
callback(absPath);
}, (error) => {
if (error) {
logger.error(`Failed to register protocol "${name}"`, { basePath, error });
}
})
}
-25
View File
@@ -1,25 +0,0 @@
// Setup static folder for common assets
import path from "path";
import { protocol } from "electron"
import logger from "../main/logger";
import { staticDir, staticProto, outDir } from "./vars";
export function registerStaticProtocol(rootFolder = staticDir) {
const scheme = staticProto.replace("://", "");
protocol.registerFileProtocol(scheme, (request, callback) => {
const relativePath = request.url.replace(staticProto, "");
const absPath = path.resolve(rootFolder, relativePath);
callback(absPath);
}, (error) => {
logger.debug(`Failed to register protocol "${scheme}"`, error);
})
}
export function getStaticUrl(filePath: string) {
return staticProto + filePath;
}
export function getStaticPath(filePath: string) {
return path.resolve(staticDir, filePath);
}
+2 -2
View File
@@ -7,8 +7,8 @@ import * as path from "path"
// Writes kubeconfigs to "embedded" store, i.e. .../Lens/kubeconfigs/
export function writeEmbeddedKubeConfig(clusterId: string, kubeConfig: string): string {
// This can be called from main & renderer
const a = (app || remote.app)
const kubeConfigBase = path.join(a.getPath("userData"), "kubeconfigs")
const userData = (app || remote.app).getPath("userData");
const kubeConfigBase = path.join(userData, "kubeconfigs")
ensureDirSync(kubeConfigBase)
const kubeConfigFile = path.join(kubeConfigBase, clusterId)
+5 -5
View File
@@ -1,9 +1,7 @@
// App's common configuration for any process (main, renderer, build pipeline, etc.)
import packageInfo from "../../package.json"
import path from "path";
export const appName = "lens"
// Flags
export const isMac = process.platform === "darwin"
export const isWindows = process.platform === "win32"
export const isDebugging = process.env.DEBUG === "true";
@@ -12,6 +10,10 @@ export const isDevelopment = isDebugging || !isProduction;
export const buildVersion = process.env.BUILD_VERSION;
export const isTestEnv = !!process.env.JEST_WORKER_ID;
export const appName = `${packageInfo.productName}${isDevelopment ? "Dev" : ""}`
export const appProto = "lens" // app's "userData" folder (e.g. "lens://icons/logo.svg")
export const staticProto = "static" // static content folder (e.g. "static://RELEASE_NOTES.md")
// Paths
export const contextDir = process.cwd();
export const staticDir = path.join(contextDir, "static");
@@ -22,8 +24,6 @@ export const htmlTemplate = path.resolve(rendererDir, "template.html");
export const sassCommonVars = path.resolve(rendererDir, "components/vars.scss");
// Apis
export const staticProto = "static://"
export const apiPrefix = {
BASE: '/api',
KUBE_BASE: '/api-kube', // kubernetes cluster api
+46 -30
View File
@@ -1,11 +1,11 @@
import { action, computed, toJS } from "mobx";
import { action, observable } from "mobx";
import { BaseStore } from "./base-store";
import { clusterStore } from "./cluster-store"
export type WorkspaceId = string;
export interface WorkspaceStoreModel {
currentWorkspace?: WorkspaceId; // last visited/activated
currentWorkspace?: WorkspaceId;
workspaces: Workspace[]
}
@@ -18,17 +18,14 @@ export interface Workspace {
export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
static readonly defaultId: WorkspaceId = "default"
protected data: WorkspaceStoreModel = {
currentWorkspace: WorkspaceStore.defaultId,
workspaces: [{
@observable currentWorkspace = WorkspaceStore.defaultId;
@observable workspaces = observable.map<WorkspaceId, Workspace>({
[WorkspaceStore.defaultId]: {
id: WorkspaceStore.defaultId,
name: "default"
}]
}
@computed get workspaces() {
return toJS(this.data.workspaces);
}
}
});
private constructor() {
super({
@@ -36,40 +33,59 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
});
}
public getById(id: WorkspaceId): Workspace {
return this.workspaces.find(workspace => workspace.id === id);
}
public getIndexById(id: WorkspaceId): number {
return this.workspaces.findIndex(workspace => workspace.id === id);
getById(id: WorkspaceId): Workspace {
return this.workspaces.get(id);
}
@action
setCurrent(id: WorkspaceId) {
this.data.currentWorkspace = id;
if (!this.getById(id)) return;
this.currentWorkspace = id;
}
@action
public saveWorkspace(newWorkspace: Workspace) {
const workspace = this.getById(newWorkspace.id);
if (workspace) {
Object.assign(workspace, newWorkspace);
public saveWorkspace(workspace: Workspace) {
const id = workspace.id;
const existingWorkspace = this.getById(id);
if (existingWorkspace) {
Object.assign(existingWorkspace, workspace);
} else {
this.data.workspaces.push(newWorkspace);
this.workspaces.set(id, workspace);
}
}
@action
public removeWorkspace(workspaceOrId: Workspace | WorkspaceId) {
const workspace = this.getById(typeof workspaceOrId == "string" ? workspaceOrId : workspaceOrId.id);
public removeWorkspace(id: WorkspaceId) {
const workspace = this.getById(id);
if (!workspace) return;
if (workspace.id === WorkspaceStore.defaultId) {
if (id === WorkspaceStore.defaultId) {
throw new Error("Cannot remove default workspace");
}
const index = this.getIndexById(workspace.id);
if (index > -1) {
this.data.workspaces.splice(index, 1)
clusterStore.removeByWorkspaceId(workspace.id)
if (id === this.currentWorkspace) {
this.currentWorkspace = WorkspaceStore.defaultId;
}
this.workspaces.delete(id);
clusterStore.removeByWorkspaceId(id)
}
@action
protected fromStore({ currentWorkspace, workspaces = [] }: WorkspaceStoreModel) {
if (currentWorkspace) {
this.currentWorkspace = currentWorkspace
}
if (workspaces.length) {
this.workspaces.clear();
workspaces.forEach(workspace => {
this.workspaces.set(workspace.id, workspace)
})
}
}
toJSON(): WorkspaceStoreModel {
const { currentWorkspace, workspaces } = this;
return {
currentWorkspace: currentWorkspace,
workspaces: Array.from(workspaces.values()),
}
}
}