@burdenoff/microfe-adaptercloud 2026.802.2 → 2026.825.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/components/viz/TopologyGraph.d.ts +1 -0
- package/dist/adaptercloud/components/viz/TopologyGraph.d.ts.map +1 -1
- package/dist/adaptercloud/components/viz/TopologyGraph.js.map +1 -1
- package/dist/adaptercloud/hooks/useAdapterCloudApi.d.ts +7 -0
- package/dist/adaptercloud/hooks/useAdapterCloudApi.d.ts.map +1 -1
- package/dist/adaptercloud/hooks/useAdapterCloudApi.js +52 -7
- package/dist/adaptercloud/hooks/useAdapterCloudApi.js.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionDetailPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionDetailPage.js +147 -135
- package/dist/adaptercloud/pages/connections/ConnectionDetailPage.js.map +1 -1
- package/dist/adaptercloud/pages/connections/connectionSync.d.ts +4 -0
- package/dist/adaptercloud/pages/connections/connectionSync.d.ts.map +1 -0
- package/dist/adaptercloud/pages/connections/connectionSync.js +8 -0
- package/dist/adaptercloud/pages/connections/connectionSync.js.map +1 -0
- package/dist/adaptercloud/pages/topology/TopologyPage.d.ts +1 -1
- package/dist/adaptercloud/pages/topology/TopologyPage.d.ts.map +1 -1
- package/dist/adaptercloud/pages/topology/TopologyPage.js +185 -188
- package/dist/adaptercloud/pages/topology/TopologyPage.js.map +1 -1
- package/dist/adaptercloud/pages/topology/topologyImpact.d.ts +8 -0
- package/dist/adaptercloud/pages/topology/topologyImpact.d.ts.map +1 -0
- package/dist/adaptercloud/pages/topology/topologyImpact.js +17 -0
- package/dist/adaptercloud/pages/topology/topologyImpact.js.map +1 -0
- package/package.json +2 -2
|
@@ -6,256 +6,268 @@ import { DataState as c } from "../../components/DataState.js";
|
|
|
6
6
|
import { useConnection as l, useDisableConnection as u, useSetConnectionStatus as d, useStartSyncRun as f } from "../../hooks/useAdapterCloudApi.js";
|
|
7
7
|
import { formatDate as p } from "../../utils/formatters.js";
|
|
8
8
|
import { ConfirmDialog as m } from "../../components/ConfirmDialog.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
9
|
+
import { canStartConnectionSync as h } from "./connectionSync.js";
|
|
10
|
+
import { useCallback as g, useState as _ } from "react";
|
|
11
|
+
import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
12
|
+
import { ArrowLeft as y, Ban as b, Loader2 as x, Pencil as S, Play as C, RefreshCw as w, Server as T } from "lucide-react";
|
|
13
|
+
import { useParams as E } from "react-router";
|
|
14
|
+
import { jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
15
|
+
import { GlassCard as k } from "@burdenoff/fe-libs/ui";
|
|
15
16
|
//#region src/adaptercloud/pages/connections/ConnectionDetailPage.tsx
|
|
16
|
-
var
|
|
17
|
+
var A = [
|
|
17
18
|
"CONNECTED",
|
|
18
19
|
"DEGRADED",
|
|
19
20
|
"ERROR",
|
|
20
21
|
"PENDING"
|
|
21
|
-
],
|
|
22
|
+
], j = [
|
|
22
23
|
"DISCOVERY",
|
|
23
24
|
"RECONCILE",
|
|
24
25
|
"COST_INGEST",
|
|
25
26
|
"FULL"
|
|
26
27
|
];
|
|
27
|
-
function
|
|
28
|
-
let { id:
|
|
29
|
-
let n =
|
|
28
|
+
function M() {
|
|
29
|
+
let { id: M } = E(), { navigateTo: N } = e(), { t: P } = v(), F = g((e, t) => {
|
|
30
|
+
let n = P(e);
|
|
30
31
|
return n === e ? t : n;
|
|
31
|
-
}, [
|
|
32
|
-
|
|
33
|
-
id:
|
|
32
|
+
}, [P]), I = l(M), L = d(), R = u(), z = f(), B = I.data, V = B ? h(B.status) : !1, [H, U] = _(null), [W, G] = _(null), [K, q] = _(!1), J = g((e) => G(e instanceof Error ? e.message : "Action failed. Please try again."), []), Y = g((e) => {
|
|
33
|
+
M && (G(null), L.mutate({
|
|
34
|
+
id: M,
|
|
34
35
|
status: e
|
|
35
|
-
}, { onError:
|
|
36
|
+
}, { onError: J }));
|
|
36
37
|
}, [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
]),
|
|
41
|
-
|
|
42
|
-
onSuccess: () =>
|
|
43
|
-
onError:
|
|
38
|
+
M,
|
|
39
|
+
L,
|
|
40
|
+
J
|
|
41
|
+
]), X = g(() => {
|
|
42
|
+
M && (G(null), R.mutate(M, {
|
|
43
|
+
onSuccess: () => q(!1),
|
|
44
|
+
onError: J
|
|
44
45
|
}));
|
|
45
46
|
}, [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
]),
|
|
50
|
-
|
|
51
|
-
connectionId:
|
|
47
|
+
M,
|
|
48
|
+
R,
|
|
49
|
+
J
|
|
50
|
+
]), Z = g((e) => {
|
|
51
|
+
!M || !V || (G(null), U(e), z.mutate({
|
|
52
|
+
connectionId: M,
|
|
52
53
|
kind: e
|
|
53
54
|
}, {
|
|
54
55
|
onSuccess: () => {
|
|
55
|
-
|
|
56
|
+
U(null), N("/sync-runs");
|
|
56
57
|
},
|
|
57
58
|
onError: (e) => {
|
|
58
|
-
|
|
59
|
+
U(null), J(e);
|
|
59
60
|
}
|
|
60
61
|
}));
|
|
61
62
|
}, [
|
|
62
|
-
j,
|
|
63
|
-
R,
|
|
64
63
|
M,
|
|
65
|
-
|
|
64
|
+
V,
|
|
65
|
+
z,
|
|
66
|
+
N,
|
|
67
|
+
J
|
|
66
68
|
]);
|
|
67
|
-
return /* @__PURE__ */
|
|
68
|
-
title:
|
|
69
|
-
description:
|
|
70
|
-
actions: /* @__PURE__ */
|
|
69
|
+
return /* @__PURE__ */ O(t, {
|
|
70
|
+
title: B?.name ?? F("adaptercloud.connections.detailTitle", "Connection"),
|
|
71
|
+
description: B?.adapter?.name,
|
|
72
|
+
actions: /* @__PURE__ */ O("div", {
|
|
71
73
|
className: "flex items-center gap-2",
|
|
72
|
-
children: [/* @__PURE__ */
|
|
74
|
+
children: [/* @__PURE__ */ O("button", {
|
|
73
75
|
type: "button",
|
|
74
|
-
onClick: () =>
|
|
76
|
+
onClick: () => N("/connections"),
|
|
75
77
|
className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent",
|
|
76
|
-
children: [/* @__PURE__ */
|
|
77
|
-
}),
|
|
78
|
+
children: [/* @__PURE__ */ D(y, { className: "h-4 w-4" }), F("adaptercloud.common.back", "Back")]
|
|
79
|
+
}), B && /* @__PURE__ */ O("button", {
|
|
78
80
|
type: "button",
|
|
79
|
-
onClick: () =>
|
|
81
|
+
onClick: () => N(`/connections/${B.id}/edit`),
|
|
80
82
|
className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent",
|
|
81
|
-
children: [/* @__PURE__ */
|
|
83
|
+
children: [/* @__PURE__ */ D(S, { className: "h-4 w-4" }), F("adaptercloud.common.edit", "Edit")]
|
|
82
84
|
})]
|
|
83
85
|
}),
|
|
84
|
-
children: [/* @__PURE__ */
|
|
85
|
-
isLoading:
|
|
86
|
-
isError:
|
|
87
|
-
isEmpty: !
|
|
88
|
-
error:
|
|
89
|
-
onRetry: () => void
|
|
90
|
-
emptyTitle:
|
|
91
|
-
children:
|
|
86
|
+
children: [/* @__PURE__ */ D(c, {
|
|
87
|
+
isLoading: I.isLoading,
|
|
88
|
+
isError: I.isError,
|
|
89
|
+
isEmpty: !I.isLoading && !B,
|
|
90
|
+
error: I.error,
|
|
91
|
+
onRetry: () => void I.refetch(),
|
|
92
|
+
emptyTitle: F("adaptercloud.connections.notFound", "Connection not found"),
|
|
93
|
+
children: B && /* @__PURE__ */ O("div", {
|
|
92
94
|
className: "space-y-6",
|
|
93
95
|
children: [
|
|
94
|
-
|
|
96
|
+
W && /* @__PURE__ */ D("p", {
|
|
95
97
|
role: "alert",
|
|
96
98
|
"aria-live": "polite",
|
|
97
99
|
className: "rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
98
|
-
children:
|
|
100
|
+
children: W
|
|
99
101
|
}),
|
|
100
|
-
/* @__PURE__ */
|
|
102
|
+
/* @__PURE__ */ O(k, {
|
|
101
103
|
className: "p-6",
|
|
102
104
|
children: [
|
|
103
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ O("div", {
|
|
104
106
|
className: "mb-4 flex flex-wrap items-center gap-3",
|
|
105
|
-
children: [/* @__PURE__ */
|
|
107
|
+
children: [/* @__PURE__ */ D(s, { status: B.status }), /* @__PURE__ */ D("span", {
|
|
106
108
|
className: "inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
|
|
107
|
-
children: n[
|
|
109
|
+
children: n[B.authMethod]
|
|
108
110
|
})]
|
|
109
111
|
}),
|
|
110
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ O("dl", {
|
|
111
113
|
className: "grid grid-cols-2 gap-4 text-sm sm:grid-cols-4",
|
|
112
114
|
children: [
|
|
113
|
-
/* @__PURE__ */
|
|
115
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("dt", {
|
|
114
116
|
className: "text-text-secondary",
|
|
115
|
-
children:
|
|
116
|
-
}), /* @__PURE__ */
|
|
117
|
+
children: F("adaptercloud.connections.region", "Region")
|
|
118
|
+
}), /* @__PURE__ */ D("dd", {
|
|
117
119
|
className: "mt-0.5 font-medium text-text-primary",
|
|
118
|
-
children:
|
|
120
|
+
children: B.region ?? "—"
|
|
119
121
|
})] }),
|
|
120
|
-
/* @__PURE__ */
|
|
122
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("dt", {
|
|
121
123
|
className: "text-text-secondary",
|
|
122
|
-
children:
|
|
123
|
-
}), /* @__PURE__ */
|
|
124
|
+
children: F("adaptercloud.connections.environment", "Environment")
|
|
125
|
+
}), /* @__PURE__ */ D("dd", {
|
|
124
126
|
className: "mt-0.5 font-medium text-text-primary",
|
|
125
|
-
children:
|
|
127
|
+
children: B.environment ?? "—"
|
|
126
128
|
})] }),
|
|
127
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("dt", {
|
|
128
130
|
className: "text-text-secondary",
|
|
129
|
-
children:
|
|
130
|
-
}), /* @__PURE__ */
|
|
131
|
+
children: F("adaptercloud.connections.resourceCount", "Resources")
|
|
132
|
+
}), /* @__PURE__ */ D("dd", {
|
|
131
133
|
className: "mt-0.5 font-medium tabular-nums text-text-primary",
|
|
132
|
-
children:
|
|
134
|
+
children: B.resourceCount
|
|
133
135
|
})] }),
|
|
134
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("dt", {
|
|
135
137
|
className: "text-text-secondary",
|
|
136
|
-
children:
|
|
137
|
-
}), /* @__PURE__ */
|
|
138
|
+
children: F("adaptercloud.connections.lastSynced", "Last synced")
|
|
139
|
+
}), /* @__PURE__ */ D("dd", {
|
|
138
140
|
className: "mt-0.5 font-medium text-text-primary",
|
|
139
|
-
children:
|
|
141
|
+
children: B.lastSyncedAt ? p(B.lastSyncedAt) : "—"
|
|
140
142
|
})] })
|
|
141
143
|
]
|
|
142
144
|
}),
|
|
143
|
-
|
|
145
|
+
B.lastError && /* @__PURE__ */ D("p", {
|
|
144
146
|
className: "mt-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
|
|
145
|
-
children:
|
|
147
|
+
children: B.lastError
|
|
146
148
|
}),
|
|
147
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ O("div", {
|
|
148
150
|
className: "mt-5 border-t border-border-subtle pt-5",
|
|
149
|
-
children: [/* @__PURE__ */
|
|
151
|
+
children: [/* @__PURE__ */ D("h3", {
|
|
150
152
|
className: "mb-3 text-sm font-semibold text-text-primary",
|
|
151
|
-
children:
|
|
152
|
-
}), /* @__PURE__ */
|
|
153
|
+
children: F("adaptercloud.connections.setHealth", "Set health")
|
|
154
|
+
}), /* @__PURE__ */ O("div", {
|
|
153
155
|
className: "flex flex-wrap gap-2",
|
|
154
|
-
children: [
|
|
156
|
+
children: [A.map((e) => /* @__PURE__ */ D("button", {
|
|
155
157
|
type: "button",
|
|
156
|
-
disabled:
|
|
157
|
-
onClick: () =>
|
|
158
|
+
disabled: L.isPending || B.status === e,
|
|
159
|
+
onClick: () => Y(e),
|
|
158
160
|
className: "rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-40",
|
|
159
161
|
children: r[e]
|
|
160
|
-
}, e)),
|
|
162
|
+
}, e)), B.status !== "DISABLED" && /* @__PURE__ */ O("button", {
|
|
161
163
|
type: "button",
|
|
162
|
-
disabled:
|
|
163
|
-
onClick: () =>
|
|
164
|
+
disabled: R.isPending,
|
|
165
|
+
onClick: () => q(!0),
|
|
164
166
|
className: "inline-flex 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-40",
|
|
165
|
-
children: [/* @__PURE__ */
|
|
167
|
+
children: [/* @__PURE__ */ D(b, { className: "h-3.5 w-3.5" }), F("adaptercloud.connections.disable", "Disable")]
|
|
166
168
|
})]
|
|
167
169
|
})]
|
|
168
170
|
}),
|
|
169
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ O("div", {
|
|
170
172
|
className: "mt-5 border-t border-border-subtle pt-5",
|
|
171
|
-
children: [
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
173
|
+
children: [
|
|
174
|
+
/* @__PURE__ */ O("h3", {
|
|
175
|
+
className: "mb-3 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
176
|
+
children: [/* @__PURE__ */ D(w, { className: "h-4 w-4" }), F("adaptercloud.connections.startSync", "Start a sync run")]
|
|
177
|
+
}),
|
|
178
|
+
!V && /* @__PURE__ */ D("p", {
|
|
179
|
+
id: "disabled-connection-sync-help",
|
|
180
|
+
className: "mb-3 text-sm text-text-secondary",
|
|
181
|
+
children: F("adaptercloud.connections.disabledSyncHelp", "Sync runs are unavailable while this connection is disabled. Set its health to re-enable sync.")
|
|
182
|
+
}),
|
|
183
|
+
/* @__PURE__ */ D("div", {
|
|
184
|
+
className: "flex flex-wrap gap-2",
|
|
185
|
+
children: j.map((e) => {
|
|
186
|
+
let t = z.isPending && H === e;
|
|
187
|
+
return /* @__PURE__ */ O("button", {
|
|
188
|
+
type: "button",
|
|
189
|
+
disabled: z.isPending || !V,
|
|
190
|
+
"aria-describedby": V ? void 0 : "disabled-connection-sync-help",
|
|
191
|
+
title: V ? void 0 : F("adaptercloud.connections.disabledSyncTooltip", "Re-enable this connection before starting a sync run."),
|
|
192
|
+
onClick: () => Z(e),
|
|
193
|
+
className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:opacity-50",
|
|
194
|
+
children: [t ? /* @__PURE__ */ D(x, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ D(C, { className: "h-4 w-4" }), o[e]]
|
|
195
|
+
}, e);
|
|
196
|
+
})
|
|
185
197
|
})
|
|
186
|
-
|
|
198
|
+
]
|
|
187
199
|
})
|
|
188
200
|
]
|
|
189
201
|
}),
|
|
190
|
-
|
|
202
|
+
B.config != null && /* @__PURE__ */ O(k, {
|
|
191
203
|
className: "p-6",
|
|
192
|
-
children: [/* @__PURE__ */
|
|
204
|
+
children: [/* @__PURE__ */ D("h3", {
|
|
193
205
|
className: "mb-3 text-sm font-semibold text-text-primary",
|
|
194
|
-
children:
|
|
195
|
-
}), /* @__PURE__ */
|
|
206
|
+
children: F("adaptercloud.connections.config", "Configuration")
|
|
207
|
+
}), /* @__PURE__ */ D("pre", {
|
|
196
208
|
className: "overflow-auto rounded-lg bg-bg-sunken p-4 text-xs text-text-secondary",
|
|
197
|
-
children: JSON.stringify(
|
|
209
|
+
children: JSON.stringify(B.config, null, 2)
|
|
198
210
|
})]
|
|
199
211
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ O("section", { children: [/* @__PURE__ */ O("div", {
|
|
201
213
|
className: "mb-3 flex items-center justify-between",
|
|
202
|
-
children: [/* @__PURE__ */
|
|
214
|
+
children: [/* @__PURE__ */ D("h3", {
|
|
203
215
|
className: "text-base font-semibold text-text-primary",
|
|
204
|
-
children:
|
|
205
|
-
}), /* @__PURE__ */
|
|
216
|
+
children: F("adaptercloud.connections.discoveredResources", "Discovered Resources")
|
|
217
|
+
}), /* @__PURE__ */ D("button", {
|
|
206
218
|
type: "button",
|
|
207
|
-
onClick: () =>
|
|
219
|
+
onClick: () => N(`/resources?connectionId=${B.id}`),
|
|
208
220
|
className: "text-sm font-medium text-accent-blue hover:underline",
|
|
209
|
-
children:
|
|
221
|
+
children: F("adaptercloud.common.viewAll", "View all")
|
|
210
222
|
})]
|
|
211
|
-
}),
|
|
223
|
+
}), B.resources && B.resources.length > 0 ? /* @__PURE__ */ D("div", {
|
|
212
224
|
className: "divide-y divide-border rounded-xl border border-border-subtle bg-bg-surface",
|
|
213
|
-
children:
|
|
225
|
+
children: B.resources.slice(0, 10).map((e) => /* @__PURE__ */ O("button", {
|
|
214
226
|
type: "button",
|
|
215
|
-
onClick: () =>
|
|
227
|
+
onClick: () => N(`/resources/${e.id}`),
|
|
216
228
|
className: "flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-accent/50",
|
|
217
229
|
children: [
|
|
218
|
-
/* @__PURE__ */
|
|
219
|
-
/* @__PURE__ */
|
|
230
|
+
/* @__PURE__ */ D(T, { className: "h-4 w-4 shrink-0 text-text-secondary" }),
|
|
231
|
+
/* @__PURE__ */ O("div", {
|
|
220
232
|
className: "min-w-0 flex-1",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
233
|
+
children: [/* @__PURE__ */ D("p", {
|
|
222
234
|
className: "truncate text-sm font-medium text-text-primary",
|
|
223
235
|
children: e.name
|
|
224
|
-
}), /* @__PURE__ */
|
|
236
|
+
}), /* @__PURE__ */ O("p", {
|
|
225
237
|
className: "mt-0.5 text-xs text-text-secondary",
|
|
226
238
|
children: [e.resourceType, e.region ? ` · ${e.region}` : ""]
|
|
227
239
|
})]
|
|
228
240
|
}),
|
|
229
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ D("span", {
|
|
230
242
|
className: "hidden text-xs text-text-secondary sm:inline",
|
|
231
243
|
children: i(e.monthlyCost)
|
|
232
244
|
}),
|
|
233
|
-
/* @__PURE__ */
|
|
245
|
+
/* @__PURE__ */ D(s, {
|
|
234
246
|
status: e.state,
|
|
235
247
|
label: a[e.state]
|
|
236
248
|
})
|
|
237
249
|
]
|
|
238
250
|
}, e.id))
|
|
239
|
-
}) : /* @__PURE__ */
|
|
251
|
+
}) : /* @__PURE__ */ D("p", {
|
|
240
252
|
className: "rounded-xl border border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary",
|
|
241
|
-
children:
|
|
253
|
+
children: F("adaptercloud.connections.noResources", "No resources discovered yet. Start a discovery sync run.")
|
|
242
254
|
})] })
|
|
243
255
|
]
|
|
244
256
|
})
|
|
245
|
-
}), /* @__PURE__ */
|
|
246
|
-
open:
|
|
247
|
-
onOpenChange:
|
|
248
|
-
title:
|
|
249
|
-
description:
|
|
250
|
-
confirmLabel:
|
|
251
|
-
cancelLabel:
|
|
252
|
-
onConfirm:
|
|
253
|
-
isPending:
|
|
257
|
+
}), /* @__PURE__ */ D(m, {
|
|
258
|
+
open: K,
|
|
259
|
+
onOpenChange: q,
|
|
260
|
+
title: F("adaptercloud.connections.disableTitle", "Disable this connection?"),
|
|
261
|
+
description: F("adaptercloud.connections.disablePrompt", "Disabling stops discovery and sync runs against this target. You can re-enable it later by setting its health."),
|
|
262
|
+
confirmLabel: F("adaptercloud.connections.disable", "Disable"),
|
|
263
|
+
cancelLabel: F("adaptercloud.common.cancel", "Cancel"),
|
|
264
|
+
onConfirm: X,
|
|
265
|
+
isPending: R.isPending,
|
|
254
266
|
tone: "danger"
|
|
255
267
|
})]
|
|
256
268
|
});
|
|
257
269
|
}
|
|
258
270
|
//#endregion
|
|
259
|
-
export {
|
|
271
|
+
export { M as ConnectionDetailPage };
|
|
260
272
|
|
|
261
273
|
//# sourceMappingURL=ConnectionDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionDetailPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/connections/ConnectionDetailPage.tsx"],"sourcesContent":["/**\n * Connection Detail Page\n * @module adaptercloud/pages/connections\n *\n * One connection (`adaConnection`) — its adapter, health, config, and the\n * resources it has discovered. Supports the validated health transition\n * (`adaSetConnectionStatus`), disable (`adaDisableConnection`), and starting a\n * sync run (`adaStartSyncRun`) against it.\n */\n\nimport { useCallback, useState } from 'react';\nimport { Loader2 } from 'lucide-react';\nimport { useParams } from 'react-router';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowLeft, Ban, Pencil, Play, RefreshCw, Server } from 'lucide-react';\nimport { GlassCard } 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 {\n useConnection,\n useDisableConnection,\n useSetConnectionStatus,\n useStartSyncRun,\n} from '../../hooks/useAdapterCloudApi';\nimport {\n authMethodLabels,\n connectionStatusLabels,\n resourceStateLabels,\n syncKindLabels,\n} from '../../utils/domain';\nimport { formatDate } from '../../utils/formatters';\nimport { formatMoney } from '../../utils/domain';\nimport type { AdaConnectionStatus, AdaSyncKind } from '../../types';\n\nconst TRANSITIONABLE: AdaConnectionStatus[] = ['CONNECTED', 'DEGRADED', 'ERROR', 'PENDING'];\nconst SYNC_KINDS: AdaSyncKind[] = ['DISCOVERY', 'RECONCILE', 'COST_INGEST', 'FULL'];\n\nexport function ConnectionDetailPage() {\n const { id } = useParams<{ id: string }>();\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 query = useConnection(id);\n const setStatus = useSetConnectionStatus();\n const disable = useDisableConnection();\n const startRun = useStartSyncRun();\n const conn = query.data;\n\n const [runningKind, setRunningKind] = useState<AdaSyncKind | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n const [confirmDisableOpen, setConfirmDisableOpen] = useState(false);\n\n const onError = useCallback(\n (err: unknown) =>\n setActionError(err instanceof Error ? err.message : 'Action failed. Please try again.'),\n []\n );\n\n const handleSetStatus = useCallback(\n (newStatus: AdaConnectionStatus) => {\n if (!id) return;\n setActionError(null);\n setStatus.mutate({ id, status: newStatus }, { onError });\n },\n [id, setStatus, onError]\n );\n\n const handleDisable = useCallback(() => {\n if (!id) return;\n setActionError(null);\n disable.mutate(id, {\n onSuccess: () => setConfirmDisableOpen(false),\n onError,\n });\n }, [id, disable, onError]);\n\n const handleStartKind = useCallback(\n (kind: AdaSyncKind) => {\n if (!id) return;\n setActionError(null);\n setRunningKind(kind);\n startRun.mutate(\n { connectionId: id, kind },\n {\n onSuccess: () => {\n setRunningKind(null);\n navigateTo('/sync-runs');\n },\n onError: (err) => {\n setRunningKind(null);\n onError(err);\n },\n }\n );\n },\n [id, startRun, navigateTo, onError]\n );\n\n return (\n <PageLayout\n title={conn?.name ?? t('adaptercloud.connections.detailTitle', 'Connection')}\n description={conn?.adapter?.name}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/connections')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n {t('adaptercloud.common.back', 'Back')}\n </button>\n {conn && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/connections/${conn.id}/edit`)}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n <Pencil className=\"h-4 w-4\" />\n {t('adaptercloud.common.edit', 'Edit')}\n </button>\n )}\n </div>\n }\n >\n <DataState\n isLoading={query.isLoading}\n isError={query.isError}\n isEmpty={!query.isLoading && !conn}\n error={query.error}\n onRetry={() => void query.refetch()}\n emptyTitle={t('adaptercloud.connections.notFound', 'Connection not found')}\n >\n {conn && (\n <div className=\"space-y-6\">\n {actionError && (\n <p\n role=\"alert\"\n aria-live=\"polite\"\n className=\"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 {/* Health + actions */}\n <GlassCard className=\"p-6\">\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <StatusBadge status={conn.status} />\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\">\n {authMethodLabels[conn.authMethod]}\n </span>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-4 text-sm sm:grid-cols-4\">\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.region', 'Region')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">{conn.region ?? '—'}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.environment', 'Environment')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {conn.environment ?? '—'}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.resourceCount', 'Resources')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n {conn.resourceCount}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.lastSynced', 'Last synced')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {conn.lastSyncedAt ? formatDate(conn.lastSyncedAt) : '—'}\n </dd>\n </div>\n </dl>\n\n {conn.lastError && (\n <p className=\"mt-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {conn.lastError}\n </p>\n )}\n\n {/* Health transitions */}\n <div className=\"mt-5 border-t border-border-subtle pt-5\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.connections.setHealth', 'Set health')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {TRANSITIONABLE.map((s) => (\n <button\n key={s}\n type=\"button\"\n disabled={setStatus.isPending || conn.status === s}\n onClick={() => handleSetStatus(s)}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {connectionStatusLabels[s]}\n </button>\n ))}\n {conn.status !== 'DISABLED' && (\n <button\n type=\"button\"\n disabled={disable.isPending}\n onClick={() => setConfirmDisableOpen(true)}\n className=\"inline-flex 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-40\"\n >\n <Ban className=\"h-3.5 w-3.5\" />\n {t('adaptercloud.connections.disable', 'Disable')}\n </button>\n )}\n </div>\n </div>\n\n {/* Start sync run */}\n <div className=\"mt-5 border-t border-border-subtle pt-5\">\n <h3 className=\"mb-3 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <RefreshCw className=\"h-4 w-4\" />\n {t('adaptercloud.connections.startSync', 'Start a sync run')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {SYNC_KINDS.map((k) => {\n const pending = startRun.isPending && runningKind === k;\n return (\n <button\n key={k}\n type=\"button\"\n disabled={startRun.isPending}\n onClick={() => handleStartKind(k)}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:opacity-50\"\n >\n {pending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Play className=\"h-4 w-4\" />\n )}\n {syncKindLabels[k]}\n </button>\n );\n })}\n </div>\n </div>\n </GlassCard>\n\n {/* Config */}\n {conn.config != null && (\n <GlassCard className=\"p-6\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.connections.config', 'Configuration')}\n </h3>\n <pre className=\"overflow-auto rounded-lg bg-bg-sunken p-4 text-xs text-text-secondary\">\n {JSON.stringify(conn.config, null, 2)}\n </pre>\n </GlassCard>\n )}\n\n {/* Resources */}\n <section>\n <div className=\"mb-3 flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n {t('adaptercloud.connections.discoveredResources', 'Discovered Resources')}\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/resources?connectionId=${conn.id}`)}\n className=\"text-sm font-medium text-accent-blue hover:underline\"\n >\n {t('adaptercloud.common.viewAll', 'View all')}\n </button>\n </div>\n {conn.resources && conn.resources.length > 0 ? (\n <div className=\"divide-y divide-border rounded-xl border border-border-subtle bg-bg-surface\">\n {conn.resources.slice(0, 10).map((r) => (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => navigateTo(`/resources/${r.id}`)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-accent/50\"\n >\n <Server className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{r.name}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {r.resourceType}\n {r.region ? ` · ${r.region}` : ''}\n </p>\n </div>\n <span className=\"hidden text-xs text-text-secondary sm:inline\">\n {formatMoney(r.monthlyCost)}\n </span>\n <StatusBadge status={r.state} label={resourceStateLabels[r.state]} />\n </button>\n ))}\n </div>\n ) : (\n <p className=\"rounded-xl border border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary\">\n {t(\n 'adaptercloud.connections.noResources',\n 'No resources discovered yet. Start a discovery sync run.'\n )}\n </p>\n )}\n </section>\n </div>\n )}\n </DataState>\n\n <ConfirmDialog\n open={confirmDisableOpen}\n onOpenChange={setConfirmDisableOpen}\n title={t('adaptercloud.connections.disableTitle', 'Disable this connection?')}\n description={t(\n 'adaptercloud.connections.disablePrompt',\n 'Disabling stops discovery and sync runs against this target. You can re-enable it later by setting its health.'\n )}\n confirmLabel={t('adaptercloud.connections.disable', 'Disable')}\n cancelLabel={t('adaptercloud.common.cancel', 'Cancel')}\n onConfirm={handleDisable}\n isPending={disable.isPending}\n tone=\"danger\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConnectionDetailPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/connections/ConnectionDetailPage.tsx"],"sourcesContent":["/**\n * Connection Detail Page\n * @module adaptercloud/pages/connections\n *\n * One connection (`adaConnection`) — its adapter, health, config, and the\n * resources it has discovered. Supports the validated health transition\n * (`adaSetConnectionStatus`), disable (`adaDisableConnection`), and starting a\n * sync run (`adaStartSyncRun`) against it.\n */\n\nimport { useCallback, useState } from 'react';\nimport { Loader2 } from 'lucide-react';\nimport { useParams } from 'react-router';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowLeft, Ban, Pencil, Play, RefreshCw, Server } from 'lucide-react';\nimport { GlassCard } 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 {\n useConnection,\n useDisableConnection,\n useSetConnectionStatus,\n useStartSyncRun,\n} from '../../hooks/useAdapterCloudApi';\nimport {\n authMethodLabels,\n connectionStatusLabels,\n resourceStateLabels,\n syncKindLabels,\n} from '../../utils/domain';\nimport { formatDate } from '../../utils/formatters';\nimport { formatMoney } from '../../utils/domain';\nimport type { AdaConnectionStatus, AdaSyncKind } from '../../types';\nimport { canStartConnectionSync } from './connectionSync';\n\nconst TRANSITIONABLE: AdaConnectionStatus[] = ['CONNECTED', 'DEGRADED', 'ERROR', 'PENDING'];\nconst SYNC_KINDS: AdaSyncKind[] = ['DISCOVERY', 'RECONCILE', 'COST_INGEST', 'FULL'];\n\nexport function ConnectionDetailPage() {\n const { id } = useParams<{ id: string }>();\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 query = useConnection(id);\n const setStatus = useSetConnectionStatus();\n const disable = useDisableConnection();\n const startRun = useStartSyncRun();\n const conn = query.data;\n const syncEnabled = conn ? canStartConnectionSync(conn.status) : false;\n\n const [runningKind, setRunningKind] = useState<AdaSyncKind | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n const [confirmDisableOpen, setConfirmDisableOpen] = useState(false);\n\n const onError = useCallback(\n (err: unknown) =>\n setActionError(err instanceof Error ? err.message : 'Action failed. Please try again.'),\n []\n );\n\n const handleSetStatus = useCallback(\n (newStatus: AdaConnectionStatus) => {\n if (!id) return;\n setActionError(null);\n setStatus.mutate({ id, status: newStatus }, { onError });\n },\n [id, setStatus, onError]\n );\n\n const handleDisable = useCallback(() => {\n if (!id) return;\n setActionError(null);\n disable.mutate(id, {\n onSuccess: () => setConfirmDisableOpen(false),\n onError,\n });\n }, [id, disable, onError]);\n\n const handleStartKind = useCallback(\n (kind: AdaSyncKind) => {\n if (!id || !syncEnabled) return;\n setActionError(null);\n setRunningKind(kind);\n startRun.mutate(\n { connectionId: id, kind },\n {\n onSuccess: () => {\n setRunningKind(null);\n navigateTo('/sync-runs');\n },\n onError: (err) => {\n setRunningKind(null);\n onError(err);\n },\n }\n );\n },\n [id, syncEnabled, startRun, navigateTo, onError]\n );\n\n return (\n <PageLayout\n title={conn?.name ?? t('adaptercloud.connections.detailTitle', 'Connection')}\n description={conn?.adapter?.name}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/connections')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n {t('adaptercloud.common.back', 'Back')}\n </button>\n {conn && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/connections/${conn.id}/edit`)}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent\"\n >\n <Pencil className=\"h-4 w-4\" />\n {t('adaptercloud.common.edit', 'Edit')}\n </button>\n )}\n </div>\n }\n >\n <DataState\n isLoading={query.isLoading}\n isError={query.isError}\n isEmpty={!query.isLoading && !conn}\n error={query.error}\n onRetry={() => void query.refetch()}\n emptyTitle={t('adaptercloud.connections.notFound', 'Connection not found')}\n >\n {conn && (\n <div className=\"space-y-6\">\n {actionError && (\n <p\n role=\"alert\"\n aria-live=\"polite\"\n className=\"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 {/* Health + actions */}\n <GlassCard className=\"p-6\">\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <StatusBadge status={conn.status} />\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\">\n {authMethodLabels[conn.authMethod]}\n </span>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-4 text-sm sm:grid-cols-4\">\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.region', 'Region')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">{conn.region ?? '—'}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.environment', 'Environment')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {conn.environment ?? '—'}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.resourceCount', 'Resources')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n {conn.resourceCount}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.connections.lastSynced', 'Last synced')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {conn.lastSyncedAt ? formatDate(conn.lastSyncedAt) : '—'}\n </dd>\n </div>\n </dl>\n\n {conn.lastError && (\n <p className=\"mt-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {conn.lastError}\n </p>\n )}\n\n {/* Health transitions */}\n <div className=\"mt-5 border-t border-border-subtle pt-5\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.connections.setHealth', 'Set health')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {TRANSITIONABLE.map((s) => (\n <button\n key={s}\n type=\"button\"\n disabled={setStatus.isPending || conn.status === s}\n onClick={() => handleSetStatus(s)}\n className=\"rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {connectionStatusLabels[s]}\n </button>\n ))}\n {conn.status !== 'DISABLED' && (\n <button\n type=\"button\"\n disabled={disable.isPending}\n onClick={() => setConfirmDisableOpen(true)}\n className=\"inline-flex 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-40\"\n >\n <Ban className=\"h-3.5 w-3.5\" />\n {t('adaptercloud.connections.disable', 'Disable')}\n </button>\n )}\n </div>\n </div>\n\n {/* Start sync run */}\n <div className=\"mt-5 border-t border-border-subtle pt-5\">\n <h3 className=\"mb-3 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <RefreshCw className=\"h-4 w-4\" />\n {t('adaptercloud.connections.startSync', 'Start a sync run')}\n </h3>\n {!syncEnabled && (\n <p\n id=\"disabled-connection-sync-help\"\n className=\"mb-3 text-sm text-text-secondary\"\n >\n {t(\n 'adaptercloud.connections.disabledSyncHelp',\n 'Sync runs are unavailable while this connection is disabled. Set its health to re-enable sync.'\n )}\n </p>\n )}\n <div className=\"flex flex-wrap gap-2\">\n {SYNC_KINDS.map((k) => {\n const pending = startRun.isPending && runningKind === k;\n return (\n <button\n key={k}\n type=\"button\"\n disabled={startRun.isPending || !syncEnabled}\n aria-describedby={syncEnabled ? undefined : 'disabled-connection-sync-help'}\n title={\n syncEnabled\n ? undefined\n : t(\n 'adaptercloud.connections.disabledSyncTooltip',\n 'Re-enable this connection before starting a sync run.'\n )\n }\n onClick={() => handleStartKind(k)}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-accent disabled:opacity-50\"\n >\n {pending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Play className=\"h-4 w-4\" />\n )}\n {syncKindLabels[k]}\n </button>\n );\n })}\n </div>\n </div>\n </GlassCard>\n\n {/* Config */}\n {conn.config != null && (\n <GlassCard className=\"p-6\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.connections.config', 'Configuration')}\n </h3>\n <pre className=\"overflow-auto rounded-lg bg-bg-sunken p-4 text-xs text-text-secondary\">\n {JSON.stringify(conn.config, null, 2)}\n </pre>\n </GlassCard>\n )}\n\n {/* Resources */}\n <section>\n <div className=\"mb-3 flex items-center justify-between\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n {t('adaptercloud.connections.discoveredResources', 'Discovered Resources')}\n </h3>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/resources?connectionId=${conn.id}`)}\n className=\"text-sm font-medium text-accent-blue hover:underline\"\n >\n {t('adaptercloud.common.viewAll', 'View all')}\n </button>\n </div>\n {conn.resources && conn.resources.length > 0 ? (\n <div className=\"divide-y divide-border rounded-xl border border-border-subtle bg-bg-surface\">\n {conn.resources.slice(0, 10).map((r) => (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => navigateTo(`/resources/${r.id}`)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-accent/50\"\n >\n <Server className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{r.name}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {r.resourceType}\n {r.region ? ` · ${r.region}` : ''}\n </p>\n </div>\n <span className=\"hidden text-xs text-text-secondary sm:inline\">\n {formatMoney(r.monthlyCost)}\n </span>\n <StatusBadge status={r.state} label={resourceStateLabels[r.state]} />\n </button>\n ))}\n </div>\n ) : (\n <p className=\"rounded-xl border border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary\">\n {t(\n 'adaptercloud.connections.noResources',\n 'No resources discovered yet. Start a discovery sync run.'\n )}\n </p>\n )}\n </section>\n </div>\n )}\n </DataState>\n\n <ConfirmDialog\n open={confirmDisableOpen}\n onOpenChange={setConfirmDisableOpen}\n title={t('adaptercloud.connections.disableTitle', 'Disable this connection?')}\n description={t(\n 'adaptercloud.connections.disablePrompt',\n 'Disabling stops discovery and sync runs against this target. You can re-enable it later by setting its health.'\n )}\n confirmLabel={t('adaptercloud.connections.disable', 'Disable')}\n cancelLabel={t('adaptercloud.common.cancel', 'Cancel')}\n onConfirm={handleDisable}\n isPending={disable.isPending}\n tone=\"danger\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectionSync.d.ts","sourceRoot":"","sources":["../../../../src/adaptercloud/pages/connections/connectionSync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAE3E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectionSync.js","names":[],"sources":["../../../../src/adaptercloud/pages/connections/connectionSync.ts"],"sourcesContent":["import type { AdaConnectionStatus } from '../../types';\n\nexport function canStartConnectionSync(status: AdaConnectionStatus): boolean {\n return status !== 'DISABLED';\n}\n"],"mappings":";AAEA,SAAgB,EAAuB,GAAsC;CAC3E,OAAO,MAAW;AACpB"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* live node-link map, grouped into human "zones" (Public Cloud, Kubernetes,
|
|
7
7
|
* Edge / IoT, Data Systems, Network) and wired together by the topology edges
|
|
8
8
|
* (`adaListTopologyEdges`). Selecting a node opens an inspector with its
|
|
9
|
-
* dependency count and
|
|
9
|
+
* dependency count and transitive dependent-impact count. All data is live from the
|
|
10
10
|
* deployed `wspace-adaptercloud-svc` subgraph — nodes from `adaListResources`,
|
|
11
11
|
* edges from `adaListTopologyEdges`. No mocks.
|
|
12
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopologyPage.d.ts","sourceRoot":"","sources":["../../../../src/adaptercloud/pages/topology/TopologyPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"TopologyPage.d.ts","sourceRoot":"","sources":["../../../../src/adaptercloud/pages/topology/TopologyPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyEH,wBAAgB,YAAY,gCA6a3B"}
|