@burdenoff/microfe-adaptercloud 2026.825.4 → 2026.829.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adaptercloud/AdapterCloudRoot.d.ts.map +1 -1
- package/dist/adaptercloud/AdapterCloudRoot.js +52 -55
- package/dist/adaptercloud/AdapterCloudRoot.js.map +1 -1
- package/dist/adaptercloud/components/ActiveSwitch.d.ts +17 -0
- package/dist/adaptercloud/components/ActiveSwitch.d.ts.map +1 -0
- package/dist/adaptercloud/components/ActiveSwitch.js +28 -0
- package/dist/adaptercloud/components/ActiveSwitch.js.map +1 -0
- package/dist/adaptercloud/components/index.d.ts +1 -0
- package/dist/adaptercloud/components/index.d.ts.map +1 -1
- package/dist/adaptercloud/hooks/index.d.ts +1 -0
- package/dist/adaptercloud/hooks/index.d.ts.map +1 -1
- package/dist/adaptercloud/hooks/useAdapterCloudApi.d.ts +28 -2
- package/dist/adaptercloud/hooks/useAdapterCloudApi.d.ts.map +1 -1
- package/dist/adaptercloud/hooks/useAdapterCloudApi.js +318 -291
- package/dist/adaptercloud/hooks/useAdapterCloudApi.js.map +1 -1
- package/dist/adaptercloud/hooks/useTr.d.ts +2 -0
- package/dist/adaptercloud/hooks/useTr.d.ts.map +1 -0
- package/dist/adaptercloud/hooks/useTr.js +14 -0
- package/dist/adaptercloud/hooks/useTr.js.map +1 -0
- package/dist/adaptercloud/pages/OverviewPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/OverviewPage.js +117 -120
- package/dist/adaptercloud/pages/OverviewPage.js.map +1 -1
- package/dist/adaptercloud/pages/adapters/AdaptersListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/adapters/AdaptersListPage.js +6 -5
- package/dist/adaptercloud/pages/adapters/AdaptersListPage.js.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionDetailPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionDetailPage.js +217 -104
- package/dist/adaptercloud/pages/connections/ConnectionDetailPage.js.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionsListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionsListPage.js +6 -5
- package/dist/adaptercloud/pages/connections/ConnectionsListPage.js.map +1 -1
- package/dist/adaptercloud/pages/costs/CostsPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/costs/CostsPage.js +183 -156
- package/dist/adaptercloud/pages/costs/CostsPage.js.map +1 -1
- package/dist/adaptercloud/pages/drift/DriftListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/drift/DriftListPage.js +108 -107
- package/dist/adaptercloud/pages/drift/DriftListPage.js.map +1 -1
- package/dist/adaptercloud/pages/policies/PoliciesListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/policies/PoliciesListPage.js +141 -131
- package/dist/adaptercloud/pages/policies/PoliciesListPage.js.map +1 -1
- package/dist/adaptercloud/pages/policies/PolicyDetailPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/policies/PolicyDetailPage.js +171 -117
- package/dist/adaptercloud/pages/policies/PolicyDetailPage.js.map +1 -1
- package/dist/adaptercloud/pages/resources/ResourcesListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/resources/ResourcesListPage.js +85 -66
- package/dist/adaptercloud/pages/resources/ResourcesListPage.js.map +1 -1
- package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.js +148 -121
- package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.js.map +1 -1
- package/dist/adaptercloud/pages/violations/ViolationsListPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/violations/ViolationsListPage.js +145 -144
- package/dist/adaptercloud/pages/violations/ViolationsListPage.js.map +1 -1
- package/dist/utils/pageContext.d.ts +0 -2
- package/dist/utils/pageContext.d.ts.map +1 -1
- package/dist/utils/pageContext.js +1 -3
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,88 +4,95 @@ import { PageLayout as n } from "../../components/PageLayout.js";
|
|
|
4
4
|
import { syncKindLabels as r, syncStatusLabels as i } from "../../utils/domain.js";
|
|
5
5
|
import { StatusBadge as a } from "../../components/StatusBadge.js";
|
|
6
6
|
import { DataState as o } from "../../components/DataState.js";
|
|
7
|
-
import { useCancelSyncRun as s,
|
|
8
|
-
import { formatDate as
|
|
9
|
-
import { ConfirmDialog as
|
|
10
|
-
import { useCallback as
|
|
11
|
-
import { useI18n as
|
|
12
|
-
import { Activity as
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
7
|
+
import { useCancelSyncRun as s, useConnections as c, useSyncRuns as l } from "../../hooks/useAdapterCloudApi.js";
|
|
8
|
+
import { formatDate as u } from "../../utils/formatters.js";
|
|
9
|
+
import { ConfirmDialog as d } from "../../components/ConfirmDialog.js";
|
|
10
|
+
import { useCallback as f, useState as p } from "react";
|
|
11
|
+
import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
12
|
+
import { Activity as h, Boxes as g, ChevronLeft as _, ChevronRight as v, Cloud as y, Cpu as b, Database as x, HardDrive as S, Loader2 as C, Network as w, Puzzle as T, Radio as E, Server as D, XCircle as O } from "lucide-react";
|
|
13
|
+
import { useSearchParams as k } from "react-router";
|
|
14
|
+
import { jsx as A, jsxs as j } from "react/jsx-runtime";
|
|
15
|
+
import { ResponsiveTable as M } from "@burdenoff/fe-libs/ui";
|
|
15
16
|
//#region src/adaptercloud/pages/sync-runs/SyncRunsListPage.tsx
|
|
16
|
-
var
|
|
17
|
-
PUBLIC_CLOUD:
|
|
18
|
-
PRIVATE_CLOUD:
|
|
19
|
-
SAAS:
|
|
20
|
-
ON_PREM:
|
|
21
|
-
EDGE:
|
|
22
|
-
IOT:
|
|
23
|
-
KUBERNETES:
|
|
24
|
-
NETWORK:
|
|
25
|
-
DATA_SYSTEM:
|
|
26
|
-
CUSTOM:
|
|
27
|
-
},
|
|
17
|
+
var N = 20, P = 100, F = {
|
|
18
|
+
PUBLIC_CLOUD: y,
|
|
19
|
+
PRIVATE_CLOUD: y,
|
|
20
|
+
SAAS: y,
|
|
21
|
+
ON_PREM: S,
|
|
22
|
+
EDGE: E,
|
|
23
|
+
IOT: b,
|
|
24
|
+
KUBERNETES: g,
|
|
25
|
+
NETWORK: w,
|
|
26
|
+
DATA_SYSTEM: x,
|
|
27
|
+
CUSTOM: T
|
|
28
|
+
}, I = {
|
|
28
29
|
DISCOVERY: "bg-accent-blue-subtle text-accent-blue",
|
|
29
30
|
RECONCILE: "bg-status-warning-bg-subtle text-status-warning-text",
|
|
30
31
|
COST_INGEST: "bg-accent-purple-subtle text-accent-purple",
|
|
31
32
|
FULL: "bg-bg-sunken text-text-secondary"
|
|
32
33
|
};
|
|
33
|
-
function
|
|
34
|
-
return /* @__PURE__ */
|
|
35
|
-
className: t("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
|
|
34
|
+
function L({ kind: e }) {
|
|
35
|
+
return /* @__PURE__ */ A("span", {
|
|
36
|
+
className: t("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium", I[e]),
|
|
36
37
|
children: r[e]
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
|
-
function
|
|
40
|
+
function R(e, t) {
|
|
40
41
|
if (!e || !t) return null;
|
|
41
42
|
let n = new Date(t).getTime() - new Date(e).getTime();
|
|
42
43
|
if (!Number.isFinite(n) || n < 0) return null;
|
|
43
44
|
let r = Math.floor(n / 1e3), i = Math.floor(r / 3600), a = Math.floor(r % 3600 / 60), o = r % 60;
|
|
44
45
|
return i > 0 ? `${i}h ${a}m ${o}s` : a > 0 ? `${a}m ${o}s` : `${o}s`;
|
|
45
46
|
}
|
|
46
|
-
function
|
|
47
|
-
let { navigateTo: t } = e(), { t: r } =
|
|
47
|
+
function z() {
|
|
48
|
+
let { navigateTo: t } = e(), { t: r } = m(), g = f((e, t) => {
|
|
48
49
|
let n = r(e);
|
|
49
50
|
return n === e ? t : n;
|
|
50
|
-
}, [r]), [
|
|
51
|
-
|
|
51
|
+
}, [r]), [y, b] = p(""), [x, S] = p(0), [w, T] = p(null), [E, I] = p(null), [z, B] = k(), V = z.get("connectionId") ?? "", H = c({ pagination: { limit: P } }).data?.items ?? [], U = !!V && !H.some((e) => e.id === V), W = f((e) => {
|
|
52
|
+
B((t) => {
|
|
53
|
+
let n = new URLSearchParams(t);
|
|
54
|
+
return e ? n.set("connectionId", e) : n.delete("connectionId"), n;
|
|
55
|
+
}, { replace: !0 }), S(0);
|
|
56
|
+
}, [B]), G = l({
|
|
57
|
+
connectionId: V || void 0,
|
|
58
|
+
status: y || void 0,
|
|
52
59
|
pagination: {
|
|
53
|
-
limit:
|
|
54
|
-
offset:
|
|
60
|
+
limit: N,
|
|
61
|
+
offset: x
|
|
55
62
|
}
|
|
56
|
-
}),
|
|
57
|
-
|
|
58
|
-
onSuccess: () =>
|
|
59
|
-
onError: (e) =>
|
|
63
|
+
}), K = s(), q = G.data?.items ?? [], J = G.data?.pageInfo.hasMore ?? !1, Y = G.data?.pageInfo.totalCount, X = K.isPending ? K.variables : void 0, Z = f((e) => {
|
|
64
|
+
T(null), K.mutate(e, {
|
|
65
|
+
onSuccess: () => I(null),
|
|
66
|
+
onError: (e) => T(e instanceof Error ? e.message : "Failed to cancel run.")
|
|
60
67
|
});
|
|
61
|
-
}, [
|
|
68
|
+
}, [K]), Q = (e, t) => e.status === "QUEUED" || e.status === "RUNNING" ? /* @__PURE__ */ A("span", {
|
|
62
69
|
className: "text-text-tertiary",
|
|
63
70
|
children: "—"
|
|
64
|
-
}) : /* @__PURE__ */
|
|
71
|
+
}) : /* @__PURE__ */ A("span", {
|
|
65
72
|
className: "tabular-nums text-text-primary",
|
|
66
73
|
children: t
|
|
67
|
-
}),
|
|
74
|
+
}), $ = [
|
|
68
75
|
{
|
|
69
76
|
key: "kind",
|
|
70
|
-
header:
|
|
77
|
+
header: g("adaptercloud.syncRuns.kind", "Kind"),
|
|
71
78
|
priority: "primary",
|
|
72
|
-
cell: (e) => /* @__PURE__ */
|
|
79
|
+
cell: (e) => /* @__PURE__ */ A(L, { kind: e.kind })
|
|
73
80
|
},
|
|
74
81
|
{
|
|
75
82
|
key: "connection",
|
|
76
|
-
header:
|
|
83
|
+
header: g("adaptercloud.syncRuns.connection", "Connection"),
|
|
77
84
|
priority: "secondary",
|
|
78
85
|
cell: (e) => {
|
|
79
86
|
let t = e.connection?.adapter?.kind;
|
|
80
|
-
return /* @__PURE__ */
|
|
87
|
+
return /* @__PURE__ */ j("div", {
|
|
81
88
|
className: "flex min-w-0 items-center gap-2",
|
|
82
|
-
children: [/* @__PURE__ */
|
|
89
|
+
children: [/* @__PURE__ */ A("span", {
|
|
83
90
|
className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-bg-sunken text-text-secondary",
|
|
84
|
-
children: /* @__PURE__ */
|
|
85
|
-
}), e.connection?.name ? /* @__PURE__ */
|
|
91
|
+
children: /* @__PURE__ */ A(t ? F[t] : D, { className: "h-3.5 w-3.5" })
|
|
92
|
+
}), e.connection?.name ? /* @__PURE__ */ A("span", {
|
|
86
93
|
className: "truncate text-sm text-text-primary",
|
|
87
94
|
children: e.connection.name
|
|
88
|
-
}) : /* @__PURE__ */
|
|
95
|
+
}) : /* @__PURE__ */ A("span", {
|
|
89
96
|
className: "text-sm text-text-tertiary",
|
|
90
97
|
children: "—"
|
|
91
98
|
})]
|
|
@@ -94,14 +101,14 @@ function I() {
|
|
|
94
101
|
},
|
|
95
102
|
{
|
|
96
103
|
key: "status",
|
|
97
|
-
header:
|
|
104
|
+
header: g("adaptercloud.syncRuns.status", "Status"),
|
|
98
105
|
priority: "secondary",
|
|
99
|
-
cell: (e) => /* @__PURE__ */
|
|
106
|
+
cell: (e) => /* @__PURE__ */ j("div", {
|
|
100
107
|
className: "flex flex-col gap-1",
|
|
101
|
-
children: [/* @__PURE__ */
|
|
108
|
+
children: [/* @__PURE__ */ A(a, {
|
|
102
109
|
status: e.status,
|
|
103
110
|
label: i[e.status]
|
|
104
|
-
}), e.error && /* @__PURE__ */
|
|
111
|
+
}), e.error && /* @__PURE__ */ A("span", {
|
|
105
112
|
className: "max-w-xs truncate text-xs text-status-error-text",
|
|
106
113
|
title: e.error,
|
|
107
114
|
children: e.error
|
|
@@ -110,170 +117,190 @@ function I() {
|
|
|
110
117
|
},
|
|
111
118
|
{
|
|
112
119
|
key: "discovered",
|
|
113
|
-
header:
|
|
120
|
+
header: g("adaptercloud.syncRuns.discovered", "Discovered"),
|
|
114
121
|
priority: "secondary",
|
|
115
122
|
headerClassName: "text-right",
|
|
116
123
|
cellClassName: "text-right",
|
|
117
|
-
cell: (e) =>
|
|
124
|
+
cell: (e) => Q(e, e.discoveredCount)
|
|
118
125
|
},
|
|
119
126
|
{
|
|
120
127
|
key: "reconciled",
|
|
121
|
-
header:
|
|
128
|
+
header: g("adaptercloud.syncRuns.reconciled", "Reconciled"),
|
|
122
129
|
priority: "secondary",
|
|
123
130
|
headerClassName: "text-right",
|
|
124
131
|
cellClassName: "text-right",
|
|
125
|
-
cell: (e) =>
|
|
132
|
+
cell: (e) => Q(e, e.reconciledCount)
|
|
126
133
|
},
|
|
127
134
|
{
|
|
128
135
|
key: "drift",
|
|
129
|
-
header:
|
|
136
|
+
header: g("adaptercloud.syncRuns.drift", "Drift"),
|
|
130
137
|
priority: "secondary",
|
|
131
138
|
headerClassName: "text-right",
|
|
132
139
|
cellClassName: "text-right",
|
|
133
|
-
cell: (e) =>
|
|
140
|
+
cell: (e) => Q(e, e.driftCount)
|
|
134
141
|
},
|
|
135
142
|
{
|
|
136
143
|
key: "violations",
|
|
137
|
-
header:
|
|
144
|
+
header: g("adaptercloud.syncRuns.violations", "Violations"),
|
|
138
145
|
priority: "secondary",
|
|
139
146
|
headerClassName: "text-right",
|
|
140
147
|
cellClassName: "text-right",
|
|
141
|
-
cell: (e) =>
|
|
148
|
+
cell: (e) => Q(e, e.violationCount)
|
|
142
149
|
},
|
|
143
150
|
{
|
|
144
151
|
key: "started",
|
|
145
|
-
header:
|
|
152
|
+
header: g("adaptercloud.syncRuns.started", "Started"),
|
|
146
153
|
priority: "secondary",
|
|
147
|
-
cell: (e) => e.startedAt ? /* @__PURE__ */
|
|
154
|
+
cell: (e) => e.startedAt ? /* @__PURE__ */ A("span", {
|
|
148
155
|
className: "whitespace-nowrap text-xs text-text-secondary",
|
|
149
|
-
children:
|
|
150
|
-
}) : /* @__PURE__ */
|
|
156
|
+
children: u(e.startedAt)
|
|
157
|
+
}) : /* @__PURE__ */ A("span", {
|
|
151
158
|
className: "text-xs text-text-tertiary",
|
|
152
159
|
children: "—"
|
|
153
160
|
})
|
|
154
161
|
},
|
|
155
162
|
{
|
|
156
163
|
key: "duration",
|
|
157
|
-
header:
|
|
164
|
+
header: g("adaptercloud.syncRuns.duration", "Duration"),
|
|
158
165
|
priority: "secondary",
|
|
159
166
|
headerClassName: "text-right",
|
|
160
167
|
cellClassName: "text-right",
|
|
161
168
|
cell: (e) => {
|
|
162
|
-
let t =
|
|
163
|
-
return t ? /* @__PURE__ */
|
|
169
|
+
let t = R(e.startedAt, e.finishedAt);
|
|
170
|
+
return t ? /* @__PURE__ */ A("span", {
|
|
164
171
|
className: "whitespace-nowrap text-xs tabular-nums text-text-secondary",
|
|
165
172
|
children: t
|
|
166
|
-
}) : /* @__PURE__ */
|
|
173
|
+
}) : /* @__PURE__ */ A("span", {
|
|
167
174
|
className: "text-xs text-text-tertiary",
|
|
168
175
|
children: "—"
|
|
169
176
|
});
|
|
170
177
|
}
|
|
171
178
|
}
|
|
172
179
|
];
|
|
173
|
-
return /* @__PURE__ */
|
|
174
|
-
title:
|
|
175
|
-
description:
|
|
180
|
+
return /* @__PURE__ */ j(n, {
|
|
181
|
+
title: g("adaptercloud.syncRuns.title", "Sync Runs"),
|
|
182
|
+
description: g("adaptercloud.syncRuns.subtitle", "Discovery, reconciliation and cost-ingest executions that keep the picture live."),
|
|
176
183
|
children: [
|
|
177
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ j("div", {
|
|
178
185
|
className: "mb-6 flex flex-wrap gap-3",
|
|
179
|
-
children: /* @__PURE__ */
|
|
180
|
-
value:
|
|
186
|
+
children: [/* @__PURE__ */ j("select", {
|
|
187
|
+
value: y,
|
|
181
188
|
onChange: (e) => {
|
|
182
|
-
|
|
189
|
+
b(e.target.value), S(0);
|
|
183
190
|
},
|
|
184
|
-
"aria-label":
|
|
191
|
+
"aria-label": g("adaptercloud.syncRuns.filterByStatus", "Filter by status"),
|
|
185
192
|
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
186
|
-
children: [/* @__PURE__ */
|
|
193
|
+
children: [/* @__PURE__ */ A("option", {
|
|
187
194
|
value: "",
|
|
188
|
-
children:
|
|
189
|
-
}), Object.keys(i).map((e) => /* @__PURE__ */
|
|
195
|
+
children: g("adaptercloud.syncRuns.allStatuses", "All statuses")
|
|
196
|
+
}), Object.keys(i).map((e) => /* @__PURE__ */ A("option", {
|
|
190
197
|
value: e,
|
|
191
198
|
children: i[e]
|
|
192
199
|
}, e))]
|
|
193
|
-
})
|
|
200
|
+
}), /* @__PURE__ */ j("select", {
|
|
201
|
+
value: V,
|
|
202
|
+
onChange: (e) => W(e.target.value),
|
|
203
|
+
"aria-label": g("adaptercloud.syncRuns.filterByConnection", "Filter by connection"),
|
|
204
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
205
|
+
children: [
|
|
206
|
+
/* @__PURE__ */ A("option", {
|
|
207
|
+
value: "",
|
|
208
|
+
children: g("adaptercloud.syncRuns.allConnections", "All connections")
|
|
209
|
+
}),
|
|
210
|
+
U && /* @__PURE__ */ A("option", {
|
|
211
|
+
value: V,
|
|
212
|
+
children: V
|
|
213
|
+
}),
|
|
214
|
+
H.map((e) => /* @__PURE__ */ A("option", {
|
|
215
|
+
value: e.id,
|
|
216
|
+
children: e.name
|
|
217
|
+
}, e.id))
|
|
218
|
+
]
|
|
219
|
+
})]
|
|
194
220
|
}),
|
|
195
|
-
|
|
221
|
+
w && /* @__PURE__ */ A("p", {
|
|
196
222
|
role: "alert",
|
|
197
223
|
"aria-live": "polite",
|
|
198
224
|
className: "mb-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
199
|
-
children:
|
|
225
|
+
children: w
|
|
200
226
|
}),
|
|
201
|
-
/* @__PURE__ */
|
|
202
|
-
isLoading:
|
|
203
|
-
isError:
|
|
204
|
-
isEmpty:
|
|
205
|
-
error:
|
|
206
|
-
onRetry: () => void
|
|
207
|
-
emptyTitle:
|
|
208
|
-
emptyDescription:
|
|
209
|
-
emptyIcon: /* @__PURE__ */
|
|
210
|
-
emptyAction: /* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ j(o, {
|
|
228
|
+
isLoading: G.isLoading,
|
|
229
|
+
isError: G.isError,
|
|
230
|
+
isEmpty: q.length === 0,
|
|
231
|
+
error: G.error,
|
|
232
|
+
onRetry: () => void G.refetch(),
|
|
233
|
+
emptyTitle: g("adaptercloud.syncRuns.emptyTitle", "No sync runs yet"),
|
|
234
|
+
emptyDescription: g("adaptercloud.syncRuns.emptyDescription", "Start a sync run from a connection to keep the inventory current."),
|
|
235
|
+
emptyIcon: /* @__PURE__ */ A(h, { className: "h-10 w-10" }),
|
|
236
|
+
emptyAction: /* @__PURE__ */ A("button", {
|
|
211
237
|
type: "button",
|
|
212
238
|
onClick: () => t("/connections"),
|
|
213
239
|
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:opacity-90",
|
|
214
|
-
children:
|
|
240
|
+
children: g("adaptercloud.syncRuns.goToConnections", "Go to connections")
|
|
215
241
|
}),
|
|
216
|
-
children: [/* @__PURE__ */
|
|
217
|
-
data:
|
|
218
|
-
columns:
|
|
242
|
+
children: [/* @__PURE__ */ A(M, {
|
|
243
|
+
data: q,
|
|
244
|
+
columns: $,
|
|
219
245
|
rowKey: (e) => e.id,
|
|
220
246
|
onRowClick: (e) => t(`/connections/${e.connectionId}`),
|
|
221
|
-
rowActions: (e) => e.status === "QUEUED" || e.status === "RUNNING" ? /* @__PURE__ */
|
|
247
|
+
rowActions: (e) => e.status === "QUEUED" || e.status === "RUNNING" ? /* @__PURE__ */ j("button", {
|
|
222
248
|
type: "button",
|
|
223
|
-
disabled:
|
|
249
|
+
disabled: X === e.id,
|
|
224
250
|
onClick: () => {
|
|
225
|
-
|
|
251
|
+
T(null), I(e);
|
|
226
252
|
},
|
|
227
253
|
className: "inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50",
|
|
228
|
-
children: [
|
|
254
|
+
children: [X === e.id ? /* @__PURE__ */ A(C, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ A(O, { className: "h-3.5 w-3.5" }), g("adaptercloud.syncRuns.cancel", "Cancel")]
|
|
229
255
|
}) : null
|
|
230
|
-
}), (
|
|
256
|
+
}), (x > 0 || J) && /* @__PURE__ */ j("div", {
|
|
231
257
|
className: "mt-6 flex items-center justify-between",
|
|
232
258
|
children: [
|
|
233
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ j("button", {
|
|
234
260
|
type: "button",
|
|
235
|
-
disabled:
|
|
236
|
-
onClick: () =>
|
|
261
|
+
disabled: x === 0,
|
|
262
|
+
onClick: () => S((e) => Math.max(0, e - N)),
|
|
237
263
|
className: "inline-flex items-center gap-1 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50",
|
|
238
|
-
children: [/* @__PURE__ */
|
|
264
|
+
children: [/* @__PURE__ */ A(_, { className: "h-4 w-4" }), g("adaptercloud.common.prev", "Previous")]
|
|
239
265
|
}),
|
|
240
|
-
/* @__PURE__ */
|
|
241
|
-
className: "text-sm text-text-secondary",
|
|
266
|
+
/* @__PURE__ */ j("span", {
|
|
267
|
+
className: "text-sm tabular-nums text-text-secondary",
|
|
242
268
|
children: [
|
|
243
|
-
|
|
269
|
+
g("adaptercloud.common.showing", "Showing"),
|
|
244
270
|
" ",
|
|
245
|
-
|
|
271
|
+
x + 1,
|
|
246
272
|
"–",
|
|
247
|
-
|
|
273
|
+
x + q.length,
|
|
274
|
+
Y != null && ` ${g("adaptercloud.common.of", "of")} ${Y}`
|
|
248
275
|
]
|
|
249
276
|
}),
|
|
250
|
-
/* @__PURE__ */
|
|
277
|
+
/* @__PURE__ */ j("button", {
|
|
251
278
|
type: "button",
|
|
252
|
-
disabled: !
|
|
253
|
-
onClick: () =>
|
|
279
|
+
disabled: !J,
|
|
280
|
+
onClick: () => S((e) => e + N),
|
|
254
281
|
className: "inline-flex items-center gap-1 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50",
|
|
255
|
-
children: [
|
|
282
|
+
children: [g("adaptercloud.common.next", "Next"), /* @__PURE__ */ A(v, { className: "h-4 w-4" })]
|
|
256
283
|
})
|
|
257
284
|
]
|
|
258
285
|
})]
|
|
259
286
|
}),
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
open: !!
|
|
287
|
+
/* @__PURE__ */ A(d, {
|
|
288
|
+
open: !!E,
|
|
262
289
|
onOpenChange: (e) => {
|
|
263
|
-
e ||
|
|
290
|
+
e || I(null);
|
|
264
291
|
},
|
|
265
|
-
title:
|
|
266
|
-
description:
|
|
267
|
-
confirmLabel:
|
|
268
|
-
cancelLabel:
|
|
269
|
-
onConfirm: () =>
|
|
270
|
-
isPending: !!
|
|
292
|
+
title: g("adaptercloud.syncRuns.cancelTitle", "Cancel this sync run?"),
|
|
293
|
+
description: g("adaptercloud.syncRuns.cancelPrompt", "The run will stop and transition to Cancelled. Any work already done is kept, but it will not finish."),
|
|
294
|
+
confirmLabel: g("adaptercloud.syncRuns.confirmCancel", "Cancel run"),
|
|
295
|
+
cancelLabel: g("adaptercloud.syncRuns.keepRunning", "Keep running"),
|
|
296
|
+
onConfirm: () => E && Z(E.id),
|
|
297
|
+
isPending: !!E && X === E?.id,
|
|
271
298
|
tone: "danger"
|
|
272
299
|
})
|
|
273
300
|
]
|
|
274
301
|
});
|
|
275
302
|
}
|
|
276
303
|
//#endregion
|
|
277
|
-
export {
|
|
304
|
+
export { z as SyncRunsListPage };
|
|
278
305
|
|
|
279
306
|
//# sourceMappingURL=SyncRunsListPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SyncRunsListPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/sync-runs/SyncRunsListPage.tsx"],"sourcesContent":["/**\n * Sync Runs History Page\n * @module adaptercloud/pages/sync-runs\n *\n * The operations log (`adaListSyncRuns`) — every discovery / reconcile /\n * cost-ingest / full execution with its lifecycle and counters. On md+ this\n * renders a dense operations table (Kind · Connection · Status · counters ·\n * Started · Duration) so runs compare at a glance; below 768px it reflows to a\n * card per run (via fe-libs `ResponsiveTable`). Filters by status; queued/running\n * runs can be cancelled via `adaCancelSyncRun`.\n */\n\nimport { useState, useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Activity,\n ChevronLeft,\n ChevronRight,\n XCircle,\n Loader2,\n Server,\n Cloud,\n Radio,\n Cpu,\n Boxes,\n Network,\n Database,\n HardDrive,\n Puzzle,\n type LucideIcon,\n} from 'lucide-react';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataState } from '../../components/DataState';\nimport { ConfirmDialog } from '../../components/ConfirmDialog';\nimport { useAdapterCloud } from '../../context/AdapterCloudContext';\nimport { useSyncRuns, useCancelSyncRun } from '../../hooks/useAdapterCloudApi';\nimport { syncKindLabels, syncStatusLabels } from '../../utils/domain';\nimport { formatDate } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { AdaAdapterKind, AdaSyncKind, AdaSyncRun, AdaSyncStatus } from '../../types';\n\nconst PAGE_SIZE = 20;\n\n/**\n * Per-adapter-kind glyph — stands in for the vendor logos (aws / gcp / azure /\n * snowflake) in the mock. Keyed off the run's bound connection's adapter kind.\n */\nconst adapterKindIcon: Record<AdaAdapterKind, LucideIcon> = {\n PUBLIC_CLOUD: Cloud,\n PRIVATE_CLOUD: Cloud,\n SAAS: Cloud,\n ON_PREM: HardDrive,\n EDGE: Radio,\n IOT: Cpu,\n KUBERNETES: Boxes,\n NETWORK: Network,\n DATA_SYSTEM: Database,\n CUSTOM: Puzzle,\n};\n\n/** Colored kind pill (semantic tokens only), mirroring the mock's kind badges. */\nconst kindBadgeClass: Record<AdaSyncKind, string> = {\n DISCOVERY: 'bg-accent-blue-subtle text-accent-blue',\n RECONCILE: 'bg-status-warning-bg-subtle text-status-warning-text',\n COST_INGEST: 'bg-accent-purple-subtle text-accent-purple',\n FULL: 'bg-bg-sunken text-text-secondary',\n};\n\nfunction KindBadge({ kind }: { kind: AdaSyncKind }) {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n kindBadgeClass[kind]\n )}\n >\n {syncKindLabels[kind]}\n </span>\n );\n}\n\n/** Elapsed wall-clock between start and finish, e.g. \"3m 12s\". Null if unfinished. */\nfunction formatDuration(startedAt: string | null, finishedAt: string | null): string | null {\n if (!startedAt || !finishedAt) return null;\n const ms = new Date(finishedAt).getTime() - new Date(startedAt).getTime();\n if (!Number.isFinite(ms) || ms < 0) return null;\n const totalSeconds = Math.floor(ms / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;\n if (minutes > 0) return `${minutes}m ${seconds}s`;\n return `${seconds}s`;\n}\n\nexport function SyncRunsListPage() {\n const { navigateTo } = useAdapterCloud();\n const { t: translate } = useI18n();\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n const [status, setStatus] = useState<AdaSyncStatus | ''>('');\n const [offset, setOffset] = useState(0);\n const [actionError, setActionError] = useState<string | null>(null);\n const [confirmTarget, setConfirmTarget] = useState<AdaSyncRun | null>(null);\n\n const query = useSyncRuns({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset },\n });\n const cancel = useCancelSyncRun();\n\n const items = query.data?.items ?? [];\n const hasMore = query.data?.pageInfo.hasMore ?? false;\n\n // Per-id pending so cancelling one run only disables/spins that row's button.\n const pendingId = cancel.isPending ? cancel.variables : undefined;\n\n const handleCancel = useCallback(\n (id: string) => {\n setActionError(null);\n cancel.mutate(id, {\n onSuccess: () => setConfirmTarget(null),\n onError: (err) =>\n setActionError(err instanceof Error ? err.message : 'Failed to cancel run.'),\n });\n },\n [cancel]\n );\n\n // Counters are meaningless until a run has produced results — dim them to an\n // em-dash while queued/running, matching the mock.\n const counterCell = (run: AdaSyncRun, value: number) =>\n run.status === 'QUEUED' || run.status === 'RUNNING' ? (\n <span className=\"text-text-tertiary\">—</span>\n ) : (\n <span className=\"tabular-nums text-text-primary\">{value}</span>\n );\n\n const columns: ResponsiveTableColumn<AdaSyncRun>[] = [\n {\n key: 'kind',\n header: t('adaptercloud.syncRuns.kind', 'Kind'),\n priority: 'primary',\n cell: (run) => <KindBadge kind={run.kind} />,\n },\n {\n key: 'connection',\n header: t('adaptercloud.syncRuns.connection', 'Connection'),\n priority: 'secondary',\n cell: (run) => {\n const kind = run.connection?.adapter?.kind;\n const Icon = kind ? adapterKindIcon[kind] : Server;\n return (\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-bg-sunken text-text-secondary\">\n <Icon className=\"h-3.5 w-3.5\" />\n </span>\n {run.connection?.name ? (\n <span className=\"truncate text-sm text-text-primary\">{run.connection.name}</span>\n ) : (\n <span className=\"text-sm text-text-tertiary\">—</span>\n )}\n </div>\n );\n },\n },\n {\n key: 'status',\n header: t('adaptercloud.syncRuns.status', 'Status'),\n priority: 'secondary',\n cell: (run) => (\n <div className=\"flex flex-col gap-1\">\n <StatusBadge status={run.status} label={syncStatusLabels[run.status]} />\n {run.error && (\n <span className=\"max-w-xs truncate text-xs text-status-error-text\" title={run.error}>\n {run.error}\n </span>\n )}\n </div>\n ),\n },\n {\n key: 'discovered',\n header: t('adaptercloud.syncRuns.discovered', 'Discovered'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.discoveredCount),\n },\n {\n key: 'reconciled',\n header: t('adaptercloud.syncRuns.reconciled', 'Reconciled'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.reconciledCount),\n },\n {\n key: 'drift',\n header: t('adaptercloud.syncRuns.drift', 'Drift'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.driftCount),\n },\n {\n key: 'violations',\n header: t('adaptercloud.syncRuns.violations', 'Violations'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.violationCount),\n },\n {\n key: 'started',\n header: t('adaptercloud.syncRuns.started', 'Started'),\n priority: 'secondary',\n cell: (run) =>\n run.startedAt ? (\n <span className=\"whitespace-nowrap text-xs text-text-secondary\">\n {formatDate(run.startedAt)}\n </span>\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'duration',\n header: t('adaptercloud.syncRuns.duration', 'Duration'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => {\n const duration = formatDuration(run.startedAt, run.finishedAt);\n return duration ? (\n <span className=\"whitespace-nowrap text-xs tabular-nums text-text-secondary\">\n {duration}\n </span>\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n );\n },\n },\n ];\n\n return (\n <PageLayout\n title={t('adaptercloud.syncRuns.title', 'Sync Runs')}\n description={t(\n 'adaptercloud.syncRuns.subtitle',\n 'Discovery, reconciliation and cost-ingest executions that keep the picture live.'\n )}\n >\n <div className=\"mb-6 flex flex-wrap gap-3\">\n <select\n value={status}\n onChange={(e) => {\n setStatus(e.target.value as AdaSyncStatus | '');\n setOffset(0);\n }}\n aria-label={t('adaptercloud.syncRuns.filterByStatus', 'Filter by status')}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">{t('adaptercloud.syncRuns.allStatuses', 'All statuses')}</option>\n {(Object.keys(syncStatusLabels) as AdaSyncStatus[]).map((s) => (\n <option key={s} value={s}>\n {syncStatusLabels[s]}\n </option>\n ))}\n </select>\n </div>\n\n {actionError && (\n <p\n role=\"alert\"\n aria-live=\"polite\"\n className=\"mb-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n >\n {actionError}\n </p>\n )}\n\n <DataState\n isLoading={query.isLoading}\n isError={query.isError}\n isEmpty={items.length === 0}\n error={query.error}\n onRetry={() => void query.refetch()}\n emptyTitle={t('adaptercloud.syncRuns.emptyTitle', 'No sync runs yet')}\n emptyDescription={t(\n 'adaptercloud.syncRuns.emptyDescription',\n 'Start a sync run from a connection to keep the inventory current.'\n )}\n emptyIcon={<Activity className=\"h-10 w-10\" />}\n emptyAction={\n <button\n type=\"button\"\n onClick={() => navigateTo('/connections')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:opacity-90\"\n >\n {t('adaptercloud.syncRuns.goToConnections', 'Go to connections')}\n </button>\n }\n >\n <ResponsiveTable\n data={items}\n columns={columns}\n rowKey={(run) => run.id}\n onRowClick={(run) => navigateTo(`/connections/${run.connectionId}`)}\n rowActions={(run) => {\n const cancellable = run.status === 'QUEUED' || run.status === 'RUNNING';\n if (!cancellable) return null;\n return (\n <button\n type=\"button\"\n disabled={pendingId === run.id}\n onClick={() => {\n setActionError(null);\n setConfirmTarget(run);\n }}\n className=\"inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n {pendingId === run.id ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <XCircle className=\"h-3.5 w-3.5\" />\n )}\n {t('adaptercloud.syncRuns.cancel', 'Cancel')}\n </button>\n );\n }}\n />\n\n {(offset > 0 || hasMore) && (\n <div className=\"mt-6 flex items-center justify-between\">\n <button\n type=\"button\"\n disabled={offset === 0}\n onClick={() => setOffset((o) => Math.max(0, o - PAGE_SIZE))}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n {t('adaptercloud.common.prev', 'Previous')}\n </button>\n <span className=\"text-sm text-text-secondary\">\n {t('adaptercloud.common.showing', 'Showing')} {offset + 1}–{offset + items.length}\n </span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => setOffset((o) => o + PAGE_SIZE)}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {t('adaptercloud.common.next', 'Next')}\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </DataState>\n\n <ConfirmDialog\n open={Boolean(confirmTarget)}\n onOpenChange={(open) => {\n if (!open) setConfirmTarget(null);\n }}\n title={t('adaptercloud.syncRuns.cancelTitle', 'Cancel this sync run?')}\n description={t(\n 'adaptercloud.syncRuns.cancelPrompt',\n 'The run will stop and transition to Cancelled. Any work already done is kept, but it will not finish.'\n )}\n confirmLabel={t('adaptercloud.syncRuns.confirmCancel', 'Cancel run')}\n cancelLabel={t('adaptercloud.syncRuns.keepRunning', 'Keep running')}\n onConfirm={() => confirmTarget && handleCancel(confirmTarget.id)}\n isPending={Boolean(confirmTarget) && pendingId === confirmTarget?.id}\n tone=\"danger\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SyncRunsListPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/sync-runs/SyncRunsListPage.tsx"],"sourcesContent":["/**\n * Sync Runs History Page\n * @module adaptercloud/pages/sync-runs\n *\n * The operations log (`adaListSyncRuns`) — every discovery / reconcile /\n * cost-ingest / full execution with its lifecycle and counters. On md+ this\n * renders a dense operations table (Kind · Connection · Status · counters ·\n * Started · Duration) so runs compare at a glance; below 768px it reflows to a\n * card per run (via fe-libs `ResponsiveTable`). Filters by status; queued/running\n * runs can be cancelled via `adaCancelSyncRun`.\n */\n\nimport { useState, useCallback } from 'react';\nimport { useSearchParams } from 'react-router';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Activity,\n ChevronLeft,\n ChevronRight,\n XCircle,\n Loader2,\n Server,\n Cloud,\n Radio,\n Cpu,\n Boxes,\n Network,\n Database,\n HardDrive,\n Puzzle,\n type LucideIcon,\n} from 'lucide-react';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { DataState } from '../../components/DataState';\nimport { ConfirmDialog } from '../../components/ConfirmDialog';\nimport { useAdapterCloud } from '../../context/AdapterCloudContext';\nimport { useConnections, useSyncRuns, useCancelSyncRun } from '../../hooks/useAdapterCloudApi';\nimport { syncKindLabels, syncStatusLabels } from '../../utils/domain';\nimport { formatDate } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { AdaAdapterKind, AdaSyncKind, AdaSyncRun, AdaSyncStatus } from '../../types';\n\nconst PAGE_SIZE = 20;\n\n/** How many connections the scope dropdown offers (one page of the inventory). */\nconst CONNECTION_OPTIONS_LIMIT = 100;\n\n/**\n * Per-adapter-kind glyph — stands in for the vendor logos (aws / gcp / azure /\n * snowflake) in the mock. Keyed off the run's bound connection's adapter kind.\n */\nconst adapterKindIcon: Record<AdaAdapterKind, LucideIcon> = {\n PUBLIC_CLOUD: Cloud,\n PRIVATE_CLOUD: Cloud,\n SAAS: Cloud,\n ON_PREM: HardDrive,\n EDGE: Radio,\n IOT: Cpu,\n KUBERNETES: Boxes,\n NETWORK: Network,\n DATA_SYSTEM: Database,\n CUSTOM: Puzzle,\n};\n\n/** Colored kind pill (semantic tokens only), mirroring the mock's kind badges. */\nconst kindBadgeClass: Record<AdaSyncKind, string> = {\n DISCOVERY: 'bg-accent-blue-subtle text-accent-blue',\n RECONCILE: 'bg-status-warning-bg-subtle text-status-warning-text',\n COST_INGEST: 'bg-accent-purple-subtle text-accent-purple',\n FULL: 'bg-bg-sunken text-text-secondary',\n};\n\nfunction KindBadge({ kind }: { kind: AdaSyncKind }) {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',\n kindBadgeClass[kind]\n )}\n >\n {syncKindLabels[kind]}\n </span>\n );\n}\n\n/** Elapsed wall-clock between start and finish, e.g. \"3m 12s\". Null if unfinished. */\nfunction formatDuration(startedAt: string | null, finishedAt: string | null): string | null {\n if (!startedAt || !finishedAt) return null;\n const ms = new Date(finishedAt).getTime() - new Date(startedAt).getTime();\n if (!Number.isFinite(ms) || ms < 0) return null;\n const totalSeconds = Math.floor(ms / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;\n if (minutes > 0) return `${minutes}m ${seconds}s`;\n return `${seconds}s`;\n}\n\nexport function SyncRunsListPage() {\n const { navigateTo } = useAdapterCloud();\n const { t: translate } = useI18n();\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n const [status, setStatus] = useState<AdaSyncStatus | ''>('');\n const [offset, setOffset] = useState(0);\n const [actionError, setActionError] = useState<string | null>(null);\n const [confirmTarget, setConfirmTarget] = useState<AdaSyncRun | null>(null);\n\n // The connection scope lives in the URL so a connection detail page can deep\n // link into its own run history (`/sync-runs?connectionId=…`) and the filter\n // survives a reload. `adaListSyncRuns` filters by `connectionId` server-side.\n const [searchParams, setSearchParams] = useSearchParams();\n const connectionId = searchParams.get('connectionId') ?? '';\n\n const connectionsQuery = useConnections({ pagination: { limit: CONNECTION_OPTIONS_LIMIT } });\n const connectionOptions = connectionsQuery.data?.items ?? [];\n // A deep link can name a connection outside the loaded option page; keep it\n // selectable (by id) rather than silently resetting the filter to \"All\".\n const scopedConnectionMissing =\n Boolean(connectionId) && !connectionOptions.some((c) => c.id === connectionId);\n\n const setConnectionScope = useCallback(\n (value: string) => {\n setSearchParams(\n (prev) => {\n const next = new URLSearchParams(prev);\n if (value) next.set('connectionId', value);\n else next.delete('connectionId');\n return next;\n },\n { replace: true }\n );\n setOffset(0);\n },\n [setSearchParams]\n );\n\n const query = useSyncRuns({\n connectionId: connectionId || undefined,\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset },\n });\n const cancel = useCancelSyncRun();\n\n const items = query.data?.items ?? [];\n const hasMore = query.data?.pageInfo.hasMore ?? false;\n // Estate-wide total for the current filter. Nullable on older deployed\n // schemas — the footer then falls back to the bare offset range.\n const totalCount = query.data?.pageInfo.totalCount;\n\n // Per-id pending so cancelling one run only disables/spins that row's button.\n const pendingId = cancel.isPending ? cancel.variables : undefined;\n\n const handleCancel = useCallback(\n (id: string) => {\n setActionError(null);\n cancel.mutate(id, {\n onSuccess: () => setConfirmTarget(null),\n onError: (err) =>\n setActionError(err instanceof Error ? err.message : 'Failed to cancel run.'),\n });\n },\n [cancel]\n );\n\n // Counters are meaningless until a run has produced results — dim them to an\n // em-dash while queued/running, matching the mock.\n const counterCell = (run: AdaSyncRun, value: number) =>\n run.status === 'QUEUED' || run.status === 'RUNNING' ? (\n <span className=\"text-text-tertiary\">—</span>\n ) : (\n <span className=\"tabular-nums text-text-primary\">{value}</span>\n );\n\n const columns: ResponsiveTableColumn<AdaSyncRun>[] = [\n {\n key: 'kind',\n header: t('adaptercloud.syncRuns.kind', 'Kind'),\n priority: 'primary',\n cell: (run) => <KindBadge kind={run.kind} />,\n },\n {\n key: 'connection',\n header: t('adaptercloud.syncRuns.connection', 'Connection'),\n priority: 'secondary',\n cell: (run) => {\n const kind = run.connection?.adapter?.kind;\n const Icon = kind ? adapterKindIcon[kind] : Server;\n return (\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-bg-sunken text-text-secondary\">\n <Icon className=\"h-3.5 w-3.5\" />\n </span>\n {run.connection?.name ? (\n <span className=\"truncate text-sm text-text-primary\">{run.connection.name}</span>\n ) : (\n <span className=\"text-sm text-text-tertiary\">—</span>\n )}\n </div>\n );\n },\n },\n {\n key: 'status',\n header: t('adaptercloud.syncRuns.status', 'Status'),\n priority: 'secondary',\n cell: (run) => (\n <div className=\"flex flex-col gap-1\">\n <StatusBadge status={run.status} label={syncStatusLabels[run.status]} />\n {run.error && (\n <span className=\"max-w-xs truncate text-xs text-status-error-text\" title={run.error}>\n {run.error}\n </span>\n )}\n </div>\n ),\n },\n {\n key: 'discovered',\n header: t('adaptercloud.syncRuns.discovered', 'Discovered'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.discoveredCount),\n },\n {\n key: 'reconciled',\n header: t('adaptercloud.syncRuns.reconciled', 'Reconciled'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.reconciledCount),\n },\n {\n key: 'drift',\n header: t('adaptercloud.syncRuns.drift', 'Drift'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.driftCount),\n },\n {\n key: 'violations',\n header: t('adaptercloud.syncRuns.violations', 'Violations'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => counterCell(run, run.violationCount),\n },\n {\n key: 'started',\n header: t('adaptercloud.syncRuns.started', 'Started'),\n priority: 'secondary',\n cell: (run) =>\n run.startedAt ? (\n <span className=\"whitespace-nowrap text-xs text-text-secondary\">\n {formatDate(run.startedAt)}\n </span>\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n ),\n },\n {\n key: 'duration',\n header: t('adaptercloud.syncRuns.duration', 'Duration'),\n priority: 'secondary',\n headerClassName: 'text-right',\n cellClassName: 'text-right',\n cell: (run) => {\n const duration = formatDuration(run.startedAt, run.finishedAt);\n return duration ? (\n <span className=\"whitespace-nowrap text-xs tabular-nums text-text-secondary\">\n {duration}\n </span>\n ) : (\n <span className=\"text-xs text-text-tertiary\">—</span>\n );\n },\n },\n ];\n\n return (\n <PageLayout\n title={t('adaptercloud.syncRuns.title', 'Sync Runs')}\n description={t(\n 'adaptercloud.syncRuns.subtitle',\n 'Discovery, reconciliation and cost-ingest executions that keep the picture live.'\n )}\n >\n <div className=\"mb-6 flex flex-wrap gap-3\">\n <select\n value={status}\n onChange={(e) => {\n setStatus(e.target.value as AdaSyncStatus | '');\n setOffset(0);\n }}\n aria-label={t('adaptercloud.syncRuns.filterByStatus', 'Filter by status')}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">{t('adaptercloud.syncRuns.allStatuses', 'All statuses')}</option>\n {(Object.keys(syncStatusLabels) as AdaSyncStatus[]).map((s) => (\n <option key={s} value={s}>\n {syncStatusLabels[s]}\n </option>\n ))}\n </select>\n\n <select\n value={connectionId}\n onChange={(e) => setConnectionScope(e.target.value)}\n aria-label={t('adaptercloud.syncRuns.filterByConnection', 'Filter by connection')}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">{t('adaptercloud.syncRuns.allConnections', 'All connections')}</option>\n {scopedConnectionMissing && <option value={connectionId}>{connectionId}</option>}\n {connectionOptions.map((c) => (\n <option key={c.id} value={c.id}>\n {c.name}\n </option>\n ))}\n </select>\n </div>\n\n {actionError && (\n <p\n role=\"alert\"\n aria-live=\"polite\"\n className=\"mb-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n >\n {actionError}\n </p>\n )}\n\n <DataState\n isLoading={query.isLoading}\n isError={query.isError}\n isEmpty={items.length === 0}\n error={query.error}\n onRetry={() => void query.refetch()}\n emptyTitle={t('adaptercloud.syncRuns.emptyTitle', 'No sync runs yet')}\n emptyDescription={t(\n 'adaptercloud.syncRuns.emptyDescription',\n 'Start a sync run from a connection to keep the inventory current.'\n )}\n emptyIcon={<Activity className=\"h-10 w-10\" />}\n emptyAction={\n <button\n type=\"button\"\n onClick={() => navigateTo('/connections')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:opacity-90\"\n >\n {t('adaptercloud.syncRuns.goToConnections', 'Go to connections')}\n </button>\n }\n >\n <ResponsiveTable\n data={items}\n columns={columns}\n rowKey={(run) => run.id}\n onRowClick={(run) => navigateTo(`/connections/${run.connectionId}`)}\n rowActions={(run) => {\n const cancellable = run.status === 'QUEUED' || run.status === 'RUNNING';\n if (!cancellable) return null;\n return (\n <button\n type=\"button\"\n disabled={pendingId === run.id}\n onClick={() => {\n setActionError(null);\n setConfirmTarget(run);\n }}\n className=\"inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n {pendingId === run.id ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <XCircle className=\"h-3.5 w-3.5\" />\n )}\n {t('adaptercloud.syncRuns.cancel', 'Cancel')}\n </button>\n );\n }}\n />\n\n {(offset > 0 || hasMore) && (\n <div className=\"mt-6 flex items-center justify-between\">\n <button\n type=\"button\"\n disabled={offset === 0}\n onClick={() => setOffset((o) => Math.max(0, o - PAGE_SIZE))}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n {t('adaptercloud.common.prev', 'Previous')}\n </button>\n <span className=\"text-sm tabular-nums text-text-secondary\">\n {t('adaptercloud.common.showing', 'Showing')} {offset + 1}–{offset + items.length}\n {totalCount != null && ` ${t('adaptercloud.common.of', 'of')} ${totalCount}`}\n </span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => setOffset((o) => o + PAGE_SIZE)}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {t('adaptercloud.common.next', 'Next')}\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </DataState>\n\n <ConfirmDialog\n open={Boolean(confirmTarget)}\n onOpenChange={(open) => {\n if (!open) setConfirmTarget(null);\n }}\n title={t('adaptercloud.syncRuns.cancelTitle', 'Cancel this sync run?')}\n description={t(\n 'adaptercloud.syncRuns.cancelPrompt',\n 'The run will stop and transition to Cancelled. Any work already done is kept, but it will not finish.'\n )}\n confirmLabel={t('adaptercloud.syncRuns.confirmCancel', 'Cancel run')}\n cancelLabel={t('adaptercloud.syncRuns.keepRunning', 'Keep running')}\n onConfirm={() => confirmTarget && handleCancel(confirmTarget.id)}\n isPending={Boolean(confirmTarget) && pendingId === confirmTarget?.id}\n tone=\"danger\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViolationsListPage.d.ts","sourceRoot":"","sources":["../../../../src/adaptercloud/pages/violations/ViolationsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuCH,wBAAgB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"ViolationsListPage.d.ts","sourceRoot":"","sources":["../../../../src/adaptercloud/pages/violations/ViolationsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuCH,wBAAgB,kBAAkB,gCA+XjC"}
|