From 88983b7e34d3255b51b59e0a3ccfca9c2d7d58bd Mon Sep 17 00:00:00 2001 From: "Recuenco, David" Date: Sun, 27 Nov 2022 15:16:15 +0100 Subject: [PATCH] ADD themes, load and save preferences --- package-lock.json | 13 +++ package.json | 1 + src/background/ipc.js | 21 ++++- src/background/main.js | 5 ++ src/background/menu.js | 73 +++++++++++++++++ src/background/preload.js | 17 +++- src/background/windows.js | 3 + src/foreground/App.vue | 83 ++++++++++++++++++- src/foreground/components/AppHeader.vue | 2 +- src/foreground/components/ResourceDetail.vue | 2 +- src/foreground/events.js | 3 + src/foreground/main.js | 29 ++++++- src/foreground/pages/ContextResource.vue | 4 +- src/foreground/pages/Home.vue | 69 ++++++++++++---- src/foreground/pages/Preferences.vue | 59 +++++++++++++- src/foreground/styles/defs.scss | 86 +++++++++++++++++++- src/foreground/styles/global.scss | 10 ++- src/foreground/themes.js | 16 ++++ 18 files changed, 470 insertions(+), 26 deletions(-) create mode 100644 src/background/menu.js create mode 100644 src/background/windows.js create mode 100644 src/foreground/events.js create mode 100644 src/foreground/themes.js diff --git a/package-lock.json b/package-lock.json index 983c137..4e45e8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "eslint": "8.28.0", "js-yaml": "4.1.0", "luxon": "3.1.0", + "mitt": "3.0.0", "sass": "1.56.1", "vite": "3.2.4", "vue": "3.2.45", @@ -6447,6 +6448,12 @@ "node": ">= 8" } }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", + "dev": true + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -13699,6 +13706,12 @@ "yallist": "^4.0.0" } }, + "mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", + "dev": true + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", diff --git a/package.json b/package.json index f9e56c4..f90a530 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "eslint": "8.28.0", "js-yaml": "4.1.0", "luxon": "3.1.0", + "mitt": "3.0.0", "sass": "1.56.1", "vite": "3.2.4", "vue": "3.2.45", diff --git a/src/background/ipc.js b/src/background/ipc.js index 0332119..6986e53 100644 --- a/src/background/ipc.js +++ b/src/background/ipc.js @@ -1,7 +1,7 @@ const { homedir } = require('os'); const { resolve } = require('path'); const { readdir } = require('fs/promises'); -const { ipcMain } = require('electron'); +const { ipcMain, shell } = require('electron'); const { KubeConfig, CoreV1Api, BatchV1Api, AppsV1Api, NetworkingV1Api, RbacAuthorizationV1Api } = require('@kubernetes/client-node'); const { getDB, saveDB } = require('./db'); const { loadKubeConfig } = require('./kubernetes'); @@ -174,6 +174,25 @@ function registerIpcHandlers() { stopLogEmitter(context, podName, containerName); }); + + ipcMain.handle('getPreferences', async () => { + const db = await getDB(); + + return db.preferences || {}; + }); + + ipcMain.handle('savePreferences', async (event, data) => { + const db = await getDB(); + + db.preferences = data; + + await saveDB(db); + }); + + const openGitHubRepository = () => shell.openExternal('https://github.com/RecuencoJones/vizkochos'); + + ipcMain.on('openGitHubRepository', openGitHubRepository); + ipcMain.handle('openGitHubRepository', openGitHubRepository); } module.exports = { registerIpcHandlers }; diff --git a/src/background/main.js b/src/background/main.js index 8924f46..18c4334 100644 --- a/src/background/main.js +++ b/src/background/main.js @@ -2,6 +2,8 @@ const { resolve } = require('path'); const { app, BrowserWindow, screen } = require('electron'); const { registerIpcHandlers } = require('./ipc'); const { isDevelopment } = require('./constants'); +const { setMenu } = require('./menu'); +const { windows } = require('./windows'); if (require('electron-squirrel-startup')) { app.quit(); @@ -24,11 +26,14 @@ const createWindow = () => { const productionHtml = resolve(__dirname, '..', '..', 'dist', 'index.html'); window.loadFile(productionHtml); } + + windows.set('appWindow', window); }; async function main() { await app.whenReady(); + setMenu(); registerIpcHandlers(); createWindow(); diff --git a/src/background/menu.js b/src/background/menu.js new file mode 100644 index 0000000..3a67c60 --- /dev/null +++ b/src/background/menu.js @@ -0,0 +1,73 @@ +const { Menu, ipcMain } = require('electron'); +const { windows } = require('./windows'); + +const sendToAppWindow = (...data) => windows.get('appWindow').webContents.send(...data); + +/** @type {Array} */ +const appMenu = [ + { + role: 'fileMenu', + submenu: [ + { + role: 'newContext', + label: 'New Context', + accelerator: 'CommandOrControl+N', + click() { + sendToAppWindow('app-menu-relay', { command: 'file:newContext' }); + } + }, + { type: 'separator' }, + { + role: 'quickstart', + label: 'Go to Quickstart', + accelerator: 'CommandOrControl+Shift+H', + click() { + sendToAppWindow('app-menu-relay', { command: 'file:quickstart' }); + } + }, + { type: 'separator' }, + { + role: 'preferences', + label: 'Preferences', + accelerator: 'CommandOrControl+,', + click() { + sendToAppWindow('app-menu-relay', { command: 'file:preferences' }); + } + } + ] + }, + { role: 'editMenu' }, + { role: 'viewMenu' }, + { role: 'windowMenu' }, + { + role: 'helpMenu', + label: 'Help', + submenu: [ + { + role: 'shortcuts', + label: 'Shortcuts', + accelerator: 'CommandOrControl+/', + click() { + sendToAppWindow('app-menu-relay', { command: 'help:shortcuts' }); + } + }, + { + role: 'openInGitHub', + label: 'Open in GitHub', + click() { + ipcMain.emit('openGitHubRepository'); + } + } + ] + } +]; + +if (process.platform === 'darwin') { + appMenu.unshift({ role: 'appMenu' }); +} + +function setMenu() { + Menu.setApplicationMenu(Menu.buildFromTemplate(appMenu)); +} + +module.exports = { setMenu }; diff --git a/src/background/preload.js b/src/background/preload.js index a9dcba2..39c9fa0 100644 --- a/src/background/preload.js +++ b/src/background/preload.js @@ -1,4 +1,5 @@ const { contextBridge, ipcRenderer } = require('electron'); +const { EventEmitter } = require('events'); const invokify = (name) => (...args) => ipcRenderer.invoke(name, ...args); @@ -18,7 +19,10 @@ contextBridge.exposeInMainWorld('api', { 'addRecentView', 'listRecentViews', 'listResourceType', - 'getContextOverview' + 'getContextOverview', + 'getPreferences', + 'savePreferences', + 'openGitHubRepository' ), async subscribeToContainerLogs(contextName, podName, containerName, fn) { ipcRenderer.on(`logs:${ podName }:${ containerName }`, fn); @@ -27,5 +31,16 @@ contextBridge.exposeInMainWorld('api', { async unsubscribeFromContainerLogs(contextName, podName, containerName) { ipcRenderer.removeAllListeners(`logs:${ podName }:${ containerName }`); await ipcRenderer.invoke('unsubscribeFromContainerLogs', contextName, podName, containerName); + }, + subscribeToAppMenuEvents(...eventListeners) { + const events = new EventEmitter(); + + eventListeners.forEach(({ event, handler }) => { + events.on(event, handler); + }); + + ipcRenderer.on('app-menu-relay', (e, { command, ...data }) => { + events.emit(command, data); + }); } }); diff --git a/src/background/windows.js b/src/background/windows.js new file mode 100644 index 0000000..53b1f69 --- /dev/null +++ b/src/background/windows.js @@ -0,0 +1,3 @@ +const windows = new Map(); + +module.exports = { windows }; diff --git a/src/foreground/App.vue b/src/foreground/App.vue index ab2fa08..97e9f68 100644 --- a/src/foreground/App.vue +++ b/src/foreground/App.vue @@ -1,19 +1,76 @@ @@ -21,10 +78,13 @@ export default { diff --git a/src/foreground/components/AppHeader.vue b/src/foreground/components/AppHeader.vue index 8080408..0c41ef6 100644 --- a/src/foreground/components/AppHeader.vue +++ b/src/foreground/components/AppHeader.vue @@ -17,7 +17,7 @@ height: 2rem; padding: .25rem 1rem; background-color: var(--color-header-background); - box-shadow: 0 0 3px 2px var(--color-header-background); + box-shadow: 0 0 3px 2px var(--color-box-shadow); z-index: 2; &__left, diff --git a/src/foreground/components/ResourceDetail.vue b/src/foreground/components/ResourceDetail.vue index c5f2ccd..0061508 100644 --- a/src/foreground/components/ResourceDetail.vue +++ b/src/foreground/components/ResourceDetail.vue @@ -161,7 +161,7 @@ export default { overflow: auto; padding: 1rem; background-color: var(--color-detail-background); - box-shadow: 0 0 3px 0 var(--color-dark-cookie); + box-shadow: 0 0 3px 0 var(--color-box-shadow); table { padding: .5rem; diff --git a/src/foreground/events.js b/src/foreground/events.js new file mode 100644 index 0000000..e34c2db --- /dev/null +++ b/src/foreground/events.js @@ -0,0 +1,3 @@ +import mitt from 'mitt'; + +export const events = mitt(); diff --git a/src/foreground/main.js b/src/foreground/main.js index be53d9b..098f47a 100644 --- a/src/foreground/main.js +++ b/src/foreground/main.js @@ -45,4 +45,31 @@ const app = createApp(App); app.use(router); -app.mount('#app'); +const appInstance = app.mount('#app'); + +window.api.subscribeToAppMenuEvents( + { + event: 'file:newContext', + handler() { + router.push('/contexts/new'); + } + }, + { + event: 'file:quickstart', + handler() { + router.push('/'); + } + }, + { + event: 'file:preferences', + handler() { + router.push('/preferences'); + } + }, + { + event: 'help:shortcuts', + handler() { + appInstance.toggleShortcuts(); + } + } +); diff --git a/src/foreground/pages/ContextResource.vue b/src/foreground/pages/ContextResource.vue index 124d1c9..d21441f 100644 --- a/src/foreground/pages/ContextResource.vue +++ b/src/foreground/pages/ContextResource.vue @@ -97,7 +97,7 @@ export default { .resource.toolbar-layout { .view { padding: 0; - box-shadow: inset 0 0 3px 0 var(--color-dark-cookie); + box-shadow: inset 0 0 3px 0 var(--color-box-shadow); table { width: 100%; @@ -107,7 +107,7 @@ export default { thead th { position: sticky; top: 0; - background: white; + background: var(--color-resource-table-header); } th { diff --git a/src/foreground/pages/Home.vue b/src/foreground/pages/Home.vue index 65b7d7e..1571195 100644 --- a/src/foreground/pages/Home.vue +++ b/src/foreground/pages/Home.vue @@ -1,21 +1,44 @@