@open-mercato/core 0.6.2-develop.3330.1.8ad2b3b84c → 0.6.2-develop.3366.1.4692954e44
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/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/sync_excel_upload/index.js +37 -0
- package/dist/generated/entities/sync_excel_upload/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +4 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +19 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/customers/search.js +3 -2
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/cancel.js +16 -0
- package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
- package/dist/modules/data_sync/di.js +2 -1
- package/dist/modules/data_sync/di.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js +178 -54
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-run-service.js +23 -0
- package/dist/modules/data_sync/lib/sync-run-service.js.map +3 -3
- package/dist/modules/integrations/backend/integrations/[id]/page.js +241 -55
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +3 -3
- package/dist/modules/sync_excel/acl.js +10 -0
- package/dist/modules/sync_excel/acl.js.map +7 -0
- package/dist/modules/sync_excel/api/import/route.js +164 -0
- package/dist/modules/sync_excel/api/import/route.js.map +7 -0
- package/dist/modules/sync_excel/api/preview/route.js +84 -0
- package/dist/modules/sync_excel/api/preview/route.js.map +7 -0
- package/dist/modules/sync_excel/api/upload/route.js +131 -0
- package/dist/modules/sync_excel/api/upload/route.js.map +7 -0
- package/dist/modules/sync_excel/data/entities.js +79 -0
- package/dist/modules/sync_excel/data/entities.js.map +7 -0
- package/dist/modules/sync_excel/data/validators.js +58 -0
- package/dist/modules/sync_excel/data/validators.js.map +7 -0
- package/dist/modules/sync_excel/di.js +11 -0
- package/dist/modules/sync_excel/di.js.map +7 -0
- package/dist/modules/sync_excel/index.js +11 -0
- package/dist/modules/sync_excel/index.js.map +7 -0
- package/dist/modules/sync_excel/integration.js +36 -0
- package/dist/modules/sync_excel/integration.js.map +7 -0
- package/dist/modules/sync_excel/lib/adapters/customers.js +852 -0
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +7 -0
- package/dist/modules/sync_excel/lib/column-detector.js +77 -0
- package/dist/modules/sync_excel/lib/column-detector.js.map +7 -0
- package/dist/modules/sync_excel/lib/mapping.js +16 -0
- package/dist/modules/sync_excel/lib/mapping.js.map +7 -0
- package/dist/modules/sync_excel/lib/parser.js +125 -0
- package/dist/modules/sync_excel/lib/parser.js.map +7 -0
- package/dist/modules/sync_excel/lib/scope.js +44 -0
- package/dist/modules/sync_excel/lib/scope.js.map +7 -0
- package/dist/modules/sync_excel/lib/upload-storage.js +63 -0
- package/dist/modules/sync_excel/lib/upload-storage.js.map +7 -0
- package/dist/modules/sync_excel/migrations/Migration20260329181120_sync_excel.js +11 -0
- package/dist/modules/sync_excel/migrations/Migration20260329181120_sync_excel.js.map +7 -0
- package/dist/modules/sync_excel/setup.js +19 -0
- package/dist/modules/sync_excel/setup.js.map +7 -0
- package/dist/modules/sync_excel/widgets/injection/upload-config/target-options.js +293 -0
- package/dist/modules/sync_excel/widgets/injection/upload-config/target-options.js.map +7 -0
- package/dist/modules/sync_excel/widgets/injection/upload-config/widget.client.js +934 -0
- package/dist/modules/sync_excel/widgets/injection/upload-config/widget.client.js.map +7 -0
- package/dist/modules/sync_excel/widgets/injection/upload-config/widget.js +15 -0
- package/dist/modules/sync_excel/widgets/injection/upload-config/widget.js.map +7 -0
- package/dist/modules/sync_excel/widgets/injection-table.js +17 -0
- package/dist/modules/sync_excel/widgets/injection-table.js.map +7 -0
- package/generated/entities/sync_excel_upload/index.ts +17 -0
- package/generated/entities.ids.generated.ts +4 -0
- package/generated/entity-fields-registry.ts +19 -0
- package/package.json +7 -7
- package/src/modules/customers/search.ts +3 -2
- package/src/modules/data_sync/api/runs/[id]/cancel.ts +18 -0
- package/src/modules/data_sync/di.ts +4 -1
- package/src/modules/data_sync/lib/adapter.ts +15 -0
- package/src/modules/data_sync/lib/sync-engine.ts +205 -52
- package/src/modules/data_sync/lib/sync-run-service.ts +24 -0
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +220 -15
- package/src/modules/integrations/i18n/de.json +9 -0
- package/src/modules/integrations/i18n/en.json +9 -0
- package/src/modules/integrations/i18n/es.json +9 -0
- package/src/modules/integrations/i18n/pl.json +9 -0
- package/src/modules/sync_excel/acl.ts +6 -0
- package/src/modules/sync_excel/api/import/route.ts +182 -0
- package/src/modules/sync_excel/api/preview/route.ts +89 -0
- package/src/modules/sync_excel/api/upload/route.ts +144 -0
- package/src/modules/sync_excel/data/entities.ts +61 -0
- package/src/modules/sync_excel/data/validators.ts +58 -0
- package/src/modules/sync_excel/di.ts +9 -0
- package/src/modules/sync_excel/i18n/de.json +107 -0
- package/src/modules/sync_excel/i18n/en.json +107 -0
- package/src/modules/sync_excel/i18n/es.json +107 -0
- package/src/modules/sync_excel/i18n/pl.json +107 -0
- package/src/modules/sync_excel/index.ts +7 -0
- package/src/modules/sync_excel/integration.ts +31 -0
- package/src/modules/sync_excel/lib/adapters/customers.ts +1097 -0
- package/src/modules/sync_excel/lib/column-detector.ts +91 -0
- package/src/modules/sync_excel/lib/mapping.ts +19 -0
- package/src/modules/sync_excel/lib/parser.ts +165 -0
- package/src/modules/sync_excel/lib/scope.ts +63 -0
- package/src/modules/sync_excel/lib/upload-storage.ts +79 -0
- package/src/modules/sync_excel/migrations/.snapshot-open-mercato.json +199 -0
- package/src/modules/sync_excel/migrations/Migration20260329181120_sync_excel.ts +10 -0
- package/src/modules/sync_excel/setup.ts +20 -0
- package/src/modules/sync_excel/widgets/injection/upload-config/target-options.ts +351 -0
- package/src/modules/sync_excel/widgets/injection/upload-config/widget.client.tsx +1224 -0
- package/src/modules/sync_excel/widgets/injection/upload-config/widget.ts +30 -0
- package/src/modules/sync_excel/widgets/injection-table.ts +15 -0
|
@@ -47,6 +47,11 @@ const UNSUPPORTED_CREDENTIAL_FIELD_TYPES = /* @__PURE__ */ new Set(["oauth", "ss
|
|
|
47
47
|
function isEditableCredentialField(field) {
|
|
48
48
|
return !UNSUPPORTED_CREDENTIAL_FIELD_TYPES.has(field.type);
|
|
49
49
|
}
|
|
50
|
+
const LOG_LEVEL_STYLES = {
|
|
51
|
+
info: "bg-blue-100 text-blue-800",
|
|
52
|
+
warn: "bg-yellow-100 text-yellow-800",
|
|
53
|
+
error: "bg-red-100 text-red-800"
|
|
54
|
+
};
|
|
50
55
|
const HEALTH_STATUS_STYLES = {
|
|
51
56
|
healthy: "bg-green-100 text-green-800",
|
|
52
57
|
degraded: "bg-yellow-100 text-yellow-800",
|
|
@@ -59,6 +64,66 @@ const HEALTH_STATUS_ICONS = {
|
|
|
59
64
|
unhealthy: XCircle,
|
|
60
65
|
unconfigured: AlertTriangle
|
|
61
66
|
};
|
|
67
|
+
function formatRunStatusLabel(status, t) {
|
|
68
|
+
switch (status) {
|
|
69
|
+
case "pending":
|
|
70
|
+
return t("integrations.detail.runActivity.status.pending", "Pending");
|
|
71
|
+
case "running":
|
|
72
|
+
return t("integrations.detail.runActivity.status.running", "Running");
|
|
73
|
+
case "completed":
|
|
74
|
+
return t("integrations.detail.runActivity.status.completed", "Completed");
|
|
75
|
+
case "failed":
|
|
76
|
+
return t("integrations.detail.runActivity.status.failed", "Failed");
|
|
77
|
+
case "cancelled":
|
|
78
|
+
return t("integrations.detail.runActivity.status.cancelled", "Cancelled");
|
|
79
|
+
default:
|
|
80
|
+
return status;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function RunActivityStrip({
|
|
84
|
+
run,
|
|
85
|
+
refreshedAt,
|
|
86
|
+
isRefreshing,
|
|
87
|
+
onRefresh,
|
|
88
|
+
t
|
|
89
|
+
}) {
|
|
90
|
+
if (!run) return null;
|
|
91
|
+
const progress = typeof run.progressJob?.progressPercent === "number" ? run.progressJob.progressPercent : 0;
|
|
92
|
+
const processed = typeof run.progressJob?.processedCount === "number" ? run.progressJob.processedCount : 0;
|
|
93
|
+
const total = typeof run.progressJob?.totalCount === "number" ? run.progressJob.totalCount : null;
|
|
94
|
+
const statusClass = run.status === "completed" ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300" : run.status === "failed" ? "border-red-500/30 bg-red-500/10 text-red-700 dark:text-red-300" : run.status === "cancelled" ? "border-zinc-500/30 bg-zinc-500/10 text-zinc-700 dark:text-zinc-300" : "border-blue-500/30 bg-blue-500/10 text-blue-700 dark:text-blue-300";
|
|
95
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border bg-muted/20 px-4 py-3 text-sm", children: [
|
|
96
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "outline", className: cn("gap-1.5", statusClass), children: [
|
|
97
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: cn("h-3.5 w-3.5", run.status === "running" ? "animate-spin" : "") }),
|
|
98
|
+
formatRunStatusLabel(run.status, t)
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
101
|
+
t("integrations.detail.runActivity.processed", "Processed"),
|
|
102
|
+
": ",
|
|
103
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
|
|
104
|
+
processed,
|
|
105
|
+
total !== null ? ` / ${total}` : ""
|
|
106
|
+
] })
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
109
|
+
t("integrations.detail.runActivity.progress", "Progress"),
|
|
110
|
+
": ",
|
|
111
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
|
|
112
|
+
progress,
|
|
113
|
+
"%"
|
|
114
|
+
] })
|
|
115
|
+
] }),
|
|
116
|
+
refreshedAt ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
117
|
+
t("integrations.detail.runActivity.lastRefreshed", "Last refreshed"),
|
|
118
|
+
": ",
|
|
119
|
+
new Date(refreshedAt).toLocaleTimeString()
|
|
120
|
+
] }) : null,
|
|
121
|
+
/* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "ml-auto", onClick: onRefresh, disabled: isRefreshing, children: [
|
|
122
|
+
isRefreshing ? /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "mr-2 h-4 w-4" }),
|
|
123
|
+
t("integrations.detail.runActivity.refresh", "Refresh")
|
|
124
|
+
] })
|
|
125
|
+
] });
|
|
126
|
+
}
|
|
62
127
|
function DetailLogSparkline({ counts, className }) {
|
|
63
128
|
const max = Math.max(1, ...counts);
|
|
64
129
|
const w = 120;
|
|
@@ -217,6 +282,9 @@ function IntegrationDetailPage({ params }) {
|
|
|
217
282
|
const [isCheckingHealth, setIsCheckingHealth] = React.useState(false);
|
|
218
283
|
const [isTogglingState, setIsTogglingState] = React.useState(false);
|
|
219
284
|
const [latestHealthResult, setLatestHealthResult] = React.useState(null);
|
|
285
|
+
const [activeRunDetail, setActiveRunDetail] = React.useState(null);
|
|
286
|
+
const [activeRunRefreshedAt, setActiveRunRefreshedAt] = React.useState(null);
|
|
287
|
+
const [isRefreshingRunActivity, setIsRefreshingRunActivity] = React.useState(false);
|
|
220
288
|
const [activeTab, setActiveTab] = React.useState("credentials");
|
|
221
289
|
const credentialsFormId = React.useId();
|
|
222
290
|
const resolveCurrentIntegrationId = React.useCallback(() => {
|
|
@@ -297,6 +365,35 @@ function IntegrationDetailPage({ params }) {
|
|
|
297
365
|
const refreshLogs = React.useCallback(async () => {
|
|
298
366
|
await loadLogs();
|
|
299
367
|
}, [loadLogs]);
|
|
368
|
+
const refreshHealthSnapshot = React.useCallback(async () => {
|
|
369
|
+
await loadDetail();
|
|
370
|
+
}, [loadDetail]);
|
|
371
|
+
const runIdFromUrl = searchParams?.get("runId") ?? null;
|
|
372
|
+
const refreshRunActivity = React.useCallback(async (options) => {
|
|
373
|
+
if (!runIdFromUrl) {
|
|
374
|
+
setActiveRunDetail(null);
|
|
375
|
+
setActiveRunRefreshedAt(null);
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
if (options?.showLoading) setIsRefreshingRunActivity(true);
|
|
379
|
+
try {
|
|
380
|
+
const call = await apiCall(
|
|
381
|
+
`/api/data_sync/runs/${encodeURIComponent(runIdFromUrl)}`,
|
|
382
|
+
void 0,
|
|
383
|
+
{ fallback: null }
|
|
384
|
+
);
|
|
385
|
+
await loadLogs();
|
|
386
|
+
await loadDetail();
|
|
387
|
+
if (call.ok && call.result) {
|
|
388
|
+
setActiveRunDetail(call.result);
|
|
389
|
+
setActiveRunRefreshedAt((/* @__PURE__ */ new Date()).toISOString());
|
|
390
|
+
return call.result;
|
|
391
|
+
}
|
|
392
|
+
return null;
|
|
393
|
+
} finally {
|
|
394
|
+
if (options?.showLoading) setIsRefreshingRunActivity(false);
|
|
395
|
+
}
|
|
396
|
+
}, [loadDetail, loadLogs, runIdFromUrl]);
|
|
300
397
|
const injectionContext = React.useMemo(
|
|
301
398
|
() => ({
|
|
302
399
|
formId: mutationContextId,
|
|
@@ -313,6 +410,7 @@ function IntegrationDetailPage({ params }) {
|
|
|
313
410
|
setActiveTab,
|
|
314
411
|
refreshDetail,
|
|
315
412
|
refreshLogs,
|
|
413
|
+
refreshHealthSnapshot,
|
|
316
414
|
retryLastMutation
|
|
317
415
|
}),
|
|
318
416
|
[
|
|
@@ -324,6 +422,7 @@ function IntegrationDetailPage({ params }) {
|
|
|
324
422
|
latestHealthResult,
|
|
325
423
|
mutationContextId,
|
|
326
424
|
refreshDetail,
|
|
425
|
+
refreshHealthSnapshot,
|
|
327
426
|
refreshLogs,
|
|
328
427
|
retryLastMutation
|
|
329
428
|
]
|
|
@@ -571,8 +670,12 @@ function IntegrationDetailPage({ params }) {
|
|
|
571
670
|
});
|
|
572
671
|
}), [editableCredentialFields, t]);
|
|
573
672
|
const latestHealthLog = React.useMemo(() => logs.find(isHealthLog) ?? null, [logs]);
|
|
574
|
-
const
|
|
575
|
-
|
|
673
|
+
const latestOperationalLog = React.useMemo(
|
|
674
|
+
() => logs.find((log) => typeof log.payload?.operationalStatus === "string" || typeof log.payload?.summary === "string") ?? null,
|
|
675
|
+
[logs]
|
|
676
|
+
);
|
|
677
|
+
const healthMessage = latestHealthResult?.message ?? (typeof latestHealthLog?.payload?.message === "string" ? latestHealthLog.payload.message : typeof latestOperationalLog?.payload?.summary === "string" ? latestOperationalLog.payload.summary : null);
|
|
678
|
+
const healthDetailsSource = latestHealthResult?.details ?? extractHealthDetails(latestHealthLog?.payload ?? latestOperationalLog?.payload);
|
|
576
679
|
const healthDetails = latestHealthLog?.code ? { ...healthDetailsSource, code: latestHealthLog.code } : healthDetailsSource;
|
|
577
680
|
const healthDetailEntries = Object.entries(healthDetails);
|
|
578
681
|
const resolvedIntegration = detail?.integration ?? null;
|
|
@@ -622,8 +725,37 @@ function IntegrationDetailPage({ params }) {
|
|
|
622
725
|
setActiveTab(nextTab);
|
|
623
726
|
if (!currentIntegrationId) return;
|
|
624
727
|
const basePath = `/backend/integrations/${encodeURIComponent(currentIntegrationId)}`;
|
|
625
|
-
|
|
626
|
-
|
|
728
|
+
const params2 = new URLSearchParams(searchParams?.toString() ?? "");
|
|
729
|
+
if (nextTab === "credentials") params2.delete("tab");
|
|
730
|
+
else params2.set("tab", nextTab);
|
|
731
|
+
const query = params2.toString();
|
|
732
|
+
router.replace(query ? `${basePath}?${query}` : basePath);
|
|
733
|
+
}, [resolveCurrentIntegrationId, router, searchParams, visibleTabIds]);
|
|
734
|
+
React.useEffect(() => {
|
|
735
|
+
if (!runIdFromUrl) {
|
|
736
|
+
setActiveRunDetail(null);
|
|
737
|
+
setActiveRunRefreshedAt(null);
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
if (activeTab !== "logs" && activeTab !== "health") return;
|
|
741
|
+
let cancelled = false;
|
|
742
|
+
let timeoutId = null;
|
|
743
|
+
const poll = async () => {
|
|
744
|
+
const detail2 = await refreshRunActivity();
|
|
745
|
+
if (cancelled) return;
|
|
746
|
+
const status = detail2?.status ?? null;
|
|
747
|
+
if (status === "pending" || status === "running") {
|
|
748
|
+
timeoutId = setTimeout(() => {
|
|
749
|
+
void poll();
|
|
750
|
+
}, 4e3);
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
void poll();
|
|
754
|
+
return () => {
|
|
755
|
+
cancelled = true;
|
|
756
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
757
|
+
};
|
|
758
|
+
}, [activeTab, refreshRunActivity, runIdFromUrl]);
|
|
627
759
|
if (isLoading) return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(LoadingMessage, { label: t("integrations.detail.title") }) }) });
|
|
628
760
|
if (error || !detail || !resolvedIntegration || !resolvedState) {
|
|
629
761
|
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(ErrorMessage, { label: error ?? t("integrations.detail.loadError") }) }) });
|
|
@@ -855,67 +987,121 @@ function IntegrationDetailPage({ params }) {
|
|
|
855
987
|
isEnabled: resolvedState.isEnabled
|
|
856
988
|
}
|
|
857
989
|
) }) : null,
|
|
858
|
-
showHealthTab ? /* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */ jsx(
|
|
860
|
-
|
|
990
|
+
showHealthTab ? /* @__PURE__ */ jsxs(TabsContent, { value: "health", className: "mt-0 space-y-4", children: [
|
|
991
|
+
/* @__PURE__ */ jsx(
|
|
992
|
+
RunActivityStrip,
|
|
993
|
+
{
|
|
994
|
+
run: activeRunDetail,
|
|
995
|
+
refreshedAt: activeRunRefreshedAt,
|
|
996
|
+
isRefreshing: isRefreshingRunActivity,
|
|
997
|
+
onRefresh: () => void refreshRunActivity({ showLoading: true }),
|
|
998
|
+
t
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
/* @__PURE__ */ jsxs(Card, { className: "gap-4 py-4", children: [
|
|
1002
|
+
/* @__PURE__ */ jsx(CardHeader, { className: "px-5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1003
|
+
/* @__PURE__ */ jsx(CardTitle, { children: t("integrations.detail.health.title") }),
|
|
1004
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1005
|
+
/* @__PURE__ */ jsxs(
|
|
1006
|
+
Button,
|
|
1007
|
+
{
|
|
1008
|
+
type: "button",
|
|
1009
|
+
variant: "outline",
|
|
1010
|
+
size: "sm",
|
|
1011
|
+
onClick: () => void refreshRunActivity({ showLoading: true }),
|
|
1012
|
+
disabled: isRefreshingRunActivity || !runIdFromUrl,
|
|
1013
|
+
children: [
|
|
1014
|
+
isRefreshingRunActivity ? /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "mr-2 h-4 w-4" }),
|
|
1015
|
+
t("integrations.detail.runActivity.refresh", "Refresh")
|
|
1016
|
+
]
|
|
1017
|
+
}
|
|
1018
|
+
),
|
|
1019
|
+
/* @__PURE__ */ jsxs(
|
|
1020
|
+
Button,
|
|
1021
|
+
{
|
|
1022
|
+
type: "button",
|
|
1023
|
+
variant: "outline",
|
|
1024
|
+
size: "sm",
|
|
1025
|
+
onClick: () => void handleHealthCheck(),
|
|
1026
|
+
disabled: isCheckingHealth,
|
|
1027
|
+
children: [
|
|
1028
|
+
isCheckingHealth ? /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ jsx(Zap, { className: "mr-2 h-4 w-4" }),
|
|
1029
|
+
isCheckingHealth ? t("integrations.detail.health.checking") : t("integrations.detail.health.check")
|
|
1030
|
+
]
|
|
1031
|
+
}
|
|
1032
|
+
)
|
|
1033
|
+
] })
|
|
1034
|
+
] }) }),
|
|
1035
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-3 px-5", children: [
|
|
1036
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border bg-muted/20 px-4 py-3", children: [
|
|
1037
|
+
displayHealthStatus ? /* @__PURE__ */ jsxs(Badge, { className: `gap-1.5 ${HEALTH_STATUS_STYLES[displayHealthStatus] ?? ""}`, children: [
|
|
1038
|
+
HealthStatusIcon ? /* @__PURE__ */ jsx(HealthStatusIcon, { className: "h-3.5 w-3.5" }) : null,
|
|
1039
|
+
t(`integrations.detail.health.${displayHealthStatus}`)
|
|
1040
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
1041
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" }),
|
|
1042
|
+
/* @__PURE__ */ jsx("span", { children: t("integrations.detail.health.unknown") })
|
|
1043
|
+
] }),
|
|
1044
|
+
healthStatusDescription ? /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 text-sm text-muted-foreground", children: healthStatusDescription }) : null,
|
|
1045
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground md:ml-auto", children: resolvedState.lastHealthCheckedAt ? t("integrations.detail.health.lastChecked", { date: new Date(resolvedState.lastHealthCheckedAt).toLocaleString() }) : t("integrations.detail.health.neverChecked") })
|
|
1046
|
+
] }),
|
|
1047
|
+
healthMessage || healthDetailEntries.length > 0 ? /* @__PURE__ */ jsxs("div", { className: `grid gap-3 ${healthMessage && healthDetailEntries.length > 0 ? "xl:grid-cols-[minmax(0,1.25fr)_minmax(0,1fr)]" : ""}`, children: [
|
|
1048
|
+
healthMessage ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border px-4 py-3", children: [
|
|
1049
|
+
/* @__PURE__ */ jsx("p", { className: "text-overline font-medium uppercase tracking-widest text-muted-foreground", children: t("integrations.detail.health.lastResult", "Last result") }),
|
|
1050
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm", children: healthMessage })
|
|
1051
|
+
] }) : null,
|
|
1052
|
+
healthDetailEntries.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border px-4 py-3", children: [
|
|
1053
|
+
/* @__PURE__ */ jsx("p", { className: "text-overline font-medium uppercase tracking-widest text-muted-foreground", children: t("integrations.detail.health.details", "Details") }),
|
|
1054
|
+
/* @__PURE__ */ jsx("dl", { className: "mt-2 grid gap-x-6 gap-y-2 sm:grid-cols-2", children: healthDetailEntries.map(([key, value]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
1055
|
+
/* @__PURE__ */ jsx("dt", { className: "text-xs font-medium text-muted-foreground", children: formatLogDetailLabel(key) }),
|
|
1056
|
+
/* @__PURE__ */ jsx("dd", { className: "mt-0.5 text-sm", children: formatHealthValue(value) })
|
|
1057
|
+
] }, key)) })
|
|
1058
|
+
] }) : null
|
|
1059
|
+
] }) : null
|
|
1060
|
+
] })
|
|
1061
|
+
] })
|
|
1062
|
+
] }) : null,
|
|
1063
|
+
showLogsTab ? /* @__PURE__ */ jsxs(TabsContent, { value: "logs", className: "mt-0 space-y-4", children: [
|
|
1064
|
+
/* @__PURE__ */ jsx(
|
|
1065
|
+
RunActivityStrip,
|
|
1066
|
+
{
|
|
1067
|
+
run: activeRunDetail,
|
|
1068
|
+
refreshedAt: activeRunRefreshedAt,
|
|
1069
|
+
isRefreshing: isRefreshingRunActivity,
|
|
1070
|
+
onRefresh: () => void refreshRunActivity({ showLoading: true }),
|
|
1071
|
+
t
|
|
1072
|
+
}
|
|
1073
|
+
),
|
|
1074
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1075
|
+
/* @__PURE__ */ jsx("div", { className: "inline-flex", children: /* @__PURE__ */ jsxs(
|
|
1076
|
+
Select,
|
|
1077
|
+
{
|
|
1078
|
+
value: logLevel || void 0,
|
|
1079
|
+
onValueChange: (value) => setLogLevel(value ?? ""),
|
|
1080
|
+
children: [
|
|
1081
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "lg", className: "min-w-40", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("integrations.detail.logs.level.all") }) }),
|
|
1082
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
1083
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "info", children: t("integrations.detail.logs.level.info") }),
|
|
1084
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "warn", children: t("integrations.detail.logs.level.warn") }),
|
|
1085
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "error", children: t("integrations.detail.logs.level.error") })
|
|
1086
|
+
] })
|
|
1087
|
+
]
|
|
1088
|
+
}
|
|
1089
|
+
) }),
|
|
861
1090
|
/* @__PURE__ */ jsxs(
|
|
862
1091
|
Button,
|
|
863
1092
|
{
|
|
864
1093
|
type: "button",
|
|
865
1094
|
variant: "outline",
|
|
866
1095
|
size: "sm",
|
|
867
|
-
onClick: () => void
|
|
868
|
-
disabled:
|
|
1096
|
+
onClick: () => void refreshRunActivity({ showLoading: true }),
|
|
1097
|
+
disabled: isRefreshingRunActivity || !runIdFromUrl,
|
|
869
1098
|
children: [
|
|
870
|
-
|
|
871
|
-
|
|
1099
|
+
isRefreshingRunActivity ? /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "mr-2 h-4 w-4" }),
|
|
1100
|
+
t("integrations.detail.runActivity.refresh", "Refresh")
|
|
872
1101
|
]
|
|
873
1102
|
}
|
|
874
1103
|
)
|
|
875
|
-
] })
|
|
876
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-3 px-5", children: [
|
|
877
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 rounded-lg border bg-muted/20 px-4 py-3", children: [
|
|
878
|
-
displayHealthStatus ? /* @__PURE__ */ jsxs(Badge, { className: `gap-1.5 ${HEALTH_STATUS_STYLES[displayHealthStatus] ?? ""}`, children: [
|
|
879
|
-
HealthStatusIcon ? /* @__PURE__ */ jsx(HealthStatusIcon, { className: "h-3.5 w-3.5" }) : null,
|
|
880
|
-
t(`integrations.detail.health.${displayHealthStatus}`)
|
|
881
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
882
|
-
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" }),
|
|
883
|
-
/* @__PURE__ */ jsx("span", { children: t("integrations.detail.health.unknown") })
|
|
884
|
-
] }),
|
|
885
|
-
healthStatusDescription ? /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 text-sm text-muted-foreground", children: healthStatusDescription }) : null,
|
|
886
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground md:ml-auto", children: resolvedState.lastHealthCheckedAt ? t("integrations.detail.health.lastChecked", { date: new Date(resolvedState.lastHealthCheckedAt).toLocaleString() }) : t("integrations.detail.health.neverChecked") })
|
|
887
|
-
] }),
|
|
888
|
-
healthMessage || healthDetailEntries.length > 0 ? /* @__PURE__ */ jsxs("div", { className: `grid gap-3 ${healthMessage && healthDetailEntries.length > 0 ? "xl:grid-cols-[minmax(0,1.25fr)_minmax(0,1fr)]" : ""}`, children: [
|
|
889
|
-
healthMessage ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border px-4 py-3", children: [
|
|
890
|
-
/* @__PURE__ */ jsx("p", { className: "text-overline font-medium uppercase tracking-widest text-muted-foreground", children: t("integrations.detail.health.lastResult", "Last result") }),
|
|
891
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm", children: healthMessage })
|
|
892
|
-
] }) : null,
|
|
893
|
-
healthDetailEntries.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border px-4 py-3", children: [
|
|
894
|
-
/* @__PURE__ */ jsx("p", { className: "text-overline font-medium uppercase tracking-widest text-muted-foreground", children: t("integrations.detail.health.details", "Details") }),
|
|
895
|
-
/* @__PURE__ */ jsx("dl", { className: "mt-2 grid gap-x-6 gap-y-2 sm:grid-cols-2", children: healthDetailEntries.map(([key, value]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
896
|
-
/* @__PURE__ */ jsx("dt", { className: "text-xs font-medium text-muted-foreground", children: formatLogDetailLabel(key) }),
|
|
897
|
-
/* @__PURE__ */ jsx("dd", { className: "mt-0.5 text-sm", children: formatHealthValue(value) })
|
|
898
|
-
] }, key)) })
|
|
899
|
-
] }) : null
|
|
900
|
-
] }) : null
|
|
901
|
-
] })
|
|
902
|
-
] }) }) : null,
|
|
903
|
-
showLogsTab ? /* @__PURE__ */ jsxs(TabsContent, { value: "logs", className: "mt-0 space-y-4", children: [
|
|
904
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsx("div", { className: "inline-flex", children: /* @__PURE__ */ jsxs(
|
|
905
|
-
Select,
|
|
906
|
-
{
|
|
907
|
-
value: logLevel || void 0,
|
|
908
|
-
onValueChange: (value) => setLogLevel(value ?? ""),
|
|
909
|
-
children: [
|
|
910
|
-
/* @__PURE__ */ jsx(SelectTrigger, { size: "lg", className: "min-w-40", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("integrations.detail.logs.level.all") }) }),
|
|
911
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
912
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "info", children: t("integrations.detail.logs.level.info") }),
|
|
913
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "warn", children: t("integrations.detail.logs.level.warn") }),
|
|
914
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "error", children: t("integrations.detail.logs.level.error") })
|
|
915
|
-
] })
|
|
916
|
-
]
|
|
917
|
-
}
|
|
918
|
-
) }) }),
|
|
1104
|
+
] }),
|
|
919
1105
|
isLoadingLogs ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-8", children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(
|
|
920
1106
|
LogList,
|
|
921
1107
|
{
|