@burdenoff/microfe-channel 2026.519.1 → 2026.520.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.
Files changed (52) hide show
  1. package/dist/channel/ChannelRoot.d.ts.map +1 -1
  2. package/dist/channel/ChannelRoot.js +23 -29
  3. package/dist/channel/ChannelRoot.js.map +1 -1
  4. package/dist/channel/components/AdapterCredentialsForm.js +7 -7
  5. package/dist/channel/components/AdapterCredentialsForm.js.map +1 -1
  6. package/dist/channel/components/FeatureNotEnabled.d.ts +3 -0
  7. package/dist/channel/components/FeatureNotEnabled.d.ts.map +1 -1
  8. package/dist/channel/components/FeatureNotEnabled.js +31 -13
  9. package/dist/channel/components/FeatureNotEnabled.js.map +1 -1
  10. package/dist/channel/hooks/useChannels.d.ts +17 -3
  11. package/dist/channel/hooks/useChannels.d.ts.map +1 -1
  12. package/dist/channel/hooks/useChannels.js +64 -18
  13. package/dist/channel/hooks/useChannels.js.map +1 -1
  14. package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts.map +1 -1
  15. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js +307 -274
  16. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js.map +1 -1
  17. package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts.map +1 -1
  18. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js +31 -31
  19. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js.map +1 -1
  20. package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts.map +1 -1
  21. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +22 -22
  22. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -1
  23. package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +1 -1
  24. package/dist/channel/modules/channels/pages/ChannelUsersPage.js +193 -137
  25. package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -1
  26. package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts.map +1 -1
  27. package/dist/channel/modules/channels/pages/ChannelsListPage.js +320 -248
  28. package/dist/channel/modules/channels/pages/ChannelsListPage.js.map +1 -1
  29. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts.map +1 -1
  30. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +5 -5
  31. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -1
  32. package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +1 -1
  33. package/dist/channel/modules/channels/pages/ConnectionsListPage.js +160 -112
  34. package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -1
  35. package/dist/channel/modules/channels/pages/CreateChannelPage.js +4 -4
  36. package/dist/channel/modules/channels/pages/CreateChannelPage.js.map +1 -1
  37. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +1 -1
  38. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +221 -157
  39. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -1
  40. package/dist/channel/modules/channels/pages/EditChannelPage.js +9 -9
  41. package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -1
  42. package/dist/channel/modules/channels/pages/SendMessagePage.d.ts.map +1 -1
  43. package/dist/channel/modules/channels/pages/SendMessagePage.js +89 -89
  44. package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -1
  45. package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +1 -1
  46. package/dist/channel/modules/channels/pages/WebhookEventsPage.js +188 -126
  47. package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -1
  48. package/dist/generated/global-operations.d.ts +2 -0
  49. package/dist/generated/global-operations.d.ts.map +1 -1
  50. package/dist/generated/global-operations.js +2 -0
  51. package/dist/generated/global-operations.js.map +1 -1
  52. package/package.json +1 -1
@@ -7,290 +7,318 @@ import { CHANNEL_PERMISSIONS as o } from "../../../constants/permissions.js";
7
7
  import { useExportWebhookEvents as s } from "../hooks/useExport.js";
8
8
  import { useCallback as c, useEffect as l, useState as u } from "react";
9
9
  import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
- import { AlertCircle as f, ArrowLeft as p, CheckCircle2 as m, Clock as h, Download as g, Eye as _, EyeOff as v, Loader2 as y, RefreshCw as b, XCircle as x } from "lucide-react";
11
- import { useNavigate as S, useParams as C } from "react-router-dom";
12
- import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
10
+ import { AlertCircle as f, ArrowLeft as p, CheckCircle2 as m, ChevronLeft as h, ChevronRight as g, Clock as _, Download as v, Eye as y, EyeOff as b, Loader2 as x, RefreshCw as S, XCircle as C } from "lucide-react";
11
+ import { useNavigate as w, useParams as T } from "react-router-dom";
12
+ import { Fragment as E, jsx as D, jsxs as O } from "react/jsx-runtime";
13
13
  //#region src/channel/modules/channels/pages/WebhookEventsPage.tsx
