feat: implement MariaDB export wizard and backend management services
This commit is contained in:
@@ -1043,6 +1043,25 @@ export function registerIpcHandlers(): void {
|
|||||||
}, dbName, savePath, compress, (msg) => log(msg))
|
}, 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
|
// CLI & Environment
|
||||||
ipcMain.handle('cli:get-config', async () => {
|
ipcMain.handle('cli:get-config', async () => {
|
||||||
const settings = configService.getSettings()
|
const settings = configService.getSettings()
|
||||||
|
|||||||
@@ -134,25 +134,21 @@ export class CliBinService {
|
|||||||
if (process.platform !== 'win32') return
|
if (process.platform !== 'win32') return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use PowerShell to manage PATH safely.
|
|
||||||
// 1. Get current User PATH
|
|
||||||
// 2. Add binDir if not exists
|
|
||||||
// 3. Set new PATH
|
|
||||||
// 4. Broadcast WM_SETTINGCHANGE to notify system
|
|
||||||
const binDir = this.getBinDirInternal()
|
const binDir = this.getBinDirInternal()
|
||||||
|
|
||||||
|
// We use Base64 encoding for the PS command to avoid any escaping issues with quotes, semicolons, etc.
|
||||||
const psScript = `
|
const psScript = `
|
||||||
|
$binDir = '${binDir}'
|
||||||
$currentPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
$currentPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
||||||
if ($currentPath -notlike '*${binDir}*') {
|
if ($currentPath -notlike "*$binDir*") {
|
||||||
$newPath = $currentPath
|
$newPath = $currentPath
|
||||||
if ($newPath -and -not $newPath.EndsWith(';')) { $newPath += ';' }
|
if ($newPath -and -not $newPath.EndsWith(';')) { $newPath += ';' }
|
||||||
$newPath += '${binDir}'
|
$newPath += $binDir
|
||||||
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
||||||
|
|
||||||
# Notify Windows of the change (WM_SETTINGCHANGE)
|
|
||||||
$signature = @'
|
$signature = @'
|
||||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out IntPtr lpdwResult);
|
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out IntPtr lpdwResult);
|
||||||
'@
|
'@
|
||||||
$type = Add-Type -MemberDefinition $signature -Name "Win32" -Namespace "Native" -PassThru -ErrorAction SilentlyContinue
|
$type = Add-Type -MemberDefinition $signature -Name "Win32" -Namespace "Native" -PassThru -ErrorAction SilentlyContinue
|
||||||
if ($type) {
|
if ($type) {
|
||||||
@@ -164,7 +160,9 @@ export class CliBinService {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const { stdout } = await execAsync(`powershell -Command "${psScript.replace(/\n/g, ' ')}"`)
|
const encodedCommand = Buffer.from(psScript, 'utf16le').toString('base64')
|
||||||
|
const { stdout } = await execAsync(`powershell -EncodedCommand ${encodedCommand}`)
|
||||||
|
|
||||||
if (stdout.includes('PATH_UPDATED')) {
|
if (stdout.includes('PATH_UPDATED')) {
|
||||||
console.log(`Successfully added Multi-PHP bin to User PATH: ${binDir}`)
|
console.log(`Successfully added Multi-PHP bin to User PATH: ${binDir}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import fs from 'fs'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { app } from 'electron'
|
import { app } from 'electron'
|
||||||
import { configService } from './ConfigService'
|
import { configService } from './ConfigService'
|
||||||
|
import { mariaDbOperationService } from './MariaDbOperationService'
|
||||||
|
|
||||||
export interface MariaDbVersion {
|
export interface MariaDbVersion {
|
||||||
id: string
|
id: string
|
||||||
@@ -156,6 +157,64 @@ export class MariaDbManagerService {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProcessList(versionId: string) {
|
||||||
|
const version = this.versions.find(v => v.id === versionId)
|
||||||
|
if (!version) throw new Error('Version not found')
|
||||||
|
|
||||||
|
const binaryPath = await this.getMariaDbBinaryPath(version.version)
|
||||||
|
if (!binaryPath) throw new Error('MariaDB binary not found')
|
||||||
|
|
||||||
|
const settings = configService.getSettings()
|
||||||
|
const config = {
|
||||||
|
binPath: binaryPath,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: version.port,
|
||||||
|
rootUser: 'root',
|
||||||
|
rootPass: settings.mariaDbPasswords?.[versionId] || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await mariaDbOperationService.runQuery(config, 'SHOW FULL PROCESSLIST')
|
||||||
|
if (!result.success) throw new Error(result.error)
|
||||||
|
|
||||||
|
// Parse mysql tab-separated output
|
||||||
|
const lines = result.output.split('\n').filter(l => l.trim().length > 0)
|
||||||
|
if (lines.length === 0) return []
|
||||||
|
|
||||||
|
const headers = lines[0].split('\t')
|
||||||
|
const rows = lines.slice(1).map(line => {
|
||||||
|
const values = line.split('\t')
|
||||||
|
const row: any = {}
|
||||||
|
headers.forEach((h, i) => {
|
||||||
|
row[h] = values[i] === 'NULL' ? null : values[i]
|
||||||
|
})
|
||||||
|
return row
|
||||||
|
})
|
||||||
|
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
async killProcess(versionId: string, processId: string) {
|
||||||
|
const version = this.versions.find(v => v.id === versionId)
|
||||||
|
if (!version) throw new Error('Version not found')
|
||||||
|
|
||||||
|
const binaryPath = await this.getMariaDbBinaryPath(version.version)
|
||||||
|
if (!binaryPath) throw new Error('MariaDB binary not found')
|
||||||
|
|
||||||
|
const settings = configService.getSettings()
|
||||||
|
const config = {
|
||||||
|
binPath: binaryPath,
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: version.port,
|
||||||
|
rootUser: 'root',
|
||||||
|
rootPass: settings.mariaDbPasswords?.[versionId] || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await mariaDbOperationService.runQuery(config, `KILL ${processId}`)
|
||||||
|
if (!result.success) throw new Error(result.error)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mariaDbManagerService = new MariaDbManagerService()
|
export const mariaDbManagerService = new MariaDbManagerService()
|
||||||
|
|||||||
+155
-1
@@ -166,6 +166,12 @@ function App(): JSX.Element {
|
|||||||
const [pmaProgress, setPmaProgress] = useState(0)
|
const [pmaProgress, setPmaProgress] = useState(0)
|
||||||
const [isMariaDbWizardOpen, setIsMariaDbWizardOpen] = useState(false)
|
const [isMariaDbWizardOpen, setIsMariaDbWizardOpen] = useState(false)
|
||||||
const [isMariaDbExportWizardOpen, setIsMariaDbExportWizardOpen] = useState(false)
|
const [isMariaDbExportWizardOpen, setIsMariaDbExportWizardOpen] = useState(false)
|
||||||
|
|
||||||
|
// MariaDB Process List State
|
||||||
|
const [processList, setProcessList] = useState<any[]>([])
|
||||||
|
const [isProcessListOpen, setIsProcessListOpen] = useState(false)
|
||||||
|
const [selectedMariaDbId, setSelectedMariaDbId] = useState<string | null>(null)
|
||||||
|
const [isProcessListLoading, setIsProcessListLoading] = useState(false)
|
||||||
const [isNginxConfigOpen, setIsNginxConfigOpen] = useState(false)
|
const [isNginxConfigOpen, setIsNginxConfigOpen] = useState(false)
|
||||||
const [nginxConfig, setNginxConfig] = useState('')
|
const [nginxConfig, setNginxConfig] = useState('')
|
||||||
const [isApacheConfigOpen, setIsApacheConfigOpen] = useState(false)
|
const [isApacheConfigOpen, setIsApacheConfigOpen] = useState(false)
|
||||||
@@ -327,12 +333,20 @@ function App(): JSX.Element {
|
|||||||
if (logDialogOpen && selectedService) {
|
if (logDialogOpen && selectedService) {
|
||||||
logInterval = setInterval(() => {
|
logInterval = setInterval(() => {
|
||||||
fetchLogs(selectedService)
|
fetchLogs(selectedService)
|
||||||
}, 1000)
|
}, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
|
let processInterval: NodeJS.Timeout | null = null
|
||||||
|
if (isProcessListOpen && selectedMariaDbId) {
|
||||||
|
processInterval = setInterval(() => {
|
||||||
|
fetchProcessList(selectedMariaDbId)
|
||||||
|
}, 3000)
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
if (logInterval) clearInterval(logInterval)
|
if (logInterval) clearInterval(logInterval)
|
||||||
|
if (processInterval) clearInterval(processInterval)
|
||||||
if (typeof removePhpListener === 'function') removePhpListener()
|
if (typeof removePhpListener === 'function') removePhpListener()
|
||||||
if (typeof removeMariaDbListener === 'function') removeMariaDbListener()
|
if (typeof removeMariaDbListener === 'function') removeMariaDbListener()
|
||||||
if (typeof removeNginxListener === 'function') removeNginxListener()
|
if (typeof removeNginxListener === 'function') removeNginxListener()
|
||||||
@@ -866,6 +880,45 @@ function App(): JSX.Element {
|
|||||||
setIsPhpExtensionsOpen(true)
|
setIsPhpExtensionsOpen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleOpenProcessList = async (id: string) => {
|
||||||
|
setSelectedMariaDbId(id)
|
||||||
|
setIsProcessListOpen(true)
|
||||||
|
fetchProcessList(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchProcessList = async (id: string) => {
|
||||||
|
if (!window.api) return
|
||||||
|
setIsProcessListLoading(true)
|
||||||
|
const list = await window.api.invoke('mariadb:processlist', id)
|
||||||
|
setProcessList(list || [])
|
||||||
|
setIsProcessListLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleKillProcess = async (id: string, pid: string) => {
|
||||||
|
if (!window.api) return
|
||||||
|
const result = await Swal.fire({
|
||||||
|
title: t('mariadb_process_monitor.kill_confirm'),
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#d33',
|
||||||
|
cancelButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: t('mariadb_process_monitor.kill_btn'),
|
||||||
|
cancelButtonText: t('common.cancel'),
|
||||||
|
background: '#1a1d21',
|
||||||
|
color: '#fff'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
const res = await window.api.invoke('mariadb:kill-process', { versionId: id, processId: pid })
|
||||||
|
if (res.success) {
|
||||||
|
setNotification({ open: true, message: t('common.ok'), severity: 'success' })
|
||||||
|
fetchProcessList(id)
|
||||||
|
} else {
|
||||||
|
setNotification({ open: true, message: res.error, severity: 'error' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const installedPhpVersions = phpVersions.filter(v => v.status === 'installed')
|
const installedPhpVersions = phpVersions.filter(v => v.status === 'installed')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -1584,6 +1637,9 @@ function App(): JSX.Element {
|
|||||||
<IconButton onClick={() => handleOpenLogs(`mariadb:${v.version}`)} title={t('diagnostics.logs')} size="small" sx={{ bgcolor: 'rgba(255,255,255,0.05)' }}>
|
<IconButton onClick={() => handleOpenLogs(`mariadb:${v.version}`)} title={t('diagnostics.logs')} size="small" sx={{ bgcolor: 'rgba(255,255,255,0.05)' }}>
|
||||||
<TerminalIcon fontSize="small" />
|
<TerminalIcon fontSize="small" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
<IconButton onClick={() => handleOpenProcessList(v.id)} title={t('mariadb_process_monitor.title')} size="small" sx={{ bgcolor: 'rgba(255,255,255,0.05)', '&:hover': { color: 'primary.main' } }}>
|
||||||
|
<ToolsIcon fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
<IconButton onClick={() => handleResetData(`mariadb:${v.version}`)} title={t('common.reset')} size="small" sx={{ bgcolor: 'rgba(255,255,255,0.05)', '&:hover': { color: 'error.main' } }}>
|
<IconButton onClick={() => handleResetData(`mariadb:${v.version}`)} title={t('common.reset')} size="small" sx={{ bgcolor: 'rgba(255,255,255,0.05)', '&:hover': { color: 'error.main' } }}>
|
||||||
<ResetIcon fontSize="small" />
|
<ResetIcon fontSize="small" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -2106,8 +2162,106 @@ function App(): JSX.Element {
|
|||||||
open={isMariaDbExportWizardOpen}
|
open={isMariaDbExportWizardOpen}
|
||||||
onClose={() => setIsMariaDbExportWizardOpen(false)}
|
onClose={() => setIsMariaDbExportWizardOpen(false)}
|
||||||
mariaDbVersions={mariaDbVersions}
|
mariaDbVersions={mariaDbVersions}
|
||||||
|
versionId={selectedMariaDbId || ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* MariaDB Process List Dialog */}
|
||||||
|
<Dialog
|
||||||
|
open={isProcessListOpen}
|
||||||
|
onClose={() => setIsProcessListOpen(false)}
|
||||||
|
maxWidth="lg"
|
||||||
|
fullWidth
|
||||||
|
PaperProps={{
|
||||||
|
sx: {
|
||||||
|
bgcolor: '#1a1d21',
|
||||||
|
color: '#fff',
|
||||||
|
borderRadius: 2
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogTitle sx={{ borderBottom: '1px solid rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<DbIcon color="primary" />
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{t('mariadb_process_monitor.title')} - {selectedMariaDbId}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', gap: 1 }}>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
startIcon={isProcessListLoading ? <CircularProgress size={16} /> : <RefreshIcon />}
|
||||||
|
onClick={() => selectedMariaDbId && fetchProcessList(selectedMariaDbId)}
|
||||||
|
disabled={isProcessListLoading}
|
||||||
|
>
|
||||||
|
{t('mariadb_process_monitor.refresh_btn')}
|
||||||
|
</Button>
|
||||||
|
<IconButton size="small" onClick={() => setIsProcessListOpen(false)} sx={{ color: 'rgba(255,255,255,0.5)' }}>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent sx={{ p: 0 }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 500 }}>
|
||||||
|
<Table stickyHeader size="small">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.id')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.user')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.host')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.db')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.command')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.time')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.state')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.info')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem' }}>{t('mariadb_process_monitor.columns.progress')}</TableCell>
|
||||||
|
<TableCell sx={{ bgcolor: '#24292e', color: 'rgba(255,255,255,0.5)', fontWeight: 'bold', fontSize: '0.75rem', textAlign: 'right' }}>{t('common.actions')}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{processList.length === 0 ? (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={10} sx={{ textAlign: 'center', py: 4, color: 'rgba(255,255,255,0.3)', fontStyle: 'italic' }}>
|
||||||
|
{t('mariadb_process_monitor.no_processes')}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
) : (
|
||||||
|
processList.map((p) => (
|
||||||
|
<TableRow key={p.Id} hover sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)', color: 'primary.light' }}>{p.Id}</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)' }}>{p.User}</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)', fontSize: '0.7rem', opacity: 0.7 }}>{p.Host}</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)' }}>{p.db || <Typography component="span" variant="caption" sx={{ opacity: 0.3 }}>NULL</Typography>}</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)' }}>
|
||||||
|
<Chip label={p.Command} size="small" variant="outlined" sx={{ height: 18, fontSize: '0.65rem', color: p.Command === 'Query' ? 'success.main' : 'inherit' }} />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)' }}>{p.Time}s</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)', fontSize: '0.75rem', color: p.State === 'starting' ? 'warning.main' : 'inherit' }}>{p.State}</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)', maxWidth: 200, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', fontSize: '0.7rem', fontFamily: 'monospace' }} title={p.Info}>
|
||||||
|
{p.Info || ''}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)', fontSize: '0.75rem' }}>
|
||||||
|
{p.Progress ? `${parseFloat(p.Progress).toFixed(2)}%` : '-'}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell sx={{ borderColor: 'rgba(255,255,255,0.05)', textAlign: 'right' }}>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
color="error"
|
||||||
|
variant="text"
|
||||||
|
onClick={() => selectedMariaDbId && handleKillProcess(selectedMariaDbId, p.Id)}
|
||||||
|
sx={{ fontSize: '0.65rem', p: 0, minWidth: 'auto' }}
|
||||||
|
>
|
||||||
|
{t('mariadb_process_monitor.kill_btn')}
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isNginxConfigOpen}
|
open={isNginxConfigOpen}
|
||||||
onClose={() => setIsNginxConfigOpen(false)}
|
onClose={() => setIsNginxConfigOpen(false)}
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ interface MariaDbExportWizardProps {
|
|||||||
open: boolean
|
open: boolean
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
mariaDbVersions: any[]
|
mariaDbVersions: any[]
|
||||||
|
versionId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const MariaDbExportWizard: React.FC<MariaDbExportWizardProps> = ({ open, onClose, mariaDbVersions }) => {
|
const MariaDbExportWizard: React.FC<MariaDbExportWizardProps> = ({ open, onClose, mariaDbVersions, versionId }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
@@ -65,10 +66,14 @@ const MariaDbExportWizard: React.FC<MariaDbExportWizardProps> = ({ open, onClose
|
|||||||
setSavePath('')
|
setSavePath('')
|
||||||
setLogs([])
|
setLogs([])
|
||||||
setExportResult(null)
|
setExportResult(null)
|
||||||
|
if (versionId) {
|
||||||
|
setSelectedVersion(versionId)
|
||||||
|
} else {
|
||||||
const installedVersion = mariaDbVersions.find(v => v.status === 'installed')
|
const installedVersion = mariaDbVersions.find(v => v.status === 'installed')
|
||||||
if (installedVersion) setSelectedVersion(installedVersion.id)
|
if (installedVersion) setSelectedVersion(installedVersion.id)
|
||||||
}
|
}
|
||||||
}, [open, mariaDbVersions])
|
}
|
||||||
|
}, [open, mariaDbVersions, versionId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (logEndRef.current) {
|
if (logEndRef.current) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
|
"actions": "Actions",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"stop": "Stop",
|
"stop": "Stop",
|
||||||
"restart": "Restart",
|
"restart": "Restart",
|
||||||
@@ -254,5 +255,23 @@
|
|||||||
"prev_match": "Previous (Shift+Enter)",
|
"prev_match": "Previous (Shift+Enter)",
|
||||||
"next_match": "Next (Enter)"
|
"next_match": "Next (Enter)"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"mariadb_process_monitor": {
|
||||||
|
"title": "MariaDB Process List",
|
||||||
|
"kill_btn": "KILL",
|
||||||
|
"kill_confirm": "Are you sure you want to kill this process?",
|
||||||
|
"refresh_btn": "Refresh",
|
||||||
|
"no_processes": "No active processes found.",
|
||||||
|
"columns": {
|
||||||
|
"id": "ID",
|
||||||
|
"user": "User",
|
||||||
|
"host": "Host",
|
||||||
|
"db": "db",
|
||||||
|
"command": "Command",
|
||||||
|
"time": "Time",
|
||||||
|
"state": "State",
|
||||||
|
"info": "Info",
|
||||||
|
"progress": "Progress"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
|
"actions": "İşlem",
|
||||||
"start": "Başlat",
|
"start": "Başlat",
|
||||||
"stop": "Durdur",
|
"stop": "Durdur",
|
||||||
"restart": "Yeniden Başlat",
|
"restart": "Yeniden Başlat",
|
||||||
@@ -79,7 +80,7 @@
|
|||||||
"updated": "Proje başarıyla güncellendi.",
|
"updated": "Proje başarıyla güncellendi.",
|
||||||
"deleted": "Proje silindi.",
|
"deleted": "Proje silindi.",
|
||||||
"delete_confirm": "Bu projeyi silmek istediğinize emin misiniz? Dosyalarınız silinmez, sadece listeden kaldırılır.",
|
"delete_confirm": "Bu projeyi silmek istediğinize emin misiniz? Dosyalarınız silinmez, sadece listeden kaldırılır.",
|
||||||
"browse" : "Gözat"
|
"browse": "Gözat"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"general": "Genel Ayarlar",
|
"general": "Genel Ayarlar",
|
||||||
@@ -249,5 +250,23 @@
|
|||||||
"prev_match": "Önceki (Shift+Enter)",
|
"prev_match": "Önceki (Shift+Enter)",
|
||||||
"next_match": "Sonraki (Enter)"
|
"next_match": "Sonraki (Enter)"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"mariadb_process_monitor": {
|
||||||
|
"title": "MariaDB Süreç Listesi (Process List)",
|
||||||
|
"kill_btn": "KILL",
|
||||||
|
"kill_confirm": "Bu süreci sonlandırmak istediğinizden emin misiniz?",
|
||||||
|
"refresh_btn": "Yenile",
|
||||||
|
"no_processes": "Aktif süreç bulunamadı.",
|
||||||
|
"columns": {
|
||||||
|
"id": "ID",
|
||||||
|
"user": "Kullanıcı",
|
||||||
|
"host": "Host",
|
||||||
|
"db": "Veritabanı",
|
||||||
|
"command": "Komut",
|
||||||
|
"time": "Süre",
|
||||||
|
"state": "Durum",
|
||||||
|
"info": "Bilgi",
|
||||||
|
"progress": "İlerleme"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user