diff --git a/src/main/index.ts b/src/main/index.ts index 0c5558ec33..a4e38cdb0c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -18,6 +18,7 @@ import { userStore } from "../common/user-store"; import { workspaceStore } from "../common/workspace-store"; import { tracker } from "../common/tracker"; import logger from "./logger" +import { initMenu } from "./menu"; let windowManager: WindowManager; let clusterManager: ClusterManager; @@ -30,6 +31,7 @@ if (app.commandLine.getSwitchValue("proxy-server") !== "") { async function main() { await shellSync(); + initMenu(); const workingDir = path.join(app.getPath("appData"), appName); app.setName(appName); diff --git a/src/main/menu.ts b/src/main/menu.ts index 5a6f86160d..c820f38e76 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -1,47 +1,58 @@ -import type { WindowManager } from "./window-manager"; -import { app, BrowserWindow, dialog, Menu, MenuItem, MenuItemConstructorOptions, shell, webContents } from "electron" -import { autorun } from "mobx"; +import { app, BrowserWindow, dialog, ipcMain, Menu, MenuItem, MenuItemConstructorOptions, shell, webContents } from "electron" +import { autorun, observable } from "mobx"; +import { broadcastIpc } from "../common/ipc"; import { appName, isMac, issuesTrackerUrl, isWindows, slackUrl } from "../common/vars"; -import { clusterStore } from "../common/cluster-store"; +import { ClusterId, clusterStore } from "../common/cluster-store"; import { addClusterURL } from "../renderer/components/+add-cluster/add-cluster.route"; import { preferencesURL } from "../renderer/components/+preferences/preferences.route"; import { whatsNewURL } from "../renderer/components/+whats-new/whats-new.route"; import { clusterSettingsURL } from "../renderer/components/+cluster-settings/cluster-settings.route"; import logger from "./logger"; -export function initMenu(windowManager: WindowManager) { - autorun(() => { - logger.debug(`[MENU]: building menu, cluster=${clusterStore.activeClusterId}`); - buildMenu(windowManager); +const activeClusterView = observable.box(); + +export function initMenu() { + autorun(buildMenu); + ipcMain.on("menu:refresh", (evt, activeClusterId: ClusterId) => { + activeClusterView.set(activeClusterId); }); } -export function buildMenu(windowManager: WindowManager) { +export function buildMenu() { function macOnly(menuItems: MenuItemConstructorOptions[]): MenuItemConstructorOptions[] { if (!isMac) return []; return menuItems; } + function navigate(url: string, toClusterView = false) { + logger.info(`[MENU]: navigating to ${url}`); + const clusterId = activeClusterView.get(); + broadcastIpc({ + channel: "menu:navigate" + (toClusterView ? `:${clusterId}` : ""), + args: [url], + }) + } + const fileMenu: MenuItemConstructorOptions = { label: isMac ? app.getName() : "File", submenu: [ { label: 'Add Cluster', click() { - windowManager.navigateMain(addClusterURL()) + navigate(addClusterURL()) } }, - ...(clusterStore.activeCluster ? [{ + ...(activeClusterView.get() ? [{ label: 'Cluster Settings', click() { - windowManager.navigateMain(clusterSettingsURL()) + navigate(clusterSettingsURL(), true) } }] : []), { type: 'separator' }, { label: 'Preferences', click() { - windowManager.navigateMain(preferencesURL()) + navigate(preferencesURL()) } }, ...macOnly([ @@ -112,7 +123,7 @@ export function buildMenu(windowManager: WindowManager) { { label: "What's new?", click() { - windowManager.navigateMain(whatsNewURL()) + navigate(whatsNewURL()) }, }, { diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index 099007dd99..512a36bc74 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -1,6 +1,5 @@ import { BrowserWindow, shell } from "electron" import windowStateKeeper from "electron-window-state" -import { initMenu } from "./menu"; export class WindowManager { protected mainView: BrowserWindow; @@ -8,8 +7,6 @@ export class WindowManager { protected windowState: windowStateKeeper.State; constructor(protected proxyPort: number) { - initMenu(this); - // Manage main window size and position with state persistence this.windowState = windowStateKeeper({ defaultHeight: 900, @@ -42,11 +39,6 @@ export class WindowManager { this.showMain(); } - // fixme - navigateMain(url: string) { - this.mainView.webContents.executeJavaScript("console.log('implement me!')") - } - async showMain() { await this.showSplash(); await this.mainView.loadURL(`http://localhost:${this.proxyPort}`) diff --git a/src/renderer/components/cluster-manager/cluster-manager.tsx b/src/renderer/components/cluster-manager/cluster-manager.tsx index 5370d9288d..08a053c14e 100644 --- a/src/renderer/components/cluster-manager/cluster-manager.tsx +++ b/src/renderer/components/cluster-manager/cluster-manager.tsx @@ -35,7 +35,7 @@ function initView(clusterId: ClusterId) { return; } logger.info(`[CLUSTER-VIEW]: init dashboard, clusterId=${clusterId}`) - const lensViewsHolder = document.getElementById("lens-views"); // defined in cluster-manager's css-grid + const parentElem = document.getElementById("lens-views"); // defined in cluster-manager's css-grid const webview = document.createElement("webview"); webview.setAttribute("src", `//${clusterId}.${location.host}`) webview.setAttribute("nodeintegration", "true") @@ -50,7 +50,7 @@ function initView(clusterId: ClusterId) { logger.error(`[CLUSTER-VIEW]: failed to load, clusterId=${clusterId}`, event) }); lensViews.set(clusterId, { clusterId, view: webview }); - lensViewsHolder.appendChild(webview); // add to dom and init cluster-page loading + parentElem.appendChild(webview); // add to dom and init cluster-page loading } function refreshViews() { diff --git a/src/renderer/components/cluster-manager/cluster-view.route.ts b/src/renderer/components/cluster-manager/cluster-view.route.ts index 2797453cf3..3078db4f94 100644 --- a/src/renderer/components/cluster-manager/cluster-view.route.ts +++ b/src/renderer/components/cluster-manager/cluster-view.route.ts @@ -1,6 +1,8 @@ +import { reaction } from "mobx"; +import { ipcRenderer } from "electron"; import { matchPath, RouteProps } from "react-router"; import { buildURL, navigation } from "../../navigation"; -import { clusterStore } from "../../../common/cluster-store"; +import { clusterStore, getHostedClusterId } from "../../../common/cluster-store"; export interface IClusterViewRouteParams { clusterId: string; @@ -25,3 +27,15 @@ export function getMatchedClusterId(): string { export function getMatchedCluster() { return clusterStore.getById(getMatchedClusterId()) } + +// Refresh global menu depending on active route's type (common/cluster view) +if (ipcRenderer) { + const isMainView = !getHostedClusterId(); + if (isMainView) { + reaction(() => getMatchedClusterId(), clusterId => { + ipcRenderer.send("menu:refresh", clusterId); + }, { + fireImmediately: true + }) + } +} diff --git a/src/renderer/navigation.ts b/src/renderer/navigation.ts index edfaff9a6d..eb46fe728c 100644 --- a/src/renderer/navigation.ts +++ b/src/renderer/navigation.ts @@ -1,12 +1,23 @@ // Navigation helpers +import { ipcRenderer } from "electron"; import { compile } from "path-to-regexp" import { createBrowserHistory, createMemoryHistory, Location, LocationDescriptor } from "history"; import { createObservableHistory } from "mobx-observable-history"; +import { getHostedClusterId } from "../common/cluster-store"; export const history = typeof window !== "undefined" ? createBrowserHistory() : createMemoryHistory(); export const navigation = createObservableHistory(history); +// handle navigation from global menu +if (ipcRenderer) { + const clusterId = getHostedClusterId(); + const channel = "menu:navigate" + (clusterId ? `:${clusterId}` : ""); + ipcRenderer.on(channel, (event, path: string) => { + navigate(path); + }) +} + export function navigate(location: LocationDescriptor) { navigation.location = location as Location; }