From f059ebb83be5b99e5f743ee38275358ef677563d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Cmit=20Tun=C3=A7?= Date: Thu, 2 Apr 2026 12:13:29 +0300 Subject: [PATCH] feat: initialize electron main process with tray support and implement core IPC service handlers --- src/main/index.ts | 4 +- src/main/ipc/index.ts | 96 +++++++-------- src/renderer/src/App.tsx | 200 ++++++++++++++++++++++++++++++- src/renderer/src/locales/en.json | 5 +- src/renderer/src/locales/tr.json | 5 +- 5 files changed, 253 insertions(+), 57 deletions(-) diff --git a/src/main/index.ts b/src/main/index.ts index 49497ab..5ccc820 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -46,8 +46,8 @@ function createTray(): void { function createWindow(): void { mainWindow = new BrowserWindow({ - width: 1200, - height: 800, + width: 1400, + height: 900, show: false, autoHideMenuBar: true, icon: join(__dirname, '../../resources/icon.png'), diff --git a/src/main/ipc/index.ts b/src/main/ipc/index.ts index 4c38ede..00bfc1d 100644 --- a/src/main/ipc/index.ts +++ b/src/main/ipc/index.ts @@ -256,6 +256,54 @@ async function restartApache(): Promise<{ success: boolean; message: string }> { } export function registerIpcHandlers(): void { + ipcMain.handle('mariadb:processlist', async (_event, versionId) => { + try { + return await mariaDbManagerService.getProcessList(versionId) + } catch (error: any) { + console.error('Failed to get process list:', error) + return [] + } + }) + + ipcMain.handle('mariadb:kill-process', async (_event, { versionId, processId }) => { + try { + await mariaDbManagerService.killProcess(versionId, processId) + return { success: true } + } catch (error: any) { + console.error('Failed to kill process:', error) + return { success: false, error: error.message } + } + }) + + // CLI & Environment + ipcMain.handle('cli:get-config', async () => { + const settings = configService.getSettings() + return { + enabled: settings.cliEnvEnabled !== false, + defaultPhp: settings.defaultPhpVersion, + defaultMariaDb: settings.defaultMariaDbVersion, + binDir: cliBinService.getBinDir(), + aliases: cliBinService.getAllAliases() + } + }) + + ipcMain.handle('cli:set-config', async (_event, config: any) => { + const settings = configService.getSettings() + configService.updateSettings({ + ...settings, + cliEnvEnabled: config.enabled, + defaultPhpVersion: config.defaultPhp, + defaultMariaDbVersion: config.defaultMariaDb + }) + await cliAliasService.generateAliases() + return { success: true } + }) + + ipcMain.handle('cli:sync', async () => { + await cliAliasService.generateAliases() + return { success: true } + }) + // Service management ipcMain.handle('services:reload', async (_event, serviceName: string) => { if (serviceName === 'nginx') return await reloadNginx() @@ -1042,52 +1090,4 @@ export function registerIpcHandlers(): void { rootPass: rootPass || '' }, dbName, savePath, compress, (msg) => log(msg)) }) - - ipcMain.handle('mariadb:processlist', async (_event, versionId) => { - try { - return await mariaDbManagerService.getProcessList(versionId) - } catch (error: any) { - console.error('Failed to get process list:', error) - return [] - } - }) - - ipcMain.handle('mariadb:kill-process', async (_event, { versionId, processId }) => { - try { - await mariaDbManagerService.killProcess(versionId, processId) - return { success: true } - } catch (error: any) { - console.error('Failed to kill process:', error) - return { success: false, error: error.message } - } - }) - - // CLI & Environment - ipcMain.handle('cli:get-config', async () => { - const settings = configService.getSettings() - return { - enabled: settings.cliEnvEnabled !== false, - defaultPhp: settings.defaultPhpVersion, - defaultMariaDb: settings.defaultMariaDbVersion, - binDir: cliBinService.getBinDir(), - aliases: cliBinService.getAllAliases() - } - }) - - ipcMain.handle('cli:set-config', async (_event, config: any) => { - const settings = configService.getSettings() - configService.updateSettings({ - ...settings, - cliEnvEnabled: config.enabled, - defaultPhpVersion: config.defaultPhp, - defaultMariaDbVersion: config.defaultMariaDb - }) - await cliAliasService.generateAliases() - return { success: true } - }) - - ipcMain.handle('cli:sync', async () => { - await cliAliasService.generateAliases() - return { success: true } - }) } diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 8cd6e66..2b1b9e6 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -1,4 +1,7 @@ import { useState, useEffect } from 'react' +import Prism from 'prismjs' +import 'prismjs/themes/prism-tomorrow.css' +import 'prismjs/components/prism-sql' import logo from './assets/logo.svg' import { Box, @@ -169,9 +172,10 @@ function App(): JSX.Element { // MariaDB Process List State const [processList, setProcessList] = useState([]) - const [isProcessListOpen, setIsProcessListOpen] = useState(false) - const [selectedMariaDbId, setSelectedMariaDbId] = useState(null) const [isProcessListLoading, setIsProcessListLoading] = useState(false) + const [selectedMariaDbId, setSelectedMariaDbId] = useState('') + const [isProcessListOpen, setIsProcessListOpen] = useState(false) + const [selectedQuery, setSelectedQuery] = useState(null) const [isNginxConfigOpen, setIsNginxConfigOpen] = useState(false) const [nginxConfig, setNginxConfig] = useState('') const [isApacheConfigOpen, setIsApacheConfigOpen] = useState(false) @@ -193,6 +197,25 @@ function App(): JSX.Element { return { filePath, line, host } } + // Auto-refresh for Process Monitor + useEffect(() => { + if (activeTab === 'db_monitor' && selectedMariaDbId) { + fetchProcessList(selectedMariaDbId) + const interval = setInterval(() => { + fetchProcessList(selectedMariaDbId) + }, 3000) + return () => clearInterval(interval) + } + return () => { } + }, [activeTab, selectedMariaDbId]) + + useEffect(() => { + if (activeTab === 'db_monitor' && !selectedMariaDbId && mariaDbVersions.length > 0) { + const installed = mariaDbVersions.find(v => v.status === 'installed') + if (installed) setSelectedMariaDbId(installed.id) + } + }, [activeTab, mariaDbVersions]) + const fetchStatus = async () => { if (window.api && window.api.getServiceStatus) { const currentStatus = await window.api.getServiceStatus() @@ -882,8 +905,7 @@ function App(): JSX.Element { const handleOpenProcessList = async (id: string) => { setSelectedMariaDbId(id) - setIsProcessListOpen(true) - fetchProcessList(id) + setActiveTab('db_monitor') } const fetchProcessList = async (id: string) => { @@ -923,6 +945,67 @@ function App(): JSX.Element { return ( <> + setSelectedQuery(null)} + maxWidth="lg" + fullWidth + PaperProps={{ + sx: { + bgcolor: '#1a1d21', + backgroundImage: 'none', + color: '#fff', + borderRadius: 2, + border: '1px solid rgba(255,255,255,0.1)' + } + }} + > + + {t('mariadb_process_monitor.query_details')} + setSelectedQuery(null)} sx={{ color: 'rgba(255,255,255,0.5)' }}> + + + + + +
+                            
+                        
+
+
+ + + + +
+ + + setActiveTab('db_monitor')} sx={{ '&:hover': { color: 'primary.main' } }}> + + + setActiveTab('settings')} sx={{ ml: 1 }}> @@ -1023,6 +1111,12 @@ function App(): JSX.Element { + + setActiveTab('db_monitor')}> + + + + @@ -1038,7 +1132,7 @@ function App(): JSX.Element { - + {activeTab === 'settings' && ( @@ -1657,6 +1751,102 @@ function App(): JSX.Element { )} + {activeTab === 'db_monitor' && ( + + + + + + {t('mariadb_process_monitor.title')} + + + {t('mariadb_process_monitor.auto_refresh_desc')} + + + + + {t('settings.mariadb_versions')} + + + {isProcessListLoading && } + + + + + + + + ID + USER + HOST + DB + COMMAND + TIME + STATE + INFO + PROGRESS + ACTION + + + + {processList.length === 0 ? ( + + + {t('common.no_data')} + + + ) : ( + processList.map((proc) => ( + + {proc.Id} + {proc.User} + {proc.Host} + {proc.db || 'system'} + {proc.Command} + {proc.Time}s + {proc.State || '-'} + + + setSelectedQuery(proc.Info)} + sx={{ + cursor: proc.Info ? 'pointer' : 'default', + '&:hover': { color: proc.Info ? '#39A7FF' : 'inherit' }, + transition: 'color 0.2s' + }} + > + {proc.Info || '-'} + + + + {proc.Progress}% + + handleKillProcess(selectedMariaDbId, proc.Id)}> + + + + + )) + )} + +
+
+
+
+ )} + {activeTab === 'tools' && ( diff --git a/src/renderer/src/locales/en.json b/src/renderer/src/locales/en.json index 7f696c9..bf7e917 100644 --- a/src/renderer/src/locales/en.json +++ b/src/renderer/src/locales/en.json @@ -257,10 +257,13 @@ } }, "mariadb_process_monitor": { - "title": "MariaDB Process List", + "title": "MariaDB Process Monitor", + "auto_refresh_desc": "The process list is automatically refreshed every 3 seconds.", "kill_btn": "KILL", "kill_confirm": "Are you sure you want to kill this process?", "refresh_btn": "Refresh", + "click_to_view_sql": "Click to View SQL Query", + "query_details": "Query Details", "no_processes": "No active processes found.", "columns": { "id": "ID", diff --git a/src/renderer/src/locales/tr.json b/src/renderer/src/locales/tr.json index fe17186..d43a271 100644 --- a/src/renderer/src/locales/tr.json +++ b/src/renderer/src/locales/tr.json @@ -252,10 +252,13 @@ } }, "mariadb_process_monitor": { - "title": "MariaDB Süreç Listesi (Process List)", + "title": "MariaDB Süreç İzleyici", + "auto_refresh_desc": "Süreç listesi her 3 saniyede bir otomatik olarak yenilenir.", "kill_btn": "KILL", "kill_confirm": "Bu süreci sonlandırmak istediğinizden emin misiniz?", "refresh_btn": "Yenile", + "click_to_view_sql": "SQL Sorgusunu Görüntülemek İçin Tıklayın", + "query_details": "Sorgu Detayları", "no_processes": "Aktif süreç bulunamadı.", "columns": { "id": "ID",