14
- var D = {
14
+ var k = {
15
15
  PENDING: {
16
16
  label: "Pending",
17
17
  color: "text-muted-foreground bg-muted",
18
- icon: h
18
+ icon: _
19
19
  },
20
20
  PROCESSING: {
21
21
  label: "Processing",
22
22
  color: "text-accent-primary bg-accent-primary/10",
23
- icon: b
23
+ icon: S
24
24
  },
25
25
  COMPLETED: {
26
26
  label: "Completed",
27
- color: "text-success-500 bg-success-100",
27
+ color: "text-status-success-text bg-status-success-bg-subtle",
28
28
  icon: m
29
29
  },
30
30
  FAILED: {
31
31
  label: "Failed",
32
- color: "text-error-500 bg-error-100",
33
- icon: x
32
+ color: "text-status-error-text bg-status-error-bg-subtle",
33
+ icon: C
34
34
  },
35
35
  IGNORED: {
36
36
  label: "Ignored",
37
- color: "text-warning-500 bg-warning-100",
38
- icon: v
37
+ color: "text-status-warning-text bg-status-warning-bg-subtle",
38
+ icon: b
39
39
  }
40
40
  };
41
- function O() {
42
- let { channelId: m } = C(), h = S(), { t: x } = d(), O = (e, t) => {
43
- let n = x(e);
41
+ function A() {
42
+ let { channelId: m } = T(), _ = w(), { t: C } = d(), A = (e, t) => {
43
+ let n = C(e);
44
44
  return n === e ? t : n;
45
- }, { organizationId: k } = e(), { triggerExport: A, isExporting: j, exportError: M } = s(k ?? void 0, m), [N, P] = u(!0), [F, I] = u([]), [L, R] = u(null), [z, B] = u(25), { channel: V, isLoading: H, error: U, fetchWebhookEvents: W } = i(m), G = c(async () => {
45
+ }, { organizationId: j } = e(), { triggerExport: M, isExporting: N, exportError: P } = s(j ?? void 0, m), [F, I] = u(!0), [L, R] = u([]), [z, B] = u(null), [V, H] = u(25), [U, W] = u(0), [G, K] = u([void 0]), [q, J] = u(0), { channel: Y, isLoading: X, error: Z, fetchWebhookEvents: Q } = i(m), $ = c(async (e) => {
46
46
  if (m) {
47
- P(!0);
47
+ I(!0);
48
48
  try {
49
- I(await W(z));
49
+ let t = await Q(V, e);
50
+ return R(t.items), W(t.total), t.nextCursor;
50
51
  } finally {
51
- P(!1);
52
+ I(!1);
52
53
  }
53
54
  }
54
55
  }, [
55
56
  m,
56
- W,
57
- z
57
+ Q,
58
+ V
58
59
  ]);
59
60
  l(() => {
60
- Promise.resolve().then(() => G());
61
- }, [G]), r({
61
+ Promise.resolve().then(() => {
62
+ K([void 0]), J(0), $(void 0);
63
+ });
64
+ }, [V]), l(() => {
65
+ Promise.resolve().then(() => $(G[q]));
66
+ }, [q]), l(() => {
67
+ Promise.resolve().then(() => $(void 0));
68
+ }, []);
69
+ let ee = c(async () => {
70
+ let e = await $(G[q]);
71
+ e && K((t) => {
72
+ let n = [...t];
73
+ return n[q + 1] || (n[q + 1] = e), n;
74
+ }), J((e) => e + 1);
75
+ }, [
76
+ G,
77
+ q,
78
+ $
79
+ ]), te = c(() => {
80
+ let e = q - 1;
81
+ J(e), $(G[e]);
82
+ }, [
83
+ G,
84
+ q,
85
+ $
86
+ ]), ne = L.length === V, re = q > 0;
87
+ r({
62
88
  query: n,
63
89
  variables: { channelId: m },
64
90
  operationName: "WebhookReceived",
65
91
  enabled: !!m,
66
92
  onData: () => {
67
- t("webhook.received", { channelId: m }), G();
93
+ t("webhook.received", { channelId: m }), $(G[q]);
94
+ },
95
+ pollFn: () => {
96
+ $(G[q]);
68
97
  },
69
- pollFn: G,
70
98
  pollIntervalMs: 6e4
71
99
  });
72
- let K = (e) => D[e] || D.PENDING;
73
- return H || N ? /* @__PURE__ */ T("div", {
100
+ let ie = (e) => k[e] || k.PENDING;
101
+ return X ? /* @__PURE__ */ D("div", {
74
102
  className: "flex items-center justify-center min-h-screen",
75
- children: /* @__PURE__ */ T(y, {
103
+ children: /* @__PURE__ */ D(x, {
76
104
  size: 32,
77
105
  className: "animate-spin text-accent-primary"
78
106
  })
79
- }) : U || !V ? /* @__PURE__ */ T("div", {
107
+ }) : Z || !Y ? /* @__PURE__ */ D("div", {
80
108
  className: "p-6",
81
- children: /* @__PURE__ */ E("div", {
82
- className: "flex items-center gap-3 p-4 bg-error-100 border border-error-500 rounded-lg",
109
+ children: /* @__PURE__ */ O("div", {
110
+ className: "flex items-center gap-3 p-4 bg-status-error-bg-subtle border border-status-error-border rounded-lg",
83
111
  children: [
84
- /* @__PURE__ */ T(f, {
112
+ /* @__PURE__ */ D(f, {
85
113
  size: 20,
86
- className: "text-error-500"
114
+ className: "text-status-error-text"
87
115
  }),
88
- /* @__PURE__ */ T("div", { children: /* @__PURE__ */ T("p", {
89
- className: "text-sm font-medium text-error-700",
90
- children: U || "Channel not found"
116
+ /* @__PURE__ */ D("div", { children: /* @__PURE__ */ D("p", {
117
+ className: "text-sm font-medium text-status-error-text",
118
+ children: Z || "Channel not found"
91
119
  }) }),
92
- /* @__PURE__ */ T("button", {
93
- onClick: () => h(`/channels/${m}`),
94
- className: "ml-auto px-3 py-1 text-sm text-error-700 hover:bg-error-200 rounded transition-colors",
120
+ /* @__PURE__ */ D("button", {
121
+ onClick: () => _(`/channels/${m}`),
122
+ className: "ml-auto px-3 py-1 text-sm text-status-error-text hover:bg-status-error-bg-subtle rounded transition-colors",
95
123
  children: "Go Back"
96
124
  })
97
125
  ]
98
126
  })
99
- }) : /* @__PURE__ */ T(a, {
127
+ }) : /* @__PURE__ */ D(a, {
100
128
  permission: o.CHANNEL_WEBHOOK_READ,
101
- children: /* @__PURE__ */ E("div", {
129
+ children: /* @__PURE__ */ O("div", {
102
130
  className: "space-y-6 p-3 sm:p-6",
103
131
  children: [
104
- /* @__PURE__ */ E("div", {
132
+ /* @__PURE__ */ O("div", {
105
133
  className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
106
- children: [/* @__PURE__ */ E("div", {
134
+ children: [/* @__PURE__ */ O("div", {
107
135
  className: "flex items-center gap-3",
108
- children: [/* @__PURE__ */ T("button", {
109
- onClick: () => h(`/channels/${m}`),
110
- "aria-label": O("channel.backToChannel", "Back to channel"),
136
+ children: [/* @__PURE__ */ D("button", {
137
+ onClick: () => _(`/channels/${m}`),
138
+ "aria-label": A("channel.backToChannel", "Back to channel"),
111
139
  className: "p-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-lg transition-colors",
112
- children: /* @__PURE__ */ T(p, {
140
+ children: /* @__PURE__ */ D(p, {
113
141
  size: 20,
114
142
  "aria-hidden": "true"
115
143
  })
116
- }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("h1", {
144
+ }), /* @__PURE__ */ O("div", { children: [/* @__PURE__ */ D("h1", {
117
145
  className: "text-xl sm:text-2xl font-bold text-foreground",
118
- children: O("channel.webhookEvents", "Webhook Events")
119
- }), /* @__PURE__ */ E("p", {
146
+ children: A("channel.webhookEvents", "Webhook Events")
147
+ }), /* @__PURE__ */ O("p", {
120
148
  className: "text-sm text-muted-foreground mt-1",
121
- children: [V.name, " - Event history"]
149
+ children: [Y.name, " - Event history"]
122
150
  })] })]
123
- }), /* @__PURE__ */ E("div", {
151
+ }), /* @__PURE__ */ O("div", {
124
152
  className: "flex items-center gap-3",
125
153
  children: [
126
- /* @__PURE__ */ E("select", {
127
- value: z,
128
- onChange: (e) => B(Number(e.target.value)),
154
+ /* @__PURE__ */ O("select", {
155
+ value: V,
156
+ onChange: (e) => H(Number(e.target.value)),
129
157
  className: "px-3 py-2 text-sm bg-surface border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-action-primary-bg/50 text-foreground",
130
158
  children: [
131
- /* @__PURE__ */ T("option", {
159
+ /* @__PURE__ */ D("option", {
132
160
  value: 10,
133
161
  children: "10 results"
134
162
  }),
135
- /* @__PURE__ */ T("option", {
163
+ /* @__PURE__ */ D("option", {
136
164
  value: 25,
137
165
  children: "25 results"
138
166
  }),
139
- /* @__PURE__ */ T("option", {
167
+ /* @__PURE__ */ D("option", {
140
168
  value: 50,
141
169
  children: "50 results"
142
170
  }),
143
- /* @__PURE__ */ T("option", {
171
+ /* @__PURE__ */ D("option", {
144
172
  value: 100,
145
173
  children: "100 results"
146
174
  })
147
175
  ]
148
176
  }),
149
- /* @__PURE__ */ E("button", {
150
- onClick: G,
151
- disabled: N,
177
+ /* @__PURE__ */ O("button", {
178
+ onClick: () => void $(G[q]),
179
+ disabled: F,
152
180
  className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50",
153
- children: [/* @__PURE__ */ T(b, {
181
+ children: [/* @__PURE__ */ D(S, {
154
182
  size: 16,
155
- className: N ? "animate-spin" : ""
156
- }), O("channel.refresh", "Refresh")]
183
+ className: F ? "animate-spin" : ""
184
+ }), A("channel.refresh", "Refresh")]
157
185
  }),
158
- /* @__PURE__ */ T(a, {
186
+ /* @__PURE__ */ D(a, {
159
187
  permission: o.CHANNEL_ADMIN,
160
- children: /* @__PURE__ */ E("button", {
161
- onClick: () => void A(),
162
- disabled: j,
188
+ children: /* @__PURE__ */ O("button", {
189
+ onClick: () => void M(),
190
+ disabled: N,
163
191
  className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-fg border border-border hover:bg-bg-elevated rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
164
- title: O("channel.exportCSV", "Export to CSV"),
165
- children: [j ? /* @__PURE__ */ T(y, {
192
+ title: A("channel.exportCSV", "Export to CSV"),
193
+ children: [N ? /* @__PURE__ */ D(x, {
166
194
  size: 16,
167
195
  className: "animate-spin"
168
- }) : /* @__PURE__ */ T(g, { size: 16 }), O("channel.export", "Export")]
196
+ }) : /* @__PURE__ */ D(v, { size: 16 }), A("channel.export", "Export")]
169
197
  })
170
198
  })
171
199
  ]
172
200
  })]
173
201
  }),
174
- M && /* @__PURE__ */ E("div", {
175
- className: "p-4 bg-error-100 border border-error-500 rounded-lg flex items-center gap-3",
176
- children: [/* @__PURE__ */ T(f, {
202
+ P && /* @__PURE__ */ O("div", {
203
+ className: "p-4 bg-status-error-bg-subtle border border-status-error-border rounded-lg flex items-center gap-3",
204
+ children: [/* @__PURE__ */ D(f, {
177
205
  size: 20,
178
- className: "text-error-500"
179
- }), /* @__PURE__ */ T("p", {
180
- className: "text-sm text-error-700 flex-1",
181
- children: M
206
+ className: "text-status-error-text"
207
+ }), /* @__PURE__ */ D("p", {
208
+ className: "text-sm text-status-error-text flex-1",
209
+ children: P
182
210
  })]
183
211
  }),
184
- /* @__PURE__ */ T("div", {
212
+ /* @__PURE__ */ D("div", {
185
213
  className: "p-4 bg-surface border border-border rounded-lg",
186
- children: /* @__PURE__ */ T("p", {
214
+ children: /* @__PURE__ */ D("p", {
187
215
  className: "text-sm text-muted-foreground",
188
216
  children: "Webhook events show all incoming webhooks received by this channel. Data is retained for 7 days."
189
217
  })
190
218
  }),
191
- /* @__PURE__ */ T("div", {
219
+ /* @__PURE__ */ D("div", {
192
220
  className: "bg-surface border border-border rounded-lg overflow-hidden",
193
- children: /* @__PURE__ */ T("div", {
221
+ children: /* @__PURE__ */ D("div", {
194
222
  className: "overflow-x-auto min-w-full",
195
- children: /* @__PURE__ */ E("table", {
223
+ children: /* @__PURE__ */ O("table", {
196
224
  className: "w-full min-w-[600px]",
197
- children: [/* @__PURE__ */ T("thead", {
225
+ children: [/* @__PURE__ */ D("thead", {
198
226
  className: "bg-muted/50 border-b border-border",
199
- children: /* @__PURE__ */ E("tr", { children: [
200
- /* @__PURE__ */ T("th", {
227
+ children: /* @__PURE__ */ O("tr", { children: [
228
+ /* @__PURE__ */ D("th", {
201
229
  className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
202
- children: O("channel.status", "Status")
230
+ children: A("channel.status", "Status")
203
231
  }),
204
- /* @__PURE__ */ T("th", {
232
+ /* @__PURE__ */ D("th", {
205
233
  className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
206
- children: O("channel.eventType", "Event Type")
234
+ children: A("channel.eventType", "Event Type")
207
235
  }),
208
- /* @__PURE__ */ T("th", {
236
+ /* @__PURE__ */ D("th", {
209
237
  className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
210
- children: O("channel.duplicate", "Duplicate")
238
+ children: A("channel.duplicate", "Duplicate")
211
239
  }),
212
- /* @__PURE__ */ T("th", {
240
+ /* @__PURE__ */ D("th", {
213
241
  className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
214
- children: O("channel.processedAt", "Processed At")
242
+ children: A("channel.processedAt", "Processed At")
215
243
  }),
216
- /* @__PURE__ */ T("th", {
244
+ /* @__PURE__ */ D("th", {
217
245
  className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
218
- children: O("channel.error", "Error")
246
+ children: A("channel.error", "Error")
219
247
  }),
220
- /* @__PURE__ */ T("th", {
248
+ /* @__PURE__ */ D("th", {
221
249
  className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
222
- children: O("channel.actions", "Actions")
250
+ children: A("channel.actions", "Actions")
223
251
  })
224
252
  ] })
225
- }), /* @__PURE__ */ T("tbody", {
253
+ }), /* @__PURE__ */ D("tbody", {
226
254
  className: "divide-y divide-border",
227
- children: F.length === 0 ? /* @__PURE__ */ T("tr", { children: /* @__PURE__ */ T("td", {
255
+ children: L.length === 0 ? /* @__PURE__ */ D("tr", { children: /* @__PURE__ */ D("td", {
228
256
  colSpan: 6,
229
257
  className: "px-4 py-8 text-center text-muted-foreground",
230
- children: O("channel.noWebhookEventsFound", "No webhook events found")
231
- }) }) : F.map((e) => {
232
- let t = K(e.status), n = t.icon, r = L === e.id;
233
- return /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ E("tr", {
258
+ children: A("channel.noWebhookEventsFound", "No webhook events found")
259
+ }) }) : L.map((e) => {
260
+ let t = ie(e.status), n = t.icon, r = z === e.id;
261
+ return /* @__PURE__ */ O(E, { children: [/* @__PURE__ */ O("tr", {
234
262
  className: "hover:bg-muted/30 transition-colors",
235
263
  children: [
236
- /* @__PURE__ */ T("td", {
264
+ /* @__PURE__ */ D("td", {
237
265
  className: "px-4 py-3",
238
- children: /* @__PURE__ */ E("div", {
266
+ children: /* @__PURE__ */ O("div", {
239
267
  className: "flex items-center gap-2",
240
- children: [/* @__PURE__ */ T(n, {
268
+ children: [/* @__PURE__ */ D(n, {
241
269
  size: 14,
242
270
  className: t.color.split(" ")[0]
243
- }), /* @__PURE__ */ T("span", {
271
+ }), /* @__PURE__ */ D("span", {
244
272
  className: `text-sm font-medium ${t.color}`,
245
273
  children: t.label
246
274
  })]
247
275
  })
248
276
  }),
249
- /* @__PURE__ */ T("td", {
277
+ /* @__PURE__ */ D("td", {
250
278
  className: "px-4 py-3 text-sm font-mono text-foreground",
251
279
  children: e.eventType
252
280
  }),
253
- /* @__PURE__ */ T("td", {
281
+ /* @__PURE__ */ D("td", {
254
282
  className: "px-4 py-3",
255
- children: e.isDuplicate ? /* @__PURE__ */ T("span", {
256
- className: "text-xs text-warning-500 bg-warning-100 px-2 py-1 rounded",
283
+ children: e.isDuplicate ? /* @__PURE__ */ D("span", {
284
+ className: "text-xs text-status-warning-text bg-status-warning-bg-subtle px-2 py-1 rounded",
257
285
  children: "Duplicate"
258
- }) : /* @__PURE__ */ T("span", {
286
+ }) : /* @__PURE__ */ D("span", {
259
287
  className: "text-xs text-muted-foreground",
260
288
  children: "No"
261
289
  })
262
290
  }),
263
- /* @__PURE__ */ T("td", {
291
+ /* @__PURE__ */ D("td", {
264
292
  className: "px-4 py-3 text-sm text-muted-foreground",
265
293
  children: e.processedAt ? new Date(e.processedAt).toLocaleString() : "-"
266
294
  }),
267
- /* @__PURE__ */ T("td", {
268
- className: "px-4 py-3 text-sm text-error-500 max-w-xs truncate",
295
+ /* @__PURE__ */ D("td", {
296
+ className: "px-4 py-3 text-sm text-status-error-text max-w-xs truncate",
269
297
  children: e.errorMessage || "-"
270
298
  }),
271
- /* @__PURE__ */ T("td", {
299
+ /* @__PURE__ */ D("td", {
272
300
  className: "px-4 py-3",
273
- children: /* @__PURE__ */ T("button", {
274
- onClick: () => R(r ? null : e.id),
275
- "aria-label": r ? O("channel.hidePayload", "Hide payload") : O("channel.viewPayload", "View payload"),
301
+ children: /* @__PURE__ */ D("button", {
302
+ onClick: () => B(r ? null : e.id),
303
+ "aria-label": r ? A("channel.hidePayload", "Hide payload") : A("channel.viewPayload", "View payload"),
276
304
  "aria-expanded": r,
277
305
  className: "p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors",
278
- children: T(r ? v : _, {
306
+ children: D(r ? b : y, {
279
307
  size: 16,
280
308
  "aria-hidden": "true"
281
309
  })
282
310
  })
283
311
  })
284
312
  ]
285
- }, e.id), r && /* @__PURE__ */ T("tr", { children: /* @__PURE__ */ T("td", {
313
+ }, e.id), r && /* @__PURE__ */ D("tr", { children: /* @__PURE__ */ D("td", {
286
314
  colSpan: 6,
287
315
  className: "px-4 py-3 bg-muted/30",
288
- children: /* @__PURE__ */ E("div", {
316
+ children: /* @__PURE__ */ O("div", {
289
317
  className: "text-xs",
290
- children: [/* @__PURE__ */ E("p", {
318
+ children: [/* @__PURE__ */ O("p", {
291
319
  className: "text-muted-foreground mb-1",
292
- children: [O("channel.payload", "Payload"), ":"]
293
- }), /* @__PURE__ */ T("pre", {
320
+ children: [A("channel.payload", "Payload"), ":"]
321
+ }), /* @__PURE__ */ D("pre", {
294
322
  className: "bg-surface p-2 rounded border border-border overflow-auto",
295
323
  children: JSON.stringify(e.payload, null, 2)
296
324
  })]
@@ -300,12 +328,46 @@ function O() {
300
328
  })]
301
329
  })
302
330
  })
331
+ }),
332
+ /* @__PURE__ */ O("div", {
333
+ className: "flex items-center justify-between",
334
+ children: [/* @__PURE__ */ D("p", {
335
+ className: "text-sm text-muted-foreground",
336
+ children: U > 0 && /* @__PURE__ */ O(E, { children: [
337
+ A("channel.page", "Page"),
338
+ " ",
339
+ /* @__PURE__ */ D("span", {
340
+ className: "font-medium",
341
+ children: q + 1
342
+ }),
343
+ " · ",
344
+ A("channel.totalRecords", "Total"),
345
+ ": ",
346
+ /* @__PURE__ */ D("span", {
347
+ className: "font-medium",
348
+ children: U
349
+ })
350
+ ] })
351
+ }), /* @__PURE__ */ O("div", {
352
+ className: "flex items-center gap-2",
353
+ children: [/* @__PURE__ */ O("button", {
354
+ onClick: te,
355
+ disabled: !re || F,
356
+ className: "flex items-center gap-1 px-3 py-1.5 text-sm border border-border rounded-lg hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
357
+ children: [/* @__PURE__ */ D(h, { size: 16 }), A("channel.previous", "Previous")]
358
+ }), /* @__PURE__ */ O("button", {
359
+ onClick: () => void ee(),
360
+ disabled: !ne || F,
361
+ className: "flex items-center gap-1 px-3 py-1.5 text-sm border border-border rounded-lg hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
362
+ children: [A("channel.next", "Next"), /* @__PURE__ */ D(g, { size: 16 })]
363
+ })]
364
+ })]
303
365
  })
304
366
  ]
305
367
  })
306
368
  });
307
369
  }
308
370
  //#endregion
309
- export { O as WebhookEventsPage };
371
+ export { A as WebhookEventsPage };
310
372
 
311
373
  //# sourceMappingURL=WebhookEventsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookEventsPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/WebhookEventsPage.tsx"],"sourcesContent":["/**\n * Webhook Events Page\n *\n * Displays webhook event history for a specific channel\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n ArrowLeft,\n Loader2,\n AlertCircle,\n CheckCircle2,\n XCircle,\n Clock,\n RefreshCw,\n Eye,\n EyeOff,\n Download,\n} from 'lucide-react';\nimport { useChannel, type WebhookEvent as WebhookEventType } from '../../../hooks/useChannels';\nimport type { WebhookProcessingStatus } from '../../../hooks/useChannels';\nimport { useChannel as useChannelContext } from '../../../providers/ChannelProvider';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\nimport { emitShellEvent } from '../../../utils/shellBridge';\nimport {\n WEBHOOK_RECEIVED_SUBSCRIPTION,\n useChannelSubscription,\n} from '../../../hooks/useChannelSubscription';\nimport { useExportWebhookEvents } from '../hooks/useExport';\n\nconst STATUS_CONFIG: Record<\n WebhookProcessingStatus,\n { label: string; color: string; icon: typeof CheckCircle2 }\n> = {\n PENDING: { label: 'Pending', color: 'text-muted-foreground bg-muted', icon: Clock },\n PROCESSING: {\n label: 'Processing',\n color: 'text-accent-primary bg-accent-primary/10',\n icon: RefreshCw,\n },\n COMPLETED: { label: 'Completed', color: 'text-success-500 bg-success-100', icon: CheckCircle2 },\n FAILED: { label: 'Failed', color: 'text-error-500 bg-error-100', icon: XCircle },\n IGNORED: { label: 'Ignored', color: 'text-warning-500 bg-warning-100', icon: EyeOff },\n};\n\nexport function WebhookEventsPage() {\n const { channelId } = useParams<{ channelId: string }>();\n const navigate = useNavigate();\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 const { organizationId } = useChannelContext();\n const {\n triggerExport: exportWebhooks,\n isExporting: isExportingWebhooks,\n exportError: exportWebhooksError,\n } = useExportWebhookEvents(organizationId ?? undefined, channelId);\n const [isLoadingEvents, setIsLoadingEvents] = useState(true);\n const [events, setEvents] = useState<WebhookEventType[]>([]);\n const [expandedEvent, setExpandedEvent] = useState<string | null>(null);\n const [limit, setLimit] = useState(25);\n\n const { channel, isLoading, error, fetchWebhookEvents } = useChannel(channelId);\n\n const loadEvents = useCallback(async () => {\n if (!channelId) return;\n setIsLoadingEvents(true);\n try {\n const data = await fetchWebhookEvents(limit);\n setEvents(data);\n } finally {\n setIsLoadingEvents(false);\n }\n }, [channelId, fetchWebhookEvents, limit]);\n\n useEffect(() => {\n void Promise.resolve().then(() => loadEvents());\n }, [loadEvents]);\n\n // Real-time webhook stream. Subscribes when the gateway exposes\n // `webhookReceived`; otherwise polls every 60s as a graceful fallback.\n // Conservative fallback keeps gateway/svc cost low when subs are\n // unavailable; live updates flow through the subscription path.\n useChannelSubscription({\n query: WEBHOOK_RECEIVED_SUBSCRIPTION,\n variables: { channelId },\n operationName: 'WebhookReceived',\n enabled: Boolean(channelId),\n onData: () => {\n emitShellEvent('webhook.received', { channelId });\n void loadEvents();\n },\n pollFn: loadEvents,\n pollIntervalMs: 60_000,\n });\n\n const getStatusConfig = (status: WebhookProcessingStatus) => {\n return STATUS_CONFIG[status] || STATUS_CONFIG.PENDING;\n };\n\n // Loading state\n if (isLoading || isLoadingEvents) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 size={32} className=\"animate-spin text-accent-primary\" />\n </div>\n );\n }\n\n // Error state\n if (error || !channel) {\n return (\n <div className=\"p-6\">\n <div className=\"flex items-center gap-3 p-4 bg-error-100 border border-error-500 rounded-lg\">\n <AlertCircle size={20} className=\"text-error-500\" />\n <div>\n <p className=\"text-sm font-medium text-error-700\">{error || 'Channel not found'}</p>\n </div>\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"ml-auto px-3 py-1 text-sm text-error-700 hover:bg-error-200 rounded transition-colors\"\n >\n Go Back\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_WEBHOOK_READ}>\n <div className=\"space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n aria-label={tr('channel.backToChannel', 'Back to channel')}\n className=\"p-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-lg transition-colors\"\n >\n <ArrowLeft size={20} aria-hidden=\"true\" />\n </button>\n <div>\n <h1 className=\"text-xl sm:text-2xl font-bold text-foreground\">\n {tr('channel.webhookEvents', 'Webhook Events')}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">{channel.name} - Event history</p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <select\n value={limit}\n onChange={(e) => setLimit(Number(e.target.value))}\n className=\"px-3 py-2 text-sm bg-surface border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-action-primary-bg/50 text-foreground\"\n >\n <option value={10}>10 results</option>\n <option value={25}>25 results</option>\n <option value={50}>50 results</option>\n <option value={100}>100 results</option>\n </select>\n <button\n onClick={loadEvents}\n disabled={isLoadingEvents}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50\"\n >\n <RefreshCw size={16} className={isLoadingEvents ? 'animate-spin' : ''} />\n {tr('channel.refresh', 'Refresh')}\n </button>\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_ADMIN}>\n <button\n onClick={() => void exportWebhooks()}\n disabled={isExportingWebhooks}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-fg border border-border hover:bg-bg-elevated rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={tr('channel.exportCSV', 'Export to CSV')}\n >\n {isExportingWebhooks ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <Download size={16} />\n )}\n {tr('channel.export', 'Export')}\n </button>\n </PermissionGuard>\n </div>\n </div>\n\n {/* Export Error Banner */}\n {exportWebhooksError && (\n <div className=\"p-4 bg-error-100 border border-error-500 rounded-lg flex items-center gap-3\">\n <AlertCircle size={20} className=\"text-error-500\" />\n <p className=\"text-sm text-error-700 flex-1\">{exportWebhooksError}</p>\n </div>\n )}\n\n {/* Info Banner */}\n <div className=\"p-4 bg-surface border border-border rounded-lg\">\n <p className=\"text-sm text-muted-foreground\">\n Webhook events show all incoming webhooks received by this channel. Data is retained for\n 7 days.\n </p>\n </div>\n\n {/* Events List */}\n <div className=\"bg-surface border border-border rounded-lg overflow-hidden\">\n <div className=\"overflow-x-auto min-w-full\">\n <table className=\"w-full min-w-[600px]\">\n <thead className=\"bg-muted/50 border-b border-border\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.status', 'Status')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.eventType', 'Event Type')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.duplicate', 'Duplicate')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.processedAt', 'Processed At')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.error', 'Error')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {events.length === 0 ? (\n <tr>\n <td colSpan={6} className=\"px-4 py-8 text-center text-muted-foreground\">\n {tr('channel.noWebhookEventsFound', 'No webhook events found')}\n </td>\n </tr>\n ) : (\n events.map((event) => {\n const statusConfig = getStatusConfig(event.status as WebhookProcessingStatus);\n const StatusIcon = statusConfig.icon;\n const isExpanded = expandedEvent === event.id;\n return (\n <>\n <tr key={event.id} className=\"hover:bg-muted/30 transition-colors\">\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n <StatusIcon size={14} className={statusConfig.color.split(' ')[0]} />\n <span className={`text-sm font-medium ${statusConfig.color}`}>\n {statusConfig.label}\n </span>\n </div>\n </td>\n <td className=\"px-4 py-3 text-sm font-mono text-foreground\">\n {event.eventType}\n </td>\n <td className=\"px-4 py-3\">\n {event.isDuplicate ? (\n <span className=\"text-xs text-warning-500 bg-warning-100 px-2 py-1 rounded\">\n Duplicate\n </span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">No</span>\n )}\n </td>\n <td className=\"px-4 py-3 text-sm text-muted-foreground\">\n {event.processedAt ? new Date(event.processedAt).toLocaleString() : '-'}\n </td>\n <td className=\"px-4 py-3 text-sm text-error-500 max-w-xs truncate\">\n {event.errorMessage || '-'}\n </td>\n <td className=\"px-4 py-3\">\n <button\n onClick={() => setExpandedEvent(isExpanded ? null : event.id)}\n aria-label={\n isExpanded\n ? tr('channel.hidePayload', 'Hide payload')\n : tr('channel.viewPayload', 'View payload')\n }\n aria-expanded={isExpanded}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors\"\n >\n {isExpanded ? (\n <EyeOff size={16} aria-hidden=\"true\" />\n ) : (\n <Eye size={16} aria-hidden=\"true\" />\n )}\n </button>\n </td>\n </tr>\n {isExpanded && (\n <tr key={`${event.id}-payload`}>\n <td colSpan={6} className=\"px-4 py-3 bg-muted/30\">\n <div className=\"text-xs\">\n <p className=\"text-muted-foreground mb-1\">\n {tr('channel.payload', 'Payload')}:\n </p>\n <pre className=\"bg-surface p-2 rounded border border-border overflow-auto\">\n {JSON.stringify(event.payload, null, 2)}\n </pre>\n </div>\n </td>\n </tr>\n )}\n </>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"WebhookEventsPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/WebhookEventsPage.tsx"],"sourcesContent":["/**\n * Webhook Events Page\n *\n * Displays webhook event history for a specific channel\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n ArrowLeft,\n Loader2,\n AlertCircle,\n CheckCircle2,\n XCircle,\n Clock,\n RefreshCw,\n Eye,\n EyeOff,\n Download,\n ChevronLeft,\n ChevronRight,\n} from 'lucide-react';\nimport { useChannel, type WebhookEvent as WebhookEventType } from '../../../hooks/useChannels';\nimport type { WebhookProcessingStatus } from '../../../hooks/useChannels';\nimport { useChannel as useChannelContext } from '../../../providers/ChannelProvider';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\nimport { emitShellEvent } from '../../../utils/shellBridge';\nimport {\n WEBHOOK_RECEIVED_SUBSCRIPTION,\n useChannelSubscription,\n} from '../../../hooks/useChannelSubscription';\nimport { useExportWebhookEvents } from '../hooks/useExport';\n\nconst STATUS_CONFIG: Record<\n WebhookProcessingStatus,\n { label: string; color: string; icon: typeof CheckCircle2 }\n> = {\n PENDING: { label: 'Pending', color: 'text-muted-foreground bg-muted', icon: Clock },\n PROCESSING: {\n label: 'Processing',\n color: 'text-accent-primary bg-accent-primary/10',\n icon: RefreshCw,\n },\n COMPLETED: {\n label: 'Completed',\n color: 'text-status-success-text bg-status-success-bg-subtle',\n icon: CheckCircle2,\n },\n FAILED: {\n label: 'Failed',\n color: 'text-status-error-text bg-status-error-bg-subtle',\n icon: XCircle,\n },\n IGNORED: {\n label: 'Ignored',\n color: 'text-status-warning-text bg-status-warning-bg-subtle',\n icon: EyeOff,\n },\n};\n\nexport function WebhookEventsPage() {\n const { channelId } = useParams<{ channelId: string }>();\n const navigate = useNavigate();\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 const { organizationId } = useChannelContext();\n const {\n triggerExport: exportWebhooks,\n isExporting: isExportingWebhooks,\n exportError: exportWebhooksError,\n } = useExportWebhookEvents(organizationId ?? undefined, channelId);\n const [isLoadingEvents, setIsLoadingEvents] = useState(true);\n const [events, setEvents] = useState<WebhookEventType[]>([]);\n const [expandedEvent, setExpandedEvent] = useState<string | null>(null);\n const [limit, setLimit] = useState(25);\n const [total, setTotal] = useState(0);\n const [cursorStack, setCursorStack] = useState<(string | undefined)[]>([undefined]);\n const [currentPageIdx, setCurrentPageIdx] = useState(0);\n\n const { channel, isLoading, error, fetchWebhookEvents } = useChannel(channelId);\n\n const loadEvents = useCallback(\n async (cursor?: string) => {\n if (!channelId) return;\n setIsLoadingEvents(true);\n try {\n const result = await fetchWebhookEvents(limit, cursor);\n setEvents(result.items);\n setTotal(result.total);\n return result.nextCursor;\n } finally {\n setIsLoadingEvents(false);\n }\n },\n [channelId, fetchWebhookEvents, limit]\n );\n\n useEffect(() => {\n void Promise.resolve().then(() => {\n setCursorStack([undefined]);\n setCurrentPageIdx(0);\n void loadEvents(undefined);\n });\n }, [limit]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n void Promise.resolve().then(() => loadEvents(cursorStack[currentPageIdx]));\n }, [currentPageIdx]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Initial load\n useEffect(() => {\n void Promise.resolve().then(() => loadEvents(undefined));\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleNextPage = useCallback(async () => {\n const nextCursor = await loadEvents(cursorStack[currentPageIdx]);\n if (nextCursor) {\n setCursorStack((prev) => {\n const next = [...prev];\n if (!next[currentPageIdx + 1]) {\n next[currentPageIdx + 1] = nextCursor;\n }\n return next;\n });\n }\n setCurrentPageIdx((p) => p + 1);\n }, [cursorStack, currentPageIdx, loadEvents]);\n\n const handlePrevPage = useCallback(() => {\n const prevIdx = currentPageIdx - 1;\n setCurrentPageIdx(prevIdx);\n void loadEvents(cursorStack[prevIdx]);\n }, [cursorStack, currentPageIdx, loadEvents]);\n\n const hasNextPage = events.length === limit;\n const hasPrevPage = currentPageIdx > 0;\n\n // Real-time webhook stream. Subscribes when the gateway exposes\n // `webhookReceived`; otherwise polls every 60s as a graceful fallback.\n useChannelSubscription({\n query: WEBHOOK_RECEIVED_SUBSCRIPTION,\n variables: { channelId },\n operationName: 'WebhookReceived',\n enabled: Boolean(channelId),\n onData: () => {\n emitShellEvent('webhook.received', { channelId });\n void loadEvents(cursorStack[currentPageIdx]);\n },\n pollFn: () => {\n void loadEvents(cursorStack[currentPageIdx]);\n },\n pollIntervalMs: 60_000,\n });\n\n const getStatusConfig = (status: WebhookProcessingStatus) => {\n return STATUS_CONFIG[status] || STATUS_CONFIG.PENDING;\n };\n\n // Loading state (only show full-screen for initial channel load)\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 size={32} className=\"animate-spin text-accent-primary\" />\n </div>\n );\n }\n\n // Error state\n if (error || !channel) {\n return (\n <div className=\"p-6\">\n <div className=\"flex items-center gap-3 p-4 bg-status-error-bg-subtle border border-status-error-border rounded-lg\">\n <AlertCircle size={20} className=\"text-status-error-text\" />\n <div>\n <p className=\"text-sm font-medium text-status-error-text\">\n {error || 'Channel not found'}\n </p>\n </div>\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"ml-auto px-3 py-1 text-sm text-status-error-text hover:bg-status-error-bg-subtle rounded transition-colors\"\n >\n Go Back\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_WEBHOOK_READ}>\n <div className=\"space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n aria-label={tr('channel.backToChannel', 'Back to channel')}\n className=\"p-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-lg transition-colors\"\n >\n <ArrowLeft size={20} aria-hidden=\"true\" />\n </button>\n <div>\n <h1 className=\"text-xl sm:text-2xl font-bold text-foreground\">\n {tr('channel.webhookEvents', 'Webhook Events')}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">{channel.name} - Event history</p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <select\n value={limit}\n onChange={(e) => setLimit(Number(e.target.value))}\n className=\"px-3 py-2 text-sm bg-surface border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-action-primary-bg/50 text-foreground\"\n >\n <option value={10}>10 results</option>\n <option value={25}>25 results</option>\n <option value={50}>50 results</option>\n <option value={100}>100 results</option>\n </select>\n <button\n onClick={() => void loadEvents(cursorStack[currentPageIdx])}\n disabled={isLoadingEvents}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50\"\n >\n <RefreshCw size={16} className={isLoadingEvents ? 'animate-spin' : ''} />\n {tr('channel.refresh', 'Refresh')}\n </button>\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_ADMIN}>\n <button\n onClick={() => void exportWebhooks()}\n disabled={isExportingWebhooks}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-fg border border-border hover:bg-bg-elevated rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n title={tr('channel.exportCSV', 'Export to CSV')}\n >\n {isExportingWebhooks ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <Download size={16} />\n )}\n {tr('channel.export', 'Export')}\n </button>\n </PermissionGuard>\n </div>\n </div>\n\n {/* Export Error Banner */}\n {exportWebhooksError && (\n <div className=\"p-4 bg-status-error-bg-subtle border border-status-error-border rounded-lg flex items-center gap-3\">\n <AlertCircle size={20} className=\"text-status-error-text\" />\n <p className=\"text-sm text-status-error-text flex-1\">{exportWebhooksError}</p>\n </div>\n )}\n\n {/* Info Banner */}\n <div className=\"p-4 bg-surface border border-border rounded-lg\">\n <p className=\"text-sm text-muted-foreground\">\n Webhook events show all incoming webhooks received by this channel. Data is retained for\n 7 days.\n </p>\n </div>\n\n {/* Events List */}\n <div className=\"bg-surface border border-border rounded-lg overflow-hidden\">\n <div className=\"overflow-x-auto min-w-full\">\n <table className=\"w-full min-w-[600px]\">\n <thead className=\"bg-muted/50 border-b border-border\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.status', 'Status')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.eventType', 'Event Type')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.duplicate', 'Duplicate')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.processedAt', 'Processed At')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.error', 'Error')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {tr('channel.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {events.length === 0 ? (\n <tr>\n <td colSpan={6} className=\"px-4 py-8 text-center text-muted-foreground\">\n {tr('channel.noWebhookEventsFound', 'No webhook events found')}\n </td>\n </tr>\n ) : (\n events.map((event) => {\n const statusConfig = getStatusConfig(event.status as WebhookProcessingStatus);\n const StatusIcon = statusConfig.icon;\n const isExpanded = expandedEvent === event.id;\n return (\n <>\n <tr key={event.id} className=\"hover:bg-muted/30 transition-colors\">\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n <StatusIcon size={14} className={statusConfig.color.split(' ')[0]} />\n <span className={`text-sm font-medium ${statusConfig.color}`}>\n {statusConfig.label}\n </span>\n </div>\n </td>\n <td className=\"px-4 py-3 text-sm font-mono text-foreground\">\n {event.eventType}\n </td>\n <td className=\"px-4 py-3\">\n {event.isDuplicate ? (\n <span className=\"text-xs text-status-warning-text bg-status-warning-bg-subtle px-2 py-1 rounded\">\n Duplicate\n </span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">No</span>\n )}\n </td>\n <td className=\"px-4 py-3 text-sm text-muted-foreground\">\n {event.processedAt ? new Date(event.processedAt).toLocaleString() : '-'}\n </td>\n <td className=\"px-4 py-3 text-sm text-status-error-text max-w-xs truncate\">\n {event.errorMessage || '-'}\n </td>\n <td className=\"px-4 py-3\">\n <button\n onClick={() => setExpandedEvent(isExpanded ? null : event.id)}\n aria-label={\n isExpanded\n ? tr('channel.hidePayload', 'Hide payload')\n : tr('channel.viewPayload', 'View payload')\n }\n aria-expanded={isExpanded}\n className=\"p-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors\"\n >\n {isExpanded ? (\n <EyeOff size={16} aria-hidden=\"true\" />\n ) : (\n <Eye size={16} aria-hidden=\"true\" />\n )}\n </button>\n </td>\n </tr>\n {isExpanded && (\n <tr key={`${event.id}-payload`}>\n <td colSpan={6} className=\"px-4 py-3 bg-muted/30\">\n <div className=\"text-xs\">\n <p className=\"text-muted-foreground mb-1\">\n {tr('channel.payload', 'Payload')}:\n </p>\n <pre className=\"bg-surface p-2 rounded border border-border overflow-auto\">\n {JSON.stringify(event.payload, null, 2)}\n </pre>\n </div>\n </td>\n </tr>\n )}\n </>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Pagination footer */}\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {total > 0 && (\n <>\n {tr('channel.page', 'Page')}{' '}\n <span className=\"font-medium\">{currentPageIdx + 1}</span>\n {' · '}\n {tr('channel.totalRecords', 'Total')}: <span className=\"font-medium\">{total}</span>\n </>\n )}\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={handlePrevPage}\n disabled={!hasPrevPage || isLoadingEvents}\n className=\"flex items-center gap-1 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 <ChevronLeft size={16} />\n {tr('channel.previous', 'Previous')}\n </button>\n <button\n onClick={() => void handleNextPage()}\n disabled={!hasNextPage || isLoadingEvents}\n className=\"flex items-center gap-1 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 <ChevronRight size={16} />\n </button>\n </div>\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -817,6 +817,8 @@ export type SendNotificationMutation = {
817
817
  sentAt?: string | null;
818
818
  title: string;
819
819
  message: string;
820
+ errorMessage?: string | null;
821
+ errorCode?: string | null;
820
822
  };
821
823
  };
822
824
  export declare const ChannelFieldsFragmentDoc: Apollo.DocumentNode;