@burdenoff/microfe-channel 2026.519.1 → 2026.520.2
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/channel/ChannelRoot.d.ts.map +1 -1
- package/dist/channel/ChannelRoot.js +23 -29
- package/dist/channel/ChannelRoot.js.map +1 -1
- package/dist/channel/components/AdapterCredentialsForm.js +7 -7
- package/dist/channel/components/AdapterCredentialsForm.js.map +1 -1
- package/dist/channel/components/FeatureNotEnabled.d.ts +3 -0
- package/dist/channel/components/FeatureNotEnabled.d.ts.map +1 -1
- package/dist/channel/components/FeatureNotEnabled.js +31 -13
- package/dist/channel/components/FeatureNotEnabled.js.map +1 -1
- package/dist/channel/hooks/useChannels.d.ts +17 -3
- package/dist/channel/hooks/useChannels.d.ts.map +1 -1
- package/dist/channel/hooks/useChannels.js +64 -18
- package/dist/channel/hooks/useChannels.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.js +312 -277
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.js +33 -33
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +24 -24
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelUsersPage.js +206 -142
- package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelsListPage.js +322 -248
- package/dist/channel/modules/channels/pages/ChannelsListPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +6 -6
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionsListPage.js +160 -112
- package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/CreateChannelPage.js +4 -4
- package/dist/channel/modules/channels/pages/CreateChannelPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +201 -133
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/EditChannelPage.js +9 -9
- package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/SendMessagePage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/SendMessagePage.js +89 -89
- package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -1
- package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/WebhookEventsPage.js +126 -58
- package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -1
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -1
- package/dist/generated/global-operations.js +2 -0
- package/dist/generated/global-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,33 +5,33 @@ import { useEffect as r, useState as i } from "react";
|
|
|
5
5
|
import { useI18n as a } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
6
|
import { AlertCircle as o, ArrowLeft as s, CheckCircle2 as c, Link as l, Loader2 as u, Plus as d, RefreshCw as f, Settings as p, XCircle as m } from "lucide-react";
|
|
7
7
|
import { useNavigate as h } from "react-router-dom";
|
|
8
|
-
import {
|
|
9
|
-
import { TagBadge as
|
|
8
|
+
import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
9
|
+
import { TagBadge as y } from "@burdenoff/fe-libs/tag";
|
|
10
10
|
//#region src/channel/modules/channels/pages/ConnectionsListPage.tsx
|
|
11
|
-
var
|
|
11
|
+
var b = {
|
|
12
12
|
true: {
|
|
13
13
|
icon: c,
|
|
14
|
-
color: "text-success-
|
|
14
|
+
color: "text-status-success-text",
|
|
15
15
|
label: "Healthy"
|
|
16
16
|
},
|
|
17
17
|
false: {
|
|
18
18
|
icon: m,
|
|
19
|
-
color: "text-error-
|
|
19
|
+
color: "text-status-error-text",
|
|
20
20
|
label: "Unhealthy"
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
function
|
|
24
|
-
let c = h(), { channels: m, isLoading:
|
|
23
|
+
function x() {
|
|
24
|
+
let c = h(), { channels: m, isLoading: x, error: S, refetch: C } = e();
|
|
25
25
|
r(() => {
|
|
26
26
|
let e = setInterval(() => {
|
|
27
|
-
|
|
27
|
+
C();
|
|
28
28
|
}, 6e4);
|
|
29
29
|
return () => clearInterval(e);
|
|
30
|
-
}, [
|
|
31
|
-
let { t:
|
|
32
|
-
let n =
|
|
30
|
+
}, [C]);
|
|
31
|
+
let { t: w } = a(), T = (e, t) => {
|
|
32
|
+
let n = w(e);
|
|
33
33
|
return n === e ? t : n;
|
|
34
|
-
}, [
|
|
34
|
+
}, [E, D] = i("all"), [O, k] = i("all"), [A, j] = i(0), M = m.filter((e) => e.connection).map((e) => ({
|
|
35
35
|
channelId: e.id,
|
|
36
36
|
channelName: e.name,
|
|
37
37
|
platform: e.platform,
|
|
@@ -44,106 +44,106 @@ function b() {
|
|
|
44
44
|
lastTestedAt: e.connection.lastTestedAt,
|
|
45
45
|
authType: e.connection.authType,
|
|
46
46
|
tagAssignments: e.connection.tagAssignments ?? []
|
|
47
|
-
})),
|
|
48
|
-
return
|
|
47
|
+
})), N = [...new Set(M.map((e) => e.platform))], P = M.filter((e) => !(E === "healthy" && !e.isHealthy || E === "unhealthy" && e.isHealthy || O !== "all" && e.platform !== O)), F = Math.max(1, Math.ceil(P.length / 10)), I = P.slice(A * 10, (A + 1) * 10);
|
|
48
|
+
return x ? /* @__PURE__ */ _("div", {
|
|
49
49
|
className: "flex items-center justify-center min-h-screen",
|
|
50
|
-
children: /* @__PURE__ */
|
|
51
|
-
}) :
|
|
50
|
+
children: /* @__PURE__ */ _(u, { className: "w-8 h-8 animate-spin text-muted-foreground" })
|
|
51
|
+
}) : S ? /* @__PURE__ */ v("div", {
|
|
52
52
|
className: "flex flex-col items-center justify-center min-h-screen gap-4",
|
|
53
53
|
children: [
|
|
54
|
-
/* @__PURE__ */
|
|
55
|
-
/* @__PURE__ */
|
|
54
|
+
/* @__PURE__ */ _(o, { className: "w-12 h-12 text-destructive" }),
|
|
55
|
+
/* @__PURE__ */ _("h1", {
|
|
56
56
|
className: "text-xl font-semibold",
|
|
57
|
-
children:
|
|
57
|
+
children: T("channel.loadConnectionsFailed", "Failed to load connections")
|
|
58
58
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ _("p", {
|
|
60
60
|
className: "text-sm text-muted-foreground",
|
|
61
|
-
children:
|
|
61
|
+
children: S
|
|
62
62
|
}),
|
|
63
|
-
/* @__PURE__ */
|
|
64
|
-
onClick: () =>
|
|
63
|
+
/* @__PURE__ */ _("button", {
|
|
64
|
+
onClick: () => C(),
|
|
65
65
|
className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90",
|
|
66
|
-
children:
|
|
66
|
+
children: T("channel.retry", "Retry")
|
|
67
67
|
})
|
|
68
68
|
]
|
|
69
|
-
}) : /* @__PURE__ */
|
|
69
|
+
}) : /* @__PURE__ */ _(t, {
|
|
70
70
|
permission: n.CHANNEL_CONNECTION_READ,
|
|
71
|
-
children: /* @__PURE__ */
|
|
71
|
+
children: /* @__PURE__ */ v("div", {
|
|
72
72
|
className: "min-h-screen bg-background",
|
|
73
73
|
children: [
|
|
74
|
-
/* @__PURE__ */
|
|
74
|
+
/* @__PURE__ */ _("div", {
|
|
75
75
|
className: "border-b bg-card",
|
|
76
|
-
children: /* @__PURE__ */
|
|
76
|
+
children: /* @__PURE__ */ _("div", {
|
|
77
77
|
className: "container mx-auto px-6 py-4",
|
|
78
|
-
children: /* @__PURE__ */
|
|
78
|
+
children: /* @__PURE__ */ v("div", {
|
|
79
79
|
className: "flex items-center justify-between",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
80
|
+
children: [/* @__PURE__ */ v("div", {
|
|
81
81
|
className: "flex items-center gap-4",
|
|
82
|
-
children: [/* @__PURE__ */
|
|
82
|
+
children: [/* @__PURE__ */ _("button", {
|
|
83
83
|
onClick: () => c("./list"),
|
|
84
|
-
"aria-label":
|
|
84
|
+
"aria-label": T("channel.backToChannels", "Back to channels"),
|
|
85
85
|
className: "p-2 hover:bg-muted rounded-lg transition-colors",
|
|
86
|
-
children: /* @__PURE__ */
|
|
87
|
-
}), /* @__PURE__ */
|
|
86
|
+
children: /* @__PURE__ */ _(s, { className: "w-5 h-5" })
|
|
87
|
+
}), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h1", {
|
|
88
88
|
className: "text-2xl font-bold",
|
|
89
|
-
children:
|
|
90
|
-
}), /* @__PURE__ */
|
|
89
|
+
children: T("channel.connections", "Connections")
|
|
90
|
+
}), /* @__PURE__ */ v("p", {
|
|
91
91
|
className: "text-sm text-muted-foreground",
|
|
92
92
|
children: [
|
|
93
|
-
|
|
93
|
+
P.length,
|
|
94
94
|
" connection",
|
|
95
|
-
|
|
95
|
+
P.length === 1 ? "" : "s"
|
|
96
96
|
]
|
|
97
97
|
})] })]
|
|
98
|
-
}), /* @__PURE__ */
|
|
98
|
+
}), /* @__PURE__ */ v("button", {
|
|
99
99
|
onClick: () => c("./create"),
|
|
100
100
|
className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors flex items-center gap-2",
|
|
101
|
-
children: [/* @__PURE__ */
|
|
101
|
+
children: [/* @__PURE__ */ _(d, { className: "w-4 h-4" }), T("channel.newChannel", "New Channel")]
|
|
102
102
|
})]
|
|
103
103
|
})
|
|
104
104
|
})
|
|
105
105
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
106
|
+
/* @__PURE__ */ _("div", {
|
|
107
107
|
className: "container mx-auto px-6 py-4",
|
|
108
|
-
children: /* @__PURE__ */
|
|
108
|
+
children: /* @__PURE__ */ v("div", {
|
|
109
109
|
className: "flex items-center gap-4",
|
|
110
110
|
children: [
|
|
111
|
-
/* @__PURE__ */
|
|
112
|
-
value:
|
|
113
|
-
onChange: (e) =>
|
|
111
|
+
/* @__PURE__ */ v("select", {
|
|
112
|
+
value: O,
|
|
113
|
+
onChange: (e) => k(e.target.value),
|
|
114
114
|
className: "px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary",
|
|
115
|
-
children: [/* @__PURE__ */
|
|
115
|
+
children: [/* @__PURE__ */ _("option", {
|
|
116
116
|
value: "all",
|
|
117
|
-
children:
|
|
118
|
-
}),
|
|
117
|
+
children: T("channel.allPlatforms", "All Platforms")
|
|
118
|
+
}), N.map((e) => /* @__PURE__ */ _("option", {
|
|
119
119
|
value: e,
|
|
120
120
|
children: e
|
|
121
121
|
}, e))]
|
|
122
122
|
}),
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
value:
|
|
125
|
-
onChange: (e) =>
|
|
123
|
+
/* @__PURE__ */ v("select", {
|
|
124
|
+
value: E,
|
|
125
|
+
onChange: (e) => D(e.target.value),
|
|
126
126
|
className: "px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary",
|
|
127
127
|
children: [
|
|
128
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ _("option", {
|
|
129
129
|
value: "all",
|
|
130
|
-
children:
|
|
130
|
+
children: T("channel.allStatus", "All Status")
|
|
131
131
|
}),
|
|
132
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ _("option", {
|
|
133
133
|
value: "healthy",
|
|
134
|
-
children:
|
|
134
|
+
children: T("channel.healthy", "Healthy")
|
|
135
135
|
}),
|
|
136
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ _("option", {
|
|
137
137
|
value: "unhealthy",
|
|
138
|
-
children:
|
|
138
|
+
children: T("channel.unhealthy", "Unhealthy")
|
|
139
139
|
})
|
|
140
140
|
]
|
|
141
141
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
onClick: () =>
|
|
144
|
-
"aria-label":
|
|
142
|
+
/* @__PURE__ */ _("button", {
|
|
143
|
+
onClick: () => C(),
|
|
144
|
+
"aria-label": T("channel.refresh", "Refresh"),
|
|
145
145
|
className: "p-2 hover:bg-muted rounded-lg transition-colors",
|
|
146
|
-
children: /* @__PURE__ */
|
|
146
|
+
children: /* @__PURE__ */ _(f, {
|
|
147
147
|
className: "w-5 h-5",
|
|
148
148
|
"aria-hidden": "true"
|
|
149
149
|
})
|
|
@@ -151,54 +151,54 @@ function b() {
|
|
|
151
151
|
]
|
|
152
152
|
})
|
|
153
153
|
}),
|
|
154
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ _("div", {
|
|
155
155
|
className: "container mx-auto px-6 pb-8",
|
|
156
|
-
children:
|
|
156
|
+
children: P.length === 0 ? /* @__PURE__ */ v("div", {
|
|
157
157
|
className: "text-center py-12",
|
|
158
158
|
children: [
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ _(l, { className: "w-12 h-12 mx-auto text-muted-foreground mb-4" }),
|
|
160
|
+
/* @__PURE__ */ _("h2", {
|
|
161
161
|
className: "text-lg font-semibold mb-2",
|
|
162
|
-
children:
|
|
162
|
+
children: T("channel.noConnectionsFound", "No connections found")
|
|
163
163
|
}),
|
|
164
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ _("p", {
|
|
165
165
|
className: "text-sm text-muted-foreground mb-4",
|
|
166
|
-
children: m.length === 0 ?
|
|
166
|
+
children: m.length === 0 ? T("channel.createChannelFirst", "Create a channel first to add connections") : T("channel.noConnectionsMatchFilter", "No connections match your filters")
|
|
167
167
|
}),
|
|
168
|
-
m.length === 0 ? /* @__PURE__ */
|
|
168
|
+
m.length === 0 ? /* @__PURE__ */ _("button", {
|
|
169
169
|
onClick: () => c("./create"),
|
|
170
170
|
className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90",
|
|
171
|
-
children:
|
|
172
|
-
}) : /* @__PURE__ */
|
|
171
|
+
children: T("channel.createChannel", "Create Channel")
|
|
172
|
+
}) : /* @__PURE__ */ _("button", {
|
|
173
173
|
onClick: () => {
|
|
174
|
-
|
|
174
|
+
D("all"), k("all");
|
|
175
175
|
},
|
|
176
176
|
className: "px-4 py-2 rounded-lg border hover:bg-muted",
|
|
177
|
-
children:
|
|
177
|
+
children: T("channel.clearFilters", "Clear Filters")
|
|
178
178
|
})
|
|
179
179
|
]
|
|
180
|
-
}) : /* @__PURE__ */ g("div", {
|
|
180
|
+
}) : /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("div", {
|
|
181
181
|
className: "border rounded-lg divide-y",
|
|
182
|
-
children:
|
|
183
|
-
let t =
|
|
184
|
-
return /* @__PURE__ */
|
|
182
|
+
children: I.map((e) => {
|
|
183
|
+
let t = b[String(e.isHealthy)] || b.false, n = t.icon;
|
|
184
|
+
return /* @__PURE__ */ _("div", {
|
|
185
185
|
className: "p-4 hover:bg-muted/50 transition-colors cursor-pointer",
|
|
186
186
|
onClick: () => c(`./${e.channelId}`),
|
|
187
|
-
children: /* @__PURE__ */
|
|
187
|
+
children: /* @__PURE__ */ v("div", {
|
|
188
188
|
className: "flex items-center justify-between",
|
|
189
|
-
children: [/* @__PURE__ */
|
|
189
|
+
children: [/* @__PURE__ */ v("div", {
|
|
190
190
|
className: "flex items-center gap-4",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ _("div", {
|
|
192
192
|
className: t.color,
|
|
193
193
|
"aria-label": t.label,
|
|
194
|
-
children: /* @__PURE__ */
|
|
194
|
+
children: /* @__PURE__ */ _(n, {
|
|
195
195
|
className: "w-5 h-5",
|
|
196
196
|
"aria-hidden": "true"
|
|
197
197
|
})
|
|
198
|
-
}), /* @__PURE__ */
|
|
198
|
+
}), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
|
|
199
199
|
className: "font-medium",
|
|
200
200
|
children: e.channelName
|
|
201
|
-
}), /* @__PURE__ */
|
|
201
|
+
}), /* @__PURE__ */ v("p", {
|
|
202
202
|
className: "text-sm text-muted-foreground",
|
|
203
203
|
children: [
|
|
204
204
|
e.platform,
|
|
@@ -208,73 +208,121 @@ function b() {
|
|
|
208
208
|
e.authType
|
|
209
209
|
]
|
|
210
210
|
})] })]
|
|
211
|
-
}), /* @__PURE__ */
|
|
211
|
+
}), /* @__PURE__ */ v("div", {
|
|
212
212
|
className: "flex items-center gap-4",
|
|
213
213
|
children: [
|
|
214
|
-
/* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ v("div", {
|
|
215
215
|
className: "text-right",
|
|
216
|
-
children: [/* @__PURE__ */
|
|
216
|
+
children: [/* @__PURE__ */ _("p", {
|
|
217
217
|
className: "text-sm",
|
|
218
|
-
children: e.channelStatus === "ACTIVE" ? /* @__PURE__ */
|
|
219
|
-
className: "text-success-
|
|
220
|
-
children:
|
|
221
|
-
}) : e.channelStatus === "INACTIVE" ? /* @__PURE__ */
|
|
218
|
+
children: e.channelStatus === "ACTIVE" ? /* @__PURE__ */ _("span", {
|
|
219
|
+
className: "text-status-success-text",
|
|
220
|
+
children: T("channel.activeStatus", "Active")
|
|
221
|
+
}) : e.channelStatus === "INACTIVE" ? /* @__PURE__ */ _("span", {
|
|
222
222
|
className: "text-muted-foreground",
|
|
223
|
-
children:
|
|
224
|
-
}) : e.channelStatus === "ERROR" ? /* @__PURE__ */
|
|
225
|
-
className: "text-error-
|
|
226
|
-
children:
|
|
227
|
-
}) : e.channelStatus === "SUSPENDED" ? /* @__PURE__ */
|
|
228
|
-
className: "text-warning-
|
|
229
|
-
children:
|
|
230
|
-
}) : e.channelStatus === "ARCHIVED" ? /* @__PURE__ */
|
|
223
|
+
children: T("channel.inactiveStatus", "Inactive")
|
|
224
|
+
}) : e.channelStatus === "ERROR" ? /* @__PURE__ */ _("span", {
|
|
225
|
+
className: "text-status-error-text",
|
|
226
|
+
children: T("channel.errorStatus", "Error")
|
|
227
|
+
}) : e.channelStatus === "SUSPENDED" ? /* @__PURE__ */ _("span", {
|
|
228
|
+
className: "text-status-warning-text",
|
|
229
|
+
children: T("channel.suspendedStatus", "Suspended")
|
|
230
|
+
}) : e.channelStatus === "ARCHIVED" ? /* @__PURE__ */ _("span", {
|
|
231
231
|
className: "text-muted-foreground",
|
|
232
|
-
children:
|
|
233
|
-
}) : /* @__PURE__ */
|
|
232
|
+
children: T("channel.archivedStatus", "Archived")
|
|
233
|
+
}) : /* @__PURE__ */ _("span", {
|
|
234
234
|
className: "text-muted-foreground",
|
|
235
|
-
children:
|
|
235
|
+
children: T("channel.inactiveStatus", "Inactive")
|
|
236
236
|
})
|
|
237
|
-
}), e.lastTestedAt && /* @__PURE__ */
|
|
237
|
+
}), e.lastTestedAt && /* @__PURE__ */ v("p", {
|
|
238
238
|
className: "text-xs text-muted-foreground",
|
|
239
239
|
children: ["Last tested: ", new Date(e.lastTestedAt).toLocaleDateString()]
|
|
240
240
|
})]
|
|
241
241
|
}),
|
|
242
|
-
e.needsTokenRefresh && /* @__PURE__ */
|
|
243
|
-
className: "px-2 py-1 text-xs bg-warning-
|
|
242
|
+
e.needsTokenRefresh && /* @__PURE__ */ _("span", {
|
|
243
|
+
className: "px-2 py-1 text-xs bg-status-warning-bg-subtle text-status-warning-text rounded",
|
|
244
244
|
children: "Token Expires"
|
|
245
245
|
}),
|
|
246
|
-
e.tagAssignments.length > 0 && /* @__PURE__ */
|
|
246
|
+
e.tagAssignments.length > 0 && /* @__PURE__ */ v("div", {
|
|
247
247
|
className: "flex flex-wrap gap-1",
|
|
248
248
|
"aria-label": "Connection tags",
|
|
249
|
-
children: [e.tagAssignments.slice(0, 3).map((e) => /* @__PURE__ */
|
|
249
|
+
children: [e.tagAssignments.slice(0, 3).map((e) => /* @__PURE__ */ _(y, {
|
|
250
250
|
id: e.tagId,
|
|
251
251
|
label: e.tagId,
|
|
252
252
|
size: "sm"
|
|
253
|
-
}, e.id)), e.tagAssignments.length > 3 && /* @__PURE__ */
|
|
253
|
+
}, e.id)), e.tagAssignments.length > 3 && /* @__PURE__ */ v("span", {
|
|
254
254
|
className: "text-xs text-muted-foreground",
|
|
255
255
|
children: ["+", e.tagAssignments.length - 3]
|
|
256
256
|
})]
|
|
257
257
|
}),
|
|
258
|
-
/* @__PURE__ */
|
|
258
|
+
/* @__PURE__ */ _("button", {
|
|
259
259
|
onClick: (t) => {
|
|
260
260
|
t.stopPropagation(), c(`/channels/${e.channelId}`);
|
|
261
261
|
},
|
|
262
|
-
"aria-label":
|
|
262
|
+
"aria-label": T("channel.viewChannelSettings", "View channel settings"),
|
|
263
263
|
className: "p-2 hover:bg-muted rounded-lg transition-colors",
|
|
264
|
-
children: /* @__PURE__ */
|
|
264
|
+
children: /* @__PURE__ */ _(p, { className: "w-4 h-4" })
|
|
265
265
|
})
|
|
266
266
|
]
|
|
267
267
|
})]
|
|
268
268
|
})
|
|
269
269
|
}, e.connectionId);
|
|
270
270
|
})
|
|
271
|
-
})
|
|
271
|
+
}), P.length > 10 && /* @__PURE__ */ v("div", {
|
|
272
|
+
className: "flex items-center justify-between px-4 py-3 border border-border rounded-lg mt-3",
|
|
273
|
+
children: [/* @__PURE__ */ v("p", {
|
|
274
|
+
className: "text-sm text-muted-foreground",
|
|
275
|
+
children: [
|
|
276
|
+
T("channel.showing", "Showing"),
|
|
277
|
+
" ",
|
|
278
|
+
/* @__PURE__ */ v("span", {
|
|
279
|
+
className: "font-medium",
|
|
280
|
+
children: [
|
|
281
|
+
A * 10 + 1,
|
|
282
|
+
"–",
|
|
283
|
+
Math.min((A + 1) * 10, P.length)
|
|
284
|
+
]
|
|
285
|
+
}),
|
|
286
|
+
" ",
|
|
287
|
+
T("channel.of", "of"),
|
|
288
|
+
" ",
|
|
289
|
+
/* @__PURE__ */ _("span", {
|
|
290
|
+
className: "font-medium",
|
|
291
|
+
children: P.length
|
|
292
|
+
})
|
|
293
|
+
]
|
|
294
|
+
}), /* @__PURE__ */ v("div", {
|
|
295
|
+
className: "flex items-center gap-2",
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ _("button", {
|
|
298
|
+
onClick: () => j((e) => Math.max(0, e - 1)),
|
|
299
|
+
disabled: A === 0,
|
|
300
|
+
className: "px-3 py-1.5 text-sm border border-border rounded-lg hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
|
|
301
|
+
children: T("channel.previous", "Previous")
|
|
302
|
+
}),
|
|
303
|
+
/* @__PURE__ */ v("span", {
|
|
304
|
+
className: "text-sm text-muted-foreground",
|
|
305
|
+
children: [
|
|
306
|
+
A + 1,
|
|
307
|
+
" / ",
|
|
308
|
+
F
|
|
309
|
+
]
|
|
310
|
+
}),
|
|
311
|
+
/* @__PURE__ */ _("button", {
|
|
312
|
+
onClick: () => j((e) => Math.min(F - 1, e + 1)),
|
|
313
|
+
disabled: A >= F - 1,
|
|
314
|
+
className: "px-3 py-1.5 text-sm border border-border rounded-lg hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
|
|
315
|
+
children: T("channel.next", "Next")
|
|
316
|
+
})
|
|
317
|
+
]
|
|
318
|
+
})]
|
|
319
|
+
})] })
|
|
272
320
|
})
|
|
273
321
|
]
|
|
274
322
|
})
|
|
275
323
|
});
|
|
276
324
|
}
|
|
277
325
|
//#endregion
|
|
278
|
-
export {
|
|
326
|
+
export { x as ConnectionsListPage };
|
|
279
327
|
|
|
280
328
|
//# sourceMappingURL=ConnectionsListPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionsListPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/ConnectionsListPage.tsx"],"sourcesContent":["/**\n * Connections List Page\n *\n * Displays all connections across channels with their status.\n */\n\nimport { useState, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\nimport {\n ArrowLeft,\n Plus,\n Loader2,\n AlertCircle,\n CheckCircle2,\n XCircle,\n RefreshCw,\n Settings,\n Link,\n} from 'lucide-react';\nimport { useChannels } from '../../../hooks/useChannels';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\n\nconst HEALTH_CONFIG: Record<string, { icon: typeof CheckCircle2; color: string; label: string }> = {\n true: { icon: CheckCircle2, color: 'text-success-500', label: 'Healthy' },\n false: { icon: XCircle, color: 'text-error-500', label: 'Unhealthy' },\n};\n\nexport function ConnectionsListPage() {\n const navigate = useNavigate();\n const { channels, isLoading, error, refetch } = useChannels();\n\n // Poll for connection status updates every 60 s.\n // connectionStatusChanged subscription is scoped to a single channelId;\n // this page shows all connections, so polling is used instead.\n useEffect(() => {\n const timer = setInterval(() => {\n void refetch();\n }, 60_000);\n return () => clearInterval(timer);\n }, [refetch]);\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Filter state\n const [healthFilter, setHealthFilter] = useState<string>('all');\n const [platformFilter, setPlatformFilter] = useState<string>('all');\n\n // Get all connections from channels\n const connections = channels\n .filter((ch) => ch.connection)\n .map((ch) => ({\n channelId: ch.id,\n channelName: ch.name,\n platform: ch.platform,\n adapterType: ch.adapterType,\n channelStatus: ch.status,\n connectionId: ch.connection!.id,\n isActive: ch.connection!.isActive,\n isHealthy: ch.connection!.isHealthy,\n needsTokenRefresh: ch.connection!.needsTokenRefresh,\n lastTestedAt: ch.connection!.lastTestedAt,\n authType: ch.connection!.authType,\n tagAssignments: ch.connection!.tagAssignments ?? [],\n }));\n\n // Get unique platforms\n const platforms = [...new Set(connections.map((c) => c.platform))];\n\n // Apply filters\n const filteredConnections = connections.filter((conn) => {\n if (healthFilter === 'healthy' && !conn.isHealthy) return false;\n if (healthFilter === 'unhealthy' && conn.isHealthy) return false;\n if (platformFilter !== 'all' && conn.platform !== platformFilter) return false;\n return true;\n });\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 className=\"w-8 h-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"w-12 h-12 text-destructive\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.loadConnectionsFailed', 'Failed to load connections')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{error}</p>\n <button\n onClick={() => refetch()}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90\"\n >\n {tr('channel.retry', 'Retry')}\n </button>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_READ}>\n <div className=\"min-h-screen bg-background\">\n {/* Header */}\n <div className=\"border-b bg-card\">\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => navigate('./list')}\n aria-label={tr('channel.backToChannels', 'Back to channels')}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <ArrowLeft className=\"w-5 h-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">{tr('channel.connections', 'Connections')}</h1>\n <p className=\"text-sm text-muted-foreground\">\n {filteredConnections.length} connection\n {filteredConnections.length !== 1 ? 's' : ''}\n </p>\n </div>\n </div>\n <button\n onClick={() => navigate('./create')}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors flex items-center gap-2\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('channel.newChannel', 'New Channel')}\n </button>\n </div>\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center gap-4\">\n <select\n value={platformFilter}\n onChange={(e) => setPlatformFilter(e.target.value)}\n className=\"px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"all\">{tr('channel.allPlatforms', 'All Platforms')}</option>\n {platforms.map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n\n <select\n value={healthFilter}\n onChange={(e) => setHealthFilter(e.target.value)}\n className=\"px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"all\">{tr('channel.allStatus', 'All Status')}</option>\n <option value=\"healthy\">{tr('channel.healthy', 'Healthy')}</option>\n <option value=\"unhealthy\">{tr('channel.unhealthy', 'Unhealthy')}</option>\n </select>\n\n <button\n onClick={() => refetch()}\n aria-label={tr('channel.refresh', 'Refresh')}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <RefreshCw className=\"w-5 h-5\" aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n\n {/* Connections List */}\n <div className=\"container mx-auto px-6 pb-8\">\n {filteredConnections.length === 0 ? (\n <div className=\"text-center py-12\">\n <Link className=\"w-12 h-12 mx-auto text-muted-foreground mb-4\" />\n <h2 className=\"text-lg font-semibold mb-2\">\n {tr('channel.noConnectionsFound', 'No connections found')}\n </h2>\n <p className=\"text-sm text-muted-foreground mb-4\">\n {channels.length === 0\n ? tr('channel.createChannelFirst', 'Create a channel first to add connections')\n : tr('channel.noConnectionsMatchFilter', 'No connections match your filters')}\n </p>\n {channels.length === 0 ? (\n <button\n onClick={() => navigate('./create')}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90\"\n >\n {tr('channel.createChannel', 'Create Channel')}\n </button>\n ) : (\n <button\n onClick={() => {\n setHealthFilter('all');\n setPlatformFilter('all');\n }}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted\"\n >\n {tr('channel.clearFilters', 'Clear Filters')}\n </button>\n )}\n </div>\n ) : (\n <div className=\"border rounded-lg divide-y\">\n {filteredConnections.map((conn) => {\n const health = HEALTH_CONFIG[String(conn.isHealthy)] || HEALTH_CONFIG.false;\n const HealthIcon = health.icon;\n\n return (\n <div\n key={conn.connectionId}\n className=\"p-4 hover:bg-muted/50 transition-colors cursor-pointer\"\n onClick={() => navigate(`./${conn.channelId}`)}\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className={health.color} aria-label={health.label}>\n <HealthIcon className=\"w-5 h-5\" aria-hidden=\"true\" />\n </div>\n <div>\n <p className=\"font-medium\">{conn.channelName}</p>\n <p className=\"text-sm text-muted-foreground\">\n {conn.platform} • {conn.adapterType} • {conn.authType}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm\">\n {conn.channelStatus === 'ACTIVE' ? (\n <span className=\"text-success-500\">\n {tr('channel.activeStatus', 'Active')}\n </span>\n ) : conn.channelStatus === 'INACTIVE' ? (\n <span className=\"text-muted-foreground\">\n {tr('channel.inactiveStatus', 'Inactive')}\n </span>\n ) : conn.channelStatus === 'ERROR' ? (\n <span className=\"text-error-500\">\n {tr('channel.errorStatus', 'Error')}\n </span>\n ) : conn.channelStatus === 'SUSPENDED' ? (\n <span className=\"text-warning-500\">\n {tr('channel.suspendedStatus', 'Suspended')}\n </span>\n ) : conn.channelStatus === 'ARCHIVED' ? (\n <span className=\"text-muted-foreground\">\n {tr('channel.archivedStatus', 'Archived')}\n </span>\n ) : (\n <span className=\"text-muted-foreground\">\n {tr('channel.inactiveStatus', 'Inactive')}\n </span>\n )}\n </p>\n {conn.lastTestedAt && (\n <p className=\"text-xs text-muted-foreground\">\n Last tested: {new Date(conn.lastTestedAt).toLocaleDateString()}\n </p>\n )}\n </div>\n\n {conn.needsTokenRefresh && (\n <span className=\"px-2 py-1 text-xs bg-warning-500/10 text-warning-500 rounded\">\n Token Expires\n </span>\n )}\n\n {conn.tagAssignments.length > 0 && (\n <div className=\"flex flex-wrap gap-1\" aria-label=\"Connection tags\">\n {conn.tagAssignments.slice(0, 3).map((a) => (\n <TagBadge key={a.id} id={a.tagId} label={a.tagId} size=\"sm\" />\n ))}\n {conn.tagAssignments.length > 3 && (\n <span className=\"text-xs text-muted-foreground\">\n +{conn.tagAssignments.length - 3}\n </span>\n )}\n </div>\n )}\n\n <button\n onClick={(e) => {\n e.stopPropagation();\n navigate(`/channels/${conn.channelId}`);\n }}\n aria-label={tr('channel.viewChannelSettings', 'View channel settings')}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <Settings className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":";;;;;;;;;;AAyBA,IAAM,IAA6F;CACjG,MAAM;EAAE,MAAM;EAAc,OAAO;EAAoB,OAAO;EAAW;CACzE,OAAO;EAAE,MAAM;EAAS,OAAO;EAAkB,OAAO;EAAa;CACtE;AAED,SAAgB,IAAsB;CACpC,IAAM,IAAW,GAAa,EACxB,EAAE,aAAU,cAAW,UAAO,eAAY,GAAa;AAK7D,SAAgB;EACd,IAAM,IAAQ,kBAAkB;AACzB,MAAS;KACb,IAAO;AACV,eAAa,cAAc,EAAM;IAChC,CAAC,EAAQ,CAAC;CACb,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAI9B,CAAC,GAAc,KAAmB,EAAiB,MAAM,EACzD,CAAC,GAAgB,KAAqB,EAAiB,MAAM,EAG7D,IAAc,EACjB,QAAQ,MAAO,EAAG,WAAW,CAC7B,KAAK,OAAQ;EACZ,WAAW,EAAG;EACd,aAAa,EAAG;EAChB,UAAU,EAAG;EACb,aAAa,EAAG;EAChB,eAAe,EAAG;EAClB,cAAc,EAAG,WAAY;EAC7B,UAAU,EAAG,WAAY;EACzB,WAAW,EAAG,WAAY;EAC1B,mBAAmB,EAAG,WAAY;EAClC,cAAc,EAAG,WAAY;EAC7B,UAAU,EAAG,WAAY;EACzB,gBAAgB,EAAG,WAAY,kBAAkB,EAAE;EACpD,EAAE,EAGC,IAAY,CAAC,GAAG,IAAI,IAAI,EAAY,KAAK,MAAM,EAAE,SAAS,CAAC,CAAC,EAG5D,IAAsB,EAAY,QAAQ,MAG9C,EAFI,MAAiB,aAAa,CAAC,EAAK,aACpC,MAAiB,eAAe,EAAK,aACrC,MAAmB,SAAS,EAAK,aAAa,GAElD;AA4BF,QA1BI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAS,WAAU,8CAA+C,CAAA;EAC9D,CAAA,GAIN,IAEA,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAa,WAAU,8BAA+B,CAAA;GACtD,kBAAC,MAAD;IAAI,WAAU;cACX,EAAG,iCAAiC,6BAA6B;IAC/D,CAAA;GACL,kBAAC,KAAD;IAAG,WAAU;cAAiC;IAAU,CAAA;GACxD,kBAAC,UAAD;IACE,eAAe,GAAS;IACxB,WAAU;cAET,EAAG,iBAAiB,QAAQ;IACtB,CAAA;GACL;MAKR,kBAAC,GAAD;EAAiB,YAAY,EAAoB;YAC/C,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,eAAe,EAAS,SAAS;SACjC,cAAY,EAAG,0BAA0B,mBAAmB;SAC5D,WAAU;mBAEV,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;SAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAsB,EAAG,uBAAuB,cAAc;SAAM,CAAA,EAClF,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAoB;UAAO;UAC3B,EAAoB,WAAW,IAAU,KAAN;UAClC;WACA,EAAA,CAAA,CACF;WACN,kBAAC,UAAD;QACE,eAAe,EAAS,WAAW;QACnC,WAAU;kBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAG,sBAAsB,cAAc,CACjC;UACL;;MACF,CAAA;KACF,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,UAAD;QACE,OAAO;QACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAM;QAClD,WAAU;kBAHZ,CAKE,kBAAC,UAAD;SAAQ,OAAM;mBAAO,EAAG,wBAAwB,gBAAgB;SAAU,CAAA,EACzE,EAAU,KAAK,MACd,kBAAC,UAAD;SAAgB,OAAO;mBACpB;SACM,EAFI,EAEJ,CACT,CACK;;OAET,kBAAC,UAAD;QACE,OAAO;QACP,WAAW,MAAM,EAAgB,EAAE,OAAO,MAAM;QAChD,WAAU;kBAHZ;SAKE,kBAAC,UAAD;UAAQ,OAAM;oBAAO,EAAG,qBAAqB,aAAa;UAAU,CAAA;SACpE,kBAAC,UAAD;UAAQ,OAAM;oBAAW,EAAG,mBAAmB,UAAU;UAAU,CAAA;SACnE,kBAAC,UAAD;UAAQ,OAAM;oBAAa,EAAG,qBAAqB,YAAY;UAAU,CAAA;SAClE;;OAET,kBAAC,UAAD;QACE,eAAe,GAAS;QACxB,cAAY,EAAG,mBAAmB,UAAU;QAC5C,WAAU;kBAEV,kBAAC,GAAD;SAAW,WAAU;SAAU,eAAY;SAAS,CAAA;QAC7C,CAAA;OACL;;KACF,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAoB,WAAW,IAC9B,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD,EAAM,WAAU,gDAAiD,CAAA;OACjE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,8BAA8B,uBAAuB;QACtD,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAS,WAAW,IACjB,EAAG,8BAA8B,4CAA4C,GAC7E,EAAG,oCAAoC,oCAAoC;QAC7E,CAAA;OACH,EAAS,WAAW,IACnB,kBAAC,UAAD;QACE,eAAe,EAAS,WAAW;QACnC,WAAU;kBAET,EAAG,yBAAyB,iBAAiB;QACvC,CAAA,GAET,kBAAC,UAAD;QACE,eAAe;AAEb,SADA,EAAgB,MAAM,EACtB,EAAkB,MAAM;;QAE1B,WAAU;kBAET,EAAG,wBAAwB,gBAAgB;QACrC,CAAA;OAEP;UAEN,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAoB,KAAK,MAAS;OACjC,IAAM,IAAS,EAAc,OAAO,EAAK,UAAU,KAAK,EAAc,OAChE,IAAa,EAAO;AAE1B,cACE,kBAAC,OAAD;QAEE,WAAU;QACV,eAAe,EAAS,KAAK,EAAK,YAAY;kBAE9C,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAW,EAAO;WAAO,cAAY,EAAO;qBAC/C,kBAAC,GAAD;YAAY,WAAU;YAAU,eAAY;YAAS,CAAA;WACjD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAe,EAAK;WAAgB,CAAA,EACjD,kBAAC,KAAD;WAAG,WAAU;qBAAb;YACG,EAAK;YAAS;YAAI,EAAK;YAAY;YAAI,EAAK;YAC3C;aACA,EAAA,CAAA,CACF;aAEN,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAK,kBAAkB,WACtB,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAG,wBAAwB,SAAS;cAChC,CAAA,GACL,EAAK,kBAAkB,aACzB,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAG,0BAA0B,WAAW;cACpC,CAAA,GACL,EAAK,kBAAkB,UACzB,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAG,uBAAuB,QAAQ;cAC9B,CAAA,GACL,EAAK,kBAAkB,cACzB,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAG,2BAA2B,YAAY;cACtC,CAAA,GACL,EAAK,kBAAkB,aACzB,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAG,0BAA0B,WAAW;cACpC,CAAA,GAEP,kBAAC,QAAD;cAAM,WAAU;wBACb,EAAG,0BAA0B,WAAW;cACpC,CAAA;aAEP,CAAA,EACH,EAAK,gBACJ,kBAAC,KAAD;aAAG,WAAU;uBAAb,CAA6C,iBAC7B,IAAI,KAAK,EAAK,aAAa,CAAC,oBAAoB,CAC5D;eAEF;;WAEL,EAAK,qBACJ,kBAAC,QAAD;YAAM,WAAU;sBAA+D;YAExE,CAAA;WAGR,EAAK,eAAe,SAAS,KAC5B,kBAAC,OAAD;YAAK,WAAU;YAAuB,cAAW;sBAAjD,CACG,EAAK,eAAe,MAAM,GAAG,EAAE,CAAC,KAAK,MACpC,kBAAC,GAAD;aAAqB,IAAI,EAAE;aAAO,OAAO,EAAE;aAAO,MAAK;aAAO,EAA/C,EAAE,GAA6C,CAC9D,EACD,EAAK,eAAe,SAAS,KAC5B,kBAAC,QAAD;aAAM,WAAU;uBAAhB,CAAgD,KAC5C,EAAK,eAAe,SAAS,EAC1B;eAEL;;WAGR,kBAAC,UAAD;YACE,UAAU,MAAM;AAEd,aADA,EAAE,iBAAiB,EACnB,EAAS,aAAa,EAAK,YAAY;;YAEzC,cAAY,EAAG,+BAA+B,wBAAwB;YACtE,WAAU;sBAEV,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;YACzB,CAAA;WACL;YACF;;QACF,EApFC,EAAK,aAoFN;QAER;MACE,CAAA;KAEJ,CAAA;IACF;;EACU,CAAA"}
|
|
1
|
+
{"version":3,"file":"ConnectionsListPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/ConnectionsListPage.tsx"],"sourcesContent":["/**\n * Connections List Page\n *\n * Displays all connections across channels with their status.\n */\n\nimport { useState, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\nimport {\n ArrowLeft,\n Plus,\n Loader2,\n AlertCircle,\n CheckCircle2,\n XCircle,\n RefreshCw,\n Settings,\n Link,\n} from 'lucide-react';\nimport { useChannels } from '../../../hooks/useChannels';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\n\nconst HEALTH_CONFIG: Record<string, { icon: typeof CheckCircle2; color: string; label: string }> = {\n true: { icon: CheckCircle2, color: 'text-status-success-text', label: 'Healthy' },\n false: { icon: XCircle, color: 'text-status-error-text', label: 'Unhealthy' },\n};\n\nexport function ConnectionsListPage() {\n const navigate = useNavigate();\n const { channels, isLoading, error, refetch } = useChannels();\n\n // Poll for connection status updates every 60 s.\n // connectionStatusChanged subscription is scoped to a single channelId;\n // this page shows all connections, so polling is used instead.\n useEffect(() => {\n const timer = setInterval(() => {\n void refetch();\n }, 60_000);\n return () => clearInterval(timer);\n }, [refetch]);\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Filter state\n const [healthFilter, setHealthFilter] = useState<string>('all');\n const [platformFilter, setPlatformFilter] = useState<string>('all');\n const pageSize = 10;\n const [currentPage, setCurrentPage] = useState(0);\n\n // Get all connections from channels\n const connections = channels\n .filter((ch) => ch.connection)\n .map((ch) => ({\n channelId: ch.id,\n channelName: ch.name,\n platform: ch.platform,\n adapterType: ch.adapterType,\n channelStatus: ch.status,\n connectionId: ch.connection!.id,\n isActive: ch.connection!.isActive,\n isHealthy: ch.connection!.isHealthy,\n needsTokenRefresh: ch.connection!.needsTokenRefresh,\n lastTestedAt: ch.connection!.lastTestedAt,\n authType: ch.connection!.authType,\n tagAssignments: ch.connection!.tagAssignments ?? [],\n }));\n\n // Get unique platforms\n const platforms = [...new Set(connections.map((c) => c.platform))];\n\n // Apply filters\n const filteredConnections = connections.filter((conn) => {\n if (healthFilter === 'healthy' && !conn.isHealthy) return false;\n if (healthFilter === 'unhealthy' && conn.isHealthy) return false;\n if (platformFilter !== 'all' && conn.platform !== platformFilter) return false;\n return true;\n });\n\n const totalPages = Math.max(1, Math.ceil(filteredConnections.length / pageSize));\n const pagedConnections = filteredConnections.slice(\n currentPage * pageSize,\n (currentPage + 1) * pageSize\n );\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 className=\"w-8 h-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"w-12 h-12 text-destructive\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.loadConnectionsFailed', 'Failed to load connections')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{error}</p>\n <button\n onClick={() => refetch()}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90\"\n >\n {tr('channel.retry', 'Retry')}\n </button>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_READ}>\n <div className=\"min-h-screen bg-background\">\n {/* Header */}\n <div className=\"border-b bg-card\">\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => navigate('./list')}\n aria-label={tr('channel.backToChannels', 'Back to channels')}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <ArrowLeft className=\"w-5 h-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">{tr('channel.connections', 'Connections')}</h1>\n <p className=\"text-sm text-muted-foreground\">\n {filteredConnections.length} connection\n {filteredConnections.length !== 1 ? 's' : ''}\n </p>\n </div>\n </div>\n <button\n onClick={() => navigate('./create')}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors flex items-center gap-2\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('channel.newChannel', 'New Channel')}\n </button>\n </div>\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center gap-4\">\n <select\n value={platformFilter}\n onChange={(e) => setPlatformFilter(e.target.value)}\n className=\"px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"all\">{tr('channel.allPlatforms', 'All Platforms')}</option>\n {platforms.map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n\n <select\n value={healthFilter}\n onChange={(e) => setHealthFilter(e.target.value)}\n className=\"px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"all\">{tr('channel.allStatus', 'All Status')}</option>\n <option value=\"healthy\">{tr('channel.healthy', 'Healthy')}</option>\n <option value=\"unhealthy\">{tr('channel.unhealthy', 'Unhealthy')}</option>\n </select>\n\n <button\n onClick={() => refetch()}\n aria-label={tr('channel.refresh', 'Refresh')}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <RefreshCw className=\"w-5 h-5\" aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n\n {/* Connections List */}\n <div className=\"container mx-auto px-6 pb-8\">\n {filteredConnections.length === 0 ? (\n <div className=\"text-center py-12\">\n <Link className=\"w-12 h-12 mx-auto text-muted-foreground mb-4\" />\n <h2 className=\"text-lg font-semibold mb-2\">\n {tr('channel.noConnectionsFound', 'No connections found')}\n </h2>\n <p className=\"text-sm text-muted-foreground mb-4\">\n {channels.length === 0\n ? tr('channel.createChannelFirst', 'Create a channel first to add connections')\n : tr('channel.noConnectionsMatchFilter', 'No connections match your filters')}\n </p>\n {channels.length === 0 ? (\n <button\n onClick={() => navigate('./create')}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90\"\n >\n {tr('channel.createChannel', 'Create Channel')}\n </button>\n ) : (\n <button\n onClick={() => {\n setHealthFilter('all');\n setPlatformFilter('all');\n }}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted\"\n >\n {tr('channel.clearFilters', 'Clear Filters')}\n </button>\n )}\n </div>\n ) : (\n <>\n <div className=\"border rounded-lg divide-y\">\n {pagedConnections.map((conn) => {\n const health = HEALTH_CONFIG[String(conn.isHealthy)] || HEALTH_CONFIG.false;\n const HealthIcon = health.icon;\n\n return (\n <div\n key={conn.connectionId}\n className=\"p-4 hover:bg-muted/50 transition-colors cursor-pointer\"\n onClick={() => navigate(`./${conn.channelId}`)}\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className={health.color} aria-label={health.label}>\n <HealthIcon className=\"w-5 h-5\" aria-hidden=\"true\" />\n </div>\n <div>\n <p className=\"font-medium\">{conn.channelName}</p>\n <p className=\"text-sm text-muted-foreground\">\n {conn.platform} • {conn.adapterType} • {conn.authType}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm\">\n {conn.channelStatus === 'ACTIVE' ? (\n <span className=\"text-status-success-text\">\n {tr('channel.activeStatus', 'Active')}\n </span>\n ) : conn.channelStatus === 'INACTIVE' ? (\n <span className=\"text-muted-foreground\">\n {tr('channel.inactiveStatus', 'Inactive')}\n </span>\n ) : conn.channelStatus === 'ERROR' ? (\n <span className=\"text-status-error-text\">\n {tr('channel.errorStatus', 'Error')}\n </span>\n ) : conn.channelStatus === 'SUSPENDED' ? (\n <span className=\"text-status-warning-text\">\n {tr('channel.suspendedStatus', 'Suspended')}\n </span>\n ) : conn.channelStatus === 'ARCHIVED' ? (\n <span className=\"text-muted-foreground\">\n {tr('channel.archivedStatus', 'Archived')}\n </span>\n ) : (\n <span className=\"text-muted-foreground\">\n {tr('channel.inactiveStatus', 'Inactive')}\n </span>\n )}\n </p>\n {conn.lastTestedAt && (\n <p className=\"text-xs text-muted-foreground\">\n Last tested: {new Date(conn.lastTestedAt).toLocaleDateString()}\n </p>\n )}\n </div>\n\n {conn.needsTokenRefresh && (\n <span className=\"px-2 py-1 text-xs bg-status-warning-bg-subtle text-status-warning-text rounded\">\n Token Expires\n </span>\n )}\n\n {conn.tagAssignments.length > 0 && (\n <div className=\"flex flex-wrap gap-1\" aria-label=\"Connection tags\">\n {conn.tagAssignments.slice(0, 3).map((a) => (\n <TagBadge key={a.id} id={a.tagId} label={a.tagId} size=\"sm\" />\n ))}\n {conn.tagAssignments.length > 3 && (\n <span className=\"text-xs text-muted-foreground\">\n +{conn.tagAssignments.length - 3}\n </span>\n )}\n </div>\n )}\n\n <button\n onClick={(e) => {\n e.stopPropagation();\n navigate(`/channels/${conn.channelId}`);\n }}\n aria-label={tr('channel.viewChannelSettings', 'View channel settings')}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <Settings className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n {/* Pagination */}\n {filteredConnections.length > pageSize && (\n <div className=\"flex items-center justify-between px-4 py-3 border border-border rounded-lg mt-3\">\n <p className=\"text-sm text-muted-foreground\">\n {tr('channel.showing', 'Showing')}{' '}\n <span className=\"font-medium\">\n {currentPage * pageSize + 1}–\n {Math.min((currentPage + 1) * pageSize, filteredConnections.length)}\n </span>{' '}\n {tr('channel.of', 'of')}{' '}\n <span className=\"font-medium\">{filteredConnections.length}</span>\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => setCurrentPage((p) => Math.max(0, p - 1))}\n disabled={currentPage === 0}\n className=\"px-3 py-1.5 text-sm border border-border rounded-lg hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {tr('channel.previous', 'Previous')}\n </button>\n <span className=\"text-sm text-muted-foreground\">\n {currentPage + 1} / {totalPages}\n </span>\n <button\n onClick={() => setCurrentPage((p) => Math.min(totalPages - 1, p + 1))}\n disabled={currentPage >= totalPages - 1}\n className=\"px-3 py-1.5 text-sm border border-border rounded-lg hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n {tr('channel.next', 'Next')}\n </button>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -171,10 +171,10 @@ function E() {
|
|
|
171
171
|
})
|
|
172
172
|
}),
|
|
173
173
|
y && /* @__PURE__ */ w("div", {
|
|
174
|
-
className: "flex items-center gap-3 p-3 bg-error-500/10 border border-error-
|
|
174
|
+
className: "flex items-center gap-3 p-3 bg-error-500/10 border border-status-error-border/30 rounded-lg",
|
|
175
175
|
children: [/* @__PURE__ */ C(o, {
|
|
176
176
|
size: 16,
|
|
177
|
-
className: "text-error-
|
|
177
|
+
className: "text-status-error-text shrink-0"
|
|
178
178
|
}), /* @__PURE__ */ C("p", {
|
|
179
179
|
className: "text-sm text-error-400",
|
|
180
180
|
children: y
|
|
@@ -233,7 +233,7 @@ function E() {
|
|
|
233
233
|
m("channel.name", "Name"),
|
|
234
234
|
" ",
|
|
235
235
|
/* @__PURE__ */ C("span", {
|
|
236
|
-
className: "text-error-
|
|
236
|
+
className: "text-status-error-text",
|
|
237
237
|
children: "*"
|
|
238
238
|
})
|
|
239
239
|
]
|
|
@@ -352,7 +352,7 @@ function E() {
|
|
|
352
352
|
m("channel.platform", "Platform"),
|
|
353
353
|
" ",
|
|
354
354
|
/* @__PURE__ */ C("span", {
|
|
355
|
-
className: "text-error-
|
|
355
|
+
className: "text-status-error-text",
|
|
356
356
|
children: "*"
|
|
357
357
|
})
|
|
358
358
|
]
|