1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/common/workspace-store.ts
Alex Andreev 8c73861962
Open last active cluster after switching workspaces (#1444)
* 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 commit 082774fe6e.

* Revert "Allow extension cluster menus to have a parent (#1452)"

This reverts commit 622c45cd6d.

* Revert "Use @typescript-eslint/semi."

This reverts commit 890fa5dd9e.

* Revert "Add a few missing folders to be linted."

This reverts commit c7b24c2922.

* Revert "Enforce semicolons in eslint"

This reverts commit ca67caea60.

* Revert "Make BaseStore abstract (#1431)"

This reverts commit 4b56ab7c61.

* Revert "Add Search by Ip to Pod View (#1445)"

This reverts commit 4079214dc1.

* Revert "fix extensionLoader error on dev environments where renderer might start early (#1447)"

This reverts commit 8a3613ac6f.

* 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>
2020-11-20 14:53:28 +03:00

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>();