@gravito/zenith 1.1.2 → 1.1.3
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.
- package/CHANGELOG.md +15 -0
- package/README.md +77 -22
- package/README.zh-TW.md +88 -0
- package/dist/bin.js +64681 -15842
- package/dist/client/assets/index-C80c1frR.css +1 -0
- package/dist/client/assets/index-CrWem9u3.js +434 -0
- package/dist/server/index.js +64681 -15842
- package/package.json +9 -7
- package/postcss.config.js +4 -4
- package/src/client/Layout.tsx +36 -39
- package/src/client/Sidebar.tsx +7 -7
- package/src/client/ThroughputChart.tsx +31 -17
- package/src/client/WorkerStatus.tsx +56 -80
- package/src/client/components/ConfirmDialog.tsx +22 -14
- package/src/client/components/JobInspector.tsx +95 -162
- package/src/client/index.css +29 -31
- package/src/client/pages/LoginPage.tsx +33 -31
- package/src/client/pages/MetricsPage.tsx +65 -37
- package/src/client/pages/OverviewPage.tsx +30 -28
- package/src/client/pages/PulsePage.tsx +111 -190
- package/src/client/pages/QueuesPage.tsx +82 -83
- package/src/client/pages/SchedulesPage.tsx +56 -61
- package/src/client/pages/SettingsPage.tsx +118 -137
- package/src/client/pages/WorkersPage.tsx +101 -115
- package/src/server/services/CommandService.ts +8 -9
- package/src/server/services/PulseService.ts +61 -4
- package/src/server/services/QueueService.ts +293 -0
- package/src/shared/types.ts +38 -13
- package/tailwind.config.js +75 -68
- package/tsconfig.json +28 -37
- package/tsconfig.node.json +9 -11
- package/dist/client/assets/index-BSMp8oq_.js +0 -436
- package/dist/client/assets/index-BwxlHx-_.css +0 -1
- package/dist/client/index.html +0 -13
- package/src/client/index.html +0 -12
- /package/{ECOSYSTEM_EXPANSION_RFC.md → doc/ECOSYSTEM_EXPANSION_RFC.md} +0 -0
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
2
2
|
import {
|
|
3
3
|
Bell,
|
|
4
|
-
Clock,
|
|
5
4
|
Database,
|
|
6
5
|
ExternalLink,
|
|
7
6
|
Info,
|
|
8
7
|
Monitor,
|
|
9
8
|
Moon,
|
|
10
9
|
Palette,
|
|
11
|
-
RefreshCcw,
|
|
12
10
|
Server,
|
|
13
11
|
Shield,
|
|
14
12
|
Sun,
|
|
@@ -82,43 +80,48 @@ export function SettingsPage() {
|
|
|
82
80
|
</div>
|
|
83
81
|
|
|
84
82
|
{/* Appearance Section */}
|
|
85
|
-
<section className="card-premium p-6">
|
|
86
|
-
<div className="flex items-center gap-
|
|
87
|
-
<div className="w-
|
|
88
|
-
<Palette size={
|
|
83
|
+
<section className="card-premium p-6 border-l-4 border-primary">
|
|
84
|
+
<div className="flex items-center gap-4 mb-8">
|
|
85
|
+
<div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center text-primary border border-primary/20 shadow-[0_0_15px_rgba(0,240,255,0.1)]">
|
|
86
|
+
<Palette size={24} />
|
|
89
87
|
</div>
|
|
90
88
|
<div>
|
|
91
|
-
<h2 className="text-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
<h2 className="text-xl font-black font-heading tracking-tight">
|
|
90
|
+
Appearance Architecture
|
|
91
|
+
</h2>
|
|
92
|
+
<p className="text-[10px] text-muted-foreground uppercase tracking-[0.2em] font-black opacity-50 mt-0.5">
|
|
93
|
+
Customize Visual Interface
|
|
94
94
|
</p>
|
|
95
95
|
</div>
|
|
96
96
|
</div>
|
|
97
97
|
|
|
98
|
-
<div className="space-y-
|
|
98
|
+
<div className="space-y-6">
|
|
99
99
|
<div>
|
|
100
|
-
<label
|
|
101
|
-
|
|
100
|
+
<label
|
|
101
|
+
htmlFor="theme-select"
|
|
102
|
+
className="text-[10px] font-black uppercase tracking-widest mb-4 block text-muted-foreground ml-1"
|
|
103
|
+
>
|
|
104
|
+
Interface Mode
|
|
102
105
|
</label>
|
|
103
|
-
<div id="theme-select" className="flex gap-
|
|
106
|
+
<div id="theme-select" className="flex gap-4">
|
|
104
107
|
{[
|
|
105
|
-
{ value: 'light', icon: Sun, label: '
|
|
106
|
-
{ value: 'dark', icon: Moon, label: '
|
|
107
|
-
{ value: 'system', icon: Monitor, label: '
|
|
108
|
+
{ value: 'light', icon: Sun, label: 'Standard' },
|
|
109
|
+
{ value: 'dark', icon: Moon, label: 'Quantum' },
|
|
110
|
+
{ value: 'system', icon: Monitor, label: 'Auto' },
|
|
108
111
|
].map(({ value, icon: Icon, label }) => (
|
|
109
112
|
<button
|
|
110
113
|
type="button"
|
|
111
114
|
key={value}
|
|
112
115
|
onClick={() => handleThemeChange(value as 'light' | 'dark' | 'system')}
|
|
113
116
|
className={cn(
|
|
114
|
-
'flex-1 flex items-center justify-center gap-
|
|
117
|
+
'flex-1 flex items-center justify-center gap-3 px-4 py-4 rounded-xl border transition-all font-heading uppercase text-[11px] font-black tracking-widest',
|
|
115
118
|
theme === value
|
|
116
|
-
? 'bg-primary text-primary-
|
|
117
|
-
: 'bg-
|
|
119
|
+
? 'bg-primary text-black border-primary shadow-[0_0_30px_rgba(0,240,255,0.2)] scale-[1.02]'
|
|
120
|
+
: 'bg-zinc-900/40 border-white/5 hover:border-primary/30 text-muted-foreground hover:text-foreground'
|
|
118
121
|
)}
|
|
119
122
|
>
|
|
120
123
|
<Icon size={18} />
|
|
121
|
-
<span
|
|
124
|
+
<span>{label}</span>
|
|
122
125
|
</button>
|
|
123
126
|
))}
|
|
124
127
|
</div>
|
|
@@ -127,119 +130,107 @@ export function SettingsPage() {
|
|
|
127
130
|
</section>
|
|
128
131
|
|
|
129
132
|
{/* Connection Info Section */}
|
|
130
|
-
<section className="card-premium p-6">
|
|
131
|
-
<div className="flex items-center gap-
|
|
132
|
-
<div className="w-
|
|
133
|
-
<Database size={
|
|
133
|
+
<section className="card-premium p-6 border-l-4 border-indigo-500/40">
|
|
134
|
+
<div className="flex items-center gap-4 mb-8">
|
|
135
|
+
<div className="w-12 h-12 rounded-xl bg-indigo-500/10 flex items-center justify-center text-indigo-400 border border-indigo-500/20 shadow-[0_0_15px_rgba(99,102,241,0.1)]">
|
|
136
|
+
<Database size={24} />
|
|
134
137
|
</div>
|
|
135
138
|
<div>
|
|
136
|
-
<h2 className="text-
|
|
137
|
-
<p className="text-[10px] text-muted-foreground uppercase tracking-
|
|
138
|
-
|
|
139
|
+
<h2 className="text-xl font-black font-heading tracking-tight">Quantum Connectivity</h2>
|
|
140
|
+
<p className="text-[10px] text-muted-foreground uppercase tracking-[0.2em] font-black opacity-50 mt-0.5">
|
|
141
|
+
Infrastructure Bridge Status
|
|
139
142
|
</p>
|
|
140
143
|
</div>
|
|
141
144
|
</div>
|
|
142
145
|
|
|
143
|
-
<div className="space-y-
|
|
144
|
-
<div className="flex items-center justify-between py-
|
|
146
|
+
<div className="space-y-2 font-mono">
|
|
147
|
+
<div className="flex items-center justify-between py-4 border-b border-white/5 group">
|
|
145
148
|
<div className="flex items-center gap-3">
|
|
146
|
-
<Server
|
|
147
|
-
|
|
149
|
+
<Server
|
|
150
|
+
size={16}
|
|
151
|
+
className="text-muted-foreground group-hover:text-primary transition-colors"
|
|
152
|
+
/>
|
|
153
|
+
<span className="text-xs font-bold uppercase tracking-widest text-muted-foreground">
|
|
154
|
+
Redis Protocol
|
|
155
|
+
</span>
|
|
148
156
|
</div>
|
|
149
|
-
<div className="flex items-center gap-
|
|
150
|
-
<span className="w-2 h-2 bg-
|
|
151
|
-
<span className="text-
|
|
157
|
+
<div className="flex items-center gap-3">
|
|
158
|
+
<span className="w-2 h-2 bg-emerald-500 rounded-full glow-pulse shadow-[0_0_10px_#10B981]"></span>
|
|
159
|
+
<span className="text-xs font-black text-emerald-500 uppercase tracking-[0.2em]">
|
|
160
|
+
Established
|
|
161
|
+
</span>
|
|
152
162
|
</div>
|
|
153
163
|
</div>
|
|
154
164
|
|
|
155
|
-
<div className="flex items-center justify-between py-
|
|
165
|
+
<div className="flex items-center justify-between py-4 border-b border-white/5 group">
|
|
156
166
|
<div className="flex items-center gap-3">
|
|
157
|
-
<Database
|
|
158
|
-
|
|
167
|
+
<Database
|
|
168
|
+
size={16}
|
|
169
|
+
className="text-muted-foreground group-hover:text-primary transition-colors"
|
|
170
|
+
/>
|
|
171
|
+
<span className="text-xs font-bold uppercase tracking-widest text-muted-foreground">
|
|
172
|
+
Endpoint URI
|
|
173
|
+
</span>
|
|
159
174
|
</div>
|
|
160
|
-
<code className="text-
|
|
175
|
+
<code className="text-[11px] bg-black/40 px-3 py-1.5 rounded-lg border border-white/5 text-primary">
|
|
161
176
|
{systemStatus?.redisUrl || 'redis://localhost:6379'}
|
|
162
177
|
</code>
|
|
163
178
|
</div>
|
|
164
|
-
|
|
165
|
-
<div className="flex items-center justify-between py-3 border-b border-border/30">
|
|
166
|
-
<div className="flex items-center gap-3">
|
|
167
|
-
<Clock size={16} className="text-muted-foreground" />
|
|
168
|
-
<span className="font-medium">Service Uptime</span>
|
|
169
|
-
</div>
|
|
170
|
-
<span className="text-sm font-mono font-bold">
|
|
171
|
-
{systemStatus?.uptime ? formatUptime(systemStatus.uptime) : 'Loading...'}
|
|
172
|
-
</span>
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
<div className="flex items-center justify-between py-3">
|
|
176
|
-
<div className="flex items-center gap-3">
|
|
177
|
-
<RefreshCcw size={16} className="text-muted-foreground" />
|
|
178
|
-
<span className="font-medium">Engine Version</span>
|
|
179
|
-
</div>
|
|
180
|
-
<span className="text-sm font-bold">{systemStatus?.engine || 'Loading...'}</span>
|
|
181
|
-
</div>
|
|
182
179
|
</div>
|
|
183
180
|
</section>
|
|
184
181
|
|
|
185
182
|
{/* System Info Section */}
|
|
186
|
-
<section className="card-premium p-6">
|
|
187
|
-
<div className="flex items-center gap-
|
|
188
|
-
<div className="w-
|
|
189
|
-
<Info size={
|
|
183
|
+
<section className="card-premium p-6 border-l-4 border-emerald-500/40">
|
|
184
|
+
<div className="flex items-center gap-4 mb-8">
|
|
185
|
+
<div className="w-12 h-12 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-400 border border-emerald-500/20 shadow-[0_0_15px_rgba(16,185,129,0.1)]">
|
|
186
|
+
<Info size={24} />
|
|
190
187
|
</div>
|
|
191
188
|
<div>
|
|
192
|
-
<h2 className="text-
|
|
193
|
-
<p className="text-[10px] text-muted-foreground uppercase tracking-
|
|
194
|
-
|
|
189
|
+
<h2 className="text-xl font-black font-heading tracking-tight">Quantum Runtime</h2>
|
|
190
|
+
<p className="text-[10px] text-muted-foreground uppercase tracking-[0.2em] font-black opacity-50 mt-0.5">
|
|
191
|
+
Kernel Environment & Metrics
|
|
195
192
|
</p>
|
|
196
193
|
</div>
|
|
197
194
|
</div>
|
|
198
195
|
|
|
199
|
-
<div className="grid grid-cols-2 gap-4">
|
|
200
|
-
<div className="bg-
|
|
201
|
-
<p className="text-[
|
|
202
|
-
|
|
196
|
+
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
|
197
|
+
<div className="bg-black/40 rounded-xl p-5 border border-white/5 group hover:border-primary/20 transition-all flex flex-col justify-between">
|
|
198
|
+
<p className="text-[9px] font-black text-muted-foreground/40 uppercase tracking-widest mb-2">
|
|
199
|
+
Runtime Engine
|
|
203
200
|
</p>
|
|
204
|
-
<p className="text-lg font-mono font-
|
|
205
|
-
|
|
206
|
-
<div className="bg-muted/20 rounded-xl p-4">
|
|
207
|
-
<p className="text-[10px] font-black text-muted-foreground/50 uppercase tracking-widest mb-1">
|
|
208
|
-
Environment
|
|
201
|
+
<p className="text-lg font-mono font-black text-primary/80">
|
|
202
|
+
{systemStatus?.node || '...'}
|
|
209
203
|
</p>
|
|
210
|
-
<p className="text-lg font-mono font-bold">{systemStatus?.env || '...'}</p>
|
|
211
204
|
</div>
|
|
212
|
-
<div className="bg-
|
|
213
|
-
<p className="text-[
|
|
214
|
-
|
|
205
|
+
<div className="bg-black/40 rounded-xl p-5 border border-white/5 group hover:border-primary/20 transition-all flex flex-col justify-between">
|
|
206
|
+
<p className="text-[9px] font-black text-muted-foreground/40 uppercase tracking-widest mb-2">
|
|
207
|
+
Namespace
|
|
215
208
|
</p>
|
|
216
|
-
<p className="text-
|
|
217
|
-
|
|
218
|
-
<div className="bg-muted/20 rounded-xl p-4">
|
|
219
|
-
<p className="text-[10px] font-black text-muted-foreground/50 uppercase tracking-widest mb-1">
|
|
220
|
-
Heap Used
|
|
209
|
+
<p className="text-sm font-mono font-black text-white/60 uppercase truncate">
|
|
210
|
+
{systemStatus?.env || '...'}
|
|
221
211
|
</p>
|
|
222
|
-
<p className="text-lg font-mono font-bold">{systemStatus?.memory?.heapUsed || '...'}</p>
|
|
223
212
|
</div>
|
|
224
|
-
<div className="bg-
|
|
225
|
-
<p className="text-[
|
|
226
|
-
|
|
213
|
+
<div className="bg-black/40 rounded-xl p-5 border border-white/5 group hover:border-primary/20 transition-all flex flex-col justify-between">
|
|
214
|
+
<p className="text-[9px] font-black text-muted-foreground/40 uppercase tracking-widest mb-2">
|
|
215
|
+
Memory Footprint
|
|
216
|
+
</p>
|
|
217
|
+
<p className="text-lg font-mono font-black text-white/80 tracking-tighter">
|
|
218
|
+
{systemStatus?.memory?.rss || '...'}
|
|
227
219
|
</p>
|
|
228
|
-
<p className="text-lg font-mono font-bold">{systemStatus?.memory?.total || '...'}</p>
|
|
229
220
|
</div>
|
|
230
221
|
</div>
|
|
231
222
|
</section>
|
|
232
223
|
|
|
233
224
|
{/* Alerting Section */}
|
|
234
|
-
<section className="card-premium p-6">
|
|
235
|
-
<div className="flex items-center gap-
|
|
236
|
-
<div className="w-
|
|
237
|
-
<Bell size={
|
|
225
|
+
<section className="card-premium p-6 border-l-4 border-orange-500/60">
|
|
226
|
+
<div className="flex items-center gap-4 mb-8">
|
|
227
|
+
<div className="w-12 h-12 rounded-xl bg-orange-500/10 flex items-center justify-center text-orange-500 border border-orange-500/20 shadow-[0_0_15px_rgba(249,115,22,0.1)]">
|
|
228
|
+
<Bell size={24} />
|
|
238
229
|
</div>
|
|
239
230
|
<div>
|
|
240
|
-
<h2 className="text-
|
|
241
|
-
<p className="text-[10px] text-muted-foreground uppercase tracking-
|
|
242
|
-
|
|
231
|
+
<h2 className="text-xl font-black font-heading tracking-tight">Signal Monitoring</h2>
|
|
232
|
+
<p className="text-[10px] text-muted-foreground uppercase tracking-[0.2em] font-black opacity-50 mt-0.5">
|
|
233
|
+
Automated Incident Alerting
|
|
243
234
|
</p>
|
|
244
235
|
</div>
|
|
245
236
|
</div>
|
|
@@ -247,21 +238,23 @@ export function SettingsPage() {
|
|
|
247
238
|
<div className="space-y-8">
|
|
248
239
|
{/* Notification Channels */}
|
|
249
240
|
<div className="space-y-4">
|
|
250
|
-
<h3 className="text-
|
|
251
|
-
|
|
241
|
+
<h3 className="text-[10px] font-black uppercase tracking-[0.3em] text-muted-foreground/40 mb-4 ml-1">
|
|
242
|
+
Communication Transports
|
|
252
243
|
</h3>
|
|
253
244
|
|
|
254
245
|
{/* Slack */}
|
|
255
|
-
<div className="p-
|
|
256
|
-
<div className="flex items-center justify-between mb-
|
|
257
|
-
<div className="flex items-center gap-
|
|
258
|
-
<div className="w-
|
|
259
|
-
<Bell size={
|
|
246
|
+
<div className="p-5 bg-zinc-900/40 rounded-2xl border border-white/5 group hover:border-primary/20 transition-all">
|
|
247
|
+
<div className="flex items-center justify-between mb-5">
|
|
248
|
+
<div className="flex items-center gap-4">
|
|
249
|
+
<div className="w-10 h-10 rounded-xl bg-white/5 flex items-center justify-center text-white/60 group-hover:text-primary transition-colors">
|
|
250
|
+
<Bell size={18} />
|
|
260
251
|
</div>
|
|
261
252
|
<div>
|
|
262
|
-
<h4 className="text-sm font-
|
|
263
|
-
|
|
264
|
-
|
|
253
|
+
<h4 className="text-sm font-black font-heading text-white tracking-widest uppercase">
|
|
254
|
+
Slack Bridge
|
|
255
|
+
</h4>
|
|
256
|
+
<p className="text-[9px] text-muted-foreground font-bold uppercase tracking-tighter opacity-40">
|
|
257
|
+
Standard Event Webhook
|
|
265
258
|
</p>
|
|
266
259
|
</div>
|
|
267
260
|
</div>
|
|
@@ -284,19 +277,19 @@ export function SettingsPage() {
|
|
|
284
277
|
queryClient.invalidateQueries({ queryKey: ['alerts-config'] })
|
|
285
278
|
}}
|
|
286
279
|
className={cn(
|
|
287
|
-
'px-
|
|
280
|
+
'px-4 py-1.5 rounded-lg text-[9px] font-black uppercase tracking-widest transition-all border font-mono',
|
|
288
281
|
alertConfig?.config?.channels?.slack?.enabled
|
|
289
|
-
? 'bg-
|
|
290
|
-
: 'bg-
|
|
282
|
+
? 'bg-emerald-500/10 text-emerald-500 border-emerald-500/40 shadow-[0_0_15px_rgba(16,185,129,0.1)]'
|
|
283
|
+
: 'bg-zinc-800 text-muted-foreground border-transparent opacity-40 hover:opacity-100'
|
|
291
284
|
)}
|
|
292
285
|
>
|
|
293
|
-
{alertConfig?.config?.channels?.slack?.enabled ? '
|
|
286
|
+
{alertConfig?.config?.channels?.slack?.enabled ? 'Online' : 'Offline'}
|
|
294
287
|
</button>
|
|
295
288
|
</div>
|
|
296
289
|
<div className="flex gap-3">
|
|
297
290
|
<input
|
|
298
291
|
type="password"
|
|
299
|
-
placeholder="
|
|
292
|
+
placeholder="SLACK_WEBHOOK_URL"
|
|
300
293
|
defaultValue={alertConfig?.config?.channels?.slack?.webhookUrl || ''}
|
|
301
294
|
onBlur={async (e) => {
|
|
302
295
|
const val = e.target.value
|
|
@@ -319,22 +312,24 @@ export function SettingsPage() {
|
|
|
319
312
|
})
|
|
320
313
|
queryClient.invalidateQueries({ queryKey: ['alerts-config'] })
|
|
321
314
|
}}
|
|
322
|
-
className="flex-1 bg-
|
|
315
|
+
className="flex-1 bg-black/40 border border-white/5 rounded-lg px-4 py-3 text-[11px] font-mono outline-none focus:ring-1 focus:ring-primary/30 text-primary/80 placeholder:text-white/5"
|
|
323
316
|
/>
|
|
324
317
|
</div>
|
|
325
318
|
</div>
|
|
326
319
|
|
|
327
320
|
{/* Discord */}
|
|
328
|
-
<div className="p-
|
|
329
|
-
<div className="flex items-center justify-between mb-
|
|
330
|
-
<div className="flex items-center gap-
|
|
331
|
-
<div className="w-
|
|
332
|
-
<Monitor size={
|
|
321
|
+
<div className="p-5 bg-zinc-900/40 rounded-2xl border border-white/5 group hover:border-primary/20 transition-all">
|
|
322
|
+
<div className="flex items-center justify-between mb-5">
|
|
323
|
+
<div className="flex items-center gap-4">
|
|
324
|
+
<div className="w-10 h-10 rounded-xl bg-white/5 flex items-center justify-center text-white/60 group-hover:text-[#5865F2] transition-colors">
|
|
325
|
+
<Monitor size={18} />
|
|
333
326
|
</div>
|
|
334
327
|
<div>
|
|
335
|
-
<h4 className="text-sm font-
|
|
336
|
-
|
|
337
|
-
|
|
328
|
+
<h4 className="text-sm font-black font-heading text-white tracking-widest uppercase">
|
|
329
|
+
Discord Relay
|
|
330
|
+
</h4>
|
|
331
|
+
<p className="text-[9px] text-muted-foreground font-bold uppercase tracking-tighter opacity-40">
|
|
332
|
+
Webhook Cluster Transport
|
|
338
333
|
</p>
|
|
339
334
|
</div>
|
|
340
335
|
</div>
|
|
@@ -357,19 +352,19 @@ export function SettingsPage() {
|
|
|
357
352
|
queryClient.invalidateQueries({ queryKey: ['alerts-config'] })
|
|
358
353
|
}}
|
|
359
354
|
className={cn(
|
|
360
|
-
'px-
|
|
355
|
+
'px-4 py-1.5 rounded-lg text-[9px] font-black uppercase tracking-widest transition-all border font-mono',
|
|
361
356
|
alertConfig?.config?.channels?.discord?.enabled
|
|
362
|
-
? 'bg-
|
|
363
|
-
: 'bg-
|
|
357
|
+
? 'bg-[#5865F2]/10 text-[#5865F2] border-[#5865F2]/40 shadow-[0_0_15px_rgba(88,101,242,0.1)]'
|
|
358
|
+
: 'bg-zinc-800 text-muted-foreground border-transparent opacity-40 hover:opacity-100'
|
|
364
359
|
)}
|
|
365
360
|
>
|
|
366
|
-
{alertConfig?.config?.channels?.discord?.enabled ? '
|
|
361
|
+
{alertConfig?.config?.channels?.discord?.enabled ? 'Online' : 'Offline'}
|
|
367
362
|
</button>
|
|
368
363
|
</div>
|
|
369
364
|
<div className="flex gap-3">
|
|
370
365
|
<input
|
|
371
366
|
type="password"
|
|
372
|
-
placeholder="
|
|
367
|
+
placeholder="DISCORD_WEBHOOK_URL"
|
|
373
368
|
defaultValue={alertConfig?.config?.channels?.discord?.webhookUrl || ''}
|
|
374
369
|
onBlur={async (e) => {
|
|
375
370
|
const val = e.target.value
|
|
@@ -392,7 +387,7 @@ export function SettingsPage() {
|
|
|
392
387
|
})
|
|
393
388
|
queryClient.invalidateQueries({ queryKey: ['alerts-config'] })
|
|
394
389
|
}}
|
|
395
|
-
className="flex-1 bg-
|
|
390
|
+
className="flex-1 bg-black/40 border border-white/5 rounded-lg px-4 py-3 text-[11px] font-mono outline-none focus:ring-1 focus:ring-primary/30 text-primary/80 placeholder:text-white/5"
|
|
396
391
|
/>
|
|
397
392
|
</div>
|
|
398
393
|
</div>
|
|
@@ -1004,17 +999,3 @@ export function SettingsPage() {
|
|
|
1004
999
|
</div>
|
|
1005
1000
|
)
|
|
1006
1001
|
}
|
|
1007
|
-
|
|
1008
|
-
function formatUptime(seconds: number): string {
|
|
1009
|
-
const days = Math.floor(seconds / 86400)
|
|
1010
|
-
const hours = Math.floor((seconds % 86400) / 3600)
|
|
1011
|
-
const minutes = Math.floor((seconds % 3600) / 60)
|
|
1012
|
-
|
|
1013
|
-
if (days > 0) {
|
|
1014
|
-
return `${days}d ${hours}h ${minutes}m`
|
|
1015
|
-
}
|
|
1016
|
-
if (hours > 0) {
|
|
1017
|
-
return `${hours}h ${minutes}m`
|
|
1018
|
-
}
|
|
1019
|
-
return `${minutes}m ${Math.floor(seconds % 60)}s`
|
|
1020
|
-
}
|