mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
* Save and restore lastActiveClusterId Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Activate clusters from workspaces page Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Fix saving last cluster while jumping from tray Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Adding workspace switch tests Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Remove console.log() Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Cleaning up Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Clean duplicated ClusterId definition Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Moving lastActiveClusterId field into WorkspaceModel Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * fix extensionLoader error on dev environments where renderer might start early (#1447) Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * Add Search by Ip to Pod View (#1445) Signed-off-by: Pavel Ashevskii <pashevskii@mirantis.com> * Make BaseStore abstract (#1431) * make BaseStore abstract so that implementers are forced to decide how to store data Signed-off-by: Sebastian Malton <sebastian@malton.name> * Enforce semicolons in eslint Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com> * Add a few missing folders to be linted. Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com> * Use @typescript-eslint/semi. Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com> * Allow extension cluster menus to have a parent (#1452) Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix SwitchCase indent rule in eslint (#1454) Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert "fix SwitchCase indent rule in eslint (#1454)" This reverts commit082774fe6e. * Revert "Allow extension cluster menus to have a parent (#1452)" This reverts commit622c45cd6d. * Revert "Use @typescript-eslint/semi." This reverts commit890fa5dd9e. * Revert "Add a few missing folders to be linted." This reverts commitc7b24c2922. * Revert "Enforce semicolons in eslint" This reverts commitca67caea60. * Revert "Make BaseStore abstract (#1431)" This reverts commit4b56ab7c61. * Revert "Add Search by Ip to Pod View (#1445)" This reverts commit4079214dc1. * Revert "fix extensionLoader error on dev environments where renderer might start early (#1447)" This reverts commit8a3613ac6f. * Split workspace tests to smaller ones Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Missing semicolons Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Split workspace tests a bit more Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Adding extra click in Add Cluster button Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Adding more awaits to check running cluster Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> * Wait for minikube before running tests Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> Co-authored-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Co-authored-by: pashevskii <53330707+pashevskii@users.noreply.github.com> Co-authored-by: Sebastian Malton <sebastian@malton.name> Co-authored-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
223 lines
5.5 KiB
TypeScript
223 lines
5.5 KiB
TypeScript
import { ipcRenderer } from "electron";
|
|
import { action, computed, observable, toJS, reaction } from "mobx";
|
|
import { BaseStore } from "./base-store";
|
|
import { clusterStore } from "./cluster-store";
|
|
import { appEventBus } from "./event-bus";
|
|
import { broadcastMessage } from "../common/ipc";
|
|
import logger from "../main/logger";
|
|
import type { ClusterId } from "./cluster-store";
|
|
|
|
export type WorkspaceId = string;
|
|
|
|
export interface WorkspaceStoreModel {
|
|
workspaces: WorkspaceModel[];
|
|
currentWorkspace?: WorkspaceId;
|
|
}
|
|
|
|
export interface WorkspaceModel {
|
|
id: WorkspaceId;
|
|
name: string;
|
|
description?: string;
|
|
ownerRef?: string;
|
|
lastActiveClusterId?: ClusterId;
|
|
}
|
|
|
|
export interface WorkspaceState {
|
|
enabled: boolean;
|
|
}
|
|
|
|
export class Workspace implements WorkspaceModel, WorkspaceState {
|
|
@observable id: WorkspaceId;
|
|
@observable name: string;
|
|
@observable description?: string;
|
|
@observable ownerRef?: string;
|
|
@observable enabled: boolean;
|
|
@observable lastActiveClusterId?: ClusterId;
|
|
|
|
constructor(data: WorkspaceModel) {
|
|
Object.assign(this, data);
|
|
|
|
if (!ipcRenderer) {
|
|
reaction(() => this.getState(), () => {
|
|
this.pushState();
|
|
});
|
|
}
|
|
}
|
|
|
|
get isManaged(): boolean {
|
|
return !!this.ownerRef;
|
|
}
|
|
|
|
getState(): WorkspaceState {
|
|
return {
|
|
enabled: this.enabled
|
|
};
|
|
}
|
|
|
|
pushState(state = this.getState()) {
|
|
logger.silly("[WORKSPACE] pushing state", {...state, id: this.id});
|
|
broadcastMessage("workspace:state", this.id, toJS(state));
|
|
}
|
|
|
|
@action
|
|
setState(state: WorkspaceState) {
|
|
Object.assign(this, state);
|
|
}
|
|
|
|
toJSON(): WorkspaceModel {
|
|
return toJS({
|
|
id: this.id,
|
|
name: this.name,
|
|
description: this.description,
|
|
ownerRef: this.ownerRef,
|
|
lastActiveClusterId: this.lastActiveClusterId
|
|
});
|
|
}
|
|
}
|
|
|
|
export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
|
static readonly defaultId: WorkspaceId = "default";
|
|
|
|
private constructor() {
|
|
super({
|
|
configName: "lens-workspace-store",
|
|
});
|
|
|
|
if (!ipcRenderer) {
|
|
setInterval(() => {
|
|
this.pushState();
|
|
}, 5000);
|
|
}
|
|
}
|
|
|
|
registerIpcListener() {
|
|
logger.info("[WORKSPACE-STORE] starting to listen state events");
|
|
ipcRenderer.on("workspace:state", (event, workspaceId: string, state: WorkspaceState) => {
|
|
this.getById(workspaceId)?.setState(state);
|
|
});
|
|
}
|
|
|
|
unregisterIpcListener() {
|
|
super.unregisterIpcListener();
|
|
ipcRenderer.removeAllListeners("workspace:state");
|
|
}
|
|
|
|
@observable currentWorkspaceId = WorkspaceStore.defaultId;
|
|
|
|
@observable workspaces = observable.map<WorkspaceId, Workspace>({
|
|
[WorkspaceStore.defaultId]: new Workspace({
|
|
id: WorkspaceStore.defaultId,
|
|
name: "default"
|
|
})
|
|
});
|
|
|
|
@computed get currentWorkspace(): Workspace {
|
|
return this.getById(this.currentWorkspaceId);
|
|
}
|
|
|
|
@computed get workspacesList() {
|
|
return Array.from(this.workspaces.values());
|
|
}
|
|
|
|
@computed get enabledWorkspacesList() {
|
|
return this.workspacesList.filter((w) => w.enabled);
|
|
}
|
|
|
|
pushState() {
|
|
this.workspaces.forEach((w) => {
|
|
w.pushState();
|
|
});
|
|
}
|
|
|
|
isDefault(id: WorkspaceId) {
|
|
return id === WorkspaceStore.defaultId;
|
|
}
|
|
|
|
getById(id: WorkspaceId): Workspace {
|
|
return this.workspaces.get(id);
|
|
}
|
|
|
|
getByName(name: string): Workspace {
|
|
return this.workspacesList.find(workspace => workspace.name === name);
|
|
}
|
|
|
|
@action
|
|
setActive(id = WorkspaceStore.defaultId) {
|
|
if (id === this.currentWorkspaceId) return;
|
|
if (!this.getById(id)) {
|
|
throw new Error(`workspace ${id} doesn't exist`);
|
|
}
|
|
this.currentWorkspaceId = id;
|
|
}
|
|
|
|
@action
|
|
addWorkspace(workspace: Workspace) {
|
|
const { id, name } = workspace;
|
|
if (!name.trim() || this.getByName(name.trim())) {
|
|
return;
|
|
}
|
|
this.workspaces.set(id, workspace);
|
|
appEventBus.emit({name: "workspace", action: "add"});
|
|
return workspace;
|
|
}
|
|
|
|
@action
|
|
updateWorkspace(workspace: Workspace) {
|
|
this.workspaces.set(workspace.id, workspace);
|
|
appEventBus.emit({name: "workspace", action: "update"});
|
|
}
|
|
|
|
@action
|
|
removeWorkspace(workspace: Workspace) {
|
|
this.removeWorkspaceById(workspace.id);
|
|
}
|
|
|
|
@action
|
|
removeWorkspaceById(id: WorkspaceId) {
|
|
const workspace = this.getById(id);
|
|
if (!workspace) return;
|
|
if (this.isDefault(id)) {
|
|
throw new Error("Cannot remove default workspace");
|
|
}
|
|
if (this.currentWorkspaceId === id) {
|
|
this.currentWorkspaceId = WorkspaceStore.defaultId; // reset to default
|
|
}
|
|
this.workspaces.delete(id);
|
|
appEventBus.emit({name: "workspace", action: "remove"});
|
|
clusterStore.removeByWorkspaceId(id);
|
|
}
|
|
|
|
@action
|
|
setLastActiveClusterId(clusterId?: ClusterId, workspaceId = this.currentWorkspaceId) {
|
|
this.getById(workspaceId).lastActiveClusterId = clusterId;
|
|
}
|
|
|
|
@action
|
|
protected fromStore({ currentWorkspace, workspaces = [] }: WorkspaceStoreModel) {
|
|
if (currentWorkspace) {
|
|
this.currentWorkspaceId = currentWorkspace;
|
|
}
|
|
if (workspaces.length) {
|
|
this.workspaces.clear();
|
|
workspaces.forEach(ws => {
|
|
const workspace = new Workspace(ws);
|
|
if (!workspace.isManaged) {
|
|
workspace.enabled = true;
|
|
}
|
|
this.workspaces.set(workspace.id, workspace);
|
|
});
|
|
}
|
|
}
|
|
|
|
toJSON(): WorkspaceStoreModel {
|
|
return toJS({
|
|
currentWorkspace: this.currentWorkspaceId,
|
|
workspaces: this.workspacesList.map((w) => w.toJSON()),
|
|
}, {
|
|
recurseEverything: true
|
|
});
|
|
}
|
|
}
|
|
|
|
export const workspaceStore = WorkspaceStore.getInstance<WorkspaceStore>();
|