@calltelemetry/cli 0.3.8 → 0.4.0
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/README.md +13 -1
- package/dist/commands/diag.d.ts.map +1 -1
- package/dist/commands/diag.js +7 -0
- package/dist/commands/diag.js.map +1 -1
- package/dist/commands/jtapi.d.ts.map +1 -1
- package/dist/commands/jtapi.js +10 -9
- package/dist/commands/jtapi.js.map +1 -1
- package/dist/commands/secrets.d.ts.map +1 -1
- package/dist/commands/secrets.js +12 -0
- package/dist/commands/secrets.js.map +1 -1
- package/dist/commands/users.d.ts +3 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +24 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/compose.d.ts.map +1 -1
- package/dist/lib/compose.js +1 -3
- package/dist/lib/compose.js.map +1 -1
- package/dist/lib/env.d.ts +14 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +74 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/jtapi.d.ts +67 -2
- package/dist/lib/jtapi.d.ts.map +1 -1
- package/dist/lib/jtapi.js +261 -14
- package/dist/lib/jtapi.js.map +1 -1
- package/dist/lib/paths.d.ts +1 -1
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +1 -1
- package/dist/lib/paths.js.map +1 -1
- package/dist/lib/redact.d.ts +10 -0
- package/dist/lib/redact.d.ts.map +1 -0
- package/dist/lib/redact.js +45 -0
- package/dist/lib/redact.js.map +1 -0
- package/dist/lib/secrets.d.ts +16 -1
- package/dist/lib/secrets.d.ts.map +1 -1
- package/dist/lib/secrets.js +48 -1
- package/dist/lib/secrets.js.map +1 -1
- package/dist/lib/showtech-steps.d.ts +7 -0
- package/dist/lib/showtech-steps.d.ts.map +1 -0
- package/dist/lib/showtech-steps.js +351 -0
- package/dist/lib/showtech-steps.js.map +1 -0
- package/dist/lib/users.d.ts +33 -0
- package/dist/lib/users.d.ts.map +1 -0
- package/dist/lib/users.js +67 -0
- package/dist/lib/users.js.map +1 -0
- package/dist/ui/components/AppShell.d.ts +3 -1
- package/dist/ui/components/AppShell.d.ts.map +1 -1
- package/dist/ui/components/AppShell.js +5 -2
- package/dist/ui/components/AppShell.js.map +1 -1
- package/dist/ui/components/MetricsFooter.d.ts +7 -0
- package/dist/ui/components/MetricsFooter.d.ts.map +1 -0
- package/dist/ui/components/MetricsFooter.js +36 -0
- package/dist/ui/components/MetricsFooter.js.map +1 -0
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/context/MetricsContext.d.ts +7 -0
- package/dist/ui/context/MetricsContext.d.ts.map +1 -0
- package/dist/ui/context/MetricsContext.js +13 -0
- package/dist/ui/context/MetricsContext.js.map +1 -0
- package/dist/ui/views/DiagDatabaseView.d.ts.map +1 -1
- package/dist/ui/views/DiagDatabaseView.js +36 -28
- package/dist/ui/views/DiagDatabaseView.js.map +1 -1
- package/dist/ui/views/DiagServiceView.d.ts.map +1 -1
- package/dist/ui/views/DiagServiceView.js +29 -18
- package/dist/ui/views/DiagServiceView.js.map +1 -1
- package/dist/ui/views/DiagShowTechView.d.ts +6 -0
- package/dist/ui/views/DiagShowTechView.d.ts.map +1 -0
- package/dist/ui/views/DiagShowTechView.js +68 -0
- package/dist/ui/views/DiagShowTechView.js.map +1 -0
- package/dist/ui/views/JtapiView.d.ts +7 -0
- package/dist/ui/views/JtapiView.d.ts.map +1 -0
- package/dist/ui/views/JtapiView.js +405 -0
- package/dist/ui/views/JtapiView.js.map +1 -0
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +25 -22
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/dist/ui/views/SecretsResetPasswordView.d.ts +11 -0
- package/dist/ui/views/SecretsResetPasswordView.d.ts.map +1 -0
- package/dist/ui/views/SecretsResetPasswordView.js +205 -0
- package/dist/ui/views/SecretsResetPasswordView.js.map +1 -0
- package/dist/ui/views/UserResetPasswordView.d.ts +10 -0
- package/dist/ui/views/UserResetPasswordView.d.ts.map +1 -0
- package/dist/ui/views/UserResetPasswordView.js +220 -0
- package/dist/ui/views/UserResetPasswordView.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
import { AppShell, Section, StepList, Divider, StatusLine, StatusBox, Spinner, Confirm } from '../components/index.js';
|
|
5
|
+
import { useStepRunner } from '../hooks/index.js';
|
|
6
|
+
import { isJtapiEnabled, enableJtapi, disableJtapi, getJtapiContainerStatus, getJtapiHealthCheck, getJtapiDependencyStatus, getJtapiWebConfig, checkJtapiPrereqs, waitForHealth, } from '../../lib/jtapi.js';
|
|
7
|
+
import { compose, composeExec, composeUp } from '../../lib/compose.js';
|
|
8
|
+
export function JtapiView({ onBack, initialAction }) {
|
|
9
|
+
const initialPhase = initialAction === 'enable' ? 'pre_enable'
|
|
10
|
+
: initialAction === 'disable' ? 'disabling'
|
|
11
|
+
: initialAction === 'troubleshoot' ? 'troubleshoot'
|
|
12
|
+
: 'dashboard';
|
|
13
|
+
const [phase, setPhase] = useState(initialPhase);
|
|
14
|
+
const [enabled, setEnabled] = useState(() => isJtapiEnabled());
|
|
15
|
+
const [container, setContainer] = useState(null);
|
|
16
|
+
const [health, setHealth] = useState(null);
|
|
17
|
+
const [deps, setDeps] = useState(null);
|
|
18
|
+
const [webConfig, setWebConfig] = useState(null);
|
|
19
|
+
const [prereqs, setPrereqs] = useState(null);
|
|
20
|
+
const [errorMessage, setErrorMessage] = useState('');
|
|
21
|
+
const [doneAction, setDoneAction] = useState('enable');
|
|
22
|
+
const [loading, setLoading] = useState(false);
|
|
23
|
+
// ── Dashboard data fetching ──
|
|
24
|
+
const fetchDashboard = useCallback(async () => {
|
|
25
|
+
setLoading(true);
|
|
26
|
+
try {
|
|
27
|
+
const currentEnabled = isJtapiEnabled();
|
|
28
|
+
setEnabled(currentEnabled);
|
|
29
|
+
if (currentEnabled) {
|
|
30
|
+
const [c, h, d, w] = await Promise.all([
|
|
31
|
+
getJtapiContainerStatus(),
|
|
32
|
+
getJtapiHealthCheck(),
|
|
33
|
+
getJtapiDependencyStatus(),
|
|
34
|
+
getJtapiWebConfig(),
|
|
35
|
+
]);
|
|
36
|
+
setContainer(c);
|
|
37
|
+
setHealth(h);
|
|
38
|
+
setDeps(d);
|
|
39
|
+
setWebConfig(w);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch { /* ignore dashboard fetch errors */ }
|
|
43
|
+
setLoading(false);
|
|
44
|
+
}, []);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (phase === 'dashboard')
|
|
47
|
+
fetchDashboard();
|
|
48
|
+
}, [phase, fetchDashboard]);
|
|
49
|
+
// ── Pre-enable checks ──
|
|
50
|
+
const fetchPrereqs = useCallback(async () => {
|
|
51
|
+
setPrereqs(null);
|
|
52
|
+
const results = await checkJtapiPrereqs();
|
|
53
|
+
setPrereqs(results);
|
|
54
|
+
}, []);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (phase === 'pre_enable')
|
|
57
|
+
fetchPrereqs();
|
|
58
|
+
}, [phase, fetchPrereqs]);
|
|
59
|
+
// ── Enable steps ──
|
|
60
|
+
const enableSteps = [
|
|
61
|
+
{
|
|
62
|
+
label: 'Write JTAPI configuration to .env',
|
|
63
|
+
run: async () => {
|
|
64
|
+
await enableJtapi();
|
|
65
|
+
return 'configured';
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: 'Start services with JTAPI profile',
|
|
70
|
+
run: async () => {
|
|
71
|
+
await composeUp(['-d'], { pipe: true });
|
|
72
|
+
return 'started';
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: 'Wait for sidecar health',
|
|
77
|
+
run: async (ctx) => {
|
|
78
|
+
const start = Date.now();
|
|
79
|
+
const interval = setInterval(() => {
|
|
80
|
+
const elapsed = Math.round((Date.now() - start) / 1000);
|
|
81
|
+
ctx?.log(`Waiting... ${elapsed}s`);
|
|
82
|
+
}, 5000);
|
|
83
|
+
try {
|
|
84
|
+
const healthy = await waitForHealth(90);
|
|
85
|
+
clearInterval(interval);
|
|
86
|
+
if (!healthy)
|
|
87
|
+
throw new Error('Sidecar did not become healthy within 90 seconds');
|
|
88
|
+
return 'healthy';
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
clearInterval(interval);
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
const enableRunner = useStepRunner(enableSteps);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (phase === 'enabling')
|
|
100
|
+
enableRunner.run();
|
|
101
|
+
}, [phase]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
102
|
+
// Handle enable completion / failure
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (phase !== 'enabling')
|
|
105
|
+
return;
|
|
106
|
+
const hasError = enableRunner.states.some(s => s.status === 'error');
|
|
107
|
+
if (enableRunner.isDone) {
|
|
108
|
+
setDoneAction('enable');
|
|
109
|
+
setPhase('done');
|
|
110
|
+
}
|
|
111
|
+
else if (!enableRunner.isRunning && hasError) {
|
|
112
|
+
// Rollback
|
|
113
|
+
(async () => {
|
|
114
|
+
try {
|
|
115
|
+
await compose(['--profile', 'jtapi', 'stop'], { pipe: true }).catch(() => { });
|
|
116
|
+
await disableJtapi();
|
|
117
|
+
await composeUp(['-d', '--remove-orphans'], { pipe: true }).catch(() => { });
|
|
118
|
+
}
|
|
119
|
+
catch { /* best effort */ }
|
|
120
|
+
const failedStep = enableRunner.states.find(s => s.status === 'error');
|
|
121
|
+
setErrorMessage(failedStep?.detail ?? 'Enable failed — rollback completed');
|
|
122
|
+
setPhase('error');
|
|
123
|
+
})();
|
|
124
|
+
}
|
|
125
|
+
}, [phase, enableRunner.isDone, enableRunner.isRunning, enableRunner.states]);
|
|
126
|
+
// ── Disable steps ──
|
|
127
|
+
const disableSteps = [
|
|
128
|
+
{
|
|
129
|
+
label: 'Check JTAPI status',
|
|
130
|
+
run: async () => {
|
|
131
|
+
const current = isJtapiEnabled();
|
|
132
|
+
if (!current)
|
|
133
|
+
return 'already disabled';
|
|
134
|
+
return 'enabled — proceeding to disable';
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
label: 'Stop all JTAPI services',
|
|
139
|
+
run: async () => {
|
|
140
|
+
if (!isJtapiEnabled())
|
|
141
|
+
return 'skipped';
|
|
142
|
+
await compose(['--profile', 'jtapi', 'stop'], { pipe: true });
|
|
143
|
+
return 'stopped';
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
label: 'Remove JTAPI configuration from .env',
|
|
148
|
+
run: async () => {
|
|
149
|
+
if (!isJtapiEnabled())
|
|
150
|
+
return 'skipped';
|
|
151
|
+
await disableJtapi();
|
|
152
|
+
return 'removed';
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
label: 'Restart services without JTAPI',
|
|
157
|
+
run: async () => {
|
|
158
|
+
await composeUp(['-d', '--remove-orphans'], { pipe: true });
|
|
159
|
+
return 'restarted';
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
const disableRunner = useStepRunner(disableSteps);
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (phase === 'disabling')
|
|
166
|
+
disableRunner.run();
|
|
167
|
+
}, [phase]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
if (phase !== 'disabling')
|
|
170
|
+
return;
|
|
171
|
+
const hasError = disableRunner.states.some(s => s.status === 'error');
|
|
172
|
+
if (disableRunner.isDone) {
|
|
173
|
+
setDoneAction('disable');
|
|
174
|
+
setPhase('done');
|
|
175
|
+
}
|
|
176
|
+
else if (!disableRunner.isRunning && hasError) {
|
|
177
|
+
const failedStep = disableRunner.states.find(s => s.status === 'error');
|
|
178
|
+
setErrorMessage(failedStep?.detail ?? 'Disable failed');
|
|
179
|
+
setPhase('error');
|
|
180
|
+
}
|
|
181
|
+
}, [phase, disableRunner.isDone, disableRunner.isRunning, disableRunner.states]);
|
|
182
|
+
// ── Troubleshoot steps ──
|
|
183
|
+
const troubleshootSteps = [
|
|
184
|
+
{
|
|
185
|
+
label: 'Feature State',
|
|
186
|
+
run: async () => isJtapiEnabled() ? 'Enabled' : 'Disabled',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
label: 'Container: jtapi-sidecar',
|
|
190
|
+
run: async () => {
|
|
191
|
+
const s = await getJtapiContainerStatus();
|
|
192
|
+
if (!s.running)
|
|
193
|
+
throw new Error(`${s.state} — Run: ct jtapi enable`);
|
|
194
|
+
return `${s.state} (${s.health})`;
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
label: 'Container: ct-media',
|
|
199
|
+
run: async () => {
|
|
200
|
+
const result = await compose(['ps', '--format', 'json', 'ct-media'], { pipe: true });
|
|
201
|
+
const out = String(result.stdout ?? '').trim();
|
|
202
|
+
if (!out)
|
|
203
|
+
throw new Error('not found');
|
|
204
|
+
try {
|
|
205
|
+
const obj = JSON.parse(out.split('\n')[0]);
|
|
206
|
+
if ((obj.State ?? '').toLowerCase() !== 'running')
|
|
207
|
+
throw new Error('not running');
|
|
208
|
+
return 'running';
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
if (out.toLowerCase().includes('running'))
|
|
212
|
+
return 'running';
|
|
213
|
+
throw new Error('not running');
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
label: 'Container: minio',
|
|
219
|
+
run: async () => {
|
|
220
|
+
const result = await compose(['ps', '--format', 'json', 'minio'], { pipe: true });
|
|
221
|
+
const out = String(result.stdout ?? '').trim();
|
|
222
|
+
if (!out)
|
|
223
|
+
throw new Error('not found');
|
|
224
|
+
try {
|
|
225
|
+
const obj = JSON.parse(out.split('\n')[0]);
|
|
226
|
+
if ((obj.State ?? '').toLowerCase() !== 'running')
|
|
227
|
+
throw new Error('not running');
|
|
228
|
+
return 'running';
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
if (out.toLowerCase().includes('running'))
|
|
232
|
+
return 'running';
|
|
233
|
+
throw new Error('not running');
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
label: 'Container: nats',
|
|
239
|
+
run: async () => {
|
|
240
|
+
const result = await compose(['ps', '--format', 'json', 'nats'], { pipe: true });
|
|
241
|
+
const out = String(result.stdout ?? '').trim();
|
|
242
|
+
if (!out)
|
|
243
|
+
throw new Error('not found');
|
|
244
|
+
try {
|
|
245
|
+
const obj = JSON.parse(out.split('\n')[0]);
|
|
246
|
+
if ((obj.State ?? '').toLowerCase() !== 'running')
|
|
247
|
+
throw new Error('not running');
|
|
248
|
+
return 'running';
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
if (out.toLowerCase().includes('running'))
|
|
252
|
+
return 'running';
|
|
253
|
+
throw new Error('not running');
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
label: 'NATS KV Stores',
|
|
259
|
+
run: async () => {
|
|
260
|
+
const result = await composeExec('nats', ['nats', 'kv', 'ls'], { pipe: true });
|
|
261
|
+
const out = result.stdout ?? '';
|
|
262
|
+
const buckets = out.split('\n').filter((l) => l.trim()).map((l) => l.trim());
|
|
263
|
+
return buckets.length > 0 ? buckets.join(', ') : 'none';
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
label: 'NATS Object Store',
|
|
268
|
+
run: async () => {
|
|
269
|
+
const result = await composeExec('nats', ['nats', 'object', 'ls'], { pipe: true });
|
|
270
|
+
const out = result.stdout ?? '';
|
|
271
|
+
const stores = out.split('\n').filter((l) => l.trim()).map((l) => l.trim());
|
|
272
|
+
return stores.length > 0 ? stores.join(', ') : 'none';
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
label: 'Sidecar Health',
|
|
277
|
+
run: async () => {
|
|
278
|
+
const h = await getJtapiHealthCheck();
|
|
279
|
+
if (!h.reachable)
|
|
280
|
+
throw new Error('Sidecar has 90s startup period. Wait and retry.');
|
|
281
|
+
return h.status ?? 'OK';
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
label: 'Web JTAPI Config',
|
|
286
|
+
run: async () => {
|
|
287
|
+
const config = await getJtapiWebConfig();
|
|
288
|
+
if (!config.configured)
|
|
289
|
+
throw new Error('Configure JTAPI in web UI: Settings > JTAPI');
|
|
290
|
+
return `mode=${config.mode}`;
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
];
|
|
294
|
+
const troubleshootRunner = useStepRunner(troubleshootSteps);
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
if (phase === 'troubleshoot')
|
|
297
|
+
troubleshootRunner.run();
|
|
298
|
+
}, [phase]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
299
|
+
// ── Keyboard ──
|
|
300
|
+
useInput((input, key) => {
|
|
301
|
+
if (phase === 'dashboard') {
|
|
302
|
+
if (input === 'e' && !enabled)
|
|
303
|
+
setPhase('pre_enable');
|
|
304
|
+
else if (input === 'd' && enabled)
|
|
305
|
+
setPhase('disabling');
|
|
306
|
+
else if (input === 't')
|
|
307
|
+
setPhase('troubleshoot');
|
|
308
|
+
else if (input === 'q' || key.escape)
|
|
309
|
+
onBack?.();
|
|
310
|
+
}
|
|
311
|
+
else if (phase === 'pre_enable') {
|
|
312
|
+
if (input === 'y') {
|
|
313
|
+
const critical = prereqs?.filter(r => !r.passed && r.label !== 'JTAPI status');
|
|
314
|
+
if (!critical || critical.length === 0)
|
|
315
|
+
setPhase('enabling');
|
|
316
|
+
}
|
|
317
|
+
else if (input === 'n' || key.escape)
|
|
318
|
+
setPhase('dashboard');
|
|
319
|
+
}
|
|
320
|
+
else if (phase === 'troubleshoot') {
|
|
321
|
+
if ((input === 'q' || key.escape) && troubleshootRunner.isDone)
|
|
322
|
+
setPhase('dashboard');
|
|
323
|
+
}
|
|
324
|
+
else if (phase === 'done') {
|
|
325
|
+
if (input === 'q' || key.escape)
|
|
326
|
+
onBack?.();
|
|
327
|
+
}
|
|
328
|
+
else if (phase === 'error') {
|
|
329
|
+
if (input === 'r') {
|
|
330
|
+
setErrorMessage('');
|
|
331
|
+
if (doneAction === 'enable')
|
|
332
|
+
setPhase('pre_enable');
|
|
333
|
+
else
|
|
334
|
+
setPhase('dashboard');
|
|
335
|
+
}
|
|
336
|
+
else if (input === 'q' || key.escape)
|
|
337
|
+
onBack?.();
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
// ── Render ──
|
|
341
|
+
const commandName = phase === 'enabling' ? 'ct jtapi enable'
|
|
342
|
+
: phase === 'disabling' ? 'ct jtapi disable'
|
|
343
|
+
: phase === 'troubleshoot' ? 'ct jtapi troubleshoot'
|
|
344
|
+
: 'ct jtapi';
|
|
345
|
+
const isComplete = phase === 'done' || phase === 'error' ||
|
|
346
|
+
(phase === 'dashboard' && !loading) ||
|
|
347
|
+
(phase === 'troubleshoot' && troubleshootRunner.isDone);
|
|
348
|
+
// ── Dashboard ──
|
|
349
|
+
if (phase === 'dashboard') {
|
|
350
|
+
return (_jsxs(AppShell, { command: commandName, onBack: onBack, isComplete: isComplete, children: [_jsxs(Section, { title: "JTAPI Sidecar", children: [_jsx(StatusLine, { status: enabled ? 'ok' : 'warn', label: enabled ? 'ENABLED' : 'DISABLED' }), enabled && loading && _jsx(Spinner, { label: "Loading status..." }), enabled && container && (_jsxs(_Fragment, { children: [_jsx(StatusLine, { status: container.running ? 'ok' : 'fail', label: `Container: ${container.state}${container.health !== 'unknown' ? ` (${container.health})` : ''}` }), container.uptime && (_jsx(StatusLine, { status: "info", label: `Uptime: ${container.uptime}` }))] })), enabled && webConfig && (_jsx(StatusLine, { status: webConfig.configured ? 'ok' : 'warn', label: `Config: ${webConfig.configured ? `JTAPI_MODE=${webConfig.mode}` : 'not configured'}` })), enabled && deps && deps.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: "Dependencies:" }), deps.map((d) => (_jsx(StatusLine, { status: d.running ? 'ok' : 'fail', label: ` ${d.name.padEnd(14)} ${d.running ? d.health : 'not running'}` }, d.name)))] })), !enabled && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { children: "JTAPI enables Cisco phone control (call routing, greetings, device management)." }), _jsx(Text, { children: "To get started: enable the sidecar, then configure CUCM servers in the web UI." })] }))] }), _jsx(Divider, {}), _jsx(Box, { paddingLeft: 2, children: _jsx(Text, { dimColor: true, children: enabled
|
|
351
|
+
? 'd Disable t Troubleshoot q Back'
|
|
352
|
+
: 'e Enable t Troubleshoot q Back' }) })] }));
|
|
353
|
+
}
|
|
354
|
+
// ── Pre-enable ──
|
|
355
|
+
if (phase === 'pre_enable') {
|
|
356
|
+
return (_jsx(AppShell, { command: "ct jtapi enable", onBack: () => setPhase('dashboard'), children: _jsx(Section, { title: "JTAPI Enable \u2014 Pre-flight Checks", children: !prereqs ? (_jsx(Spinner, { label: "Running pre-flight checks..." })) : (_jsxs(_Fragment, { children: [prereqs.map((r, i) => (_jsx(StatusLine, { status: r.passed ? 'ok' : (r.label === 'JTAPI status' ? 'warn' : 'fail'), label: `${r.label}: ${r.detail}` }, i))), _jsx(Divider, {}), prereqs.some(r => !r.passed && r.label !== 'JTAPI status') ? (_jsx(Text, { color: "red", children: "Cannot proceed \u2014 fix blocked checks above." })) : (_jsx(Confirm, { message: "Proceed with enable?", onConfirm: (yes) => {
|
|
357
|
+
if (yes)
|
|
358
|
+
setPhase('enabling');
|
|
359
|
+
else
|
|
360
|
+
setPhase('dashboard');
|
|
361
|
+
} }))] })) }) }));
|
|
362
|
+
}
|
|
363
|
+
// ── Enabling ──
|
|
364
|
+
if (phase === 'enabling') {
|
|
365
|
+
return (_jsx(AppShell, { command: "ct jtapi enable", children: _jsx(Section, { title: "JTAPI Enable", children: _jsx(StepList, { steps: enableRunner.states }) }) }));
|
|
366
|
+
}
|
|
367
|
+
// ── Disabling ──
|
|
368
|
+
if (phase === 'disabling') {
|
|
369
|
+
return (_jsx(AppShell, { command: "ct jtapi disable", children: _jsx(Section, { title: "JTAPI Disable", children: _jsx(StepList, { steps: disableRunner.states }) }) }));
|
|
370
|
+
}
|
|
371
|
+
// ── Troubleshoot ──
|
|
372
|
+
if (phase === 'troubleshoot') {
|
|
373
|
+
const passed = troubleshootRunner.states.filter(s => s.status === 'done').length;
|
|
374
|
+
const failed = troubleshootRunner.states.filter(s => s.status === 'error').length;
|
|
375
|
+
const total = troubleshootRunner.states.length;
|
|
376
|
+
return (_jsxs(AppShell, { command: "ct jtapi troubleshoot", onBack: () => setPhase('dashboard'), isComplete: troubleshootRunner.isDone, children: [_jsx(Section, { title: "JTAPI Troubleshoot", children: _jsx(StepList, { steps: troubleshootRunner.states }) }), troubleshootRunner.isDone && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Divider, {}), _jsx(StatusLine, { status: failed === 0 ? 'ok' : 'warn', label: failed === 0
|
|
377
|
+
? `${passed}/${total} checks passed`
|
|
378
|
+
: `${passed}/${total} checks passed, ${failed} failed` }), _jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "q Back to dashboard" }) })] }))] }));
|
|
379
|
+
}
|
|
380
|
+
// ── Done ──
|
|
381
|
+
if (phase === 'done') {
|
|
382
|
+
const isEnable = doneAction === 'enable';
|
|
383
|
+
return (_jsxs(AppShell, { command: isEnable ? 'ct jtapi enable' : 'ct jtapi disable', onBack: onBack, isComplete: true, children: [_jsx(StatusBox, { variant: "success", title: isEnable ? 'JTAPI Sidecar Enabled' : 'JTAPI Sidecar Disabled', lines: isEnable ? [
|
|
384
|
+
'The sidecar is running and healthy.',
|
|
385
|
+
'',
|
|
386
|
+
'Next steps:',
|
|
387
|
+
' 1. Upload JTAPI JAR via web UI (Settings > JTAPI)',
|
|
388
|
+
' 2. Add CUCM server via web UI (Settings > JTAPI > Servers)',
|
|
389
|
+
' 3. Restart services: ct update',
|
|
390
|
+
] : [
|
|
391
|
+
'JTAPI services have been stopped and removed from the configuration.',
|
|
392
|
+
] }), _jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "q Back" }) })] }));
|
|
393
|
+
}
|
|
394
|
+
// ── Error ──
|
|
395
|
+
if (phase === 'error') {
|
|
396
|
+
return (_jsxs(AppShell, { command: commandName, onBack: onBack, isComplete: true, children: [_jsx(StatusBox, { variant: "error", title: doneAction === 'enable' ? 'JTAPI Enable Failed' : 'JTAPI Disable Failed', lines: [
|
|
397
|
+
errorMessage,
|
|
398
|
+
'',
|
|
399
|
+
doneAction === 'enable' ? 'Rollback completed — JTAPI has been disabled.' : '',
|
|
400
|
+
'The previous configuration is still active.',
|
|
401
|
+
].filter(Boolean) }), _jsx(Box, { paddingLeft: 2, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "r Retry q Back" }) })] }));
|
|
402
|
+
}
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
//# sourceMappingURL=JtapiView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JtapiView.js","sourceRoot":"","sources":["../../../src/ui/views/JtapiView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MainMenu.d.ts","sourceRoot":"","sources":["../../../src/ui/views/MainMenu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MainMenu.d.ts","sourceRoot":"","sources":["../../../src/ui/views/MainMenu.tsx"],"names":[],"mappings":"AAgNA,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,aAAa,2CA6YlF"}
|
|
@@ -7,7 +7,7 @@ import { execa } from 'execa';
|
|
|
7
7
|
import { AppShell, Spinner, MeterBar, LogLevelBadge } from '../components/index.js';
|
|
8
8
|
import { usePolling, useLogLevel } from '../hooks/index.js';
|
|
9
9
|
import { getServiceList } from '../../lib/services.js';
|
|
10
|
-
import {
|
|
10
|
+
import { useMetrics } from '../context/MetricsContext.js';
|
|
11
11
|
import { getAppHealth } from '../../lib/rpc.js';
|
|
12
12
|
import { healthIcon, healthColor, extractUptime } from '../utils/serviceDisplay.js';
|
|
13
13
|
import { LOGO } from '../../lib/brand.js';
|
|
@@ -29,6 +29,7 @@ import { MigrateHistoryView } from './MigrateHistoryView.js';
|
|
|
29
29
|
import { MigrateWatchView } from './MigrateWatchView.js';
|
|
30
30
|
import { SecretsStatusView } from './SecretsStatusView.js';
|
|
31
31
|
import { SecretsSetupView } from './SecretsSetupView.js';
|
|
32
|
+
import { SecretsResetPasswordView } from './SecretsResetPasswordView.js';
|
|
32
33
|
import { CertsStatusView } from './CertsStatusView.js';
|
|
33
34
|
import { DockerStatusView } from './DockerStatusView.js';
|
|
34
35
|
import { DockerPruneView } from './DockerPruneView.js';
|
|
@@ -36,10 +37,8 @@ import { DockerNetworkView } from './DockerNetworkView.js';
|
|
|
36
37
|
import { DiagNetworkView } from './DiagNetworkView.js';
|
|
37
38
|
import { DiagServiceView } from './DiagServiceView.js';
|
|
38
39
|
import { DiagDatabaseView } from './DiagDatabaseView.js';
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import { JtapiStatusView } from './JtapiStatusView.js';
|
|
42
|
-
import { JtapiTroubleshootView } from './JtapiTroubleshootView.js';
|
|
40
|
+
import { DiagShowTechView } from './DiagShowTechView.js';
|
|
41
|
+
import { JtapiView } from './JtapiView.js';
|
|
43
42
|
import { OfflineListView } from './OfflineListView.js';
|
|
44
43
|
import { OfflineFetchView } from './OfflineFetchView.js';
|
|
45
44
|
import { OfflineDownloadView } from './OfflineDownloadView.js';
|
|
@@ -49,6 +48,7 @@ import { ServicesView } from './ServicesView.js';
|
|
|
49
48
|
import { ServiceLogsView } from './ServiceLogsView.js';
|
|
50
49
|
import { UpdateView } from './UpdateView.js';
|
|
51
50
|
import { SettingsView } from './SettingsView.js';
|
|
51
|
+
import { UserResetPasswordView } from './UserResetPasswordView.js';
|
|
52
52
|
/* ------------------------------------------------------------------ */
|
|
53
53
|
/* Menu definition */
|
|
54
54
|
/* ------------------------------------------------------------------ */
|
|
@@ -68,6 +68,14 @@ const MENU_ITEMS = [
|
|
|
68
68
|
description: 'Interactive container manager',
|
|
69
69
|
value: 'services',
|
|
70
70
|
},
|
|
71
|
+
{
|
|
72
|
+
label: 'Users',
|
|
73
|
+
description: 'Application user account management',
|
|
74
|
+
value: 'users',
|
|
75
|
+
children: [
|
|
76
|
+
{ label: 'Reset Password', description: 'Reset a user account password', value: 'users reset-password' },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
71
79
|
{
|
|
72
80
|
label: 'Database',
|
|
73
81
|
description: 'Backup, migrate, inspect, and compact',
|
|
@@ -93,6 +101,7 @@ const MENU_ITEMS = [
|
|
|
93
101
|
children: [
|
|
94
102
|
{ label: 'Status', description: 'Show current secrets', value: 'secrets' },
|
|
95
103
|
{ label: 'Setup', description: 'Configure secrets wizard', value: 'secrets setup' },
|
|
104
|
+
{ label: 'Reset Password', description: 'Reset service password (PostgreSQL/Minio)', value: 'secrets reset-password' },
|
|
96
105
|
],
|
|
97
106
|
},
|
|
98
107
|
{
|
|
@@ -118,18 +127,13 @@ const MENU_ITEMS = [
|
|
|
118
127
|
{ label: 'Network', description: 'Comprehensive network diagnostics', value: 'diag network' },
|
|
119
128
|
{ label: 'Service', description: 'Systemd service and container logs', value: 'diag service' },
|
|
120
129
|
{ label: 'Database', description: 'Database health and performance', value: 'diag database' },
|
|
130
|
+
{ label: 'Show Tech', description: 'Collect support bundle', value: 'diag showtech' },
|
|
121
131
|
],
|
|
122
132
|
},
|
|
123
133
|
{
|
|
124
134
|
label: 'JTAPI',
|
|
125
|
-
description: '
|
|
135
|
+
description: 'Cisco phone control sidecar',
|
|
126
136
|
value: 'jtapi',
|
|
127
|
-
children: [
|
|
128
|
-
{ label: 'Enable', description: 'Enable JTAPI sidecar', value: 'jtapi enable' },
|
|
129
|
-
{ label: 'Disable', description: 'Disable JTAPI sidecar', value: 'jtapi disable' },
|
|
130
|
-
{ label: 'Status', description: 'Show JTAPI status', value: 'jtapi status' },
|
|
131
|
-
{ label: 'Troubleshoot', description: 'Comprehensive JTAPI diagnostics', value: 'jtapi troubleshoot' },
|
|
132
|
-
],
|
|
133
137
|
},
|
|
134
138
|
{
|
|
135
139
|
label: 'Offline',
|
|
@@ -170,6 +174,7 @@ const VIEW_MAP = {
|
|
|
170
174
|
'migrate watch': (onBack) => _jsx(MigrateWatchView, { interval: 5000, onBack: onBack }),
|
|
171
175
|
'secrets': (onBack) => _jsx(SecretsStatusView, { onBack: onBack }),
|
|
172
176
|
'secrets setup': (onBack) => _jsx(SecretsSetupView, { onBack: onBack }),
|
|
177
|
+
'secrets reset-password': (onBack) => _jsx(SecretsResetPasswordView, { onBack: onBack }),
|
|
173
178
|
'certs': (onBack) => _jsx(CertsStatusView, { onBack: onBack }),
|
|
174
179
|
'docker status': (onBack) => _jsx(DockerStatusView, { onBack: onBack }),
|
|
175
180
|
'docker prune': (onBack) => _jsx(DockerPruneView, { onBack: onBack }),
|
|
@@ -177,16 +182,15 @@ const VIEW_MAP = {
|
|
|
177
182
|
'diag network': (onBack) => _jsx(DiagNetworkView, { onBack: onBack }),
|
|
178
183
|
'diag service': (onBack) => _jsx(DiagServiceView, { onBack: onBack }),
|
|
179
184
|
'diag database': (onBack) => _jsx(DiagDatabaseView, { onBack: onBack }),
|
|
180
|
-
'
|
|
181
|
-
'jtapi
|
|
182
|
-
'jtapi status': (onBack) => _jsx(JtapiStatusView, { onBack: onBack }),
|
|
183
|
-
'jtapi troubleshoot': (onBack) => _jsx(JtapiTroubleshootView, { onBack: onBack }),
|
|
185
|
+
'diag showtech': (onBack) => _jsx(DiagShowTechView, { onBack: onBack }),
|
|
186
|
+
'jtapi': (onBack) => _jsx(JtapiView, { onBack: onBack }),
|
|
184
187
|
'offline list': (onBack) => _jsx(OfflineListView, { onBack: onBack }),
|
|
185
188
|
'offline fetch': (onBack) => _jsx(OfflineFetchView, { onBack: onBack }),
|
|
186
189
|
'offline download': (onBack) => _jsx(OfflineDownloadView, { onBack: onBack }),
|
|
187
190
|
'offline apply': (onBack) => _jsx(OfflineApplyView, { onBack: onBack }),
|
|
188
191
|
'offline inspect': (onBack) => _jsx(OfflineInspectView, { onBack: onBack }),
|
|
189
192
|
'services': (onBack) => _jsx(ServicesView, { onBack: onBack }),
|
|
193
|
+
'users reset-password': (onBack) => _jsx(UserResetPasswordView, { onBack: onBack }),
|
|
190
194
|
'update': (onBack) => _jsx(UpdateView, { onBack: onBack }),
|
|
191
195
|
'settings': (onBack) => _jsx(SettingsView, { onBack: onBack }),
|
|
192
196
|
};
|
|
@@ -200,8 +204,8 @@ export function MainMenu({ version, firstRun, onCliCommand, onExit }) {
|
|
|
200
204
|
const [focusZone, setFocusZone] = useState('menu');
|
|
201
205
|
const [dashCursor, setDashCursor] = useState(0);
|
|
202
206
|
const { level: logLevel, cycle: cycleLogLevel } = useLogLevel();
|
|
207
|
+
const metrics = useMetrics();
|
|
203
208
|
const { data: services, stop: stopSvcPolling, start: startSvcPolling } = usePolling(getServiceList, 5000, false);
|
|
204
|
-
const { data: metrics, stop: stopMetrics, start: startMetrics } = usePolling(getSystemMetrics, 10000, false);
|
|
205
209
|
const { data: appHealth, stop: stopHealth, start: startHealth } = usePolling(getAppHealth, 15000, false);
|
|
206
210
|
// Cert expiry warning (passive, non-blocking)
|
|
207
211
|
const [certDaysLeft, setCertDaysLeft] = useState(null);
|
|
@@ -224,18 +228,17 @@ export function MainMenu({ version, firstRun, onCliCommand, onExit }) {
|
|
|
224
228
|
})();
|
|
225
229
|
}, []);
|
|
226
230
|
// Control polling based on phase — only poll when on home screen
|
|
231
|
+
// (System metrics are provided globally via MetricsContext)
|
|
227
232
|
useEffect(() => {
|
|
228
233
|
if (phase === 'home') {
|
|
229
234
|
startSvcPolling();
|
|
230
|
-
startMetrics();
|
|
231
235
|
startHealth();
|
|
232
236
|
}
|
|
233
237
|
else {
|
|
234
238
|
stopSvcPolling();
|
|
235
|
-
stopMetrics();
|
|
236
239
|
stopHealth();
|
|
237
240
|
}
|
|
238
|
-
}, [phase, startSvcPolling, stopSvcPolling,
|
|
241
|
+
}, [phase, startSvcPolling, stopSvcPolling, startHealth, stopHealth]);
|
|
239
242
|
const goHome = useCallback(() => {
|
|
240
243
|
setPhase('home');
|
|
241
244
|
setActiveView(null);
|
|
@@ -389,7 +392,7 @@ export function MainMenu({ version, firstRun, onCliCommand, onExit }) {
|
|
|
389
392
|
// --- Phase: first-run ---
|
|
390
393
|
if (phase === 'first-run') {
|
|
391
394
|
const options = ['Yes, keep me updated', 'No thanks'];
|
|
392
|
-
return (_jsxs(AppShell, { title: `CallTelemetry CLI v${version}`, children: [_jsx(Box, { paddingLeft: 1, marginBottom: 1, children: _jsx(Text, { color: "cyan", children: LOGO }) }), _jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsx(Text, { bold: true, children: "Welcome to CallTelemetry CLI!" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Would you like the CLI to automatically" }) }), _jsx(Text, { children: "check for updates when it starts?" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: options.map((label, i) => {
|
|
395
|
+
return (_jsxs(AppShell, { title: `CallTelemetry CLI v${version}`, hideMetrics: true, children: [_jsx(Box, { paddingLeft: 1, marginBottom: 1, children: _jsx(Text, { color: "cyan", children: LOGO }) }), _jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsx(Text, { bold: true, children: "Welcome to CallTelemetry CLI!" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Would you like the CLI to automatically" }) }), _jsx(Text, { children: "check for updates when it starts?" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: options.map((label, i) => {
|
|
393
396
|
const isActive = i === setupCursor;
|
|
394
397
|
return (_jsx(Box, { children: _jsxs(Text, { color: isActive ? 'cyan' : undefined, bold: isActive, children: [isActive ? '❯ ' : ' ', label] }) }, i));
|
|
395
398
|
}) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 Select Enter Confirm" }) })] })] }));
|
|
@@ -406,7 +409,7 @@ export function MainMenu({ version, firstRun, onCliCommand, onExit }) {
|
|
|
406
409
|
const healthyCount = serviceList.filter(s => s.health === 'healthy').length;
|
|
407
410
|
const unhealthyCount = serviceList.filter(s => s.health === 'unhealthy').length;
|
|
408
411
|
const stoppedCount = serviceList.filter(s => s.state === 'exited' || s.state === 'dead').length;
|
|
409
|
-
return (_jsxs(AppShell, { title: `CallTelemetry CLI v${version}`, logLevel: logLevel, children: [_jsx(Box, { paddingLeft: 1, marginBottom: 1, children: _jsx(Text, { color: "cyan", children: LOGO }) }), _jsx(Box, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: metrics ? (_jsxs(_Fragment, { children: [_jsx(MeterBar, { label: "RAM", percent: metrics.ram.percent, detail: metrics.ram.label }), _jsx(MeterBar, { label: "Disk", percent: metrics.disk.usedPercent, detail: metrics.disk.label }), _jsx(MeterBar, { label: "CPU", percent: metrics.cpu.percent, detail: metrics.cpu.label, thresholds: [80, 95] })] })) : (_jsx(Spinner, { label: "Loading system metrics..." })) }), appHealth === undefined ? (_jsx(Box, { paddingLeft: 2, marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Checking app health..." }) })) : (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, marginBottom: 0, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: 'App ' }), _jsxs(Text, { color: appHealth.overall === 'healthy' ? 'green' : appHealth.overall === 'degraded' ? 'yellow' : 'red', children: [appHealth.overall === 'healthy' ? '●' : appHealth.overall === 'degraded' ? '▲' : '✘', ` ${appHealth.overall}`] }), (() => {
|
|
412
|
+
return (_jsxs(AppShell, { title: `CallTelemetry CLI v${version}`, logLevel: logLevel, hideMetrics: true, children: [_jsx(Box, { paddingLeft: 1, marginBottom: 1, children: _jsx(Text, { color: "cyan", children: LOGO }) }), _jsx(Box, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: metrics ? (_jsxs(_Fragment, { children: [_jsx(MeterBar, { label: "RAM", percent: metrics.ram.percent, detail: metrics.ram.label }), _jsx(MeterBar, { label: "Disk", percent: metrics.disk.usedPercent, detail: metrics.disk.label }), _jsx(MeterBar, { label: "CPU", percent: metrics.cpu.percent, detail: metrics.cpu.label, thresholds: [80, 95] })] })) : (_jsx(Spinner, { label: "Loading system metrics..." })) }), appHealth === undefined ? (_jsx(Box, { paddingLeft: 2, marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Checking app health..." }) })) : (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, marginBottom: 0, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: 'App ' }), _jsxs(Text, { color: appHealth.overall === 'healthy' ? 'green' : appHealth.overall === 'degraded' ? 'yellow' : 'red', children: [appHealth.overall === 'healthy' ? '●' : appHealth.overall === 'degraded' ? '▲' : '✘', ` ${appHealth.overall}`] }), (() => {
|
|
410
413
|
const webSvc = serviceList.find(s => s.service === 'web');
|
|
411
414
|
const uptime = webSvc ? extractUptime(webSvc.status) : '';
|
|
412
415
|
return uptime && uptime !== 'exited' ? (_jsxs(Text, { dimColor: true, children: [' ', "Up ", uptime] })) : null;
|