From 3da4c106964f0fc29c7a9d3d50c7f3b3e6bc6bee Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:00:46 +0200 Subject: [PATCH 1/7] Default menus template --- src/main/index.ts | 2 ++ src/main/menus.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/main/menus.ts diff --git a/src/main/index.ts b/src/main/index.ts index 9b6b509..9b7c649 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -3,6 +3,8 @@ import { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import icon from '../../resources/icon.png?asset' +import './menus' + function createWindow(): void { // Create the browser window. const mainWindow = new BrowserWindow({ diff --git a/src/main/menus.ts b/src/main/menus.ts new file mode 100644 index 0000000..97b4973 --- /dev/null +++ b/src/main/menus.ts @@ -0,0 +1,13 @@ +import { Menu } from 'electron' + +const template = [ + { role: 'appMenu'}, + { role: 'fileMenu' }, + { role: 'editMenu' }, + { role: 'viewMenu' }, + { role: 'windowMenu' }, + { role: 'help' } +] + +const menu = Menu.buildFromTemplate(template) +Menu.setApplicationMenu(menu) From 9448fc99e195c74872a72339fdb1f1a54cea8a68 Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:02:22 +0200 Subject: [PATCH 2/7] Help menus --- src/main/menus.ts | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main/menus.ts b/src/main/menus.ts index 97b4973..75048ef 100644 --- a/src/main/menus.ts +++ b/src/main/menus.ts @@ -1,4 +1,4 @@ -import { Menu } from 'electron' +import { Menu, shell } from 'electron' const template = [ { role: 'appMenu'}, @@ -6,7 +6,45 @@ const template = [ { role: 'editMenu' }, { role: 'viewMenu' }, { role: 'windowMenu' }, - { role: 'help' } + { + role: 'help', + submenu: [ + { + label: 'Swagger Editor Offline', + submenu: [ + { + label: 'View on GitHub', + click: async () => { + await shell.openExternal('https://github.com/XuluWarrior/swagger-editor-offline') + } + } + ] + }, + { + label: 'Swagger Editor', + submenu: [ + { + label: 'About Swagger Editor', + click: async () => { + await shell.openExternal('https://swagger.io/tools/swagger-editor/') + } + }, + { + label: 'View Docs', + click: async () => { + await shell.openExternal('https://swagger.io/docs/open-source-tools/swagger-editor/') + } + }, + { + label: 'View on GitHub', + click: async () => { + await shell.openExternal('https://github.com/swagger-api/swagger-editor') + } + } + ] + }, + ] + } ] const menu = Menu.buildFromTemplate(template) From cbc3d6388e8d2c0ff024103f2eef0ee1b74046fc Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:10:18 +0200 Subject: [PATCH 3/7] Install is-json and js-yaml --- package-lock.json | 16 ++++++++++++++++ package.json | 3 +++ 2 files changed, 19 insertions(+) diff --git a/package-lock.json b/package-lock.json index c336d6d..9d3afc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@electron-toolkit/preload": "^3.0.1", "@electron-toolkit/utils": "^3.0.0", "electron-updater": "^6.3.4", + "is-json": "^2.0.1", + "js-yaml": "^4.1.0", "swagger-editor-dist": "^4.13.1" }, "bin": { @@ -22,6 +24,7 @@ "@electron-toolkit/eslint-config-prettier": "^2.0.0", "@electron-toolkit/eslint-config-ts": "^2.0.0", "@electron-toolkit/tsconfig": "^1.0.1", + "@types/js-yaml": "^4.0.9", "@types/node": "^22.5.4", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", @@ -2242,6 +2245,13 @@ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "license": "MIT" }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -6515,6 +6525,12 @@ "node": ">=8" } }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "license": "ISC" + }, "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", diff --git a/package.json b/package.json index c2e371b..e55baf4 100644 --- a/package.json +++ b/package.json @@ -39,12 +39,15 @@ "@electron-toolkit/preload": "^3.0.1", "@electron-toolkit/utils": "^3.0.0", "electron-updater": "^6.3.4", + "is-json": "^2.0.1", + "js-yaml": "^4.1.0", "swagger-editor-dist": "^4.13.1" }, "devDependencies": { "@electron-toolkit/eslint-config-prettier": "^2.0.0", "@electron-toolkit/eslint-config-ts": "^2.0.0", "@electron-toolkit/tsconfig": "^1.0.1", + "@types/js-yaml": "^4.0.9", "@types/node": "^22.5.4", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", From e70475958d3643cd9af4c5cf0bfc1bfe35c3701c Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:26:40 +0200 Subject: [PATCH 4/7] Electron menus plugin Listen to messages triggered by electron menus --- src/renderer/src/index.ts | 5 +++++ src/renderer/src/plugins/electron-menus.ts | 26 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/renderer/src/plugins/electron-menus.ts diff --git a/src/renderer/src/index.ts b/src/renderer/src/index.ts index 40af47b..44fba52 100644 --- a/src/renderer/src/index.ts +++ b/src/renderer/src/index.ts @@ -2,6 +2,8 @@ import 'swagger-editor-dist/swagger-editor.css' import SwaggerEditorBundle from "swagger-editor-dist/swagger-editor-bundle.js"; import SwaggerEditorStandalonePreset from "swagger-editor-dist/swagger-editor-standalone-preset.js"; +import electronMenus from './plugins/electron-menus' + window.onload = function() { // Build a system\ const editor = window.SwaggerEditorBundle({ @@ -9,6 +11,9 @@ window.onload = function() { layout: 'StandaloneLayout', presets: [ window.SwaggerEditorStandalonePreset + ], + plugins: [ + electronMenus ] }); diff --git a/src/renderer/src/plugins/electron-menus.ts b/src/renderer/src/plugins/electron-menus.ts new file mode 100644 index 0000000..1f05a9f --- /dev/null +++ b/src/renderer/src/plugins/electron-menus.ts @@ -0,0 +1,26 @@ +type System = { + specActions: { + updateSpec: (spec: string) => void + } +} + +class ElectronMenus { + system!: System; + + constructor() { + window.electron.ipcRenderer.on("update-spec", this.updateSpec); + } + + updateSpec = (_event, spec) => { + this.system.specActions.updateSpec(spec); + } + + setupPlugin = (system) => { + this.system = system; + return {} + } +}; + +const electronMenus = new ElectronMenus() + +export default electronMenus.setupPlugin From b87ec405723e3c508a9bf91a2b8453f0c5691cb0 Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:27:20 +0200 Subject: [PATCH 5/7] Import file menu command Derived from https://github.com/swagger-api/swagger-editor/blob/master/src/standalone/topbar-menu-file-import_file/components/ImportFileMenuItem.jsx --- src/main/commands.ts | 31 +++++++++++++++++++++++++++++++ src/main/menus.ts | 16 +++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/main/commands.ts diff --git a/src/main/commands.ts b/src/main/commands.ts new file mode 100644 index 0000000..8b5112d --- /dev/null +++ b/src/main/commands.ts @@ -0,0 +1,31 @@ +import {BrowserWindow, dialog} from 'electron' +import { promises as fs } from 'fs' + +import { dump, load } from "js-yaml" +import isJsonObject from "is-json" + +function updateSpec(window: BrowserWindow, content: string) { + const preparedContent = isJsonObject(content) ? dump(load(content)) : content + + window.webContents.send('update-spec', preparedContent); +} + +export async function importFile() { + const window = BrowserWindow.getFocusedWindow()! + const selected = await dialog.showOpenDialog({ + filters: [ + { name: 'OpenAPI', extensions: ['json', 'yml', 'yaml'] }, + { name: 'All Files', extensions: ['*'] } + ], + properties: ['openFile'] + }) + + if (!selected.canceled) { + try { + const content = (await fs.readFile(selected.filePaths[0])).toString() + updateSpec(window, content) + } catch(e: any) { + dialog.showErrorBox('Error loading file', `Oof! There was an error loading your document:\n\n${e.message || e}`) + } + } +} diff --git a/src/main/menus.ts b/src/main/menus.ts index 75048ef..941a317 100644 --- a/src/main/menus.ts +++ b/src/main/menus.ts @@ -1,8 +1,22 @@ import { Menu, shell } from 'electron' +import { importFile } from "./commands"; + +const isMac = process.platform === 'darwin' + const template = [ { role: 'appMenu'}, - { role: 'fileMenu' }, + { + label: 'File', + submenu: [ + { + label: 'Import file', + click: importFile + }, + { type: 'separator' }, + isMac ? { role: 'close' } : { role: 'quit' } + ] + }, { role: 'editMenu' }, { role: 'viewMenu' }, { role: 'windowMenu' }, From ada776a1fc1e643a8defee4b33c7c01573bcbf30 Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:35:33 +0200 Subject: [PATCH 6/7] Clear editor file menu item --- src/main/commands.ts | 4 ++++ src/main/menus.ts | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/commands.ts b/src/main/commands.ts index 8b5112d..e441d28 100644 --- a/src/main/commands.ts +++ b/src/main/commands.ts @@ -29,3 +29,7 @@ export async function importFile() { } } } + +export async function clearEditor() { + BrowserWindow.getFocusedWindow()!.webContents.send('update-spec', '') +} diff --git a/src/main/menus.ts b/src/main/menus.ts index 941a317..7b25def 100644 --- a/src/main/menus.ts +++ b/src/main/menus.ts @@ -1,6 +1,6 @@ import { Menu, shell } from 'electron' -import { importFile } from "./commands"; +import { clearEditor, importFile } from "./commands"; const isMac = process.platform === 'darwin' @@ -13,6 +13,10 @@ const template = [ label: 'Import file', click: importFile }, + { + label: 'Clear editor', + click: clearEditor + }, { type: 'separator' }, isMac ? { role: 'close' } : { role: 'quit' } ] From 4b7837a2fb96de050dad1b4ced6a5f88b341201d Mon Sep 17 00:00:00 2001 From: XuluWarrior Date: Mon, 23 Sep 2024 01:52:22 +0200 Subject: [PATCH 7/7] Stop typescript complaing that MenuItemConstructorOptions aren't MenuItemConstructorOptions --- src/main/menus.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/menus.ts b/src/main/menus.ts index 7b25def..492f524 100644 --- a/src/main/menus.ts +++ b/src/main/menus.ts @@ -1,4 +1,4 @@ -import { Menu, shell } from 'electron' +import { Menu, MenuItemConstructorOptions, shell } from 'electron' import { clearEditor, importFile } from "./commands"; @@ -63,7 +63,7 @@ const template = [ }, ] } -] +] as MenuItemConstructorOptions[] const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu)