From cc661527bbe9dfe81457163c383f4e1adb056a6c Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Sun, 22 Sep 2024 09:30:11 +0200 Subject: [PATCH 01/16] Add top menu to app --- desktop/index.ts | 3 +- desktop/menu.ts | 105 ++++++++++++++++++++++++++++++++++++++++++++++ desktop/window.ts | 1 - 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 desktop/menu.ts diff --git a/desktop/index.ts b/desktop/index.ts index aabeaf708..7972935c5 100644 --- a/desktop/index.ts +++ b/desktop/index.ts @@ -1,10 +1,11 @@ -import { app, dialog, BrowserWindow } from 'electron' +import { app, dialog, BrowserWindow, Menu } from 'electron' import { electronApp, optimizer } from '@electron-toolkit/utils' import { createWindow } from './window' import { createBridge } from './bridge' import { join } from 'path' import log from 'electron-log' import * as settings from './settings' +import mainMenu from './menu' // This method will be called when Electron has finished // initialization and is ready to create browser windows. diff --git a/desktop/menu.ts b/desktop/menu.ts new file mode 100644 index 000000000..6639773f4 --- /dev/null +++ b/desktop/menu.ts @@ -0,0 +1,105 @@ +import { app, Menu, MenuItemConstructorOptions } from 'electron' + +const template = [ + { + label: app.name, + submenu: [ + { role: 'about' }, + { role: 'quit' } + ] as MenuItemConstructorOptions[] + }, + { + label: 'File', + submenu: [ + { + label: 'Add', + submenu: [ + { + label: 'New file', + click: async () => { + // TODO + } + }, + { + label: 'New folder', + click: async () => { + // TODO + } + }, + { + label: 'External data', + click: async () => { + // TODO + } + }, + ] + }, + { + label: 'Delete', + click: async () => { + // TODO + } + }, + { + label: 'Publish', + click: async () => { + // TODO + } + }, + ] as MenuItemConstructorOptions[] + }, + { + label: 'Edit', + submenu: [ + { role: 'undo' }, + { role: 'redo' }, + ] as MenuItemConstructorOptions[] + }, + { + label: 'View', + submenu: [ + { role: 'reload' }, + { role: 'forceReload' }, + { type: 'separator' }, + { + label: 'Metadata', + click: async () => { + // TODO + } + }, + { + label: 'Errors panel', + click: async () => { + // TODO + } + }, + { + label: 'Source', + click: async () => { + // TODO + } + }, + ] as MenuItemConstructorOptions[] + }, + { + label: 'Help', + submenu: [ + { + label: 'ODE User guide', + click: async () => { + const { shell } = require('electron') + await shell.openExternal('https://opendataeditor.okfn.org/documentation/getting-started/') + } + }, + { + label: 'Report an issue', + click: async () => { + const { shell } = require('electron') + await shell.openExternal('https://github.com/okfn/opendataeditor/issues') + } + } + ] as MenuItemConstructorOptions[] + }, +] + +export default Menu.buildFromTemplate(template) \ No newline at end of file diff --git a/desktop/window.ts b/desktop/window.ts index 31af5d41e..132be3943 100644 --- a/desktop/window.ts +++ b/desktop/window.ts @@ -15,7 +15,6 @@ export async function createWindow() { var loadingWindow = new BrowserWindow({ resizable: false, - autoHideMenuBar: true, frame: false, ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { From 0116f3fde6cf8af036ecfa3d0c0a0081a03b7c32 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Sun, 22 Sep 2024 18:18:25 +0200 Subject: [PATCH 02/16] Add menu to app :D --- desktop/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/desktop/index.ts b/desktop/index.ts index 7972935c5..60fd18b93 100644 --- a/desktop/index.ts +++ b/desktop/index.ts @@ -56,3 +56,5 @@ process.on('unhandledRejection', async (error: any) => { // Configure logger to write to the app directory log.transports.file.resolvePath = () => join(settings.APP_HOME, 'logger', 'main.log') + +Menu.setApplicationMenu(mainMenu) From 3a15202e75055761d916aec3af8b06d4489604a4 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Sun, 22 Sep 2024 19:36:27 +0200 Subject: [PATCH 03/16] Show menu --- desktop/window.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/window.ts b/desktop/window.ts index 132be3943..f635499da 100644 --- a/desktop/window.ts +++ b/desktop/window.ts @@ -15,6 +15,7 @@ export async function createWindow() { var loadingWindow = new BrowserWindow({ resizable: false, + autoHideMenuBar: true, frame: false, ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { @@ -24,7 +25,6 @@ export async function createWindow() { const mainWindow = new BrowserWindow({ show: false, - autoHideMenuBar: true, ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { preload: join(__dirname, 'preload', 'index.js'), From 7dbb9ea4138c4765d2ddbee0d520ff33b3ad95db Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Tue, 24 Sep 2024 09:52:59 +0200 Subject: [PATCH 04/16] Fix address for 'Report an issue' menu --- desktop/menu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/menu.ts b/desktop/menu.ts index 6639773f4..a37cd5967 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -95,7 +95,7 @@ const template = [ label: 'Report an issue', click: async () => { const { shell } = require('electron') - await shell.openExternal('https://github.com/okfn/opendataeditor/issues') + await shell.openExternal('https://github.com/okfn/opendataeditor/') } } ] as MenuItemConstructorOptions[] From 3e63aa188210ddd2786a0c74a7c9c4b8bf74865a Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Tue, 24 Sep 2024 11:58:10 +0200 Subject: [PATCH 05/16] Remove unneeded 'reload' and 'force reload' from menu --- desktop/menu.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/desktop/menu.ts b/desktop/menu.ts index a37cd5967..cc319ecdc 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -58,9 +58,6 @@ const template = [ { label: 'View', submenu: [ - { role: 'reload' }, - { role: 'forceReload' }, - { type: 'separator' }, { label: 'Metadata', click: async () => { From b6db2f29f4f3a21642007cf11da6390fd9156cd4 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Thu, 26 Sep 2024 19:42:02 +0200 Subject: [PATCH 06/16] Attempt to connect main menu to app with renderer --- client/index.html | 1 + desktop/menu.ts | 5 +++-- desktop/preload/index.ts | 1 + desktop/renderer.ts | 6 ++++++ 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 desktop/renderer.ts diff --git a/client/index.html b/client/index.html index 89eeb5ba2..3e83231b9 100644 --- a/client/index.html +++ b/client/index.html @@ -13,5 +13,6 @@
+ diff --git a/desktop/menu.ts b/desktop/menu.ts index cc319ecdc..aab072cc7 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -1,4 +1,4 @@ -import { app, Menu, MenuItemConstructorOptions } from 'electron' +import { app, Menu, MenuItemConstructorOptions, BrowserWindow } from 'electron' const template = [ { @@ -23,7 +23,8 @@ const template = [ { label: 'New folder', click: async () => { - // TODO + // console.log( BrowserWindow.getAllWindows()[0].webContents ) + BrowserWindow.getAllWindows()[0].webContents.send('create-new-folder') } }, { diff --git a/desktop/preload/index.ts b/desktop/preload/index.ts index dc4bfb42b..aa6d55c47 100644 --- a/desktop/preload/index.ts +++ b/desktop/preload/index.ts @@ -3,6 +3,7 @@ import { contextBridge, ipcRenderer } from 'electron' contextBridge.exposeInMainWorld('opendataeditor', { sendFatalError: (message: string) => ipcRenderer.invoke('sendFatalError', message), openDirectoryDialog: () => ipcRenderer.invoke('openDirectoryDialog'), + onCreateNewFolder: (callback) => ipcRenderer.on('create-new-folder', (_event, value) => callback(value)), ensureLogs: (callback: any) => ipcRenderer.on('ensureLogs', (_event, message: string) => callback(message)), openPathInExplorer: (path: string) => ipcRenderer.send('openPathInExplorer', path), diff --git a/desktop/renderer.ts b/desktop/renderer.ts new file mode 100644 index 000000000..0182bb051 --- /dev/null +++ b/desktop/renderer.ts @@ -0,0 +1,6 @@ +import { openDialog } from '../client/store/actions/dialog' + +// @ts-ignore +window?.opendataeditor?.onCreateNewFolder( () => { + openDialog('addEmptyFolder') +}) \ No newline at end of file From 8c37e64bf33ef9715321b29df618af727906c1b2 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Sat, 28 Sep 2024 13:37:36 +0200 Subject: [PATCH 07/16] Second attempt to communicate main process to renderer --- desktop/menu.ts | 2 +- desktop/preload/index.ts | 2 +- desktop/renderer.ts | 3 ++- desktop/window.ts | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/desktop/menu.ts b/desktop/menu.ts index aab072cc7..3c108a210 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -24,7 +24,7 @@ const template = [ label: 'New folder', click: async () => { // console.log( BrowserWindow.getAllWindows()[0].webContents ) - BrowserWindow.getAllWindows()[0].webContents.send('create-new-folder') + BrowserWindow.getAllWindows()[0].webContents.send('menu-clicked', 'add-new-folder') } }, { diff --git a/desktop/preload/index.ts b/desktop/preload/index.ts index aa6d55c47..29705f3c6 100644 --- a/desktop/preload/index.ts +++ b/desktop/preload/index.ts @@ -3,7 +3,7 @@ import { contextBridge, ipcRenderer } from 'electron' contextBridge.exposeInMainWorld('opendataeditor', { sendFatalError: (message: string) => ipcRenderer.invoke('sendFatalError', message), openDirectoryDialog: () => ipcRenderer.invoke('openDirectoryDialog'), - onCreateNewFolder: (callback) => ipcRenderer.on('create-new-folder', (_event, value) => callback(value)), + createNewFolder: (callback: (value: string) => {}) => ipcRenderer.on('menu-clicked', (_event, value) => callback(value)), ensureLogs: (callback: any) => ipcRenderer.on('ensureLogs', (_event, message: string) => callback(message)), openPathInExplorer: (path: string) => ipcRenderer.send('openPathInExplorer', path), diff --git a/desktop/renderer.ts b/desktop/renderer.ts index 0182bb051..28e0123fb 100644 --- a/desktop/renderer.ts +++ b/desktop/renderer.ts @@ -1,6 +1,7 @@ import { openDialog } from '../client/store/actions/dialog' // @ts-ignore -window?.opendataeditor?.onCreateNewFolder( () => { +window?.opendataeditor?.createNewFolder( ( value: string ) => { + console.log('value', value) openDialog('addEmptyFolder') }) \ No newline at end of file diff --git a/desktop/window.ts b/desktop/window.ts index f635499da..1caa47b32 100644 --- a/desktop/window.ts +++ b/desktop/window.ts @@ -28,6 +28,7 @@ export async function createWindow() { ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { preload: join(__dirname, 'preload', 'index.js'), + contextIsolation: true, }, }) From 16d0d1c78f73bc599f3c739baf57ceab7f82ca14 Mon Sep 17 00:00:00 2001 From: roll Date: Mon, 30 Sep 2024 11:29:46 +0100 Subject: [PATCH 08/16] Removed renderer --- client/index.html | 1 - desktop/renderer.ts | 7 ------- 2 files changed, 8 deletions(-) delete mode 100644 desktop/renderer.ts diff --git a/client/index.html b/client/index.html index 3e83231b9..89eeb5ba2 100644 --- a/client/index.html +++ b/client/index.html @@ -13,6 +13,5 @@
- diff --git a/desktop/renderer.ts b/desktop/renderer.ts deleted file mode 100644 index 28e0123fb..000000000 --- a/desktop/renderer.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { openDialog } from '../client/store/actions/dialog' - -// @ts-ignore -window?.opendataeditor?.createNewFolder( ( value: string ) => { - console.log('value', value) - openDialog('addEmptyFolder') -}) \ No newline at end of file From b63deaa357571944ee948e29710b989f53286a32 Mon Sep 17 00:00:00 2001 From: roll Date: Mon, 30 Sep 2024 11:44:19 +0100 Subject: [PATCH 09/16] Updated menu creation --- desktop/index.ts | 10 +-- desktop/menu.ts | 146 +++++++++++++++++++-------------------- desktop/preload/index.ts | 11 ++- desktop/window.ts | 13 ++-- 4 files changed, 90 insertions(+), 90 deletions(-) diff --git a/desktop/index.ts b/desktop/index.ts index 60fd18b93..637e6f6f8 100644 --- a/desktop/index.ts +++ b/desktop/index.ts @@ -1,11 +1,11 @@ import { app, dialog, BrowserWindow, Menu } from 'electron' -import { electronApp, optimizer } from '@electron-toolkit/utils' +import { electronApp, optimizer } from '@electron-toolkit/utils' import { createWindow } from './window' import { createBridge } from './bridge' import { join } from 'path' import log from 'electron-log' import * as settings from './settings' -import mainMenu from './menu' +import { createMenu } from './menu' // This method will be called when Electron has finished // initialization and is ready to create browser windows. @@ -16,7 +16,9 @@ app.whenReady().then(async () => { log.info('## Start client') createBridge() - await createWindow() + const mainWindow = await createWindow() + const mainMenu = createMenu(mainWindow) + Menu.setApplicationMenu(mainMenu) }) // Default open or close DevTools by F12 in development @@ -56,5 +58,3 @@ process.on('unhandledRejection', async (error: any) => { // Configure logger to write to the app directory log.transports.file.resolvePath = () => join(settings.APP_HOME, 'logger', 'main.log') - -Menu.setApplicationMenu(mainMenu) diff --git a/desktop/menu.ts b/desktop/menu.ts index 3c108a210..374331f77 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -1,103 +1,97 @@ -import { app, Menu, MenuItemConstructorOptions, BrowserWindow } from 'electron' +import { app, shell, Menu, MenuItemConstructorOptions, BrowserWindow } from 'electron' -const template = [ +export function createMenu(mainWindow: BrowserWindow) { + return Menu.buildFromTemplate([ { - label: app.name, - submenu: [ - { role: 'about' }, - { role: 'quit' } - ] as MenuItemConstructorOptions[] + label: app.name, + submenu: [{ role: 'about' }, { role: 'quit' }], }, { - label: 'File', - submenu: [ + label: 'File', + submenu: [ + { + label: 'Add', + submenu: [ { - label: 'Add', - submenu: [ - { - label: 'New file', - click: async () => { - // TODO - } - }, - { - label: 'New folder', - click: async () => { - // console.log( BrowserWindow.getAllWindows()[0].webContents ) - BrowserWindow.getAllWindows()[0].webContents.send('menu-clicked', 'add-new-folder') - } - }, - { - label: 'External data', - click: async () => { - // TODO - } - }, - ] + label: 'New file', + click: async () => { + mainWindow.webContents.send('menuAddNewFile') + }, }, { - label: 'Delete', - click: async () => { - // TODO - } + label: 'New folder', + click: async () => { + // TODO + }, }, { - label: 'Publish', - click: async () => { - // TODO - } + label: 'External data', + click: async () => { + // TODO + }, }, - ] as MenuItemConstructorOptions[] + ], + }, + { + label: 'Delete', + click: async () => { + // TODO + }, + }, + { + label: 'Publish', + click: async () => { + // TODO + }, + }, + ], }, { - label: 'Edit', - submenu: [ - { role: 'undo' }, - { role: 'redo' }, - ] as MenuItemConstructorOptions[] + label: 'Edit', + submenu: [{ role: 'undo' }, { role: 'redo' }], }, { - label: 'View', - submenu: [ + label: 'View', + submenu: [ { - label: 'Metadata', - click: async () => { - // TODO - } + label: 'Metadata', + click: async () => { + // TODO + }, }, { - label: 'Errors panel', - click: async () => { - // TODO - } + label: 'Errors panel', + click: async () => { + // TODO + }, }, { - label: 'Source', - click: async () => { - // TODO - } + label: 'Source', + click: async () => { + // TODO + }, }, - ] as MenuItemConstructorOptions[] + ] as MenuItemConstructorOptions[], }, { - label: 'Help', - submenu: [ + label: 'Help', + submenu: [ { - label: 'ODE User guide', - click: async () => { - const { shell } = require('electron') - await shell.openExternal('https://opendataeditor.okfn.org/documentation/getting-started/') - } + label: 'ODE User guide', + click: async () => { + await shell.openExternal( + 'https://opendataeditor.okfn.org/documentation/getting-started/' + ) + }, }, { - label: 'Report an issue', - click: async () => { - const { shell } = require('electron') - await shell.openExternal('https://github.com/okfn/opendataeditor/') - } - } - ] as MenuItemConstructorOptions[] + label: 'Report an issue', + click: async () => { + await shell.openExternal('https://github.com/okfn/opendataeditor/') + }, + }, + ], }, -] + ]) +} -export default Menu.buildFromTemplate(template) \ No newline at end of file diff --git a/desktop/preload/index.ts b/desktop/preload/index.ts index 29705f3c6..486028308 100644 --- a/desktop/preload/index.ts +++ b/desktop/preload/index.ts @@ -3,10 +3,15 @@ import { contextBridge, ipcRenderer } from 'electron' contextBridge.exposeInMainWorld('opendataeditor', { sendFatalError: (message: string) => ipcRenderer.invoke('sendFatalError', message), openDirectoryDialog: () => ipcRenderer.invoke('openDirectoryDialog'), - createNewFolder: (callback: (value: string) => {}) => ipcRenderer.on('menu-clicked', (_event, value) => callback(value)), - - ensureLogs: (callback: any) => ipcRenderer.on('ensureLogs', (_event, message: string) => callback(message)), + ensureLogs: (callback: any) => + ipcRenderer.on('ensureLogs', (_event, message: string) => callback(message)), openPathInExplorer: (path: string) => ipcRenderer.send('openPathInExplorer', path), getAppPath: () => ipcRenderer.send('getAppPath'), closeDesktopApp: () => ipcRenderer.invoke('closeDesktopApp'), + + // Menu events + + onMenuAddNewFile: (callback: () => void) => { + ipcRenderer.on('menuAddNewFile', callback) + }, }) diff --git a/desktop/window.ts b/desktop/window.ts index 1caa47b32..2d3ffa775 100644 --- a/desktop/window.ts +++ b/desktop/window.ts @@ -12,8 +12,7 @@ const loadingEvents = new EventEmitter() import icon from './assets/icon.png?asset' export async function createWindow() { - - var loadingWindow = new BrowserWindow({ + const loadingWindow = new BrowserWindow({ resizable: false, autoHideMenuBar: true, frame: false, @@ -21,7 +20,7 @@ export async function createWindow() { webPreferences: { preload: join(__dirname, 'preload', 'index.js'), }, - }); + }) const mainWindow = new BrowserWindow({ show: false, @@ -38,7 +37,7 @@ export async function createWindow() { }) loadingEvents.on('finished', () => { - loadingWindow.close(); + loadingWindow.close() log.info('Opening index.html') // HMR for renderer base on electron-vite cli. // Load the remote URL for development or the local html file for production. @@ -59,10 +58,12 @@ export async function createWindow() { if (!is.dev) await server.runServer() - const serverStarted = await server.pollServer(); + const serverStarted = await server.pollServer() if (!serverStarted) { - throw new Error('Failed to start FastAPI server'); + throw new Error('Failed to start FastAPI server') } loadingEvents.emit('finished') + + return mainWindow } From c73d800d5c7528cc5b7e2b024c609c2394832325 Mon Sep 17 00:00:00 2001 From: roll Date: Mon, 30 Sep 2024 11:56:20 +0100 Subject: [PATCH 10/16] Connected to the client --- client/store/actions/app.ts | 18 +++- desktop/index.ts | 5 +- desktop/menu.ts | 166 ++++++++++++++++++------------------ 3 files changed, 100 insertions(+), 89 deletions(-) diff --git a/client/store/actions/app.ts b/client/store/actions/app.ts index ff76e03d9..4b46b7ea1 100644 --- a/client/store/actions/app.ts +++ b/client/store/actions/app.ts @@ -10,7 +10,8 @@ import { loadFiles } from './file' export async function onAppStart() { // @ts-ignore - const sendFatalError = window?.opendataeditor?.sendFatalError + const bridge = window?.opendataeditor + const sendFatalError = bridge?.sendFatalError let ready = false let attempt = 0 @@ -38,6 +39,7 @@ export async function onAppStart() { } // Setup project sync polling + setInterval(async () => { const result = await client.projectSync({}) @@ -58,8 +60,8 @@ export async function onAppStart() { // Register on windows close event handler (only Desktop env) // to prevent closing the app when there are unsaved changes - // @ts-ignore - if (window?.opendataeditor?.closeDesktopApp) { + + if (bridge?.closeDesktopApp) { window.onbeforeunload = (event) => { const isUpdated = getIsFileOrResourceUpdated(store.getState()) if (isUpdated) { @@ -68,9 +70,17 @@ export async function onAppStart() { } } } + + // Register menu events + + bridge?.onMenuAddNewFile(() => { + openDialog('fileUpload') + }) } export function closeDesktopApp() { // @ts-ignore - window?.opendataeditor?.closeDesktopApp() + const bridge = window?.opendataeditor + + bridge?.closeDesktopApp() } diff --git a/desktop/index.ts b/desktop/index.ts index 637e6f6f8..23e79814e 100644 --- a/desktop/index.ts +++ b/desktop/index.ts @@ -1,4 +1,4 @@ -import { app, dialog, BrowserWindow, Menu } from 'electron' +import { app, dialog, BrowserWindow } from 'electron' import { electronApp, optimizer } from '@electron-toolkit/utils' import { createWindow } from './window' import { createBridge } from './bridge' @@ -17,8 +17,7 @@ app.whenReady().then(async () => { log.info('## Start client') createBridge() const mainWindow = await createWindow() - const mainMenu = createMenu(mainWindow) - Menu.setApplicationMenu(mainMenu) + createMenu(mainWindow) }) // Default open or close DevTools by F12 in development diff --git a/desktop/menu.ts b/desktop/menu.ts index 374331f77..27d861ddb 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -1,97 +1,99 @@ -import { app, shell, Menu, MenuItemConstructorOptions, BrowserWindow } from 'electron' +import { app, shell, Menu, BrowserWindow } from 'electron' export function createMenu(mainWindow: BrowserWindow) { - return Menu.buildFromTemplate([ - { - label: app.name, - submenu: [{ role: 'about' }, { role: 'quit' }], - }, - { - label: 'File', - submenu: [ - { - label: 'Add', - submenu: [ - { - label: 'New file', - click: async () => { - mainWindow.webContents.send('menuAddNewFile') + Menu.setApplicationMenu( + Menu.buildFromTemplate([ + { + label: app.name, + submenu: [{ role: 'about' }, { role: 'quit' }], + }, + { + label: 'File', + submenu: [ + { + label: 'Add', + submenu: [ + { + label: 'New file', + click: async () => { + mainWindow.webContents.send('menuAddNewFile') + }, }, - }, - { - label: 'New folder', - click: async () => { - // TODO + { + label: 'New folder', + click: async () => { + // TODO + }, }, - }, - { - label: 'External data', - click: async () => { - // TODO + { + label: 'External data', + click: async () => { + // TODO + }, }, + ], + }, + { + label: 'Delete', + click: async () => { + // TODO }, - ], - }, - { - label: 'Delete', - click: async () => { - // TODO }, - }, - { - label: 'Publish', - click: async () => { - // TODO + { + label: 'Publish', + click: async () => { + // TODO + }, }, - }, - ], - }, - { - label: 'Edit', - submenu: [{ role: 'undo' }, { role: 'redo' }], - }, - { - label: 'View', - submenu: [ - { - label: 'Metadata', - click: async () => { - // TODO + ], + }, + { + label: 'Edit', + submenu: [{ role: 'undo' }, { role: 'redo' }], + }, + { + label: 'View', + submenu: [ + { + label: 'Metadata', + click: async () => { + // TODO + }, }, - }, - { - label: 'Errors panel', - click: async () => { - // TODO + { + label: 'Errors panel', + click: async () => { + // TODO + }, }, - }, - { - label: 'Source', - click: async () => { - // TODO + { + label: 'Source', + click: async () => { + // TODO + }, }, - }, - ] as MenuItemConstructorOptions[], - }, - { - label: 'Help', - submenu: [ - { - label: 'ODE User guide', - click: async () => { - await shell.openExternal( - 'https://opendataeditor.okfn.org/documentation/getting-started/' - ) + ], + }, + { + label: 'Help', + submenu: [ + { + label: 'ODE User guide', + click: async () => { + await shell.openExternal( + 'https://opendataeditor.okfn.org/documentation/getting-started/' + ) + }, }, - }, - { - label: 'Report an issue', - click: async () => { - await shell.openExternal('https://github.com/okfn/opendataeditor/') + { + label: 'Report an issue', + click: async () => { + await shell.openExternal('https://github.com/okfn/opendataeditor/') + }, }, - }, - ], - }, - ]) + ], + }, + ]) + ) } From 44ac3caae309a7a93325dbc4ba49eb03821d12d7 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Tue, 8 Oct 2024 23:26:57 +0200 Subject: [PATCH 11/16] Add some functionalities to menu --- client/store/actions/app.ts | 13 +++++++++++++ desktop/menu.ts | 7 +++---- desktop/preload/index.ts | 9 +++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/client/store/actions/app.ts b/client/store/actions/app.ts index 4b46b7ea1..101f5c70d 100644 --- a/client/store/actions/app.ts +++ b/client/store/actions/app.ts @@ -1,4 +1,5 @@ import * as store from '../store' +import { togglePanel } from '@client/store' import isEqual from 'fast-deep-equal' import delay from 'delay' import { openDialog } from './dialog' @@ -76,6 +77,18 @@ export async function onAppStart() { bridge?.onMenuAddNewFile(() => { openDialog('fileUpload') }) + + bridge?.onDeleteFile(() => { + openDialog('deleteFilesFolders') + }) + + bridge?.onPublishFile(() => { + openDialog('publish') + }) + + bridge?.onToggleMetadata(() => { + togglePanel('metadata') + }) } export function closeDesktopApp() { diff --git a/desktop/menu.ts b/desktop/menu.ts index 27d861ddb..53a42abe3 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -22,7 +22,6 @@ export function createMenu(mainWindow: BrowserWindow) { { label: 'New folder', click: async () => { - // TODO }, }, { @@ -36,13 +35,13 @@ export function createMenu(mainWindow: BrowserWindow) { { label: 'Delete', click: async () => { - // TODO + mainWindow.webContents.send('menuDeleteFile') }, }, { label: 'Publish', click: async () => { - // TODO + mainWindow.webContents.send('menuPublishFile') }, }, ], @@ -57,7 +56,7 @@ export function createMenu(mainWindow: BrowserWindow) { { label: 'Metadata', click: async () => { - // TODO + mainWindow.webContents.send('menuToggleMetadata') }, }, { diff --git a/desktop/preload/index.ts b/desktop/preload/index.ts index 486028308..0eba868a5 100644 --- a/desktop/preload/index.ts +++ b/desktop/preload/index.ts @@ -14,4 +14,13 @@ contextBridge.exposeInMainWorld('opendataeditor', { onMenuAddNewFile: (callback: () => void) => { ipcRenderer.on('menuAddNewFile', callback) }, + onDeleteFile: (callback: () => void) => { + ipcRenderer.on('menuDeleteFile', callback) + }, + onPublishFile: (callback: () => void) => { + ipcRenderer.on('menuPublishFile', callback) + }, + onToggleMetadata: (callback: () => void) => { + ipcRenderer.on('menuToggleMetadata', callback) + }, }) From 705d48a4b4582754ce229b012349a23448e6b2d2 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Thu, 10 Oct 2024 00:26:15 +0200 Subject: [PATCH 12/16] Add text in About popup --- desktop/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/desktop/index.ts b/desktop/index.ts index 23e79814e..968caeb29 100644 --- a/desktop/index.ts +++ b/desktop/index.ts @@ -55,5 +55,12 @@ process.on('unhandledRejection', async (error: any) => { app.quit() }) +app.setAboutPanelOptions({ + applicationName: 'Open Data Editor', + applicationVersion: '1.0.0', + website: 'https://opendataeditor.okfn.org/', + iconPath: './client/assets/ODE_sidebar_logo.svg' +}) + // Configure logger to write to the app directory log.transports.file.resolvePath = () => join(settings.APP_HOME, 'logger', 'main.log') From ff8c0f6578bf97bd58bf39687ecba6349318d500 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Thu, 10 Oct 2024 00:26:34 +0200 Subject: [PATCH 13/16] Add undo and redo actions from menu --- client/store/actions/app.ts | 17 +++++++++++++++++ desktop/menu.ts | 22 ++++++++++++++++------ desktop/preload/index.ts | 12 ++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/client/store/actions/app.ts b/client/store/actions/app.ts index 101f5c70d..968ec31bb 100644 --- a/client/store/actions/app.ts +++ b/client/store/actions/app.ts @@ -1,5 +1,6 @@ import * as store from '../store' import { togglePanel } from '@client/store' +import { undoTableChange, redoTableChange } from '@client/store' import isEqual from 'fast-deep-equal' import delay from 'delay' import { openDialog } from './dialog' @@ -89,6 +90,22 @@ export async function onAppStart() { bridge?.onToggleMetadata(() => { togglePanel('metadata') }) + + bridge?.onToggleErrorsReport(() => { + togglePanel('report') + }) + + bridge?.onToggleErrorsReport(() => { + togglePanel('source') + }) + + bridge?.onUndo(() => { + undoTableChange() + }) + + bridge?.onRedo(() => { + redoTableChange() + }) } export function closeDesktopApp() { diff --git a/desktop/menu.ts b/desktop/menu.ts index 53a42abe3..61c70abf2 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -48,27 +48,37 @@ export function createMenu(mainWindow: BrowserWindow) { }, { label: 'Edit', - submenu: [{ role: 'undo' }, { role: 'redo' }], + submenu: [{ + label: 'Undo', + click: async () => { + mainWindow.webContents.send('menuUndo') + }, + }, { + label: 'Redo', + click: async () => { + mainWindow.webContents.send('menuRedo') + }, + }], }, { label: 'View', submenu: [ { - label: 'Metadata', + label: 'Toggle Metadata Panel', click: async () => { mainWindow.webContents.send('menuToggleMetadata') }, }, { - label: 'Errors panel', + label: 'Toggle Errors Panel', click: async () => { - // TODO + mainWindow.webContents.send('menuToggleErrorsReport') }, }, { - label: 'Source', + label: 'Toggle Source Panel', click: async () => { - // TODO + mainWindow.webContents.send('menuToggleSource') }, }, ], diff --git a/desktop/preload/index.ts b/desktop/preload/index.ts index 0eba868a5..b92b39356 100644 --- a/desktop/preload/index.ts +++ b/desktop/preload/index.ts @@ -23,4 +23,16 @@ contextBridge.exposeInMainWorld('opendataeditor', { onToggleMetadata: (callback: () => void) => { ipcRenderer.on('menuToggleMetadata', callback) }, + onToggleErrorsReport: (callback: () => void) => { + ipcRenderer.on('menuToggleErrorsReport', callback) + }, + onToggleSource: (callback: () => void) => { + ipcRenderer.on('menuToggleSource', callback) + }, + onUndo: (callback: () => void) => { + ipcRenderer.on('menuUndo', callback) + }, + onRedo: (callback: () => void) => { + ipcRenderer.on('menuRedo', callback) + }, }) From 888aaa00ceda6a1123f9e85a8a64a22d84136582 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Thu, 10 Oct 2024 16:53:48 +0200 Subject: [PATCH 14/16] Add tab functionality --- client/components/Application/Dialogs/FileUpload.tsx | 4 +++- client/store/actions/app.ts | 6 +++++- client/store/actions/dialog.ts | 3 ++- client/store/state.ts | 5 +++++ desktop/menu.ts | 2 +- desktop/preload/index.ts | 3 +++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/client/components/Application/Dialogs/FileUpload.tsx b/client/components/Application/Dialogs/FileUpload.tsx index 96a0e3cf2..7c6700825 100644 --- a/client/components/Application/Dialogs/FileUpload.tsx +++ b/client/components/Application/Dialogs/FileUpload.tsx @@ -26,7 +26,9 @@ export default function FileUploadDialog() { store.closeDialog() } - const [value, setValue] = React.useState(0) + const dialogTab = store.useStore((state) => state.dialogTab) + + const [value, setValue] = React.useState(dialogTab ? dialogTab : 0) const [remoteUrlValue, setRemoteUrlValue] = React.useState('') diff --git a/client/store/actions/app.ts b/client/store/actions/app.ts index 968ec31bb..c0825fb38 100644 --- a/client/store/actions/app.ts +++ b/client/store/actions/app.ts @@ -76,7 +76,11 @@ export async function onAppStart() { // Register menu events bridge?.onMenuAddNewFile(() => { - openDialog('fileUpload') + openDialog('fileUpload', 0) + }) + + bridge?.onMenuAddExternalFile(() => { + openDialog('fileUpload', 1) }) bridge?.onDeleteFile(() => { diff --git a/client/store/actions/dialog.ts b/client/store/actions/dialog.ts index 786fb92c9..8d0de5dc0 100644 --- a/client/store/actions/dialog.ts +++ b/client/store/actions/dialog.ts @@ -10,9 +10,10 @@ export function toggleDialog(dialog: IDialog) { } } -export function openDialog(dialog: IDialog) { +export function openDialog(dialog: IDialog, dialogTab?: number) { store.setState('open-dialog', (state) => { state.dialog = dialog + state.dialogTab = dialogTab }) } diff --git a/client/store/state.ts b/client/store/state.ts index cb37eafac..2a9bffa7f 100644 --- a/client/store/state.ts +++ b/client/store/state.ts @@ -73,6 +73,11 @@ export type IState = { **/ dialog?: IDialog + /** + * Keeps track of the displayed dialog's tab + **/ + dialogTab?: number + /** * Will be opened when the main `dialog` is closed (for dialog chains) **/ diff --git a/desktop/menu.ts b/desktop/menu.ts index 61c70abf2..9bcb98783 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -27,7 +27,7 @@ export function createMenu(mainWindow: BrowserWindow) { { label: 'External data', click: async () => { - // TODO + mainWindow.webContents.send('menuAddExternalFile') }, }, ], diff --git a/desktop/preload/index.ts b/desktop/preload/index.ts index b92b39356..380ddcf82 100644 --- a/desktop/preload/index.ts +++ b/desktop/preload/index.ts @@ -14,6 +14,9 @@ contextBridge.exposeInMainWorld('opendataeditor', { onMenuAddNewFile: (callback: () => void) => { ipcRenderer.on('menuAddNewFile', callback) }, + onMenuAddExternalFile: (callback: () => void) => { + ipcRenderer.on('menuAddExternalFile', callback) + }, onDeleteFile: (callback: () => void) => { ipcRenderer.on('menuDeleteFile', callback) }, From 92cd29a838751610fad587be162e58745d7ff9e0 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Fri, 11 Oct 2024 17:16:05 +0200 Subject: [PATCH 15/16] Add 'Add files or folders' option --- desktop/menu.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/desktop/menu.ts b/desktop/menu.ts index 9bcb98783..ef9f6e3dd 100644 --- a/desktop/menu.ts +++ b/desktop/menu.ts @@ -22,6 +22,8 @@ export function createMenu(mainWindow: BrowserWindow) { { label: 'New folder', click: async () => { + // Adding the same as Add New File, because it's the same dialog + mainWindow.webContents.send('menuAddNewFile') }, }, { From ea49ee0c763a6a65d78c8e1dcae154a49e876de0 Mon Sep 17 00:00:00 2001 From: gtzatchkova Date: Mon, 14 Oct 2024 16:12:55 +0200 Subject: [PATCH 16/16] Fix typo/duplicated function --- client/store/actions/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/store/actions/app.ts b/client/store/actions/app.ts index c0825fb38..7de1cfa90 100644 --- a/client/store/actions/app.ts +++ b/client/store/actions/app.ts @@ -99,7 +99,7 @@ export async function onAppStart() { togglePanel('report') }) - bridge?.onToggleErrorsReport(() => { + bridge?.onToggleSource(() => { togglePanel('source') })