@burdenoff/microfe-adaptercloud 2026.706.2 → 2026.706.4
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.js +52 -44
- package/dist/adaptercloud/AdapterCloudRoot.js.map +1 -1
- package/dist/adaptercloud/AdapterCloudRoutes.js +18 -14
- package/dist/adaptercloud/AdapterCloudRoutes.js.map +1 -1
- package/dist/adaptercloud/components/ConfirmDialog.js.map +1 -1
- package/dist/adaptercloud/components/viz/BarChart.js +32 -0
- package/dist/adaptercloud/components/viz/BarChart.js.map +1 -0
- package/dist/adaptercloud/components/viz/Sparkline.js +50 -0
- package/dist/adaptercloud/components/viz/Sparkline.js.map +1 -0
- package/dist/adaptercloud/components/viz/StackedBar.js +1 -0
- package/dist/adaptercloud/components/viz/TopologyGraph.js +96 -0
- package/dist/adaptercloud/components/viz/TopologyGraph.js.map +1 -0
- package/dist/adaptercloud/components/viz/index.js +4 -0
- package/dist/adaptercloud/hooks/useAdapterCloudApi.js +22 -4
- package/dist/adaptercloud/hooks/useAdapterCloudApi.js.map +1 -1
- package/dist/adaptercloud/pages/OverviewPage.js.map +1 -1
- package/dist/adaptercloud/pages/adapters/AdapterDetailPage.js +176 -123
- package/dist/adaptercloud/pages/adapters/AdapterDetailPage.js.map +1 -1
- package/dist/adaptercloud/pages/adapters/AdapterFormPage.js +261 -179
- package/dist/adaptercloud/pages/adapters/AdapterFormPage.js.map +1 -1
- package/dist/adaptercloud/pages/adapters/AdaptersListPage.js.map +1 -1
- package/dist/adaptercloud/pages/connections/ConnectionsListPage.js +158 -94
- package/dist/adaptercloud/pages/connections/ConnectionsListPage.js.map +1 -1
- package/dist/adaptercloud/pages/costs/CostsPage.js +160 -111
- package/dist/adaptercloud/pages/costs/CostsPage.js.map +1 -1
- package/dist/adaptercloud/pages/drift/DriftListPage.js +163 -84
- package/dist/adaptercloud/pages/drift/DriftListPage.js.map +1 -1
- package/dist/adaptercloud/pages/policies/PoliciesListPage.js +177 -96
- package/dist/adaptercloud/pages/policies/PoliciesListPage.js.map +1 -1
- package/dist/adaptercloud/pages/resources/ResourceDetailPage.js +145 -131
- package/dist/adaptercloud/pages/resources/ResourceDetailPage.js.map +1 -1
- package/dist/adaptercloud/pages/resources/ResourcesListPage.js +10 -1
- package/dist/adaptercloud/pages/resources/ResourcesListPage.js.map +1 -1
- package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.js +226 -165
- package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.js.map +1 -1
- package/dist/adaptercloud/pages/topology/TopologyPage.js +397 -0
- package/dist/adaptercloud/pages/topology/TopologyPage.js.map +1 -0
- package/dist/adaptercloud/pages/violations/ViolationsListPage.js +184 -131
- package/dist/adaptercloud/pages/violations/ViolationsListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,133 +1,139 @@
|
|
|
1
1
|
import { useAdapterCloud as e } from "../../context/AdapterCloudContext.js";
|
|
2
2
|
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
-
import { adapterKindLabels as n
|
|
4
|
-
import { StatusBadge as
|
|
5
|
-
import { DataState as
|
|
6
|
-
import { useAdapter as
|
|
7
|
-
import { formatDate as
|
|
8
|
-
import { ConfirmDialog as
|
|
9
|
-
import { useCallback as
|
|
10
|
-
import { useI18n as
|
|
11
|
-
import { Archive as
|
|
12
|
-
import { useParams as
|
|
13
|
-
import { Fragment as
|
|
14
|
-
import { GlassCard as
|
|
3
|
+
import { adapterKindLabels as n } from "../../utils/domain.js";
|
|
4
|
+
import { StatusBadge as r } from "../../components/StatusBadge.js";
|
|
5
|
+
import { DataState as i } from "../../components/DataState.js";
|
|
6
|
+
import { useAdapter as a, useArchiveAdapter as o } from "../../hooks/useAdapterCloudApi.js";
|
|
7
|
+
import { formatDate as s } from "../../utils/formatters.js";
|
|
8
|
+
import { ConfirmDialog as c } from "../../components/ConfirmDialog.js";
|
|
9
|
+
import { useCallback as l, useState as u } from "react";
|
|
10
|
+
import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
11
|
+
import { Archive as f, ArrowLeft as p, Cable as m, Check as h, Copy as g, Pencil as _ } from "lucide-react";
|
|
12
|
+
import { useParams as v } from "react-router-dom";
|
|
13
|
+
import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
14
|
+
import { GlassCard as S } from "@burdenoff/fe-libs/ui";
|
|
15
15
|
//#region src/adaptercloud/pages/adapters/AdapterDetailPage.tsx
|
|
16
|
-
function
|
|
17
|
-
let { id:
|
|
18
|
-
let n =
|
|
16
|
+
function C() {
|
|
17
|
+
let { id: C } = v(), { navigateTo: w } = e(), { t: T } = d(), E = l((e, t) => {
|
|
18
|
+
let n = T(e);
|
|
19
19
|
return n === e ? t : n;
|
|
20
|
-
}, [
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
}, [T]), D = a(C), O = o(), k = D.data, [A, j] = u(!1), [M, N] = u(!1), P = l(() => {
|
|
21
|
+
if (k?.configSchema == null) return;
|
|
22
|
+
let e = JSON.stringify(k.configSchema, null, 2);
|
|
23
|
+
navigator.clipboard?.writeText(e).then(() => {
|
|
24
|
+
N(!0), setTimeout(() => N(!1), 1500);
|
|
25
|
+
}).catch(() => {});
|
|
26
|
+
}, [k?.configSchema]), F = l(() => {
|
|
27
|
+
C && O.mutate(C, { onSuccess: () => {
|
|
28
|
+
j(!1), w("/adapters");
|
|
23
29
|
} });
|
|
24
30
|
}, [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
O,
|
|
32
|
+
C,
|
|
33
|
+
w
|
|
28
34
|
]);
|
|
29
|
-
return /* @__PURE__ */
|
|
30
|
-
title:
|
|
31
|
-
description:
|
|
32
|
-
actions: /* @__PURE__ */
|
|
35
|
+
return /* @__PURE__ */ x(t, {
|
|
36
|
+
title: k?.name ?? E("adaptercloud.adapters.detailTitle", "Adapter"),
|
|
37
|
+
description: k?.slug,
|
|
38
|
+
actions: /* @__PURE__ */ x("div", {
|
|
33
39
|
className: "flex items-center gap-2",
|
|
34
|
-
children: [/* @__PURE__ */
|
|
40
|
+
children: [/* @__PURE__ */ x("button", {
|
|
35
41
|
type: "button",
|
|
36
|
-
onClick: () =>
|
|
42
|
+
onClick: () => w("/adapters"),
|
|
37
43
|
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",
|
|
38
|
-
children: [/* @__PURE__ */
|
|
39
|
-
}),
|
|
44
|
+
children: [/* @__PURE__ */ b(p, { className: "h-4 w-4" }), E("adaptercloud.common.back", "Back")]
|
|
45
|
+
}), k && /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ x("button", {
|
|
40
46
|
type: "button",
|
|
41
|
-
onClick: () =>
|
|
47
|
+
onClick: () => w(`/adapters/${k.id}/edit`),
|
|
42
48
|
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",
|
|
43
|
-
children: [/* @__PURE__ */
|
|
44
|
-
}),
|
|
49
|
+
children: [/* @__PURE__ */ b(_, { className: "h-4 w-4" }), E("adaptercloud.common.edit", "Edit")]
|
|
50
|
+
}), k.status !== "ARCHIVED" && /* @__PURE__ */ x("button", {
|
|
45
51
|
type: "button",
|
|
46
|
-
onClick: () =>
|
|
47
|
-
disabled:
|
|
52
|
+
onClick: () => j(!0),
|
|
53
|
+
disabled: O.isPending,
|
|
48
54
|
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-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
55
|
+
children: [/* @__PURE__ */ b(f, { className: "h-4 w-4" }), E("adaptercloud.common.archive", "Archive")]
|
|
50
56
|
})] })]
|
|
51
57
|
}),
|
|
52
|
-
children: [/* @__PURE__ */
|
|
53
|
-
isLoading:
|
|
54
|
-
isError:
|
|
55
|
-
isEmpty: !
|
|
56
|
-
error:
|
|
57
|
-
onRetry: () => void
|
|
58
|
-
emptyTitle:
|
|
59
|
-
emptyDescription:
|
|
60
|
-
children:
|
|
58
|
+
children: [/* @__PURE__ */ b(i, {
|
|
59
|
+
isLoading: D.isLoading,
|
|
60
|
+
isError: D.isError,
|
|
61
|
+
isEmpty: !D.isLoading && !k,
|
|
62
|
+
error: D.error,
|
|
63
|
+
onRetry: () => void D.refetch(),
|
|
64
|
+
emptyTitle: E("adaptercloud.adapters.notFound", "Adapter not found"),
|
|
65
|
+
emptyDescription: E("adaptercloud.adapters.notFoundDescription", "This adapter does not exist or belongs to another workspace."),
|
|
66
|
+
children: k && /* @__PURE__ */ x("div", {
|
|
61
67
|
className: "space-y-6",
|
|
62
68
|
children: [
|
|
63
|
-
/* @__PURE__ */
|
|
69
|
+
/* @__PURE__ */ x(S, {
|
|
64
70
|
className: "p-6",
|
|
65
71
|
children: [
|
|
66
|
-
/* @__PURE__ */
|
|
72
|
+
/* @__PURE__ */ x("div", {
|
|
67
73
|
className: "mb-4 flex items-center gap-3",
|
|
68
74
|
children: [
|
|
69
|
-
/* @__PURE__ */
|
|
70
|
-
/* @__PURE__ */
|
|
75
|
+
/* @__PURE__ */ b(r, { status: k.status }),
|
|
76
|
+
/* @__PURE__ */ b("span", {
|
|
71
77
|
className: "inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary",
|
|
72
|
-
children: n[
|
|
78
|
+
children: n[k.kind]
|
|
73
79
|
}),
|
|
74
|
-
/* @__PURE__ */
|
|
80
|
+
/* @__PURE__ */ x("span", {
|
|
75
81
|
className: "text-xs text-text-secondary",
|
|
76
|
-
children: ["v",
|
|
82
|
+
children: ["v", k.version]
|
|
77
83
|
})
|
|
78
84
|
]
|
|
79
85
|
}),
|
|
80
|
-
|
|
86
|
+
k.description && /* @__PURE__ */ b("p", {
|
|
81
87
|
className: "mb-4 text-sm text-text-secondary",
|
|
82
|
-
children:
|
|
88
|
+
children: k.description
|
|
83
89
|
}),
|
|
84
|
-
/* @__PURE__ */
|
|
90
|
+
/* @__PURE__ */ x("dl", {
|
|
85
91
|
className: "grid grid-cols-2 gap-4 text-sm sm:grid-cols-3",
|
|
86
92
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("dt", {
|
|
88
94
|
className: "text-text-secondary",
|
|
89
|
-
children:
|
|
90
|
-
}), /* @__PURE__ */
|
|
95
|
+
children: E("adaptercloud.adapters.vendor", "Vendor")
|
|
96
|
+
}), /* @__PURE__ */ b("dd", {
|
|
91
97
|
className: "mt-0.5 font-medium text-text-primary",
|
|
92
|
-
children:
|
|
98
|
+
children: k.vendor ?? "—"
|
|
93
99
|
})] }),
|
|
94
|
-
/* @__PURE__ */
|
|
100
|
+
/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("dt", {
|
|
95
101
|
className: "text-text-secondary",
|
|
96
|
-
children:
|
|
97
|
-
}), /* @__PURE__ */
|
|
102
|
+
children: E("adaptercloud.common.created", "Created")
|
|
103
|
+
}), /* @__PURE__ */ b("dd", {
|
|
98
104
|
className: "mt-0.5 font-medium text-text-primary",
|
|
99
|
-
children:
|
|
105
|
+
children: s(k.createdAt)
|
|
100
106
|
})] }),
|
|
101
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("dt", {
|
|
102
108
|
className: "text-text-secondary",
|
|
103
|
-
children:
|
|
104
|
-
}), /* @__PURE__ */
|
|
109
|
+
children: E("adaptercloud.common.updated", "Updated")
|
|
110
|
+
}), /* @__PURE__ */ b("dd", {
|
|
105
111
|
className: "mt-0.5 font-medium text-text-primary",
|
|
106
|
-
children:
|
|
112
|
+
children: s(k.updatedAt)
|
|
107
113
|
})] })
|
|
108
114
|
]
|
|
109
115
|
}),
|
|
110
|
-
|
|
116
|
+
k.capabilities.length > 0 && /* @__PURE__ */ x("div", {
|
|
111
117
|
className: "mt-5",
|
|
112
|
-
children: [/* @__PURE__ */
|
|
118
|
+
children: [/* @__PURE__ */ b("h3", {
|
|
113
119
|
className: "mb-2 text-sm font-semibold text-text-primary",
|
|
114
|
-
children:
|
|
115
|
-
}), /* @__PURE__ */
|
|
120
|
+
children: E("adaptercloud.adapters.capabilities", "Capabilities")
|
|
121
|
+
}), /* @__PURE__ */ b("div", {
|
|
116
122
|
className: "flex flex-wrap gap-1.5",
|
|
117
|
-
children:
|
|
123
|
+
children: k.capabilities.map((e) => /* @__PURE__ */ b("span", {
|
|
118
124
|
className: "inline-flex items-center rounded-full bg-accent-blue-subtle px-2.5 py-0.5 text-xs text-accent-blue",
|
|
119
125
|
children: e
|
|
120
126
|
}, e))
|
|
121
127
|
})]
|
|
122
128
|
}),
|
|
123
|
-
|
|
129
|
+
k.tags.length > 0 && /* @__PURE__ */ x("div", {
|
|
124
130
|
className: "mt-4",
|
|
125
|
-
children: [/* @__PURE__ */
|
|
131
|
+
children: [/* @__PURE__ */ b("h3", {
|
|
126
132
|
className: "mb-2 text-sm font-semibold text-text-primary",
|
|
127
|
-
children:
|
|
128
|
-
}), /* @__PURE__ */
|
|
133
|
+
children: E("adaptercloud.common.tags", "Tags")
|
|
134
|
+
}), /* @__PURE__ */ b("div", {
|
|
129
135
|
className: "flex flex-wrap gap-1.5",
|
|
130
|
-
children:
|
|
136
|
+
children: k.tags.map((e) => /* @__PURE__ */ b("span", {
|
|
131
137
|
className: "inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary",
|
|
132
138
|
children: e
|
|
133
139
|
}, e))
|
|
@@ -135,66 +141,113 @@ function S() {
|
|
|
135
141
|
})
|
|
136
142
|
]
|
|
137
143
|
}),
|
|
138
|
-
|
|
144
|
+
k.configSchema != null && /* @__PURE__ */ x(S, {
|
|
139
145
|
className: "p-6",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
141
|
-
className: "mb-3
|
|
142
|
-
children:
|
|
143
|
-
|
|
146
|
+
children: [/* @__PURE__ */ x("div", {
|
|
147
|
+
className: "mb-3 flex items-center justify-between gap-3",
|
|
148
|
+
children: [/* @__PURE__ */ b("h3", {
|
|
149
|
+
className: "text-sm font-semibold text-text-primary",
|
|
150
|
+
children: E("adaptercloud.adapters.configSchema", "Config Schema")
|
|
151
|
+
}), /* @__PURE__ */ b("button", {
|
|
152
|
+
type: "button",
|
|
153
|
+
onClick: P,
|
|
154
|
+
"aria-label": E("adaptercloud.common.copy", "Copy"),
|
|
155
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-2.5 py-1 text-xs font-medium text-text-secondary transition-colors hover:bg-accent hover:text-text-primary",
|
|
156
|
+
children: M ? /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b(h, { className: "h-3.5 w-3.5 text-status-success-text" }), E("adaptercloud.common.copied", "Copied")] }) : /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b(g, { className: "h-3.5 w-3.5" }), E("adaptercloud.common.copy", "Copy")] })
|
|
157
|
+
})]
|
|
158
|
+
}), /* @__PURE__ */ b("pre", {
|
|
144
159
|
className: "overflow-auto rounded-lg bg-bg-sunken p-4 text-xs text-text-secondary",
|
|
145
|
-
children: JSON.stringify(
|
|
160
|
+
children: JSON.stringify(k.configSchema, null, 2)
|
|
146
161
|
})]
|
|
147
162
|
}),
|
|
148
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ x("section", { children: [/* @__PURE__ */ b("h3", {
|
|
149
164
|
className: "mb-3 text-base font-semibold text-text-primary",
|
|
150
|
-
children:
|
|
151
|
-
}),
|
|
152
|
-
className: "
|
|
153
|
-
children:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
className: "
|
|
166
|
-
children:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
165
|
+
children: E("adaptercloud.adapters.connections", "Connections")
|
|
166
|
+
}), k.connections && k.connections.length > 0 ? /* @__PURE__ */ b("div", {
|
|
167
|
+
className: "overflow-x-auto rounded-xl border border-border-subtle bg-bg-surface",
|
|
168
|
+
children: /* @__PURE__ */ x("table", {
|
|
169
|
+
className: "w-full min-w-[32rem] text-sm",
|
|
170
|
+
children: [/* @__PURE__ */ b("thead", { children: /* @__PURE__ */ x("tr", {
|
|
171
|
+
className: "border-b border-border-subtle text-left text-xs uppercase tracking-wide text-text-secondary",
|
|
172
|
+
children: [
|
|
173
|
+
/* @__PURE__ */ b("th", {
|
|
174
|
+
scope: "col",
|
|
175
|
+
className: "px-4 py-2.5 font-medium",
|
|
176
|
+
children: E("adaptercloud.adapters.connName", "Name")
|
|
177
|
+
}),
|
|
178
|
+
/* @__PURE__ */ b("th", {
|
|
179
|
+
scope: "col",
|
|
180
|
+
className: "px-4 py-2.5 font-medium",
|
|
181
|
+
children: E("adaptercloud.resources.region", "Region")
|
|
182
|
+
}),
|
|
183
|
+
/* @__PURE__ */ b("th", {
|
|
184
|
+
scope: "col",
|
|
185
|
+
className: "px-4 py-2.5 font-medium",
|
|
186
|
+
children: E("adaptercloud.adapters.status", "Status")
|
|
187
|
+
}),
|
|
188
|
+
/* @__PURE__ */ b("th", {
|
|
189
|
+
scope: "col",
|
|
190
|
+
className: "px-4 py-2.5 text-right font-medium",
|
|
191
|
+
children: E("adaptercloud.adapters.resources", "Resources")
|
|
192
|
+
})
|
|
193
|
+
]
|
|
194
|
+
}) }), /* @__PURE__ */ b("tbody", {
|
|
195
|
+
className: "divide-y divide-border",
|
|
196
|
+
children: k.connections.map((e) => /* @__PURE__ */ x("tr", {
|
|
197
|
+
role: "link",
|
|
198
|
+
tabIndex: 0,
|
|
199
|
+
onClick: () => w(`/connections/${e.id}`),
|
|
200
|
+
onKeyDown: (t) => {
|
|
201
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), w(`/connections/${e.id}`));
|
|
202
|
+
},
|
|
203
|
+
className: "cursor-pointer transition-colors hover:bg-accent/50 focus:bg-accent/50 focus:outline-none",
|
|
204
|
+
children: [
|
|
205
|
+
/* @__PURE__ */ b("td", {
|
|
206
|
+
className: "px-4 py-3",
|
|
207
|
+
children: /* @__PURE__ */ x("span", {
|
|
208
|
+
className: "flex items-center gap-2",
|
|
209
|
+
children: [/* @__PURE__ */ b(m, { className: "h-4 w-4 shrink-0 text-text-secondary" }), /* @__PURE__ */ b("span", {
|
|
210
|
+
className: "truncate font-medium text-text-primary",
|
|
211
|
+
children: e.name
|
|
212
|
+
})]
|
|
213
|
+
})
|
|
214
|
+
}),
|
|
215
|
+
/* @__PURE__ */ b("td", {
|
|
216
|
+
className: "px-4 py-3 text-text-secondary",
|
|
217
|
+
children: e.region ?? "—"
|
|
218
|
+
}),
|
|
219
|
+
/* @__PURE__ */ b("td", {
|
|
220
|
+
className: "px-4 py-3",
|
|
221
|
+
children: /* @__PURE__ */ b(r, { status: e.status })
|
|
222
|
+
}),
|
|
223
|
+
/* @__PURE__ */ b("td", {
|
|
224
|
+
className: "px-4 py-3 text-right tabular-nums text-text-secondary",
|
|
225
|
+
children: e.resourceCount
|
|
226
|
+
})
|
|
227
|
+
]
|
|
228
|
+
}, e.id))
|
|
229
|
+
})]
|
|
230
|
+
})
|
|
231
|
+
}) : /* @__PURE__ */ b("p", {
|
|
179
232
|
className: "rounded-xl border border-border-subtle bg-bg-surface px-4 py-6 text-center text-sm text-text-secondary",
|
|
180
|
-
children:
|
|
233
|
+
children: E("adaptercloud.adapters.noConnections", "No connections use this adapter yet.")
|
|
181
234
|
})] })
|
|
182
235
|
]
|
|
183
236
|
})
|
|
184
|
-
}), /* @__PURE__ */
|
|
185
|
-
open:
|
|
186
|
-
onOpenChange:
|
|
187
|
-
title:
|
|
188
|
-
description:
|
|
189
|
-
confirmLabel:
|
|
190
|
-
cancelLabel:
|
|
191
|
-
onConfirm:
|
|
192
|
-
isPending:
|
|
237
|
+
}), /* @__PURE__ */ b(c, {
|
|
238
|
+
open: A,
|
|
239
|
+
onOpenChange: j,
|
|
240
|
+
title: E("adaptercloud.adapters.archiveTitle", "Archive this adapter?"),
|
|
241
|
+
description: E("adaptercloud.adapters.archivePrompt", "The adapter will be archived and hidden from the catalog. Existing connections keep working, but no new connections can select it."),
|
|
242
|
+
confirmLabel: E("adaptercloud.common.archive", "Archive"),
|
|
243
|
+
cancelLabel: E("adaptercloud.common.cancel", "Cancel"),
|
|
244
|
+
onConfirm: F,
|
|
245
|
+
isPending: O.isPending,
|
|
193
246
|
tone: "danger"
|
|
194
247
|
})]
|
|
195
248
|
});
|
|
196
249
|
}
|
|
197
250
|
//#endregion
|
|
198
|
-
export {
|
|
251
|
+
export { C as AdapterDetailPage };
|
|
199
252
|
|
|
200
253
|
//# sourceMappingURL=AdapterDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdapterDetailPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/adapters/AdapterDetailPage.tsx"],"sourcesContent":["/**\n * Adapter Detail Page\n * @module adaptercloud/pages/adapters\n *\n * Full view of one adapter (`adaAdapter`) — metadata, capabilities, config\n * schema and its connections. Supports archiving via `adaArchiveAdapter`.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowLeft, Archive, Cable, Pencil } 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 { useAdapter, useArchiveAdapter } from '../../hooks/useAdapterCloudApi';\nimport { adapterKindLabels, authMethodLabels } from '../../utils/domain';\nimport { formatDate } from '../../utils/formatters';\n\nexport function AdapterDetailPage() {\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 = useAdapter(id);\n const archive = useArchiveAdapter();\n const adapter = query.data;\n\n const [confirmArchiveOpen, setConfirmArchiveOpen] = useState(false);\n\n const handleArchive = useCallback(() => {\n if (!id) return;\n archive.mutate(id, {\n onSuccess: () => {\n setConfirmArchiveOpen(false);\n navigateTo('/adapters');\n },\n });\n }, [archive, id, navigateTo]);\n\n return (\n <PageLayout\n title={adapter?.name ?? t('adaptercloud.adapters.detailTitle', 'Adapter')}\n description={adapter?.slug}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/adapters')}\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 {adapter && (\n <>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/adapters/${adapter.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 {adapter.status !== 'ARCHIVED' && (\n <button\n type=\"button\"\n onClick={() => setConfirmArchiveOpen(true)}\n disabled={archive.isPending}\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-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n <Archive className=\"h-4 w-4\" />\n {t('adaptercloud.common.archive', 'Archive')}\n </button>\n )}\n </>\n )}\n </div>\n }\n >\n <DataState\n isLoading={query.isLoading}\n isError={query.isError}\n isEmpty={!query.isLoading && !adapter}\n error={query.error}\n onRetry={() => void query.refetch()}\n emptyTitle={t('adaptercloud.adapters.notFound', 'Adapter not found')}\n emptyDescription={t(\n 'adaptercloud.adapters.notFoundDescription',\n 'This adapter does not exist or belongs to another workspace.'\n )}\n >\n {adapter && (\n <div className=\"space-y-6\">\n {/* Metadata */}\n <GlassCard className=\"p-6\">\n <div className=\"mb-4 flex items-center gap-3\">\n <StatusBadge status={adapter.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 {adapterKindLabels[adapter.kind]}\n </span>\n <span className=\"text-xs text-text-secondary\">v{adapter.version}</span>\n </div>\n\n {adapter.description && (\n <p className=\"mb-4 text-sm text-text-secondary\">{adapter.description}</p>\n )}\n\n <dl className=\"grid grid-cols-2 gap-4 text-sm sm:grid-cols-3\">\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.adapters.vendor', 'Vendor')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">{adapter.vendor ?? '—'}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.common.created', 'Created')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatDate(adapter.createdAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.common.updated', 'Updated')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatDate(adapter.updatedAt)}\n </dd>\n </div>\n </dl>\n\n {adapter.capabilities.length > 0 && (\n <div className=\"mt-5\">\n <h3 className=\"mb-2 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.adapters.capabilities', 'Capabilities')}\n </h3>\n <div className=\"flex flex-wrap gap-1.5\">\n {adapter.capabilities.map((cap) => (\n <span\n key={cap}\n className=\"inline-flex items-center rounded-full bg-accent-blue-subtle px-2.5 py-0.5 text-xs text-accent-blue\"\n >\n {cap}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {adapter.tags.length > 0 && (\n <div className=\"mt-4\">\n <h3 className=\"mb-2 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.common.tags', 'Tags')}\n </h3>\n <div className=\"flex flex-wrap gap-1.5\">\n {adapter.tags.map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n )}\n </GlassCard>\n\n {/* Config schema */}\n {adapter.configSchema != null && (\n <GlassCard className=\"p-6\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.adapters.configSchema', 'Config Schema')}\n </h3>\n <pre className=\"overflow-auto rounded-lg bg-bg-sunken p-4 text-xs text-text-secondary\">\n {JSON.stringify(adapter.configSchema, null, 2)}\n </pre>\n </GlassCard>\n )}\n\n {/* Connections */}\n <section>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">\n {t('adaptercloud.adapters.connections', 'Connections')}\n </h3>\n {adapter.connections && adapter.connections.length > 0 ? (\n <div className=\"divide-y divide-border rounded-xl border border-border-subtle bg-bg-surface\">\n {adapter.connections.map((conn) => (\n <button\n key={conn.id}\n type=\"button\"\n onClick={() => navigateTo(`/connections/${conn.id}`)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-accent/50\"\n >\n <Cable 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\">\n {conn.name}\n </p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {authMethodLabels[conn.authMethod]} · {conn.resourceCount}{' '}\n {t('adaptercloud.adapters.resourcesLower', 'resources')}\n </p>\n </div>\n <StatusBadge status={conn.status} />\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('adaptercloud.adapters.noConnections', 'No connections use this adapter yet.')}\n </p>\n )}\n </section>\n </div>\n )}\n </DataState>\n\n <ConfirmDialog\n open={confirmArchiveOpen}\n onOpenChange={setConfirmArchiveOpen}\n title={t('adaptercloud.adapters.archiveTitle', 'Archive this adapter?')}\n description={t(\n 'adaptercloud.adapters.archivePrompt',\n 'The adapter will be archived and hidden from the catalog. Existing connections keep working, but no new connections can select it.'\n )}\n confirmLabel={t('adaptercloud.common.archive', 'Archive')}\n cancelLabel={t('adaptercloud.common.cancel', 'Cancel')}\n onConfirm={handleArchive}\n isPending={archive.isPending}\n tone=\"danger\"\n />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,SAAgB,IAAoB;CAClC,IAAM,EAAE,UAAO,GAA2B,EACpC,EAAE,kBAAe,GAAiB,EAClC,EAAE,GAAG,MAAc,GAAS,EAC5B,IAAI,GACP,GAAa,MAA6B;EACzC,IAAM,IAAQ,EAAU,EAAI;AAC5B,SAAO,MAAU,IAAM,IAAW;IAEpC,CAAC,EAAU,CACZ,EAEK,IAAQ,EAAW,EAAG,EACtB,IAAU,GAAmB,EAC7B,IAAU,EAAM,MAEhB,CAAC,GAAoB,KAAyB,EAAS,GAAM,EAE7D,IAAgB,QAAkB;AACjC,OACL,EAAQ,OAAO,GAAI,EACjB,iBAAiB;AAEf,GADA,EAAsB,GAAM,EAC5B,EAAW,YAAY;KAE1B,CAAC;IACD;EAAC;EAAS;EAAI;EAAW,CAAC;AAE7B,QACE,kBAAC,GAAD;EACE,OAAO,GAAS,QAAQ,EAAE,qCAAqC,UAAU;EACzE,aAAa,GAAS;EACtB,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,YAAY;IACtC,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAChC,EAAE,4BAA4B,OAAO,CAC/B;OACR,KACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,aAAa,EAAQ,GAAG,OAAO;IACzD,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAC7B,EAAE,4BAA4B,OAAO,CAC/B;OACR,EAAQ,WAAW,cAClB,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAsB,GAAK;IAC1C,UAAU,EAAQ;IAClB,WAAU;cAJZ,CAME,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA,EAC9B,EAAE,+BAA+B,UAAU,CACrC;MAEV,EAAA,CAAA,CAED;;YApCV,CAuCE,kBAAC,GAAD;GACE,WAAW,EAAM;GACjB,SAAS,EAAM;GACf,SAAS,CAAC,EAAM,aAAa,CAAC;GAC9B,OAAO,EAAM;GACb,eAAe,KAAK,EAAM,SAAS;GACnC,YAAY,EAAE,kCAAkC,oBAAoB;GACpE,kBAAkB,EAChB,6CACA,+DACD;aAEA,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf;KAEE,kBAAC,GAAD;MAAW,WAAU;gBAArB;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA;SACvC,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAkB,EAAQ;UACtB,CAAA;SACP,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAA8C,KAAE,EAAQ,QAAe;;SACnE;;OAEL,EAAQ,eACP,kBAAC,KAAD;QAAG,WAAU;kBAAoC,EAAQ;QAAgB,CAAA;OAG3E,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAE,gCAAgC,SAAS;UACzC,CAAA,EACL,kBAAC,MAAD;UAAI,WAAU;oBAAwC,EAAQ,UAAU;UAAS,CAAA,CAC7E,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAE,+BAA+B,UAAU;UACzC,CAAA,EACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAW,EAAQ,UAAU;UAC3B,CAAA,CACD,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAE,+BAA+B,UAAU;UACzC,CAAA,EACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAW,EAAQ,UAAU;UAC3B,CAAA,CACD,EAAA,CAAA;SACH;;OAEJ,EAAQ,aAAa,SAAS,KAC7B,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,sCAAsC,eAAe;SACrD,CAAA,EACL,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAQ,aAAa,KAAK,MACzB,kBAAC,QAAD;UAEE,WAAU;oBAET;UACI,EAJA,EAIA,CACP;SACE,CAAA,CACF;;OAGP,EAAQ,KAAK,SAAS,KACrB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,4BAA4B,OAAO;SACnC,CAAA,EACL,kBAAC,OAAD;SAAK,WAAU;mBACZ,EAAQ,KAAK,KAAK,MACjB,kBAAC,QAAD;UAEE,WAAU;oBAET;UACI,EAJA,EAIA,CACP;SACE,CAAA,CACF;;OAEE;;KAGX,EAAQ,gBAAgB,QACvB,kBAAC,GAAD;MAAW,WAAU;gBAArB,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAE,sCAAsC,gBAAgB;OACtD,CAAA,EACL,kBAAC,OAAD;OAAK,WAAU;iBACZ,KAAK,UAAU,EAAQ,cAAc,MAAM,EAAE;OAC1C,CAAA,CACI;;KAId,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAE,qCAAqC,cAAc;MACnD,CAAA,EACJ,EAAQ,eAAe,EAAQ,YAAY,SAAS,IACnD,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAQ,YAAY,KAAK,MACxB,kBAAC,UAAD;OAEE,MAAK;OACL,eAAe,EAAW,gBAAgB,EAAK,KAAK;OACpD,WAAU;iBAJZ;QAME,kBAAC,GAAD,EAAO,WAAU,wCAAyC,CAAA;QAC1D,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAK;UACJ,CAAA,EACJ,kBAAC,KAAD;UAAG,WAAU;oBAAb;WACG,EAAiB,EAAK;WAAY;WAAI,EAAK;WAAe;WAC1D,EAAE,wCAAwC,YAAY;WACrD;YACA;;QACN,kBAAC,GAAD,EAAa,QAAQ,EAAK,QAAU,CAAA;QAC7B;SAhBF,EAAK,GAgBH,CACT;MACE,CAAA,GAEN,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAE,uCAAuC,uCAAuC;MAC/E,CAAA,CAEE,EAAA,CAAA;KACN;;GAEE,CAAA,EAEZ,kBAAC,GAAD;GACE,MAAM;GACN,cAAc;GACd,OAAO,EAAE,sCAAsC,wBAAwB;GACvE,aAAa,EACX,uCACA,qIACD;GACD,cAAc,EAAE,+BAA+B,UAAU;GACzD,aAAa,EAAE,8BAA8B,SAAS;GACtD,WAAW;GACX,WAAW,EAAQ;GACnB,MAAK;GACL,CAAA,CACS"}
|
|
1
|
+
{"version":3,"file":"AdapterDetailPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/adapters/AdapterDetailPage.tsx"],"sourcesContent":["/**\n * Adapter Detail Page\n * @module adaptercloud/pages/adapters\n *\n * Full view of one adapter (`adaAdapter`) — metadata, capabilities, config\n * schema and its connections. Supports archiving via `adaArchiveAdapter`.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowLeft, Archive, Cable, Check, Copy, Pencil } 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 { useAdapter, useArchiveAdapter } from '../../hooks/useAdapterCloudApi';\nimport { adapterKindLabels } from '../../utils/domain';\nimport { formatDate } from '../../utils/formatters';\n\nexport function AdapterDetailPage() {\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 = useAdapter(id);\n const archive = useArchiveAdapter();\n const adapter = query.data;\n\n const [confirmArchiveOpen, setConfirmArchiveOpen] = useState(false);\n const [copied, setCopied] = useState(false);\n\n const handleCopyConfig = useCallback(() => {\n if (adapter?.configSchema == null) return;\n const text = JSON.stringify(adapter.configSchema, null, 2);\n void navigator.clipboard\n ?.writeText(text)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n })\n .catch(() => {\n /* clipboard unavailable — no-op */\n });\n }, [adapter?.configSchema]);\n\n const handleArchive = useCallback(() => {\n if (!id) return;\n archive.mutate(id, {\n onSuccess: () => {\n setConfirmArchiveOpen(false);\n navigateTo('/adapters');\n },\n });\n }, [archive, id, navigateTo]);\n\n return (\n <PageLayout\n title={adapter?.name ?? t('adaptercloud.adapters.detailTitle', 'Adapter')}\n description={adapter?.slug}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/adapters')}\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 {adapter && (\n <>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/adapters/${adapter.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 {adapter.status !== 'ARCHIVED' && (\n <button\n type=\"button\"\n onClick={() => setConfirmArchiveOpen(true)}\n disabled={archive.isPending}\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-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n <Archive className=\"h-4 w-4\" />\n {t('adaptercloud.common.archive', 'Archive')}\n </button>\n )}\n </>\n )}\n </div>\n }\n >\n <DataState\n isLoading={query.isLoading}\n isError={query.isError}\n isEmpty={!query.isLoading && !adapter}\n error={query.error}\n onRetry={() => void query.refetch()}\n emptyTitle={t('adaptercloud.adapters.notFound', 'Adapter not found')}\n emptyDescription={t(\n 'adaptercloud.adapters.notFoundDescription',\n 'This adapter does not exist or belongs to another workspace.'\n )}\n >\n {adapter && (\n <div className=\"space-y-6\">\n {/* Metadata */}\n <GlassCard className=\"p-6\">\n <div className=\"mb-4 flex items-center gap-3\">\n <StatusBadge status={adapter.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 {adapterKindLabels[adapter.kind]}\n </span>\n <span className=\"text-xs text-text-secondary\">v{adapter.version}</span>\n </div>\n\n {adapter.description && (\n <p className=\"mb-4 text-sm text-text-secondary\">{adapter.description}</p>\n )}\n\n <dl className=\"grid grid-cols-2 gap-4 text-sm sm:grid-cols-3\">\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.adapters.vendor', 'Vendor')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">{adapter.vendor ?? '—'}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.common.created', 'Created')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatDate(adapter.createdAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('adaptercloud.common.updated', 'Updated')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">\n {formatDate(adapter.updatedAt)}\n </dd>\n </div>\n </dl>\n\n {adapter.capabilities.length > 0 && (\n <div className=\"mt-5\">\n <h3 className=\"mb-2 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.adapters.capabilities', 'Capabilities')}\n </h3>\n <div className=\"flex flex-wrap gap-1.5\">\n {adapter.capabilities.map((cap) => (\n <span\n key={cap}\n className=\"inline-flex items-center rounded-full bg-accent-blue-subtle px-2.5 py-0.5 text-xs text-accent-blue\"\n >\n {cap}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {adapter.tags.length > 0 && (\n <div className=\"mt-4\">\n <h3 className=\"mb-2 text-sm font-semibold text-text-primary\">\n {t('adaptercloud.common.tags', 'Tags')}\n </h3>\n <div className=\"flex flex-wrap gap-1.5\">\n {adapter.tags.map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n )}\n </GlassCard>\n\n {/* Config schema */}\n {adapter.configSchema != null && (\n <GlassCard className=\"p-6\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t('adaptercloud.adapters.configSchema', 'Config Schema')}\n </h3>\n <button\n type=\"button\"\n onClick={handleCopyConfig}\n aria-label={t('adaptercloud.common.copy', 'Copy')}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-2.5 py-1 text-xs font-medium text-text-secondary transition-colors hover:bg-accent hover:text-text-primary\"\n >\n {copied ? (\n <>\n <Check className=\"h-3.5 w-3.5 text-status-success-text\" />\n {t('adaptercloud.common.copied', 'Copied')}\n </>\n ) : (\n <>\n <Copy className=\"h-3.5 w-3.5\" />\n {t('adaptercloud.common.copy', 'Copy')}\n </>\n )}\n </button>\n </div>\n <pre className=\"overflow-auto rounded-lg bg-bg-sunken p-4 text-xs text-text-secondary\">\n {JSON.stringify(adapter.configSchema, null, 2)}\n </pre>\n </GlassCard>\n )}\n\n {/* Connections */}\n <section>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">\n {t('adaptercloud.adapters.connections', 'Connections')}\n </h3>\n {adapter.connections && adapter.connections.length > 0 ? (\n <div className=\"overflow-x-auto rounded-xl border border-border-subtle bg-bg-surface\">\n <table className=\"w-full min-w-[32rem] text-sm\">\n <thead>\n <tr className=\"border-b border-border-subtle text-left text-xs uppercase tracking-wide text-text-secondary\">\n <th scope=\"col\" className=\"px-4 py-2.5 font-medium\">\n {t('adaptercloud.adapters.connName', 'Name')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2.5 font-medium\">\n {t('adaptercloud.resources.region', 'Region')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2.5 font-medium\">\n {t('adaptercloud.adapters.status', 'Status')}\n </th>\n <th scope=\"col\" className=\"px-4 py-2.5 text-right font-medium\">\n {t('adaptercloud.adapters.resources', 'Resources')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {adapter.connections.map((conn) => (\n <tr\n key={conn.id}\n role=\"link\"\n tabIndex={0}\n onClick={() => navigateTo(`/connections/${conn.id}`)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigateTo(`/connections/${conn.id}`);\n }\n }}\n className=\"cursor-pointer transition-colors hover:bg-accent/50 focus:bg-accent/50 focus:outline-none\"\n >\n <td className=\"px-4 py-3\">\n <span className=\"flex items-center gap-2\">\n <Cable className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <span className=\"truncate font-medium text-text-primary\">\n {conn.name}\n </span>\n </span>\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">{conn.region ?? '—'}</td>\n <td className=\"px-4 py-3\">\n <StatusBadge status={conn.status} />\n </td>\n <td className=\"px-4 py-3 text-right tabular-nums text-text-secondary\">\n {conn.resourceCount}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\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('adaptercloud.adapters.noConnections', 'No connections use this adapter yet.')}\n </p>\n )}\n </section>\n </div>\n )}\n </DataState>\n\n <ConfirmDialog\n open={confirmArchiveOpen}\n onOpenChange={setConfirmArchiveOpen}\n title={t('adaptercloud.adapters.archiveTitle', 'Archive this adapter?')}\n description={t(\n 'adaptercloud.adapters.archivePrompt',\n 'The adapter will be archived and hidden from the catalog. Existing connections keep working, but no new connections can select it.'\n )}\n confirmLabel={t('adaptercloud.common.archive', 'Archive')}\n cancelLabel={t('adaptercloud.common.cancel', 'Cancel')}\n onConfirm={handleArchive}\n isPending={archive.isPending}\n tone=\"danger\"\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|