@qwickapps/server 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +13 -116
  3. package/dist/src/core/control-panel.d.ts.map +1 -1
  4. package/dist/src/core/control-panel.js +6 -4
  5. package/dist/src/core/control-panel.js.map +1 -1
  6. package/dist/src/core/gateway.d.ts.map +1 -1
  7. package/dist/src/core/gateway.js +24 -2
  8. package/dist/src/core/gateway.js.map +1 -1
  9. package/dist/src/core/plugin-registry.d.ts +15 -2
  10. package/dist/src/core/plugin-registry.d.ts.map +1 -1
  11. package/dist/src/core/plugin-registry.js.map +1 -1
  12. package/dist/src/index.d.ts +2 -2
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +9 -3
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/plugins/api-keys/stores/postgres-store.d.ts.map +1 -1
  17. package/dist/src/plugins/api-keys/stores/postgres-store.js +29 -0
  18. package/dist/src/plugins/api-keys/stores/postgres-store.js.map +1 -1
  19. package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
  20. package/dist/src/plugins/auth/auth-plugin.js +4 -2
  21. package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
  22. package/dist/src/plugins/auth/env-config.d.ts.map +1 -1
  23. package/dist/src/plugins/auth/env-config.js +1 -0
  24. package/dist/src/plugins/auth/env-config.js.map +1 -1
  25. package/dist/src/plugins/bans/index.d.ts +1 -1
  26. package/dist/src/plugins/bans/index.d.ts.map +1 -1
  27. package/dist/src/plugins/bans/index.js +1 -1
  28. package/dist/src/plugins/bans/index.js.map +1 -1
  29. package/dist/src/plugins/bans/stores/in-memory-store.d.ts +34 -0
  30. package/dist/src/plugins/bans/stores/in-memory-store.d.ts.map +1 -0
  31. package/dist/src/plugins/bans/stores/in-memory-store.js +97 -0
  32. package/dist/src/plugins/bans/stores/in-memory-store.js.map +1 -0
  33. package/dist/src/plugins/bans/stores/index.d.ts +1 -0
  34. package/dist/src/plugins/bans/stores/index.d.ts.map +1 -1
  35. package/dist/src/plugins/bans/stores/index.js +1 -0
  36. package/dist/src/plugins/bans/stores/index.js.map +1 -1
  37. package/dist/src/plugins/cache-plugin.d.ts +35 -16
  38. package/dist/src/plugins/cache-plugin.d.ts.map +1 -1
  39. package/dist/src/plugins/cache-plugin.js +299 -20
  40. package/dist/src/plugins/cache-plugin.js.map +1 -1
  41. package/dist/src/plugins/cms/cms-plugin.d.ts.map +1 -1
  42. package/dist/src/plugins/cms/cms-plugin.js +3 -1
  43. package/dist/src/plugins/cms/cms-plugin.js.map +1 -1
  44. package/dist/src/plugins/entitlements/index.d.ts +1 -1
  45. package/dist/src/plugins/entitlements/index.d.ts.map +1 -1
  46. package/dist/src/plugins/entitlements/index.js +1 -1
  47. package/dist/src/plugins/entitlements/index.js.map +1 -1
  48. package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts +9 -0
  49. package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts.map +1 -0
  50. package/dist/src/plugins/entitlements/sources/in-memory-source.js +65 -0
  51. package/dist/src/plugins/entitlements/sources/in-memory-source.js.map +1 -0
  52. package/dist/src/plugins/entitlements/sources/index.d.ts +1 -0
  53. package/dist/src/plugins/entitlements/sources/index.d.ts.map +1 -1
  54. package/dist/src/plugins/entitlements/sources/index.js +1 -0
  55. package/dist/src/plugins/entitlements/sources/index.js.map +1 -1
  56. package/dist/src/plugins/health-plugin.d.ts.map +1 -1
  57. package/dist/src/plugins/health-plugin.js +1 -0
  58. package/dist/src/plugins/health-plugin.js.map +1 -1
  59. package/dist/src/plugins/index.d.ts +4 -4
  60. package/dist/src/plugins/index.d.ts.map +1 -1
  61. package/dist/src/plugins/index.js +4 -4
  62. package/dist/src/plugins/index.js.map +1 -1
  63. package/dist/src/plugins/logs-plugin.d.ts.map +1 -1
  64. package/dist/src/plugins/logs-plugin.js +49 -1
  65. package/dist/src/plugins/logs-plugin.js.map +1 -1
  66. package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
  67. package/dist/src/plugins/maintenance-plugin.js +39 -0
  68. package/dist/src/plugins/maintenance-plugin.js.map +1 -1
  69. package/dist/src/plugins/notifications/notifications-plugin.d.ts.map +1 -1
  70. package/dist/src/plugins/notifications/notifications-plugin.js +1 -0
  71. package/dist/src/plugins/notifications/notifications-plugin.js.map +1 -1
  72. package/dist/src/plugins/postgres-plugin.d.ts +3 -1
  73. package/dist/src/plugins/postgres-plugin.d.ts.map +1 -1
  74. package/dist/src/plugins/postgres-plugin.js +18 -8
  75. package/dist/src/plugins/postgres-plugin.js.map +1 -1
  76. package/dist/src/plugins/tenants/index.d.ts +1 -1
  77. package/dist/src/plugins/tenants/index.d.ts.map +1 -1
  78. package/dist/src/plugins/tenants/index.js +1 -1
  79. package/dist/src/plugins/tenants/index.js.map +1 -1
  80. package/dist/src/plugins/tenants/stores/in-memory-store.d.ts +59 -0
  81. package/dist/src/plugins/tenants/stores/in-memory-store.d.ts.map +1 -0
  82. package/dist/src/plugins/tenants/stores/in-memory-store.js +257 -0
  83. package/dist/src/plugins/tenants/stores/in-memory-store.js.map +1 -0
  84. package/dist/src/plugins/tenants/stores/index.d.ts +8 -0
  85. package/dist/src/plugins/tenants/stores/index.d.ts.map +1 -0
  86. package/dist/src/plugins/tenants/stores/index.js +8 -0
  87. package/dist/src/plugins/tenants/stores/index.js.map +1 -0
  88. package/dist/src/plugins/tenants/tenants-plugin.js +3 -3
  89. package/dist/src/plugins/tenants/tenants-plugin.js.map +1 -1
  90. package/dist/src/plugins/users/index.d.ts +1 -1
  91. package/dist/src/plugins/users/index.d.ts.map +1 -1
  92. package/dist/src/plugins/users/index.js +1 -1
  93. package/dist/src/plugins/users/index.js.map +1 -1
  94. package/dist/src/plugins/users/stores/in-memory-store.d.ts +36 -0
  95. package/dist/src/plugins/users/stores/in-memory-store.d.ts.map +1 -0
  96. package/dist/src/plugins/users/stores/in-memory-store.js +122 -0
  97. package/dist/src/plugins/users/stores/in-memory-store.js.map +1 -0
  98. package/dist/src/plugins/users/stores/index.d.ts +1 -0
  99. package/dist/src/plugins/users/stores/index.d.ts.map +1 -1
  100. package/dist/src/plugins/users/stores/index.js +1 -0
  101. package/dist/src/plugins/users/stores/index.js.map +1 -1
  102. package/dist/ui/src/api/controlPanelApi.d.ts +10 -1
  103. package/dist/ui/src/api/controlPanelApi.d.ts.map +1 -1
  104. package/dist/ui/src/api/controlPanelApi.js.map +1 -1
  105. package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
  106. package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts.map +1 -1
  107. package/dist/ui/src/dashboard/PluginWidgetRenderer.js +5 -1
  108. package/dist/ui/src/dashboard/PluginWidgetRenderer.js.map +1 -1
  109. package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
  110. package/dist/ui/src/dashboard/builtInWidgets.js +13 -1
  111. package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
  112. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +11 -0
  113. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts.map +1 -0
  114. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +77 -0
  115. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -0
  116. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts +10 -0
  117. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts.map +1 -0
  118. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js +14 -0
  119. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js.map +1 -0
  120. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +10 -0
  121. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts.map +1 -0
  122. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js +14 -0
  123. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js.map +1 -0
  124. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +11 -0
  125. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts.map +1 -0
  126. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +96 -0
  127. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -0
  128. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts +10 -0
  129. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts.map +1 -0
  130. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +55 -0
  131. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -0
  132. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts +10 -0
  133. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts.map +1 -0
  134. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js +14 -0
  135. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js.map +1 -0
  136. package/dist/ui/src/dashboard/widgets/index.d.ts +6 -0
  137. package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
  138. package/dist/ui/src/dashboard/widgets/index.js +6 -0
  139. package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
  140. package/dist/ui/src/pages/DashboardPage.js +1 -1
  141. package/dist/ui/src/pages/DashboardPage.js.map +1 -1
  142. package/dist-ui/assets/{index-lm1yX6UD.js → index-8y0jDGcd.js} +112 -112
  143. package/dist-ui/assets/{index-lm1yX6UD.js.map → index-8y0jDGcd.js.map} +1 -1
  144. package/dist-ui/index.html +1 -1
  145. package/dist-ui-lib/index.js +3109 -2774
  146. package/dist-ui-lib/index.js.map +1 -1
  147. package/dist-ui-lib/src/api/controlPanelApi.d.ts +10 -1
  148. package/dist-ui-lib/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
  149. package/dist-ui-lib/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +10 -0
  150. package/dist-ui-lib/src/dashboard/widgets/DatabaseOpsWidget.d.ts +9 -0
  151. package/dist-ui-lib/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +9 -0
  152. package/dist-ui-lib/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +10 -0
  153. package/dist-ui-lib/src/dashboard/widgets/SeedManagementWidget.d.ts +9 -0
  154. package/dist-ui-lib/src/dashboard/widgets/ServiceControlWidget.d.ts +9 -0
  155. package/dist-ui-lib/src/dashboard/widgets/index.d.ts +6 -0
  156. package/package.json +5 -2
  157. package/src/core/control-panel.ts +6 -4
  158. package/src/core/gateway.ts +25 -2
  159. package/src/core/plugin-registry.ts +15 -2
  160. package/src/index.ts +53 -0
  161. package/src/plugins/api-keys/stores/postgres-store.ts +30 -0
  162. package/src/plugins/auth/auth-plugin.ts +4 -2
  163. package/src/plugins/auth/env-config.ts +1 -0
  164. package/src/plugins/bans/index.ts +1 -1
  165. package/src/plugins/bans/stores/in-memory-store.ts +106 -0
  166. package/src/plugins/bans/stores/index.ts +1 -0
  167. package/src/plugins/cache-plugin.test.ts +2 -2
  168. package/src/plugins/cache-plugin.ts +331 -30
  169. package/src/plugins/cms/cms-plugin.ts +3 -1
  170. package/src/plugins/entitlements/index.ts +1 -1
  171. package/src/plugins/entitlements/sources/in-memory-source.ts +76 -0
  172. package/src/plugins/entitlements/sources/index.ts +1 -0
  173. package/src/plugins/health-plugin.ts +1 -0
  174. package/src/plugins/index.ts +4 -1
  175. package/src/plugins/logs-plugin.ts +55 -1
  176. package/src/plugins/maintenance-plugin.ts +43 -0
  177. package/src/plugins/notifications/notifications-plugin.ts +1 -0
  178. package/src/plugins/postgres-plugin.test.ts +2 -2
  179. package/src/plugins/postgres-plugin.ts +20 -9
  180. package/src/plugins/tenants/index.ts +1 -1
  181. package/src/plugins/tenants/stores/in-memory-store.ts +335 -0
  182. package/src/plugins/tenants/stores/index.ts +13 -0
  183. package/src/plugins/tenants/tenants-plugin.ts +3 -3
  184. package/src/plugins/users/index.ts +1 -1
  185. package/src/plugins/users/stores/in-memory-store.ts +140 -0
  186. package/src/plugins/users/stores/index.ts +1 -0
  187. package/src/testing/index.ts +1 -0
  188. package/src/testing/pg-mem-pool.ts +33 -0
  189. package/ui/src/api/controlPanelApi.ts +10 -1
  190. package/ui/src/dashboard/PluginWidgetRenderer.tsx +8 -0
  191. package/ui/src/dashboard/builtInWidgets.tsx +19 -1
  192. package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +195 -0
  193. package/ui/src/dashboard/widgets/DatabaseOpsWidget.tsx +29 -0
  194. package/ui/src/dashboard/widgets/EnvironmentConfigWidget.tsx +29 -0
  195. package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +247 -0
  196. package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +128 -0
  197. package/ui/src/dashboard/widgets/ServiceControlWidget.tsx +29 -0
  198. package/ui/src/dashboard/widgets/index.ts +6 -0
  199. package/ui/src/pages/DashboardPage.tsx +2 -2
  200. package/ui/src/pages/MaintenancePage.tsx +1 -1
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Logs Maintenance Widget
3
+ *
4
+ * Provides log management operations:
5
+ * - View log statistics
6
+ * - Clear log files
7
+ *
8
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
9
+ */
10
+
11
+ import { useState, useEffect } from 'react';
12
+ import {
13
+ Card,
14
+ CardContent,
15
+ Typography,
16
+ Button,
17
+ Alert,
18
+ Box,
19
+ Select,
20
+ MenuItem,
21
+ FormControl,
22
+ InputLabel,
23
+ Dialog,
24
+ DialogTitle,
25
+ DialogContent,
26
+ DialogContentText,
27
+ DialogActions,
28
+ CircularProgress,
29
+ } from '@mui/material';
30
+ import DeleteIcon from '@mui/icons-material/Delete';
31
+ import RefreshIcon from '@mui/icons-material/Refresh';
32
+
33
+ interface LogSource {
34
+ name: string;
35
+ type: string;
36
+ }
37
+
38
+ interface LogStats {
39
+ totalLogs: number;
40
+ byLevel: {
41
+ debug: number;
42
+ info: number;
43
+ warn: number;
44
+ error: number;
45
+ };
46
+ fileSize: number;
47
+ fileSizeFormatted: string;
48
+ oldestLog: string | null;
49
+ newestLog: string | null;
50
+ }
51
+
52
+ export function LogsMaintenanceWidget() {
53
+ const [sources, setSources] = useState<LogSource[]>([]);
54
+ const [selectedSource, setSelectedSource] = useState<string>('');
55
+ const [stats, setStats] = useState<LogStats | null>(null);
56
+ const [loading, setLoading] = useState(true);
57
+ const [clearing, setClearing] = useState(false);
58
+ const [error, setError] = useState<string | null>(null);
59
+ const [success, setSuccess] = useState<string | null>(null);
60
+ const [confirmOpen, setConfirmOpen] = useState(false);
61
+
62
+ const fetchSources = async () => {
63
+ try {
64
+ const response = await fetch('/api/logs/sources');
65
+ if (!response.ok) throw new Error('Failed to fetch log sources');
66
+ const data = await response.json();
67
+ setSources(data.sources || []);
68
+ if (data.sources && data.sources.length > 0 && !selectedSource) {
69
+ setSelectedSource(data.sources[0].name);
70
+ }
71
+ } catch (err) {
72
+ setError(err instanceof Error ? err.message : 'Failed to fetch log sources');
73
+ }
74
+ };
75
+
76
+ const fetchStats = async () => {
77
+ if (!selectedSource) return;
78
+
79
+ setLoading(true);
80
+ setError(null);
81
+ try {
82
+ const response = await fetch(`/api/logs/stats?source=${selectedSource}`);
83
+ if (!response.ok) throw new Error('Failed to fetch log stats');
84
+ const data = await response.json();
85
+ setStats(data);
86
+ } catch (err) {
87
+ setError(err instanceof Error ? err.message : 'Failed to fetch log stats');
88
+ setStats(null);
89
+ } finally {
90
+ setLoading(false);
91
+ }
92
+ };
93
+
94
+ useEffect(() => {
95
+ fetchSources();
96
+ }, []);
97
+
98
+ useEffect(() => {
99
+ if (selectedSource) {
100
+ fetchStats();
101
+ }
102
+ }, [selectedSource]);
103
+
104
+ const handleClearLogs = async () => {
105
+ setConfirmOpen(false);
106
+ setClearing(true);
107
+ setError(null);
108
+ setSuccess(null);
109
+
110
+ try {
111
+ const response = await fetch('/api/logs/clear', {
112
+ method: 'POST',
113
+ headers: { 'Content-Type': 'application/json' },
114
+ body: JSON.stringify({ source: selectedSource }),
115
+ });
116
+
117
+ if (!response.ok) {
118
+ const data = await response.json();
119
+ throw new Error(data.error || 'Failed to clear logs');
120
+ }
121
+
122
+ const data = await response.json();
123
+ setSuccess(data.message || 'Logs cleared successfully');
124
+
125
+ // Refresh stats
126
+ await fetchStats();
127
+ } catch (err) {
128
+ setError(err instanceof Error ? err.message : 'Failed to clear logs');
129
+ } finally {
130
+ setClearing(false);
131
+ }
132
+ };
133
+
134
+ return (
135
+ <Card>
136
+ <CardContent>
137
+ <Typography variant="h6" gutterBottom>
138
+ Log Management
139
+ </Typography>
140
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
141
+ View log statistics and clear log files
142
+ </Typography>
143
+
144
+ {error && (
145
+ <Alert severity="error" sx={{ mb: 2 }} onClose={() => setError(null)}>
146
+ {error}
147
+ </Alert>
148
+ )}
149
+
150
+ {success && (
151
+ <Alert severity="success" sx={{ mb: 2 }} onClose={() => setSuccess(null)}>
152
+ {success}
153
+ </Alert>
154
+ )}
155
+
156
+ <Box sx={{ mb: 2 }}>
157
+ <FormControl fullWidth size="small">
158
+ <InputLabel>Log Source</InputLabel>
159
+ <Select
160
+ value={selectedSource}
161
+ label="Log Source"
162
+ onChange={(e) => setSelectedSource(e.target.value)}
163
+ disabled={sources.length === 0}
164
+ >
165
+ {sources.map((source) => (
166
+ <MenuItem key={source.name} value={source.name}>
167
+ {source.name} ({source.type})
168
+ </MenuItem>
169
+ ))}
170
+ </Select>
171
+ </FormControl>
172
+ </Box>
173
+
174
+ {loading ? (
175
+ <Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
176
+ <CircularProgress size={30} />
177
+ </Box>
178
+ ) : stats ? (
179
+ <Box sx={{ mb: 2 }}>
180
+ <Typography variant="body2" color="text.secondary">
181
+ <strong>Total Logs:</strong> {stats.totalLogs.toLocaleString()}
182
+ </Typography>
183
+ <Typography variant="body2" color="text.secondary">
184
+ <strong>File Size:</strong> {stats.fileSizeFormatted}
185
+ </Typography>
186
+ <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
187
+ <strong>By Level:</strong>
188
+ </Typography>
189
+ <Box sx={{ pl: 2 }}>
190
+ <Typography variant="body2" color="text.secondary">
191
+ Debug: {stats.byLevel.debug.toLocaleString()}
192
+ </Typography>
193
+ <Typography variant="body2" color="text.secondary">
194
+ Info: {stats.byLevel.info.toLocaleString()}
195
+ </Typography>
196
+ <Typography variant="body2" color="text.secondary">
197
+ Warn: {stats.byLevel.warn.toLocaleString()}
198
+ </Typography>
199
+ <Typography variant="body2" color="error">
200
+ Error: {stats.byLevel.error.toLocaleString()}
201
+ </Typography>
202
+ </Box>
203
+ </Box>
204
+ ) : null}
205
+
206
+ <Box sx={{ display: 'flex', gap: 1 }}>
207
+ <Button
208
+ variant="outlined"
209
+ color="primary"
210
+ size="small"
211
+ startIcon={<RefreshIcon />}
212
+ onClick={fetchStats}
213
+ disabled={!selectedSource || loading}
214
+ >
215
+ Refresh
216
+ </Button>
217
+ <Button
218
+ variant="contained"
219
+ color="error"
220
+ size="small"
221
+ startIcon={clearing ? <CircularProgress size={16} color="inherit" /> : <DeleteIcon />}
222
+ onClick={() => setConfirmOpen(true)}
223
+ disabled={!selectedSource || clearing || loading}
224
+ >
225
+ Clear Logs
226
+ </Button>
227
+ </Box>
228
+
229
+ <Dialog open={confirmOpen} onClose={() => setConfirmOpen(false)}>
230
+ <DialogTitle>Clear Log File</DialogTitle>
231
+ <DialogContent>
232
+ <DialogContentText>
233
+ Are you sure you want to clear the "{selectedSource}" log file? This action cannot
234
+ be undone.
235
+ </DialogContentText>
236
+ </DialogContent>
237
+ <DialogActions>
238
+ <Button onClick={() => setConfirmOpen(false)}>Cancel</Button>
239
+ <Button onClick={handleClearLogs} color="error" variant="contained">
240
+ Clear
241
+ </Button>
242
+ </DialogActions>
243
+ </Dialog>
244
+ </CardContent>
245
+ </Card>
246
+ );
247
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Seed Management Widget
3
+ *
4
+ * Displays available seed scripts and allows executing them.
5
+ * Part of the maintenance plugin.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import { useState, useEffect } from 'react';
11
+ import {
12
+ Card,
13
+ CardContent,
14
+ Typography,
15
+ Button,
16
+ List,
17
+ ListItem,
18
+ ListItemText,
19
+ CircularProgress,
20
+ Alert,
21
+ Box,
22
+ } from '@mui/material';
23
+ import PlayArrowIcon from '@mui/icons-material/PlayArrow';
24
+
25
+ interface SeedScript {
26
+ name: string;
27
+ path: string;
28
+ size: number;
29
+ createdAt: string;
30
+ modifiedAt: string;
31
+ }
32
+
33
+ export function SeedManagementWidget() {
34
+ const [seeds, setSeeds] = useState<SeedScript[]>([]);
35
+ const [loading, setLoading] = useState(true);
36
+ const [error, setError] = useState<string | null>(null);
37
+ const [executing, setExecuting] = useState<string | null>(null);
38
+
39
+ useEffect(() => {
40
+ fetchSeeds();
41
+ }, []);
42
+
43
+ const fetchSeeds = async () => {
44
+ try {
45
+ // TODO: Add proper API endpoint for seed discovery
46
+ // const response = await api.get('/maintenance/seeds/discover');
47
+ // setSeeds(response.seeds || []);
48
+ setSeeds([]);
49
+ setError(null);
50
+ } catch (err) {
51
+ setError(err instanceof Error ? err.message : 'Failed to fetch seeds');
52
+ } finally {
53
+ setLoading(false);
54
+ }
55
+ };
56
+
57
+ const executeSeed = async (seedName: string) => {
58
+ setExecuting(seedName);
59
+ try {
60
+ // TODO: Add proper API endpoint for seed execution
61
+ // await api.post(`/maintenance/seeds/execute`, { name: seedName });
62
+ alert(`Seed ${seedName} executed successfully`);
63
+ } catch (err) {
64
+ alert(`Failed to execute seed: ${err instanceof Error ? err.message : 'Unknown error'}`);
65
+ } finally {
66
+ setExecuting(null);
67
+ }
68
+ };
69
+
70
+ if (loading) {
71
+ return (
72
+ <Card>
73
+ <CardContent>
74
+ <Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
75
+ <CircularProgress size={24} />
76
+ </Box>
77
+ </CardContent>
78
+ </Card>
79
+ );
80
+ }
81
+
82
+ return (
83
+ <Card>
84
+ <CardContent>
85
+ <Typography variant="h6" gutterBottom>
86
+ Seed Management
87
+ </Typography>
88
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
89
+ Manage and execute seed scripts
90
+ </Typography>
91
+
92
+ {error && (
93
+ <Alert severity="error" sx={{ mb: 2 }}>
94
+ {error}
95
+ </Alert>
96
+ )}
97
+
98
+ {seeds.length === 0 ? (
99
+ <Alert severity="info">No seed scripts found</Alert>
100
+ ) : (
101
+ <List>
102
+ {seeds.map((seed) => (
103
+ <ListItem
104
+ key={seed.name}
105
+ secondaryAction={
106
+ <Button
107
+ variant="contained"
108
+ size="small"
109
+ startIcon={executing === seed.name ? <CircularProgress size={16} /> : <PlayArrowIcon />}
110
+ onClick={() => executeSeed(seed.name)}
111
+ disabled={executing !== null}
112
+ >
113
+ Execute
114
+ </Button>
115
+ }
116
+ >
117
+ <ListItemText
118
+ primary={seed.name}
119
+ secondary={`Modified: ${new Date(seed.modifiedAt).toLocaleDateString()}`}
120
+ />
121
+ </ListItem>
122
+ ))}
123
+ </List>
124
+ )}
125
+ </CardContent>
126
+ </Card>
127
+ );
128
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Service Control Widget
3
+ *
4
+ * Provides controls for starting, stopping, and restarting services.
5
+ * Part of the maintenance plugin.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import { Card, CardContent, Typography, Alert } from '@mui/material';
11
+
12
+ export function ServiceControlWidget() {
13
+ return (
14
+ <Card>
15
+ <CardContent>
16
+ <Typography variant="h6" gutterBottom>
17
+ Service Control
18
+ </Typography>
19
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
20
+ Start, stop, and restart services
21
+ </Typography>
22
+
23
+ <Alert severity="info">
24
+ Service control functionality coming soon. This will allow you to manage service lifecycle.
25
+ </Alert>
26
+ </CardContent>
27
+ </Card>
28
+ );
29
+ }
@@ -10,3 +10,9 @@ export { AuthStatusWidget } from './AuthStatusWidget';
10
10
  export { NotificationsStatsWidget } from './NotificationsStatsWidget';
11
11
  export { CMSStatusWidget } from './CMSStatusWidget';
12
12
  export { CMSMaintenanceWidget } from './CMSMaintenanceWidget';
13
+ export { SeedManagementWidget } from './SeedManagementWidget';
14
+ export { ServiceControlWidget } from './ServiceControlWidget';
15
+ export { EnvironmentConfigWidget } from './EnvironmentConfigWidget';
16
+ export { DatabaseOpsWidget } from './DatabaseOpsWidget';
17
+ export { LogsMaintenanceWidget } from './LogsMaintenanceWidget';
18
+ export { CacheMaintenanceWidget } from './CacheMaintenanceWidget';
@@ -133,8 +133,8 @@ export function DashboardPage() {
133
133
  </CardActionArea>
134
134
  </Card>
135
135
 
136
- {/* Plugin widgets (from server-side widget contributions) */}
137
- <PluginWidgetRenderer />
136
+ {/* Plugin widgets (from server-side widget contributions) - status widgets only */}
137
+ <PluginWidgetRenderer widgetType="status" />
138
138
 
139
139
  {/* Legacy widgets from context (for backwards compatibility) */}
140
140
  <DashboardWidgetRenderer />
@@ -21,7 +21,7 @@ export function MaintenancePage() {
21
21
  </Typography>
22
22
 
23
23
  {/* Render all maintenance widgets from plugins */}
24
- <PluginWidgetRenderer defaultOnly={false} />
24
+ <PluginWidgetRenderer widgetType="maintenance" defaultOnly={true} />
25
25
  </Box>
26
26
  );
27
27
  }