diff --git a/src/common/workspace-store.ts b/src/common/workspace-store.ts index 921a9126a9..b037124721 100644 --- a/src/common/workspace-store.ts +++ b/src/common/workspace-store.ts @@ -26,6 +26,8 @@ export interface WorkspaceState { enabled: boolean; } +const updateFromModel = Symbol("updateFromModel"); + /** * Workspace * @@ -114,7 +116,7 @@ export class Workspace implements WorkspaceModel, WorkspaceState { /** * Push state * - * @interal + * @internal * @param state workspace state */ pushState(state = this.getState()) { @@ -130,6 +132,10 @@ export class Workspace implements WorkspaceModel, WorkspaceState { Object.assign(this, state); } + [updateFromModel] = action((model: WorkspaceModel) => { + Object.assign(this, model); + }); + toJSON(): WorkspaceModel { return toJS({ id: this.id, @@ -303,16 +309,26 @@ export class WorkspaceStore extends BaseStore { this.currentWorkspaceId = currentWorkspace; } - if (workspaces.length) { - this.workspaces.clear(); - workspaces.forEach(ws => { - const workspace = new Workspace(ws); + const currentWorkspaces = this.workspaces.toJS(); + const newWorkspaceIds = new Set([WorkspaceStore.defaultId]); // never delete default - if (!workspace.isManaged) { - workspace.enabled = true; - } - this.workspaces.set(workspace.id, workspace); - }); + for (const workspaceModel of workspaces) { + const oldWorkspace = this.workspaces.get(workspaceModel.id); + + if (oldWorkspace) { + oldWorkspace[updateFromModel](workspaceModel); + } else { + this.workspaces.set(workspaceModel.id, new Workspace(workspaceModel)); + } + + newWorkspaceIds.add(workspaceModel.id); + } + + // remove deleted workspaces + for (const workspaceId of currentWorkspaces.keys()) { + if (!newWorkspaceIds.has(workspaceId)) { + this.workspaces.delete(workspaceId); + } } } diff --git a/src/renderer/components/+landing-page/landing-page.tsx b/src/renderer/components/+landing-page/landing-page.tsx index 15e22b2c9f..830c0eb714 100644 --- a/src/renderer/components/+landing-page/landing-page.tsx +++ b/src/renderer/components/+landing-page/landing-page.tsx @@ -3,7 +3,7 @@ import React from "react"; import { computed, observable } from "mobx"; import { observer } from "mobx-react"; import { clusterStore } from "../../../common/cluster-store"; -import { Workspace, workspaceStore } from "../../../common/workspace-store"; +import { workspaceStore } from "../../../common/workspace-store"; import { WorkspaceOverview } from "./workspace-overview"; import { PageLayout } from "../layout/page-layout"; import { Notifications } from "../notifications"; @@ -13,13 +13,9 @@ import { Icon } from "../icon"; export class LandingPage extends React.Component { @observable showHint = true; - get workspace(): Workspace { - return workspaceStore.currentWorkspace; - } - @computed get clusters() { - return clusterStore.getByWorkspaceId(this.workspace.id); + return clusterStore.getByWorkspaceId(workspaceStore.currentWorkspaceId); } componentDidMount() { @@ -36,11 +32,11 @@ export class LandingPage extends React.Component { render() { const showBackButton = this.clusters.length > 0; - const header = <>

{this.workspace.name}

; + const header = <>

{workspaceStore.currentWorkspace.name}

; return ( - + ); } diff --git a/src/renderer/components/+landing-page/workspace-overview.tsx b/src/renderer/components/+landing-page/workspace-overview.tsx index 96b8f3a791..3fcb3d6ed3 100644 --- a/src/renderer/components/+landing-page/workspace-overview.tsx +++ b/src/renderer/components/+landing-page/workspace-overview.tsx @@ -1,8 +1,7 @@ import "./workspace-overview.scss"; import React, { Component } from "react"; -import { Workspace } from "../../../common/workspace-store"; -import { observer } from "mobx-react"; +import { disposeOnUnmount, observer } from "mobx-react"; import { ItemListLayout } from "../item-object-list/item-list-layout"; import { ClusterItem, WorkspaceClusterStore } from "./workspace-cluster.store"; import { navigate } from "../../navigation"; @@ -10,9 +9,8 @@ import { clusterViewURL } from "../cluster-manager/cluster-view.route"; import { WorkspaceClusterMenu } from "./workspace-cluster-menu"; import { kebabCase } from "lodash"; import { addClusterURL } from "../+add-cluster"; -interface Props { - workspace: Workspace; -} +import { observable, reaction } from "mobx"; +import { workspaceStore } from "../../../common/workspace-store"; enum sortBy { name = "name", @@ -22,20 +20,30 @@ enum sortBy { } @observer -export class WorkspaceOverview extends Component { - private workspaceClusterStore = new WorkspaceClusterStore(this.props.workspace.id); +export class WorkspaceOverview extends Component { + @observable private workspaceClusterStore?: WorkspaceClusterStore; componentDidMount() { - this.workspaceClusterStore.loadAll(); + disposeOnUnmount(this, [ + reaction(() => workspaceStore.currentWorkspaceId, workspaceId => { + this.workspaceClusterStore = new WorkspaceClusterStore(workspaceId); + this.workspaceClusterStore.loadAll().catch(error => console.log("workspaceClusterStore.loadAll", error)); + }, { + fireImmediately: true, + }) + ]); } - showCluster = ({ clusterId }: ClusterItem) => { navigate(clusterViewURL({ params: { clusterId } })); }; render() { - const { workspace } = this.props; + const { workspaceClusterStore } = this; + + if (!workspaceClusterStore) { + return null; + } return ( { isSearchable={false} isSelectable={false} className="WorkspaceOverview" - store={this.workspaceClusterStore} + store={workspaceClusterStore} sortingCallbacks={{ [sortBy.name]: (item: ClusterItem) => item.name, [sortBy.distribution]: (item: ClusterItem) => item.distribution, @@ -69,7 +77,7 @@ export class WorkspaceOverview extends Component { onAdd: () => navigate(addClusterURL()), }} renderItemMenu={(clusterItem: ClusterItem) => ( - + )} /> );