feat: add ServiceEventMonitor and PhpExtensionManager components for service tracking and management
This commit is contained in:
@@ -175,8 +175,8 @@ const PhpExtensionManager: React.FC<PhpExtensionManagerProps> = ({ open, onClose
|
||||
<CloseIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</DialogTitle>
|
||||
<DialogContent dividers sx={{ borderColor: 'rgba(255,255,255,0.05)', p: 0 }}>
|
||||
<Box sx={{ p: 1.5, bgcolor: 'rgba(255,255,255,0.02)', display: 'flex', gap: 1 }}>
|
||||
<DialogContent dividers sx={{ borderColor: 'var(--color-border-soft)', p: 0 }}>
|
||||
<Box sx={{ p: 1.5, bgcolor: 'var(--color-bg-soft)', display: 'flex', gap: 1 }}>
|
||||
<TextField
|
||||
fullWidth
|
||||
size="small"
|
||||
@@ -190,7 +190,7 @@ const PhpExtensionManager: React.FC<PhpExtensionManagerProps> = ({ open, onClose
|
||||
</InputAdornment>
|
||||
),
|
||||
className: 'text-sm',
|
||||
sx: { color: '#fff', bgcolor: 'rgba(0,0,0,0.2)', height: 32 }
|
||||
sx: { color: 'white', bgcolor: 'var(--color-bg-medium)', height: 32 }
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
@@ -223,7 +223,7 @@ const PhpExtensionManager: React.FC<PhpExtensionManagerProps> = ({ open, onClose
|
||||
<ListItem
|
||||
key={ext.name}
|
||||
divider
|
||||
sx={{ borderColor: 'rgba(255,255,255,0.03)', py: 0.5 }}
|
||||
sx={{ borderColor: 'var(--color-border-soft)', py: 0.5 }}
|
||||
secondaryAction={
|
||||
saving === ext.name ? (
|
||||
<CircularProgress size={16} />
|
||||
@@ -254,7 +254,7 @@ const PhpExtensionManager: React.FC<PhpExtensionManagerProps> = ({ open, onClose
|
||||
</List>
|
||||
)}
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ p: 1.5, bgcolor: 'rgba(255,255,255,0.01)' }}>
|
||||
<DialogActions sx={{ p: 1.5, bgcolor: 'var(--color-bg-soft)' }}>
|
||||
<Button onClick={fetchExtensions} size="small" startIcon={<RefreshIcon sx={{ fontSize: 'var(--font-size-md)' }} />} className="text-xs" sx={{ mr: 'auto' }}>
|
||||
{t('common.refresh').toUpperCase()}
|
||||
</Button>
|
||||
@@ -276,7 +276,7 @@ const PhpExtensionManager: React.FC<PhpExtensionManagerProps> = ({ open, onClose
|
||||
<DialogTitle sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, p: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Typography variant="subtitle2" className="font-black">{t('php.extensions.ini_edit', { version: phpVersion })}</Typography>
|
||||
<IconButton onClick={() => setIsRawEditorOpen(false)} size="small" sx={{ color: 'rgba(255,255,255,0.5)' }}>
|
||||
<IconButton onClick={() => setIsRawEditorOpen(false)} size="small" sx={{ color: 'var(--color-text-tertiary)' }}>
|
||||
<CloseIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
@@ -311,21 +311,21 @@ const PhpExtensionManager: React.FC<PhpExtensionManagerProps> = ({ open, onClose
|
||||
),
|
||||
className: 'text-sm',
|
||||
sx: {
|
||||
color: '#fff',
|
||||
bgcolor: 'rgba(255,255,255,0.03)',
|
||||
color: 'white',
|
||||
bgcolor: 'var(--color-bg-soft)',
|
||||
height: 32,
|
||||
'& fieldset': { borderColor: 'var(--color-border-soft)' }
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<DialogContent sx={{ p: 0, minHeight: 350, borderTop: '1px solid rgba(255,255,255,0.05)' }}>
|
||||
<DialogContent sx={{ p: 0, minHeight: 350, borderTop: '1px solid var(--color-border-soft)' }}>
|
||||
<PhpIniCodeEditor
|
||||
value={rawConfig}
|
||||
onChange={setRawConfig}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ p: 1.5, bgcolor: 'rgba(0,0,0,0.1)' }}>
|
||||
<DialogActions sx={{ p: 1.5, bgcolor: 'var(--color-bg-medium)' }}>
|
||||
<Button onClick={() => setIsRawEditorOpen(false)} size="small" className="text-secondary text-xs">
|
||||
{t('common.cancel').toUpperCase()}
|
||||
</Button>
|
||||
|
||||
@@ -135,11 +135,11 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
renderCell: (params) => {
|
||||
const status = params.value as string
|
||||
return status === 'success' ? (
|
||||
<SuccessIcon sx={{ color: 'success.main', fontSize: 'var(--font-size-md)' }} />
|
||||
<SuccessIcon sx={{ color: 'var(--color-success)', fontSize: 'var(--font-size-md)' }} />
|
||||
) : status === 'failure' ? (
|
||||
<ErrorIcon sx={{ color: 'error.main', fontSize: 'var(--font-size-md)' }} />
|
||||
<ErrorIcon sx={{ color: 'var(--color-error)', fontSize: 'var(--font-size-md)' }} />
|
||||
) : (
|
||||
<InfoIcon sx={{ color: 'info.main', fontSize: 'var(--font-size-md)' }} />
|
||||
<InfoIcon sx={{ color: 'var(--color-primary)', fontSize: 'var(--font-size-md)' }} />
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -160,7 +160,7 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
return (
|
||||
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column', bgcolor: 'var(--color-bg-dark)', color: 'var(--color-text-primary)' }}>
|
||||
{/* Header */}
|
||||
<Box sx={{ p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between', borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
|
||||
<Box sx={{ p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between', borderBottom: '1px solid var(--color-border-soft)' }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
|
||||
<HistoryIcon color="primary" />
|
||||
<Box>
|
||||
@@ -176,7 +176,7 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
<IconButton onClick={fetchEvents} size="small" sx={{ color: 'rgba(255,255,255,0.5)' }}>
|
||||
<RefreshIcon fontSize="small" />
|
||||
</IconButton>
|
||||
<IconButton onClick={handleClear} size="small" sx={{ color: '#f44336' }}>
|
||||
<IconButton onClick={handleClear} size="small" sx={{ color: 'var(--color-error)' }}>
|
||||
<ClearIcon fontSize="small" />
|
||||
</IconButton>
|
||||
{onClose && (
|
||||
@@ -194,7 +194,7 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
<CircularProgress size={30} />
|
||||
</Box>
|
||||
) : events.length === 0 ? (
|
||||
<Alert severity="info" sx={{ bgcolor: 'rgba(2, 136, 209, 0.05)', color: 'info.light' }}>
|
||||
<Alert severity="info" sx={{ bgcolor: 'var(--color-primary-soft)', color: 'var(--color-primary)' }}>
|
||||
{t('service_monitor.no_events')}
|
||||
</Alert>
|
||||
) : (
|
||||
@@ -209,9 +209,9 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
dataset={chartData}
|
||||
xAxis={[{ scaleType: 'band', dataKey: 'service' }]}
|
||||
series={[
|
||||
{ dataKey: 'start', label: t('common.start'), color: '#4caf50' },
|
||||
{ dataKey: 'stop', label: t('common.stop'), color: '#f44336' },
|
||||
{ dataKey: 'error', label: t('common.error'), color: '#ff9800' }
|
||||
{ dataKey: 'start', label: t('common.start'), color: 'var(--color-success)' },
|
||||
{ dataKey: 'stop', label: t('common.stop'), color: 'var(--color-error)' },
|
||||
{ dataKey: 'error', label: t('common.error'), color: 'var(--color-warning)' }
|
||||
]}
|
||||
slotProps={{
|
||||
legend: {
|
||||
@@ -221,10 +221,10 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
}}
|
||||
margin={{ top: 10, bottom: 50, left: 30, right: 10 }}
|
||||
sx={{
|
||||
'& .MuiChartsAxis-left .MuiChartsAxis-tickLabel': { fill: 'rgba(255,255,255,0.3)' },
|
||||
'& .MuiChartsAxis-bottom .MuiChartsAxis-tickLabel': { fill: 'rgba(255,255,255,0.3)', fontSize: 10 },
|
||||
'& .MuiChartsAxis-line': { stroke: 'rgba(255,255,255,0.1)' },
|
||||
'& .MuiChartsAxis-tick': { stroke: 'rgba(255,255,255,0.1)' }
|
||||
'& .MuiChartsAxis-left .MuiChartsAxis-tickLabel': { fill: 'var(--color-text-muted)' },
|
||||
'& .MuiChartsAxis-bottom .MuiChartsAxis-tickLabel': { fill: 'var(--color-text-muted)', fontSize: 10 },
|
||||
'& .MuiChartsAxis-line': { stroke: 'var(--color-border-soft)' },
|
||||
'& .MuiChartsAxis-tick': { stroke: 'var(--color-border-soft)' }
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
@@ -242,7 +242,7 @@ export default function ServiceEventMonitor({ onClose }: { onClose?: () => void
|
||||
border: 'none',
|
||||
color: 'var(--color-text-primary)',
|
||||
'& .MuiDataGrid-cell': { borderBottom: '1px solid var(--color-border-soft)', fontSize: 'var(--font-size-xs)' },
|
||||
'& .MuiDataGrid-columnHeaders': { bgcolor: 'rgba(255,255,255,0.03)', borderBottom: '1px solid var(--color-border-medium)' },
|
||||
'& .MuiDataGrid-columnHeaders': { bgcolor: 'var(--color-bg-soft)', borderBottom: '1px solid var(--color-border-medium)' },
|
||||
'& .MuiDataGrid-columnHeaderTitle': { fontWeight: 'bold', fontSize: 'var(--font-size-xs)', opacity: 0.5 },
|
||||
'& .MuiDataGrid-virtualScroller': { bgcolor: 'transparent' },
|
||||
'& .MuiDataGrid-footerContainer': { borderTop: '1px solid var(--color-border-soft)' }
|
||||
|
||||
Reference in New Issue
Block a user