@cartanova/qgrid-cli 2.6.10 → 2.7.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/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +137 -60
- package/bundle/dist/application/qgrid/qgrid.frame.js +5 -2
- package/bundle/dist/application/setting/setting.model.js +65 -3
- package/bundle/dist/application/setting/setting.types.js +13 -3
- package/bundle/dist/i18n/en.js +3 -1
- package/bundle/dist/i18n/ko.js +3 -1
- package/bundle/dist/utils/process-supervisor.js +22 -0
- package/bundle/dist/utils/server-restart.js +61 -0
- package/bundle/src/application/qgrid/qgrid-oauth-redirect.test.ts +7 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +113 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +172 -75
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +45 -0
- package/bundle/src/application/qgrid/qgrid.frame.ts +4 -0
- package/bundle/src/application/setting/setting.model.test.ts +104 -0
- package/bundle/src/application/setting/setting.model.ts +75 -3
- package/bundle/src/application/setting/setting.types.ts +12 -0
- package/bundle/src/application/sonamu.generated.http +7 -0
- package/bundle/src/i18n/en.ts +3 -0
- package/bundle/src/i18n/ko.ts +3 -0
- package/bundle/src/server-error-handler.test.ts +15 -0
- package/bundle/src/utils/process-supervisor.test.ts +24 -0
- package/bundle/src/utils/process-supervisor.ts +17 -0
- package/bundle/src/utils/server-restart.test.ts +76 -0
- package/bundle/src/utils/server-restart.ts +68 -0
- package/bundle/web-dist/client/assets/chat-icon-JYfue7fB.png +0 -0
- package/bundle/web-dist/client/assets/index-C24D5PiN.js +106 -0
- package/bundle/web-dist/client/assets/index-CcMEpCgt.css +1 -0
- package/bundle/web-dist/client/assets/logs-CIlZG6A3.js +1 -0
- package/bundle/web-dist/client/assets/monit-DZFBMxKl.js +1 -0
- package/bundle/web-dist/client/assets/{routes-CkBXB-V4.js → routes-C3wlSNBL.js} +2 -2
- package/bundle/web-dist/client/assets/services.generated-jGypfumC.js +51 -0
- package/bundle/web-dist/client/assets/settings-ClRDWO-8.js +1 -0
- package/bundle/web-dist/client/assets/show-BP7U8yyJ.js +2 -0
- package/bundle/web-dist/client/assets/tokens-DfQeULnJ.js +1 -0
- package/bundle/web-dist/client/assets/{use-oauth-login-flow-Bz87RV5v.js → use-oauth-login-flow-CY-ASCfL.js} +1 -1
- package/bundle/web-dist/client/index.html +3 -3
- package/bundle/web-dist/server/assets/{lazyRouteComponent-Ws7I6fL-.js → lazyRouteComponent-DOc8TV-P.js} +2 -2
- package/bundle/web-dist/server/assets/{logs-C1rxLh8H.js → logs-CfF3nmLM.js} +3 -4
- package/bundle/web-dist/server/assets/{monit-C8gx9Sar.js → monit-BSaKhh5D.js} +2 -3
- package/bundle/web-dist/server/assets/{plus-BISXNqRU.js → plus-DLFUHsfx.js} +1 -1
- package/bundle/web-dist/server/assets/{react-dom-D7duWOwf.js → react-dom-BotjLnTK.js} +1 -1
- package/bundle/web-dist/server/assets/{routes-ZW_Ih5Em.js → routes-CHMxrTT0.js} +4 -5
- package/bundle/web-dist/server/assets/{sd.generated-LO-h1_16.js → services.generated-D3Q3FYot.js} +16697 -15377
- package/bundle/web-dist/server/assets/{settings--aoatERH.js → settings-DOQjV28c.js} +271 -55
- package/bundle/web-dist/server/assets/show-Cn_C6Qvl.js +2776 -0
- package/bundle/web-dist/server/assets/{tokens-DIObtTuZ.js → tokens-c0EN3iCx.js} +4 -5
- package/bundle/web-dist/server/assets/{use-oauth-login-flow-V3k8PSqQ.js → use-oauth-login-flow-B68AbMDE.js} +1 -2
- package/bundle/web-dist/server/entry-server.generated.js +23856 -40
- package/dist/cli.js +93 -38
- package/package.json +1 -1
- package/skills/qgrid/references/cli-env-and-server-boot.md +34 -3
- package/bundle/web-dist/client/assets/index-BRRNJRgu.js +0 -78
- package/bundle/web-dist/client/assets/index-rdbxJinT.css +0 -1
- package/bundle/web-dist/client/assets/logs-BI5K8oe4.js +0 -1
- package/bundle/web-dist/client/assets/monit-4Y-Razet.js +0 -1
- package/bundle/web-dist/client/assets/sd.generated-Bwa7rses.js +0 -51
- package/bundle/web-dist/client/assets/services.generated-BzwTuZRP.js +0 -1
- package/bundle/web-dist/client/assets/settings-B62_r1i4.js +0 -1
- package/bundle/web-dist/client/assets/show-CGRchJj7.js +0 -30
- package/bundle/web-dist/client/assets/tokens-Bx5mQnoJ.js +0 -1
- package/bundle/web-dist/server/assets/services.generated-CZIChgHV.js +0 -1305
- package/bundle/web-dist/server/assets/show-BY27w9oi.js +0 -25968
- /package/bundle/web-dist/client/assets/{plus-p4vtg6LN.js → plus-DqBd6gHk.js} +0 -0
- /package/bundle/web-dist/server/assets/{cost-DzjfVtUr.js → cost-CSH_t17I.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as lucidePlus } from "./plus-
|
|
1
|
+
import { V as __toESM, _ as useQuery, a as SettingService, b as require_jsx_runtime, h as isAxiosError, n as QgridService, s as isSonamuError, x as require_react, y as useQueryClient } from "./services.generated-D3Q3FYot.js";
|
|
2
|
+
import { s as lucideRotateCcw } from "../entry-server.generated.js";
|
|
3
|
+
import { t as lucidePlus } from "./plus-DLFUHsfx.js";
|
|
4
4
|
//#region ~icons/lucide/eye.jsx
|
|
5
5
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
6
6
|
var import_jsx_runtime = require_jsx_runtime();
|
|
@@ -55,28 +55,13 @@ var lucideMinus = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg",
|
|
|
55
55
|
})
|
|
56
56
|
});
|
|
57
57
|
//#endregion
|
|
58
|
-
//#region ~icons/lucide/rotate-ccw.jsx
|
|
59
|
-
var lucideRotateCcw = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
60
|
-
viewBox: "0 0 24 24",
|
|
61
|
-
width: "1.2em",
|
|
62
|
-
height: "1.2em",
|
|
63
|
-
...props,
|
|
64
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
|
|
65
|
-
fill: "none",
|
|
66
|
-
stroke: "currentColor",
|
|
67
|
-
strokeLinecap: "round",
|
|
68
|
-
strokeLinejoin: "round",
|
|
69
|
-
strokeWidth: 2,
|
|
70
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9a9.75 9.75 0 0 0-6.74 2.74L3 8" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 3v5h5" })]
|
|
71
|
-
})
|
|
72
|
-
});
|
|
73
|
-
//#endregion
|
|
74
58
|
//#region src/components/qgrid/SettingsPanel.tsx
|
|
75
59
|
var GROUP_LABELS = {
|
|
76
60
|
openai: "OpenAI 워커",
|
|
77
61
|
slack: "Slack 알림",
|
|
78
62
|
slackConnection: "Slack 연결"
|
|
79
63
|
};
|
|
64
|
+
var RESTART_READY_TIMEOUT_MS = 180 * 1e3;
|
|
80
65
|
function maskValue(value) {
|
|
81
66
|
if (!value) return "";
|
|
82
67
|
if (value.length <= 12) return "•".repeat(value.length);
|
|
@@ -164,7 +149,7 @@ function SettingRow({ item }) {
|
|
|
164
149
|
const pending = updateMutation.isPending || resetMutation.isPending;
|
|
165
150
|
const value = draft ?? item.value;
|
|
166
151
|
const dirty = draft !== null && draft !== item.value;
|
|
167
|
-
const invalidate = () => queryClient.invalidateQueries({ queryKey:
|
|
152
|
+
const invalidate = () => queryClient.invalidateQueries({ queryKey: SettingService.getSettingListQueryOptions().queryKey });
|
|
168
153
|
const commit = async (next) => {
|
|
169
154
|
setError(null);
|
|
170
155
|
try {
|
|
@@ -301,8 +286,215 @@ function TriggerReminderButton() {
|
|
|
301
286
|
})]
|
|
302
287
|
});
|
|
303
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* 재시작은 스스로 종료하고 감독자(pm2)가 다시 띄우는 것에 맡긴다. 되돌릴 수 없고 1~2분간
|
|
291
|
+
* 요청이 실패하므로 확인 단계를 둔다 — 무엇이 일어나는지 모달이 먼저 설명한다.
|
|
292
|
+
*/
|
|
293
|
+
function RestartPanel({ supervisor }) {
|
|
294
|
+
const [confirming, setConfirming] = (0, import_react.useState)(false);
|
|
295
|
+
const [restartRequested, setRestartRequested] = (0, import_react.useState)(false);
|
|
296
|
+
const [restartStartedAt, setRestartStartedAt] = (0, import_react.useState)(null);
|
|
297
|
+
const [sawUnavailable, setSawUnavailable] = (0, import_react.useState)(false);
|
|
298
|
+
const [completing, setCompleting] = (0, import_react.useState)(false);
|
|
299
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
300
|
+
const completingRef = (0, import_react.useRef)(false);
|
|
301
|
+
const restartAttemptRef = (0, import_react.useRef)(0);
|
|
302
|
+
const queryClient = useQueryClient();
|
|
303
|
+
const mutation = SettingService.useRestartServerMutation();
|
|
304
|
+
const resetMutation = mutation.reset;
|
|
305
|
+
const healthQuery = useQuery({
|
|
306
|
+
...QgridService.healthQueryOptions(),
|
|
307
|
+
enabled: restartRequested && !completing,
|
|
308
|
+
refetchInterval: restartRequested && !completing ? 1e3 : false,
|
|
309
|
+
refetchIntervalInBackground: true,
|
|
310
|
+
retry: false
|
|
311
|
+
});
|
|
312
|
+
(0, import_react.useEffect)(() => {
|
|
313
|
+
if (!restartRequested || restartStartedAt === null || completing) return;
|
|
314
|
+
const remaining = Math.max(0, RESTART_READY_TIMEOUT_MS - (Date.now() - restartStartedAt));
|
|
315
|
+
const timeout = window.setTimeout(() => {
|
|
316
|
+
restartAttemptRef.current += 1;
|
|
317
|
+
resetMutation();
|
|
318
|
+
setConfirming(false);
|
|
319
|
+
setRestartRequested(false);
|
|
320
|
+
setRestartStartedAt(null);
|
|
321
|
+
setSawUnavailable(false);
|
|
322
|
+
setError("재시작 후 3분 안에 서버 준비를 확인하지 못했습니다. 상태를 확인한 뒤 다시 시도하세요.");
|
|
323
|
+
}, remaining);
|
|
324
|
+
return () => window.clearTimeout(timeout);
|
|
325
|
+
}, [
|
|
326
|
+
completing,
|
|
327
|
+
resetMutation,
|
|
328
|
+
restartRequested,
|
|
329
|
+
restartStartedAt
|
|
330
|
+
]);
|
|
331
|
+
(0, import_react.useEffect)(() => {
|
|
332
|
+
if (!restartRequested || restartStartedAt === null) return;
|
|
333
|
+
const currentAttemptError = healthQuery.isError && healthQuery.errorUpdatedAt >= restartStartedAt;
|
|
334
|
+
const currentAttemptData = healthQuery.isSuccess && healthQuery.dataUpdatedAt >= restartStartedAt;
|
|
335
|
+
if (currentAttemptError || currentAttemptData && !healthQuery.data.ready) {
|
|
336
|
+
setSawUnavailable(true);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (!sawUnavailable || !currentAttemptData || !healthQuery.data.ready || completingRef.current) return;
|
|
340
|
+
completingRef.current = true;
|
|
341
|
+
setCompleting(true);
|
|
342
|
+
queryClient.invalidateQueries({ queryKey: SettingService.getSettingListQueryOptions().queryKey }).then(() => {
|
|
343
|
+
restartAttemptRef.current += 1;
|
|
344
|
+
resetMutation();
|
|
345
|
+
setConfirming(false);
|
|
346
|
+
setRestartRequested(false);
|
|
347
|
+
setRestartStartedAt(null);
|
|
348
|
+
setSawUnavailable(false);
|
|
349
|
+
}).catch((cause) => {
|
|
350
|
+
restartAttemptRef.current += 1;
|
|
351
|
+
resetMutation();
|
|
352
|
+
setConfirming(false);
|
|
353
|
+
setRestartRequested(false);
|
|
354
|
+
setRestartStartedAt(null);
|
|
355
|
+
setSawUnavailable(false);
|
|
356
|
+
setError(`서버는 준비됐지만 설정을 새로고침하지 못했습니다: ${cause.message}`);
|
|
357
|
+
}).finally(() => {
|
|
358
|
+
completingRef.current = false;
|
|
359
|
+
setCompleting(false);
|
|
360
|
+
});
|
|
361
|
+
}, [
|
|
362
|
+
healthQuery.dataUpdatedAt,
|
|
363
|
+
healthQuery.data?.ready,
|
|
364
|
+
healthQuery.errorUpdatedAt,
|
|
365
|
+
healthQuery.isError,
|
|
366
|
+
healthQuery.isSuccess,
|
|
367
|
+
queryClient,
|
|
368
|
+
resetMutation,
|
|
369
|
+
restartStartedAt,
|
|
370
|
+
restartRequested,
|
|
371
|
+
sawUnavailable
|
|
372
|
+
]);
|
|
373
|
+
const restart = async () => {
|
|
374
|
+
const attempt = restartAttemptRef.current + 1;
|
|
375
|
+
restartAttemptRef.current = attempt;
|
|
376
|
+
setError(null);
|
|
377
|
+
setSawUnavailable(false);
|
|
378
|
+
setCompleting(false);
|
|
379
|
+
completingRef.current = false;
|
|
380
|
+
setRestartRequested(true);
|
|
381
|
+
setRestartStartedAt(Date.now());
|
|
382
|
+
try {
|
|
383
|
+
await mutation.mutateAsync();
|
|
384
|
+
} catch (e) {
|
|
385
|
+
if (restartAttemptRef.current !== attempt) return;
|
|
386
|
+
if (isSonamuError(e) ? e.code >= 400 && e.code < 500 : isAxiosError(e) && e.response !== void 0 && e.response.status >= 400 && e.response.status < 500) {
|
|
387
|
+
restartAttemptRef.current += 1;
|
|
388
|
+
resetMutation();
|
|
389
|
+
setConfirming(false);
|
|
390
|
+
setRestartRequested(false);
|
|
391
|
+
setRestartStartedAt(null);
|
|
392
|
+
setError(e.message || "재시작 요청이 거부되었습니다.");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
const closeConfirmation = () => {
|
|
397
|
+
if (restartRequested) return;
|
|
398
|
+
setConfirming(false);
|
|
399
|
+
setError(null);
|
|
400
|
+
};
|
|
401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
402
|
+
className: "panel overflow-hidden",
|
|
403
|
+
children: [
|
|
404
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
405
|
+
className: "panel-header px-4 py-2.5 sm:px-5",
|
|
406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
407
|
+
className: "text-[13px] font-medium text-sand-700",
|
|
408
|
+
children: "서버 제어"
|
|
409
|
+
})
|
|
410
|
+
}),
|
|
411
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
412
|
+
className: "px-4 py-3 sm:px-5 flex items-start justify-between gap-4",
|
|
413
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
414
|
+
className: "min-w-0",
|
|
415
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
416
|
+
className: "text-[13px] text-sand-800",
|
|
417
|
+
children: "qgrid 재시작"
|
|
418
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
419
|
+
className: "mt-0.5 text-[11px] text-sand-500",
|
|
420
|
+
children: supervisor ? "재시작 필요 설정을 반영하고 qgrid·Codex·Claude CLI를 확인합니다" : "로컬 실행 환경에서는 재시작할 수 없습니다"
|
|
421
|
+
})]
|
|
422
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
423
|
+
type: "button",
|
|
424
|
+
disabled: !supervisor || restartRequested || mutation.isPending,
|
|
425
|
+
onClick: () => setConfirming(true),
|
|
426
|
+
className: "shrink-0 px-2.5 py-1.5 text-[11px] font-medium rounded-lg border border-red-200 text-red-600 hover:bg-red-50 disabled:opacity-40 disabled:hover:bg-transparent transition-colors duration-150",
|
|
427
|
+
children: "재시작"
|
|
428
|
+
})]
|
|
429
|
+
}),
|
|
430
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
431
|
+
className: "px-4 pb-3 sm:px-5 text-[11px] text-red-500",
|
|
432
|
+
children: error
|
|
433
|
+
}),
|
|
434
|
+
confirming && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
435
|
+
className: "fixed inset-0 z-50 flex items-start justify-center pt-[15vh]",
|
|
436
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
437
|
+
className: "absolute inset-0 bg-sand-900/8 backdrop-blur-sm",
|
|
438
|
+
onClick: closeConfirmation,
|
|
439
|
+
onKeyDown: () => {}
|
|
440
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
441
|
+
className: "relative panel shadow-xl w-full max-w-sm mx-4",
|
|
442
|
+
children: [
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
444
|
+
className: "px-5 py-4 border-b border-sand-100/60",
|
|
445
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
|
|
446
|
+
className: "text-base font-medium text-sand-900",
|
|
447
|
+
children: restartRequested ? mutation.isPending ? "재시작 요청 중" : "서버 재연결 중" : "qgrid 재시작"
|
|
448
|
+
})
|
|
449
|
+
}),
|
|
450
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
451
|
+
className: "px-5 py-4 space-y-2",
|
|
452
|
+
children: [
|
|
453
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
454
|
+
className: "text-[13px] text-sand-700",
|
|
455
|
+
children: [
|
|
456
|
+
"워커가 다시 뜰 때까지 ",
|
|
457
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", {
|
|
458
|
+
className: "text-sand-900",
|
|
459
|
+
children: "1~2분간 요청이 실패"
|
|
460
|
+
}),
|
|
461
|
+
"합니다."
|
|
462
|
+
]
|
|
463
|
+
}),
|
|
464
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
465
|
+
className: "text-[12px] text-sand-500",
|
|
466
|
+
children: "서버를 종료하면 모니터링 도구가 다시 띄웁니다. 이때 재시작 필요 설정을 반영하고, qgrid와 Codex CLI·Claude Code의 최신 버전을 확인합니다."
|
|
467
|
+
}),
|
|
468
|
+
restartRequested && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
469
|
+
className: "text-[12px] font-medium text-sienna-600",
|
|
470
|
+
children: mutation.isPending ? "종료 요청을 처리하고 있습니다…" : sawUnavailable ? "새 서버가 준비될 때까지 연결을 확인하고 있습니다…" : "서버 종료를 기다리고 있습니다…"
|
|
471
|
+
})
|
|
472
|
+
]
|
|
473
|
+
}),
|
|
474
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
475
|
+
className: "px-5 py-3 border-t border-sand-100/60 flex justify-end gap-2",
|
|
476
|
+
children: [!restartRequested && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
477
|
+
type: "button",
|
|
478
|
+
onClick: closeConfirmation,
|
|
479
|
+
className: "px-3 py-1.5 text-[12px] rounded-lg text-sand-600 hover:bg-sand-100 transition-colors duration-150",
|
|
480
|
+
children: "취소"
|
|
481
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
482
|
+
type: "button",
|
|
483
|
+
disabled: restartRequested || mutation.isPending,
|
|
484
|
+
onClick: () => void restart(),
|
|
485
|
+
className: "px-3 py-1.5 text-[12px] font-medium rounded-lg bg-red-500 text-white hover:bg-red-600 disabled:opacity-50 transition-colors duration-150",
|
|
486
|
+
children: restartRequested ? mutation.isPending ? "요청 중" : "재연결 중" : "재시작"
|
|
487
|
+
})]
|
|
488
|
+
})
|
|
489
|
+
]
|
|
490
|
+
})]
|
|
491
|
+
})
|
|
492
|
+
]
|
|
493
|
+
});
|
|
494
|
+
}
|
|
304
495
|
function SettingsPanel() {
|
|
305
|
-
const
|
|
496
|
+
const settingsQuery = SettingService.useSettingList();
|
|
497
|
+
const { data, isLoading } = settingsQuery;
|
|
306
498
|
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
307
499
|
className: "space-y-4",
|
|
308
500
|
children: [0, 1].map((i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -323,51 +515,75 @@ function SettingsPanel() {
|
|
|
323
515
|
})]
|
|
324
516
|
}, i))
|
|
325
517
|
});
|
|
518
|
+
if (settingsQuery.isError && !data) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
519
|
+
className: "panel px-5 py-6 text-center",
|
|
520
|
+
children: [
|
|
521
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
522
|
+
className: "text-[13px] font-medium text-sand-800",
|
|
523
|
+
children: "설정을 불러오지 못했습니다"
|
|
524
|
+
}),
|
|
525
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
526
|
+
className: "mt-1 text-[11px] text-red-500",
|
|
527
|
+
children: settingsQuery.error.message
|
|
528
|
+
}),
|
|
529
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
530
|
+
type: "button",
|
|
531
|
+
onClick: () => void settingsQuery.refetch(),
|
|
532
|
+
disabled: settingsQuery.isFetching,
|
|
533
|
+
className: "mt-3 px-3 py-1.5 text-[12px] rounded-lg border border-sand-200 text-sand-600 hover:bg-sand-100 disabled:opacity-50",
|
|
534
|
+
children: settingsQuery.isFetching ? "다시 불러오는 중" : "다시 시도"
|
|
535
|
+
})
|
|
536
|
+
]
|
|
537
|
+
});
|
|
326
538
|
const settings = data?.settings ?? [];
|
|
327
539
|
const runtime = data?.runtime ?? [];
|
|
328
540
|
const groups = [...new Set(settings.map((s) => s.group))];
|
|
329
541
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
330
542
|
className: "space-y-4",
|
|
331
|
-
children: [
|
|
332
|
-
|
|
333
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
334
|
-
className: "panel-header flex items-center justify-between px-4 py-2.5 sm:px-5",
|
|
335
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
336
|
-
className: "text-[13px] font-medium text-sand-700",
|
|
337
|
-
children: "환경"
|
|
338
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
339
|
-
className: "text-[11px] text-sand-400",
|
|
340
|
-
children: "기동 시점 값"
|
|
341
|
-
})]
|
|
342
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
|
|
343
|
-
className: "px-4 py-3 sm:px-5 grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-1.5",
|
|
344
|
-
children: runtime.map((info) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
345
|
-
className: "flex items-baseline justify-between gap-3 min-w-0",
|
|
346
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
347
|
-
className: "text-[11px] text-sand-500 shrink-0",
|
|
348
|
-
children: info.label
|
|
349
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
350
|
-
className: "text-[12px] font-mono text-sand-700 truncate",
|
|
351
|
-
children: info.value
|
|
352
|
-
})]
|
|
353
|
-
}, info.label))
|
|
354
|
-
})]
|
|
355
|
-
}), groups.map((group) => {
|
|
356
|
-
const items = settings.filter((s) => s.group === group);
|
|
357
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
543
|
+
children: [
|
|
544
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
358
545
|
className: "panel overflow-hidden",
|
|
359
546
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
360
547
|
className: "panel-header flex items-center justify-between px-4 py-2.5 sm:px-5",
|
|
361
548
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
362
549
|
className: "text-[13px] font-medium text-sand-700",
|
|
363
|
-
children:
|
|
364
|
-
}),
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
550
|
+
children: "환경"
|
|
551
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
552
|
+
className: "text-[11px] text-sand-400",
|
|
553
|
+
children: "기동 시점 값"
|
|
554
|
+
})]
|
|
555
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
|
|
556
|
+
className: "px-4 py-3 sm:px-5 grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-1.5",
|
|
557
|
+
children: runtime.map((info) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
558
|
+
className: "flex items-baseline justify-between gap-3 min-w-0",
|
|
559
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
|
|
560
|
+
className: "text-[11px] text-sand-500 shrink-0",
|
|
561
|
+
children: info.label
|
|
562
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
|
|
563
|
+
className: "text-[12px] font-mono text-sand-700 truncate",
|
|
564
|
+
children: info.value
|
|
565
|
+
})]
|
|
566
|
+
}, info.label))
|
|
368
567
|
})]
|
|
369
|
-
},
|
|
370
|
-
|
|
568
|
+
}),
|
|
569
|
+
groups.map((group) => {
|
|
570
|
+
const items = settings.filter((s) => s.group === group);
|
|
571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
572
|
+
className: "panel overflow-hidden",
|
|
573
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
574
|
+
className: "panel-header flex items-center justify-between px-4 py-2.5 sm:px-5",
|
|
575
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
576
|
+
className: "text-[13px] font-medium text-sand-700",
|
|
577
|
+
children: GROUP_LABELS[group] ?? group
|
|
578
|
+
}), group === "slack" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriggerReminderButton, {})]
|
|
579
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
580
|
+
className: "divide-y divide-sand-100/80",
|
|
581
|
+
children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingRow, { item }, item.key))
|
|
582
|
+
})]
|
|
583
|
+
}, group);
|
|
584
|
+
}),
|
|
585
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RestartPanel, { supervisor: data?.supervisor ?? null })
|
|
586
|
+
]
|
|
371
587
|
});
|
|
372
588
|
}
|
|
373
589
|
//#endregion
|