@burdenoff/microfe-bigconsole 2026.1007.10 → 2026.1007.11
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/bigconsole/assistant/displayCopy.d.ts +33 -0
- package/dist/bigconsole/assistant/displayCopy.d.ts.map +1 -0
- package/dist/bigconsole/assistant/pageContext.d.ts +14 -0
- package/dist/bigconsole/assistant/pageContext.d.ts.map +1 -1
- package/dist/bigconsole/assistant/pageContext.js +6 -1
- package/dist/bigconsole/assistant/pageContext.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.d.ts.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.js +28 -27
- package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
- package/dist/bigconsole/constants/backendErrors.js +96 -0
- package/dist/bigconsole/constants/backendErrors.js.map +1 -0
- package/dist/bigconsole/hooks/useDataSinkAlerts.d.ts +23 -0
- package/dist/bigconsole/hooks/useDataSinkAlerts.d.ts.map +1 -1
- package/dist/bigconsole/hooks/useDataSinkAlerts.js +138 -113
- package/dist/bigconsole/hooks/useDataSinkAlerts.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkAlertsPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/DataSinkAlertsPage.js +53 -53
- package/dist/bigconsole/pages/DataSinkAlertsPage.js.map +1 -1
- package/dist/bigconsole/utils/backendError.d.ts +18 -0
- package/dist/bigconsole/utils/backendError.d.ts.map +1 -1
- package/dist/bigconsole/utils/backendError.js +44 -0
- package/dist/bigconsole/utils/backendError.js.map +1 -0
- package/dist/bigconsole/workflowOpen.d.ts.map +1 -1
- package/dist/bigconsole/workflowOpen.js +15 -14
- package/dist/bigconsole/workflowOpen.js.map +1 -1
- package/package.json +3 -3
|
@@ -8,36 +8,36 @@ import "../components/common/index.js";
|
|
|
8
8
|
import { BIGCONSOLE_PERMISSIONS as i } from "../../constants/permissions.js";
|
|
9
9
|
import { nativeConfirm as ee } from "../../utils/nativeBridge.js";
|
|
10
10
|
import { AlertRuleEditor as te } from "../components/datasink/AlertRuleEditor.js";
|
|
11
|
-
import { alertErrorMessage as a, useDataSinkAlerts as ne } from "../hooks/useDataSinkAlerts.js";
|
|
11
|
+
import { alertErrorMessage as a, describeAlertLoadFailure as o, useDataSinkAlerts as ne } from "../hooks/useDataSinkAlerts.js";
|
|
12
12
|
import { AlertExecutionHistory as re } from "../components/datasink/AlertExecutionHistory.js";
|
|
13
|
-
import { ALERT_VALIDATION_MESSAGES as
|
|
14
|
-
import { useEffect as
|
|
13
|
+
import { ALERT_VALIDATION_MESSAGES as s, alertDraft as c, alertDraftInput as l, validateAlertDraft as u } from "../utils/alertRules.js";
|
|
14
|
+
import { useEffect as ie, useRef as d, useState as f } from "react";
|
|
15
15
|
import { useParams as p } from "react-router";
|
|
16
|
-
import { AccessDenied as
|
|
17
|
-
import { usePermissions as
|
|
18
|
-
import { ArrowLeft as
|
|
19
|
-
import { Button as h, Switch as
|
|
20
|
-
import { Fragment as
|
|
21
|
-
import { useI18n as
|
|
16
|
+
import { AccessDenied as ae } from "@burdenoff/fe-libs/shared/components";
|
|
17
|
+
import { usePermissions as oe } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
18
|
+
import { ArrowLeft as se, Bell as ce, Loader2 as le, Plus as ue, RefreshCw as de, Trash2 as m } from "lucide-react";
|
|
19
|
+
import { Button as h, Switch as fe } from "@burdenoff/fe-libs/ui";
|
|
20
|
+
import { Fragment as pe, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
21
|
+
import { useI18n as me } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
22
22
|
//#region src/bigconsole/pages/DataSinkAlertsPage.tsx
|
|
23
23
|
function v() {
|
|
24
24
|
let { dataSinkId: e = "" } = p(), { currentUser: n, workspaceId: r } = t();
|
|
25
25
|
return /* @__PURE__ */ g(y, { dataSinkId: e }, `${n?.id ?? ""}|${r ?? ""}|${e}`);
|
|
26
26
|
}
|
|
27
27
|
function y({ dataSinkId: p }) {
|
|
28
|
-
let { t: v } =
|
|
29
|
-
|
|
28
|
+
let { t: v } = me(), y = e(), { currentUser: b, workspaceId: x } = t(), { hasPermission: S, isLoading: C } = oe(), w = S(i.DATASINK_READ), T = !C && S(i.DATASINK_UPDATE), E = ne(p, !C && w && !!x && !!b?.id), D = E.sink, O = D?.alerts ?? [], [k, he] = f(""), [A, j] = f(null), [M, N] = f(!1), P = d(!1), F = d(null), [I, L] = f(null), [R, z] = f(null), [B, V] = f(!1), [ge, H] = f(null), [U, W] = f(null), [_e, G] = f(0), K = d(0), q = d(0), J = A?.selection;
|
|
29
|
+
ie(() => {
|
|
30
30
|
J !== void 0 && document.getElementById("alert-name")?.focus();
|
|
31
31
|
}, [J]);
|
|
32
|
-
let
|
|
32
|
+
let Y = !!A && JSON.stringify(A.draft) !== A.original, X = async (e) => await ee({
|
|
33
33
|
title: v("bigconsole.alerts.confirm.title", "Confirm alert change"),
|
|
34
34
|
message: e,
|
|
35
35
|
okButtonTitle: v("bigconsole.alerts.confirm.continue", "Continue"),
|
|
36
36
|
cancelButtonTitle: v("bigconsole.alerts.rule.cancel", "Cancel")
|
|
37
|
-
}) ?? window.confirm(e),
|
|
38
|
-
if (M || !D || !await
|
|
37
|
+
}) ?? window.confirm(e), Z = () => !Y || X(v("bigconsole.alerts.confirm.discard", "Discard your unsaved rule changes?")), Q = async (e) => {
|
|
38
|
+
if (M || !D || !await Z()) return;
|
|
39
39
|
document.activeElement instanceof HTMLElement && (F.current = document.activeElement);
|
|
40
|
-
let t =
|
|
40
|
+
let t = c(e);
|
|
41
41
|
j({
|
|
42
42
|
draft: t,
|
|
43
43
|
original: JSON.stringify(t),
|
|
@@ -45,22 +45,22 @@ function y({ dataSinkId: p }) {
|
|
|
45
45
|
selection: ++q.current
|
|
46
46
|
}), K.current++, W(null), H(null), V(!1), L(null), z(null);
|
|
47
47
|
}, ve = async () => {
|
|
48
|
-
M || !await
|
|
49
|
-
},
|
|
48
|
+
M || !await Z() || (j(null), W(null), H(null), K.current++, V(!1), L(null), F.current?.isConnected && F.current.focus());
|
|
49
|
+
}, ye = async () => {
|
|
50
50
|
if (!A || !D || !T || P.current) return;
|
|
51
|
-
let e =
|
|
51
|
+
let e = u(A.draft, E.channels);
|
|
52
52
|
if (e) {
|
|
53
|
-
L(v(`bigconsole.alerts.validation.${e}`,
|
|
53
|
+
L(v(`bigconsole.alerts.validation.${e}`, s[e]));
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
P.current = !0, N(!0), L(null), z(null);
|
|
57
57
|
let t = new Set(O.map((e) => e.id));
|
|
58
58
|
try {
|
|
59
|
-
let e = await E.save(
|
|
59
|
+
let e = await E.save(l(A.draft), A.version);
|
|
60
60
|
if (!e) return;
|
|
61
61
|
let n = e.alerts?.find((e) => A.draft.id ? e.id === A.draft.id : !t.has(e.id));
|
|
62
62
|
if (n) {
|
|
63
|
-
let t =
|
|
63
|
+
let t = c(n);
|
|
64
64
|
j({
|
|
65
65
|
draft: t,
|
|
66
66
|
original: JSON.stringify(t),
|
|
@@ -74,26 +74,26 @@ function y({ dataSinkId: p }) {
|
|
|
74
74
|
} finally {
|
|
75
75
|
P.current = !1, N(!1);
|
|
76
76
|
}
|
|
77
|
-
},
|
|
77
|
+
}, be = async (e) => {
|
|
78
78
|
if (!D || !T || P.current) return;
|
|
79
79
|
let t = {
|
|
80
|
-
...
|
|
80
|
+
...c(e),
|
|
81
81
|
enabled: !e.enabled
|
|
82
|
-
}, n =
|
|
82
|
+
}, n = u(t, E.channels);
|
|
83
83
|
if (n) {
|
|
84
|
-
L(v(`bigconsole.alerts.validation.${n}`,
|
|
84
|
+
L(v(`bigconsole.alerts.validation.${n}`, s[n]));
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
87
|
P.current = !0, N(!0), L(null), z(null);
|
|
88
88
|
try {
|
|
89
|
-
await E.save(
|
|
89
|
+
await E.save(l(t), D.version) && (z(t.enabled ? v("bigconsole.alerts.feedback.enabled", "Alert rule enabled.") : v("bigconsole.alerts.feedback.disabled", "Alert rule disabled.")), G((e) => e + 1));
|
|
90
90
|
} catch (e) {
|
|
91
91
|
L(a(e));
|
|
92
92
|
} finally {
|
|
93
93
|
P.current = !1, N(!1);
|
|
94
94
|
}
|
|
95
|
-
},
|
|
96
|
-
if (!(!D || !T || P.current) && !(!await
|
|
95
|
+
}, xe = async (e) => {
|
|
96
|
+
if (!(!D || !T || P.current) && !(!await X(`${v("bigconsole.alerts.confirm.delete", "Delete alert rule")} “${e.name}”?`) || P.current)) {
|
|
97
97
|
P.current = !0, N(!0), L(null), z(null);
|
|
98
98
|
try {
|
|
99
99
|
await E.remove(e.id, D.version) && (A?.draft.id === e.id && j(null), z(v("bigconsole.alerts.feedback.deleted", "Alert rule deleted.")), G((e) => e + 1));
|
|
@@ -103,7 +103,7 @@ function y({ dataSinkId: p }) {
|
|
|
103
103
|
P.current = !1, N(!1);
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
},
|
|
106
|
+
}, Se = async () => {
|
|
107
107
|
if (!A || B || M) return;
|
|
108
108
|
let e = ++K.current, { condition: t, conditionType: n } = A.draft;
|
|
109
109
|
V(!0), H(null), W(null);
|
|
@@ -119,15 +119,15 @@ function y({ dataSinkId: p }) {
|
|
|
119
119
|
} finally {
|
|
120
120
|
K.current === e && V(!1);
|
|
121
121
|
}
|
|
122
|
-
},
|
|
123
|
-
if (!A?.draft.id || M || !await
|
|
122
|
+
}, Ce = async () => {
|
|
123
|
+
if (!A?.draft.id || M || !await Z()) return;
|
|
124
124
|
let e = await E.reload(), t = e?.alerts?.find((e) => e.id === A.draft.id);
|
|
125
125
|
if (!e) return;
|
|
126
126
|
if (!t) {
|
|
127
127
|
j(null), z(v("bigconsole.alerts.feedback.removedElsewhere", "This rule no longer exists."));
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
|
-
let n =
|
|
130
|
+
let n = c(t);
|
|
131
131
|
j({
|
|
132
132
|
draft: n,
|
|
133
133
|
original: JSON.stringify(n),
|
|
@@ -138,9 +138,9 @@ function y({ dataSinkId: p }) {
|
|
|
138
138
|
if (C || E.loading) return /* @__PURE__ */ _("div", {
|
|
139
139
|
role: "status",
|
|
140
140
|
className: "flex min-h-60 items-center justify-center p-card-padding",
|
|
141
|
-
children: [/* @__PURE__ */ g(
|
|
141
|
+
children: [/* @__PURE__ */ g(le, { className: "mr-2 h-5 w-5 animate-spin text-text-secondary" }), v("bigconsole.alerts.loading", "Loading alerts…")]
|
|
142
142
|
});
|
|
143
|
-
if (!w) return /* @__PURE__ */ g(
|
|
143
|
+
if (!w) return /* @__PURE__ */ g(ae, {
|
|
144
144
|
title: v("bigconsole.alerts.denied", "Access denied"),
|
|
145
145
|
description: v("bigconsole.alerts.deniedDescription", "You do not have permission to read this data sink.")
|
|
146
146
|
});
|
|
@@ -154,9 +154,9 @@ function y({ dataSinkId: p }) {
|
|
|
154
154
|
title: v("bigconsole.alerts.unavailable", "Alerts could not be loaded"),
|
|
155
155
|
headingLevel: 2,
|
|
156
156
|
tone: "danger",
|
|
157
|
-
description:
|
|
157
|
+
description: o(v, E),
|
|
158
158
|
actions: /* @__PURE__ */ g(h, {
|
|
159
|
-
onClick: () => void E.
|
|
159
|
+
onClick: () => void E.reloadSinkThenChannels(),
|
|
160
160
|
variant: "secondary",
|
|
161
161
|
children: v("bigconsole.alerts.retry", "Retry")
|
|
162
162
|
})
|
|
@@ -176,7 +176,7 @@ function y({ dataSinkId: p }) {
|
|
|
176
176
|
size: "sm",
|
|
177
177
|
onClick: () => y(`/datasinks/${p}`),
|
|
178
178
|
className: "mb-3",
|
|
179
|
-
children: [/* @__PURE__ */ g(
|
|
179
|
+
children: [/* @__PURE__ */ g(se, { className: "mr-2 h-4 w-4" }), v("bigconsole.alerts.back", "Back to data sink")]
|
|
180
180
|
}),
|
|
181
181
|
/* @__PURE__ */ _("h1", {
|
|
182
182
|
className: "break-words text-2xl font-bold text-text-primary",
|
|
@@ -198,7 +198,7 @@ function y({ dataSinkId: p }) {
|
|
|
198
198
|
E.reload(), E.reloadChannels(), G((e) => e + 1);
|
|
199
199
|
},
|
|
200
200
|
disabled: E.refreshing || M,
|
|
201
|
-
children: [/* @__PURE__ */ g(
|
|
201
|
+
children: [/* @__PURE__ */ g(de, { className: `mr-2 h-4 w-4 ${E.refreshing ? "animate-spin" : ""}` }), v("bigconsole.alerts.refresh", "Refresh alerts")]
|
|
202
202
|
})]
|
|
203
203
|
}),
|
|
204
204
|
R && /* @__PURE__ */ g("p", {
|
|
@@ -214,7 +214,7 @@ function y({ dataSinkId: p }) {
|
|
|
214
214
|
E.error && /* @__PURE__ */ g("p", {
|
|
215
215
|
role: "alert",
|
|
216
216
|
className: "mb-4 break-words text-sm text-status-error-text",
|
|
217
|
-
children: E
|
|
217
|
+
children: o(v, E)
|
|
218
218
|
}),
|
|
219
219
|
/* @__PURE__ */ _("div", {
|
|
220
220
|
className: "grid min-w-0 items-start gap-section-gap xl:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]",
|
|
@@ -223,12 +223,12 @@ function y({ dataSinkId: p }) {
|
|
|
223
223
|
children: [/* @__PURE__ */ _(r, {
|
|
224
224
|
title: v("bigconsole.alerts.list.title", "Alert rules"),
|
|
225
225
|
headingLevel: 2,
|
|
226
|
-
icon: /* @__PURE__ */ g(
|
|
226
|
+
icon: /* @__PURE__ */ g(ce, { className: "h-4 w-4" }),
|
|
227
227
|
actions: /* @__PURE__ */ _(h, {
|
|
228
228
|
size: "sm",
|
|
229
|
-
onClick: () => void
|
|
229
|
+
onClick: () => void Q(),
|
|
230
230
|
disabled: !T || M,
|
|
231
|
-
children: [/* @__PURE__ */ g(
|
|
231
|
+
children: [/* @__PURE__ */ g(ue, { className: "mr-2 h-4 w-4" }), v("bigconsole.alerts.list.new", "New alert rule")]
|
|
232
232
|
}),
|
|
233
233
|
children: [
|
|
234
234
|
/* @__PURE__ */ g("label", {
|
|
@@ -240,7 +240,7 @@ function y({ dataSinkId: p }) {
|
|
|
240
240
|
id: "alert-search",
|
|
241
241
|
type: "search",
|
|
242
242
|
value: k,
|
|
243
|
-
onChange: (e) =>
|
|
243
|
+
onChange: (e) => he(e.target.value),
|
|
244
244
|
placeholder: v("bigconsole.alerts.list.searchPlaceholder", "Search alerts…"),
|
|
245
245
|
className: `mb-4 w-full min-w-0 rounded-control border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary ${n}`
|
|
246
246
|
}),
|
|
@@ -300,7 +300,7 @@ function y({ dataSinkId: p }) {
|
|
|
300
300
|
children: [
|
|
301
301
|
/* @__PURE__ */ g("button", {
|
|
302
302
|
type: "button",
|
|
303
|
-
onClick: () => void
|
|
303
|
+
onClick: () => void Q(e),
|
|
304
304
|
disabled: M,
|
|
305
305
|
className: `break-words text-left font-medium text-text-primary underline-offset-4 hover:underline ${n}`,
|
|
306
306
|
children: e.name
|
|
@@ -332,9 +332,9 @@ function y({ dataSinkId: p }) {
|
|
|
332
332
|
}),
|
|
333
333
|
/* @__PURE__ */ g("td", {
|
|
334
334
|
className: "py-4 pr-2",
|
|
335
|
-
children: /* @__PURE__ */ g(
|
|
335
|
+
children: /* @__PURE__ */ g(fe, {
|
|
336
336
|
checked: e.enabled,
|
|
337
|
-
onCheckedChange: () => void
|
|
337
|
+
onCheckedChange: () => void be(e),
|
|
338
338
|
disabled: !T || M,
|
|
339
339
|
"aria-label": `${v("bigconsole.alerts.list.enabled", "Enabled")} · ${e.name}`
|
|
340
340
|
})
|
|
@@ -345,7 +345,7 @@ function y({ dataSinkId: p }) {
|
|
|
345
345
|
type: "button",
|
|
346
346
|
variant: "ghost",
|
|
347
347
|
size: "sm",
|
|
348
|
-
onClick: () => void
|
|
348
|
+
onClick: () => void xe(e),
|
|
349
349
|
disabled: !T || M,
|
|
350
350
|
"aria-label": `${v("bigconsole.alerts.confirm.delete", "Delete alert rule")} · ${e.name}`,
|
|
351
351
|
children: /* @__PURE__ */ g(m, { className: "h-4 w-4" })
|
|
@@ -373,11 +373,11 @@ function y({ dataSinkId: p }) {
|
|
|
373
373
|
owner: E.owner,
|
|
374
374
|
rules: O,
|
|
375
375
|
load: E.history,
|
|
376
|
-
refreshVersion:
|
|
376
|
+
refreshVersion: _e
|
|
377
377
|
})]
|
|
378
378
|
}), /* @__PURE__ */ g("div", {
|
|
379
379
|
className: "min-w-0",
|
|
380
|
-
children: A ? /* @__PURE__ */ _(
|
|
380
|
+
children: A ? /* @__PURE__ */ _(pe, { children: [/* @__PURE__ */ g(te, {
|
|
381
381
|
draft: A.draft,
|
|
382
382
|
channels: E.channels,
|
|
383
383
|
channelError: E.channelError,
|
|
@@ -385,7 +385,7 @@ function y({ dataSinkId: p }) {
|
|
|
385
385
|
pending: M,
|
|
386
386
|
previewing: B,
|
|
387
387
|
preview: U?.result ?? null,
|
|
388
|
-
previewError:
|
|
388
|
+
previewError: ge,
|
|
389
389
|
previewStale: !!U && (U.condition !== A.draft.condition || U.conditionType !== A.draft.conditionType || D.version > U.result.version),
|
|
390
390
|
error: I,
|
|
391
391
|
onChange: (e) => {
|
|
@@ -394,15 +394,15 @@ function y({ dataSinkId: p }) {
|
|
|
394
394
|
draft: e
|
|
395
395
|
});
|
|
396
396
|
},
|
|
397
|
-
onSave: () => void
|
|
397
|
+
onSave: () => void ye(),
|
|
398
398
|
onCancel: () => void ve(),
|
|
399
|
-
onPreview: () => void
|
|
399
|
+
onPreview: () => void Se(),
|
|
400
400
|
onReloadChannels: () => void E.reloadChannels()
|
|
401
401
|
}), A.draft.id && /* @__PURE__ */ g(h, {
|
|
402
402
|
type: "button",
|
|
403
403
|
variant: "ghost",
|
|
404
404
|
size: "sm",
|
|
405
|
-
onClick: () => void
|
|
405
|
+
onClick: () => void Ce(),
|
|
406
406
|
disabled: M || E.refreshing,
|
|
407
407
|
className: "mt-3",
|
|
408
408
|
children: v("bigconsole.alerts.rule.reloadSaved", "Reload saved rule")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataSinkAlertsPage.js","names":[],"sources":["../../../src/bigconsole/pages/DataSinkAlertsPage.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport { useParams } from 'react-router';\nimport { Button, Switch } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { ArrowLeft, Bell, Loader2, Plus, RefreshCw, Trash2 } from 'lucide-react';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\nimport { useBigConsole } from '../context';\nimport { useAppNavigate } from '../contexts';\nimport { Section, SECTION_FOCUS_RING } from '../components/common';\nimport { AlertRuleEditor } from '../components/datasink/AlertRuleEditor';\nimport { AlertExecutionHistory } from '../components/datasink/AlertExecutionHistory';\nimport { useDataSinkAlerts, alertErrorMessage, type AlertRule, type AlertPreview } from '../hooks/useDataSinkAlerts';\nimport {\n alertDraft,\n alertDraftInput,\n validateAlertDraft,\n ALERT_VALIDATION_MESSAGES,\n type AlertDraft,\n} from '../utils/alertRules';\nimport { nativeConfirm } from '../../utils/nativeBridge';\n\ninterface EditingRule {\n draft: AlertDraft;\n original: string;\n version: number;\n selection: number;\n}\ninterface PreviewResult {\n condition: string;\n conditionType: string;\n result: AlertPreview;\n}\n\nexport default function DataSinkAlertsPage() {\n const { dataSinkId = '' } = useParams<{ dataSinkId: string }>();\n const { currentUser, workspaceId } = useBigConsole();\n return (\n <DataSinkAlertsContent\n key={`${currentUser?.id ?? ''}|${workspaceId ?? ''}|${dataSinkId}`}\n dataSinkId={dataSinkId}\n />\n );\n}\n\nfunction DataSinkAlertsContent({ dataSinkId }: { dataSinkId: string }) {\n const { t } = useI18n();\n const navigate = useAppNavigate();\n const { currentUser, workspaceId } = useBigConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.DATASINK_READ);\n const canUpdate = !permissionsLoading && hasPermission(BIGCONSOLE_PERMISSIONS.DATASINK_UPDATE);\n const operations = useDataSinkAlerts(\n dataSinkId,\n !permissionsLoading && canRead && !!workspaceId && !!currentUser?.id\n );\n const sink = operations.sink;\n const rules = sink?.alerts ?? [];\n const [search, setSearch] = useState('');\n const [editing, setEditing] = useState<EditingRule | null>(null);\n const [pending, setPending] = useState(false);\n const mutationActive = useRef(false);\n const opener = useRef<HTMLElement | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [status, setStatus] = useState<string | null>(null);\n const [previewing, setPreviewing] = useState(false);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [preview, setPreview] = useState<PreviewResult | null>(null);\n const [historyVersion, setHistoryVersion] = useState(0);\n const previewRequest = useRef(0);\n const selectionCounter = useRef(0);\n const editingSelection = editing?.selection;\n useEffect(() => {\n if (editingSelection !== undefined) document.getElementById('alert-name')?.focus();\n }, [editingSelection]);\n const dirty = !!editing && JSON.stringify(editing.draft) !== editing.original;\n const confirm = async (message: string) => {\n const native = await nativeConfirm({\n title: t('bigconsole.alerts.confirm.title', 'Confirm alert change'),\n message,\n okButtonTitle: t('bigconsole.alerts.confirm.continue', 'Continue'),\n cancelButtonTitle: t('bigconsole.alerts.rule.cancel', 'Cancel'),\n });\n return native ?? window.confirm(message);\n };\n const discard = () => !dirty || confirm(t('bigconsole.alerts.confirm.discard', 'Discard your unsaved rule changes?'));\n const selectRule = async (rule?: AlertRule) => {\n if (pending || !sink || !(await discard())) return;\n if (document.activeElement instanceof HTMLElement) opener.current = document.activeElement;\n const draft = alertDraft(rule);\n setEditing({\n draft,\n original: JSON.stringify(draft),\n version: sink.version,\n selection: ++selectionCounter.current,\n });\n previewRequest.current++;\n setPreview(null);\n setPreviewError(null);\n setPreviewing(false);\n setError(null);\n setStatus(null);\n };\n const cancel = async () => {\n if (pending || !(await discard())) return;\n setEditing(null);\n setPreview(null);\n setPreviewError(null);\n previewRequest.current++;\n setPreviewing(false);\n setError(null);\n if (opener.current?.isConnected) opener.current.focus();\n };\n const save = async () => {\n if (!editing || !sink || !canUpdate || mutationActive.current) return;\n const invalid = validateAlertDraft(editing.draft, operations.channels);\n if (invalid) {\n setError(t(`bigconsole.alerts.validation.${invalid}`, ALERT_VALIDATION_MESSAGES[invalid]));\n return;\n }\n mutationActive.current = true;\n setPending(true);\n setError(null);\n setStatus(null);\n const knownIds = new Set(rules.map((rule) => rule.id));\n try {\n const saved = await operations.save(alertDraftInput(editing.draft), editing.version);\n if (!saved) return;\n const rule = saved.alerts?.find((item) =>\n editing.draft.id ? item.id === editing.draft.id : !knownIds.has(item.id)\n );\n if (rule) {\n const draft = alertDraft(rule);\n setEditing({ draft, original: JSON.stringify(draft), version: saved.version, selection: editing.selection });\n } else setEditing(null);\n setStatus(t('bigconsole.alerts.feedback.saved', 'Alert rule saved.'));\n setHistoryVersion((previous) => previous + 1);\n } catch (caught) {\n setError(alertErrorMessage(caught));\n } finally {\n mutationActive.current = false;\n setPending(false);\n }\n };\n const toggle = async (rule: AlertRule) => {\n if (!sink || !canUpdate || mutationActive.current) return;\n const draft = { ...alertDraft(rule), enabled: !rule.enabled };\n const invalid = validateAlertDraft(draft, operations.channels);\n if (invalid) {\n setError(t(`bigconsole.alerts.validation.${invalid}`, ALERT_VALIDATION_MESSAGES[invalid]));\n return;\n }\n mutationActive.current = true;\n setPending(true);\n setError(null);\n setStatus(null);\n try {\n const saved = await operations.save(alertDraftInput(draft), sink.version);\n if (saved) {\n setStatus(\n draft.enabled\n ? t('bigconsole.alerts.feedback.enabled', 'Alert rule enabled.')\n : t('bigconsole.alerts.feedback.disabled', 'Alert rule disabled.')\n );\n setHistoryVersion((previous) => previous + 1);\n }\n } catch (caught) {\n setError(alertErrorMessage(caught));\n } finally {\n mutationActive.current = false;\n setPending(false);\n }\n };\n const remove = async (rule: AlertRule) => {\n if (!sink || !canUpdate || mutationActive.current) return;\n const ok = await confirm(`${t('bigconsole.alerts.confirm.delete', 'Delete alert rule')} “${rule.name}”?`);\n if (!ok || mutationActive.current) return;\n mutationActive.current = true;\n setPending(true);\n setError(null);\n setStatus(null);\n try {\n const saved = await operations.remove(rule.id, sink.version);\n if (saved) {\n if (editing?.draft.id === rule.id) setEditing(null);\n setStatus(t('bigconsole.alerts.feedback.deleted', 'Alert rule deleted.'));\n setHistoryVersion((previous) => previous + 1);\n }\n } catch (caught) {\n setError(alertErrorMessage(caught));\n } finally {\n mutationActive.current = false;\n setPending(false);\n }\n };\n const runPreview = async () => {\n if (!editing || previewing || pending) return;\n const request = ++previewRequest.current;\n const { condition, conditionType } = editing.draft;\n setPreviewing(true);\n setPreviewError(null);\n setPreview(null);\n try {\n const result = await operations.preview(condition, conditionType);\n if (result && previewRequest.current === request) setPreview({ condition, conditionType, result });\n } catch (caught) {\n if (previewRequest.current === request) setPreviewError(alertErrorMessage(caught));\n } finally {\n if (previewRequest.current === request) setPreviewing(false);\n }\n };\n const reloadRule = async () => {\n if (!editing?.draft.id || pending || !(await discard())) return;\n const latest = await operations.reload();\n const rule = latest?.alerts?.find((item) => item.id === editing.draft.id);\n if (!latest) return;\n if (!rule) {\n setEditing(null);\n setStatus(t('bigconsole.alerts.feedback.removedElsewhere', 'This rule no longer exists.'));\n return;\n }\n const draft = alertDraft(rule);\n setEditing({\n draft,\n original: JSON.stringify(draft),\n version: latest.version,\n selection: ++selectionCounter.current,\n });\n setError(null);\n setPreview(null);\n };\n if (permissionsLoading || operations.loading)\n return (\n <div role=\"status\" className=\"flex min-h-60 items-center justify-center p-card-padding\">\n <Loader2 className=\"mr-2 h-5 w-5 animate-spin text-text-secondary\" />\n {t('bigconsole.alerts.loading', 'Loading alerts…')}\n </div>\n );\n if (!canRead)\n return (\n <AccessDenied\n title={t('bigconsole.alerts.denied', 'Access denied')}\n description={t('bigconsole.alerts.deniedDescription', 'You do not have permission to read this data sink.')}\n />\n );\n if (!workspaceId || !currentUser?.id)\n return (\n <p className=\"p-card-padding text-text-secondary\">\n {t('bigconsole.alerts.selectWorkspace', 'Select a workspace to view its alerts.')}\n </p>\n );\n if (!sink)\n return (\n <div className=\"p-card-padding\">\n <Section\n title={t('bigconsole.alerts.unavailable', 'Alerts could not be loaded')}\n headingLevel={2}\n tone=\"danger\"\n description={operations.error ?? t('bigconsole.alerts.notFound', 'Data sink not found.')}\n actions={\n <Button onClick={() => void operations.reload()} variant=\"secondary\">\n {t('bigconsole.alerts.retry', 'Retry')}\n </Button>\n }\n />\n </div>\n );\n const filtered = rules.filter((rule) =>\n `${rule.name} ${rule.condition}`.toLowerCase().includes(search.trim().toLowerCase())\n );\n return (\n <div className=\"min-w-0 p-card-padding\">\n <header className=\"mb-section-gap flex flex-col gap-form-gap sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigate(`/datasinks/${dataSinkId}`)} className=\"mb-3\">\n <ArrowLeft className=\"mr-2 h-4 w-4\" />\n {t('bigconsole.alerts.back', 'Back to data sink')}\n </Button>\n <h1 className=\"break-words text-2xl font-bold text-text-primary\">\n {t('bigconsole.alerts.title', 'Alerts')} · {sink.name || sink.key}\n </h1>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {t('bigconsole.alerts.purpose', 'Create and manage alert rules for this data sink.')}\n </p>\n </div>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => {\n void operations.reload();\n void operations.reloadChannels();\n setHistoryVersion((previous) => previous + 1);\n }}\n disabled={operations.refreshing || pending}\n >\n <RefreshCw className={`mr-2 h-4 w-4 ${operations.refreshing ? 'animate-spin' : ''}`} />\n {t('bigconsole.alerts.refresh', 'Refresh alerts')}\n </Button>\n </header>\n {status && (\n <p\n role=\"status\"\n className=\"mb-4 rounded-control bg-[var(--color-status-success-bgSubtle)] p-3 text-sm text-status-success-text\"\n >\n {status}\n </p>\n )}\n {error && !editing && (\n <p role=\"alert\" className=\"mb-4 break-words text-sm text-status-error-text\">\n {error}\n </p>\n )}\n {operations.error && (\n <p role=\"alert\" className=\"mb-4 break-words text-sm text-status-error-text\">\n {operations.error}\n </p>\n )}\n <div className=\"grid min-w-0 items-start gap-section-gap xl:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]\">\n <div className=\"min-w-0 space-y-section-gap\">\n <Section\n title={t('bigconsole.alerts.list.title', 'Alert rules')}\n headingLevel={2}\n icon={<Bell className=\"h-4 w-4\" />}\n actions={\n <Button size=\"sm\" onClick={() => void selectRule()} disabled={!canUpdate || pending}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {t('bigconsole.alerts.list.new', 'New alert rule')}\n </Button>\n }\n >\n <label htmlFor=\"alert-search\" className=\"sr-only\">\n {t('bigconsole.alerts.list.search', 'Search alerts')}\n </label>\n <input\n id=\"alert-search\"\n type=\"search\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n placeholder={t('bigconsole.alerts.list.searchPlaceholder', 'Search alerts…')}\n className={`mb-4 w-full min-w-0 rounded-control border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary ${SECTION_FOCUS_RING}`}\n />\n <div className=\"max-w-full overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <caption className=\"sr-only\">{t('bigconsole.alerts.list.caption', 'Rules for this data sink')}</caption>\n <thead>\n <tr className=\"border-b border-border-subtle text-left text-xs text-text-secondary\">\n <th scope=\"col\" className=\"pb-3 pr-2\">\n {t('bigconsole.alerts.rule.name', 'Name')}\n </th>\n <th scope=\"col\" className=\"hidden pb-3 pr-2 sm:table-cell\">\n {t('bigconsole.alerts.rule.severity', 'Severity')}\n </th>\n <th scope=\"col\" className=\"hidden pb-3 pr-2 lg:table-cell\">\n {t('bigconsole.alerts.rule.destinations', 'Delivery destinations')}\n </th>\n <th scope=\"col\" className=\"hidden pb-3 pr-2 md:table-cell\">\n {t('bigconsole.alerts.rule.throttle', 'Throttle')}\n </th>\n <th scope=\"col\" className=\"pb-3 pr-2\">\n {t('bigconsole.alerts.list.enabled', 'Enabled')}\n </th>\n <th scope=\"col\" className=\"pb-3\">\n <span className=\"sr-only\">{t('bigconsole.alerts.list.actions', 'Actions')}</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {filtered.map((rule) => (\n <tr key={rule.id} className=\"border-b border-border-subtle last:border-0\">\n <th scope=\"row\" className=\"max-w-64 py-4 pr-2 text-left font-normal\">\n <button\n type=\"button\"\n onClick={() => void selectRule(rule)}\n disabled={pending}\n className={`break-words text-left font-medium text-text-primary underline-offset-4 hover:underline ${SECTION_FOCUS_RING}`}\n >\n {rule.name}\n </button>\n <p className=\"mt-1 text-xs text-text-secondary sm:hidden\">\n {t(`bigconsole.alerts.severity.${rule.severity}`, rule.severity.toUpperCase())}\n </p>\n <p className=\"mt-1 text-xs text-text-muted md:hidden\">\n {rule.throttle?.enabled\n ? `${rule.throttle.maxAlertsPerWindow} / ${rule.throttle.windowMinutes} min`\n : t('bigconsole.alerts.list.noThrottle', 'No throttle')}\n </p>\n </th>\n <td className=\"hidden py-4 pr-2 sm:table-cell\">\n <span className=\"rounded-pill border border-border-subtle bg-bg-sunken px-2 py-1 text-xs text-text-primary\">\n {t(`bigconsole.alerts.severity.${rule.severity}`, rule.severity.toUpperCase())}\n </span>\n </td>\n <td className=\"hidden py-4 pr-2 text-xs text-text-secondary lg:table-cell\">\n {rule.deliveries.length\n ? [...new Set(rule.deliveries.map((item) => item.channel))].join(', ')\n : t('bigconsole.alerts.list.unconfigured', 'Not configured')}\n </td>\n <td className=\"hidden py-4 pr-2 text-xs text-text-secondary md:table-cell\">\n {rule.throttle?.enabled\n ? `${rule.throttle.maxAlertsPerWindow} / ${rule.throttle.windowMinutes} min`\n : t('bigconsole.alerts.list.noThrottle', 'No throttle')}\n </td>\n <td className=\"py-4 pr-2\">\n <Switch\n checked={rule.enabled}\n onCheckedChange={() => void toggle(rule)}\n disabled={!canUpdate || pending}\n aria-label={`${t('bigconsole.alerts.list.enabled', 'Enabled')} · ${rule.name}`}\n />\n </td>\n <td className=\"py-4\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void remove(rule)}\n disabled={!canUpdate || pending}\n aria-label={`${t('bigconsole.alerts.confirm.delete', 'Delete alert rule')} · ${rule.name}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {!filtered.length && (\n <p className=\"py-4 text-sm text-text-secondary\">\n {rules.length\n ? t('bigconsole.alerts.list.noMatches', 'No alerts match your search.')\n : t(\n 'bigconsole.alerts.list.empty',\n 'No alert rules yet. Create a disabled rule and preview its condition before enabling it.'\n )}\n </p>\n )}\n <p className=\"mt-3 text-xs text-text-muted\">\n {filtered.length} {t('bigconsole.alerts.list.count', 'rules shown')}\n </p>\n </Section>\n <AlertExecutionHistory\n owner={operations.owner}\n rules={rules}\n load={operations.history}\n refreshVersion={historyVersion}\n />\n </div>\n <div className=\"min-w-0\">\n {editing ? (\n <>\n <AlertRuleEditor\n draft={editing.draft}\n channels={operations.channels}\n channelError={operations.channelError}\n canUpdate={canUpdate}\n pending={pending}\n previewing={previewing}\n preview={preview?.result ?? null}\n previewError={previewError}\n previewStale={\n !!preview &&\n (preview.condition !== editing.draft.condition ||\n preview.conditionType !== editing.draft.conditionType ||\n sink.version > preview.result.version)\n }\n error={error}\n onChange={(draft) => {\n if (\n draft.condition !== editing.draft.condition ||\n draft.conditionType !== editing.draft.conditionType\n ) {\n previewRequest.current++;\n setPreviewError(null);\n setPreviewing(false);\n }\n setEditing({ ...editing, draft });\n }}\n onSave={() => void save()}\n onCancel={() => void cancel()}\n onPreview={() => void runPreview()}\n onReloadChannels={() => void operations.reloadChannels()}\n />\n {editing.draft.id && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void reloadRule()}\n disabled={pending || operations.refreshing}\n className=\"mt-3\"\n >\n {t('bigconsole.alerts.rule.reloadSaved', 'Reload saved rule')}\n </Button>\n )}\n </>\n ) : (\n <Section\n title={t('bigconsole.alerts.rule.title', 'Alert rule')}\n headingLevel={2}\n description={t(\n 'bigconsole.alerts.rule.select',\n 'Select a rule to inspect it, or create a new alert rule.'\n )}\n />\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataSinkAlertsPage.js","names":[],"sources":["../../../src/bigconsole/pages/DataSinkAlertsPage.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport { useParams } from 'react-router';\nimport { Button, Switch } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { ArrowLeft, Bell, Loader2, Plus, RefreshCw, Trash2 } from 'lucide-react';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\nimport { useBigConsole } from '../context';\nimport { useAppNavigate } from '../contexts';\nimport { Section, SECTION_FOCUS_RING } from '../components/common';\nimport { AlertRuleEditor } from '../components/datasink/AlertRuleEditor';\nimport { AlertExecutionHistory } from '../components/datasink/AlertExecutionHistory';\nimport {\n useDataSinkAlerts,\n alertErrorMessage,\n describeAlertLoadFailure,\n type AlertRule,\n type AlertPreview,\n} from '../hooks/useDataSinkAlerts';\nimport {\n alertDraft,\n alertDraftInput,\n validateAlertDraft,\n ALERT_VALIDATION_MESSAGES,\n type AlertDraft,\n} from '../utils/alertRules';\nimport { nativeConfirm } from '../../utils/nativeBridge';\n\ninterface EditingRule {\n draft: AlertDraft;\n original: string;\n version: number;\n selection: number;\n}\ninterface PreviewResult {\n condition: string;\n conditionType: string;\n result: AlertPreview;\n}\n\nexport default function DataSinkAlertsPage() {\n const { dataSinkId = '' } = useParams<{ dataSinkId: string }>();\n const { currentUser, workspaceId } = useBigConsole();\n return (\n <DataSinkAlertsContent\n key={`${currentUser?.id ?? ''}|${workspaceId ?? ''}|${dataSinkId}`}\n dataSinkId={dataSinkId}\n />\n );\n}\n\nfunction DataSinkAlertsContent({ dataSinkId }: { dataSinkId: string }) {\n const { t } = useI18n();\n const navigate = useAppNavigate();\n const { currentUser, workspaceId } = useBigConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.DATASINK_READ);\n const canUpdate = !permissionsLoading && hasPermission(BIGCONSOLE_PERMISSIONS.DATASINK_UPDATE);\n const operations = useDataSinkAlerts(\n dataSinkId,\n !permissionsLoading && canRead && !!workspaceId && !!currentUser?.id\n );\n const sink = operations.sink;\n const rules = sink?.alerts ?? [];\n const [search, setSearch] = useState('');\n const [editing, setEditing] = useState<EditingRule | null>(null);\n const [pending, setPending] = useState(false);\n const mutationActive = useRef(false);\n const opener = useRef<HTMLElement | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [status, setStatus] = useState<string | null>(null);\n const [previewing, setPreviewing] = useState(false);\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [preview, setPreview] = useState<PreviewResult | null>(null);\n const [historyVersion, setHistoryVersion] = useState(0);\n const previewRequest = useRef(0);\n const selectionCounter = useRef(0);\n const editingSelection = editing?.selection;\n useEffect(() => {\n if (editingSelection !== undefined) document.getElementById('alert-name')?.focus();\n }, [editingSelection]);\n const dirty = !!editing && JSON.stringify(editing.draft) !== editing.original;\n const confirm = async (message: string) => {\n const native = await nativeConfirm({\n title: t('bigconsole.alerts.confirm.title', 'Confirm alert change'),\n message,\n okButtonTitle: t('bigconsole.alerts.confirm.continue', 'Continue'),\n cancelButtonTitle: t('bigconsole.alerts.rule.cancel', 'Cancel'),\n });\n return native ?? window.confirm(message);\n };\n const discard = () => !dirty || confirm(t('bigconsole.alerts.confirm.discard', 'Discard your unsaved rule changes?'));\n const selectRule = async (rule?: AlertRule) => {\n if (pending || !sink || !(await discard())) return;\n if (document.activeElement instanceof HTMLElement) opener.current = document.activeElement;\n const draft = alertDraft(rule);\n setEditing({\n draft,\n original: JSON.stringify(draft),\n version: sink.version,\n selection: ++selectionCounter.current,\n });\n previewRequest.current++;\n setPreview(null);\n setPreviewError(null);\n setPreviewing(false);\n setError(null);\n setStatus(null);\n };\n const cancel = async () => {\n if (pending || !(await discard())) return;\n setEditing(null);\n setPreview(null);\n setPreviewError(null);\n previewRequest.current++;\n setPreviewing(false);\n setError(null);\n if (opener.current?.isConnected) opener.current.focus();\n };\n const save = async () => {\n if (!editing || !sink || !canUpdate || mutationActive.current) return;\n const invalid = validateAlertDraft(editing.draft, operations.channels);\n if (invalid) {\n setError(t(`bigconsole.alerts.validation.${invalid}`, ALERT_VALIDATION_MESSAGES[invalid]));\n return;\n }\n mutationActive.current = true;\n setPending(true);\n setError(null);\n setStatus(null);\n const knownIds = new Set(rules.map((rule) => rule.id));\n try {\n const saved = await operations.save(alertDraftInput(editing.draft), editing.version);\n if (!saved) return;\n const rule = saved.alerts?.find((item) =>\n editing.draft.id ? item.id === editing.draft.id : !knownIds.has(item.id)\n );\n if (rule) {\n const draft = alertDraft(rule);\n setEditing({ draft, original: JSON.stringify(draft), version: saved.version, selection: editing.selection });\n } else setEditing(null);\n setStatus(t('bigconsole.alerts.feedback.saved', 'Alert rule saved.'));\n setHistoryVersion((previous) => previous + 1);\n } catch (caught) {\n setError(alertErrorMessage(caught));\n } finally {\n mutationActive.current = false;\n setPending(false);\n }\n };\n const toggle = async (rule: AlertRule) => {\n if (!sink || !canUpdate || mutationActive.current) return;\n const draft = { ...alertDraft(rule), enabled: !rule.enabled };\n const invalid = validateAlertDraft(draft, operations.channels);\n if (invalid) {\n setError(t(`bigconsole.alerts.validation.${invalid}`, ALERT_VALIDATION_MESSAGES[invalid]));\n return;\n }\n mutationActive.current = true;\n setPending(true);\n setError(null);\n setStatus(null);\n try {\n const saved = await operations.save(alertDraftInput(draft), sink.version);\n if (saved) {\n setStatus(\n draft.enabled\n ? t('bigconsole.alerts.feedback.enabled', 'Alert rule enabled.')\n : t('bigconsole.alerts.feedback.disabled', 'Alert rule disabled.')\n );\n setHistoryVersion((previous) => previous + 1);\n }\n } catch (caught) {\n setError(alertErrorMessage(caught));\n } finally {\n mutationActive.current = false;\n setPending(false);\n }\n };\n const remove = async (rule: AlertRule) => {\n if (!sink || !canUpdate || mutationActive.current) return;\n const ok = await confirm(`${t('bigconsole.alerts.confirm.delete', 'Delete alert rule')} “${rule.name}”?`);\n if (!ok || mutationActive.current) return;\n mutationActive.current = true;\n setPending(true);\n setError(null);\n setStatus(null);\n try {\n const saved = await operations.remove(rule.id, sink.version);\n if (saved) {\n if (editing?.draft.id === rule.id) setEditing(null);\n setStatus(t('bigconsole.alerts.feedback.deleted', 'Alert rule deleted.'));\n setHistoryVersion((previous) => previous + 1);\n }\n } catch (caught) {\n setError(alertErrorMessage(caught));\n } finally {\n mutationActive.current = false;\n setPending(false);\n }\n };\n const runPreview = async () => {\n if (!editing || previewing || pending) return;\n const request = ++previewRequest.current;\n const { condition, conditionType } = editing.draft;\n setPreviewing(true);\n setPreviewError(null);\n setPreview(null);\n try {\n const result = await operations.preview(condition, conditionType);\n if (result && previewRequest.current === request) setPreview({ condition, conditionType, result });\n } catch (caught) {\n if (previewRequest.current === request) setPreviewError(alertErrorMessage(caught));\n } finally {\n if (previewRequest.current === request) setPreviewing(false);\n }\n };\n const reloadRule = async () => {\n if (!editing?.draft.id || pending || !(await discard())) return;\n const latest = await operations.reload();\n const rule = latest?.alerts?.find((item) => item.id === editing.draft.id);\n if (!latest) return;\n if (!rule) {\n setEditing(null);\n setStatus(t('bigconsole.alerts.feedback.removedElsewhere', 'This rule no longer exists.'));\n return;\n }\n const draft = alertDraft(rule);\n setEditing({\n draft,\n original: JSON.stringify(draft),\n version: latest.version,\n selection: ++selectionCounter.current,\n });\n setError(null);\n setPreview(null);\n };\n if (permissionsLoading || operations.loading)\n return (\n <div role=\"status\" className=\"flex min-h-60 items-center justify-center p-card-padding\">\n <Loader2 className=\"mr-2 h-5 w-5 animate-spin text-text-secondary\" />\n {t('bigconsole.alerts.loading', 'Loading alerts…')}\n </div>\n );\n if (!canRead)\n return (\n <AccessDenied\n title={t('bigconsole.alerts.denied', 'Access denied')}\n description={t('bigconsole.alerts.deniedDescription', 'You do not have permission to read this data sink.')}\n />\n );\n if (!workspaceId || !currentUser?.id)\n return (\n <p className=\"p-card-padding text-text-secondary\">\n {t('bigconsole.alerts.selectWorkspace', 'Select a workspace to view its alerts.')}\n </p>\n );\n if (!sink)\n return (\n <div className=\"p-card-padding\">\n <Section\n title={t('bigconsole.alerts.unavailable', 'Alerts could not be loaded')}\n headingLevel={2}\n tone=\"danger\"\n description={describeAlertLoadFailure(t, operations)}\n actions={\n <Button onClick={() => void operations.reloadSinkThenChannels()} variant=\"secondary\">\n {t('bigconsole.alerts.retry', 'Retry')}\n </Button>\n }\n />\n </div>\n );\n const filtered = rules.filter((rule) =>\n `${rule.name} ${rule.condition}`.toLowerCase().includes(search.trim().toLowerCase())\n );\n return (\n <div className=\"min-w-0 p-card-padding\">\n <header className=\"mb-section-gap flex flex-col gap-form-gap sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigate(`/datasinks/${dataSinkId}`)} className=\"mb-3\">\n <ArrowLeft className=\"mr-2 h-4 w-4\" />\n {t('bigconsole.alerts.back', 'Back to data sink')}\n </Button>\n <h1 className=\"break-words text-2xl font-bold text-text-primary\">\n {t('bigconsole.alerts.title', 'Alerts')} · {sink.name || sink.key}\n </h1>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {t('bigconsole.alerts.purpose', 'Create and manage alert rules for this data sink.')}\n </p>\n </div>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => {\n void operations.reload();\n void operations.reloadChannels();\n setHistoryVersion((previous) => previous + 1);\n }}\n disabled={operations.refreshing || pending}\n >\n <RefreshCw className={`mr-2 h-4 w-4 ${operations.refreshing ? 'animate-spin' : ''}`} />\n {t('bigconsole.alerts.refresh', 'Refresh alerts')}\n </Button>\n </header>\n {status && (\n <p\n role=\"status\"\n className=\"mb-4 rounded-control bg-[var(--color-status-success-bgSubtle)] p-3 text-sm text-status-success-text\"\n >\n {status}\n </p>\n )}\n {error && !editing && (\n <p role=\"alert\" className=\"mb-4 break-words text-sm text-status-error-text\">\n {error}\n </p>\n )}\n {operations.error && (\n <p role=\"alert\" className=\"mb-4 break-words text-sm text-status-error-text\">\n {describeAlertLoadFailure(t, operations)}\n </p>\n )}\n <div className=\"grid min-w-0 items-start gap-section-gap xl:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]\">\n <div className=\"min-w-0 space-y-section-gap\">\n <Section\n title={t('bigconsole.alerts.list.title', 'Alert rules')}\n headingLevel={2}\n icon={<Bell className=\"h-4 w-4\" />}\n actions={\n <Button size=\"sm\" onClick={() => void selectRule()} disabled={!canUpdate || pending}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {t('bigconsole.alerts.list.new', 'New alert rule')}\n </Button>\n }\n >\n <label htmlFor=\"alert-search\" className=\"sr-only\">\n {t('bigconsole.alerts.list.search', 'Search alerts')}\n </label>\n <input\n id=\"alert-search\"\n type=\"search\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n placeholder={t('bigconsole.alerts.list.searchPlaceholder', 'Search alerts…')}\n className={`mb-4 w-full min-w-0 rounded-control border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary ${SECTION_FOCUS_RING}`}\n />\n <div className=\"max-w-full overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <caption className=\"sr-only\">{t('bigconsole.alerts.list.caption', 'Rules for this data sink')}</caption>\n <thead>\n <tr className=\"border-b border-border-subtle text-left text-xs text-text-secondary\">\n <th scope=\"col\" className=\"pb-3 pr-2\">\n {t('bigconsole.alerts.rule.name', 'Name')}\n </th>\n <th scope=\"col\" className=\"hidden pb-3 pr-2 sm:table-cell\">\n {t('bigconsole.alerts.rule.severity', 'Severity')}\n </th>\n <th scope=\"col\" className=\"hidden pb-3 pr-2 lg:table-cell\">\n {t('bigconsole.alerts.rule.destinations', 'Delivery destinations')}\n </th>\n <th scope=\"col\" className=\"hidden pb-3 pr-2 md:table-cell\">\n {t('bigconsole.alerts.rule.throttle', 'Throttle')}\n </th>\n <th scope=\"col\" className=\"pb-3 pr-2\">\n {t('bigconsole.alerts.list.enabled', 'Enabled')}\n </th>\n <th scope=\"col\" className=\"pb-3\">\n <span className=\"sr-only\">{t('bigconsole.alerts.list.actions', 'Actions')}</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {filtered.map((rule) => (\n <tr key={rule.id} className=\"border-b border-border-subtle last:border-0\">\n <th scope=\"row\" className=\"max-w-64 py-4 pr-2 text-left font-normal\">\n <button\n type=\"button\"\n onClick={() => void selectRule(rule)}\n disabled={pending}\n className={`break-words text-left font-medium text-text-primary underline-offset-4 hover:underline ${SECTION_FOCUS_RING}`}\n >\n {rule.name}\n </button>\n <p className=\"mt-1 text-xs text-text-secondary sm:hidden\">\n {t(`bigconsole.alerts.severity.${rule.severity}`, rule.severity.toUpperCase())}\n </p>\n <p className=\"mt-1 text-xs text-text-muted md:hidden\">\n {rule.throttle?.enabled\n ? `${rule.throttle.maxAlertsPerWindow} / ${rule.throttle.windowMinutes} min`\n : t('bigconsole.alerts.list.noThrottle', 'No throttle')}\n </p>\n </th>\n <td className=\"hidden py-4 pr-2 sm:table-cell\">\n <span className=\"rounded-pill border border-border-subtle bg-bg-sunken px-2 py-1 text-xs text-text-primary\">\n {t(`bigconsole.alerts.severity.${rule.severity}`, rule.severity.toUpperCase())}\n </span>\n </td>\n <td className=\"hidden py-4 pr-2 text-xs text-text-secondary lg:table-cell\">\n {rule.deliveries.length\n ? [...new Set(rule.deliveries.map((item) => item.channel))].join(', ')\n : t('bigconsole.alerts.list.unconfigured', 'Not configured')}\n </td>\n <td className=\"hidden py-4 pr-2 text-xs text-text-secondary md:table-cell\">\n {rule.throttle?.enabled\n ? `${rule.throttle.maxAlertsPerWindow} / ${rule.throttle.windowMinutes} min`\n : t('bigconsole.alerts.list.noThrottle', 'No throttle')}\n </td>\n <td className=\"py-4 pr-2\">\n <Switch\n checked={rule.enabled}\n onCheckedChange={() => void toggle(rule)}\n disabled={!canUpdate || pending}\n aria-label={`${t('bigconsole.alerts.list.enabled', 'Enabled')} · ${rule.name}`}\n />\n </td>\n <td className=\"py-4\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void remove(rule)}\n disabled={!canUpdate || pending}\n aria-label={`${t('bigconsole.alerts.confirm.delete', 'Delete alert rule')} · ${rule.name}`}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {!filtered.length && (\n <p className=\"py-4 text-sm text-text-secondary\">\n {rules.length\n ? t('bigconsole.alerts.list.noMatches', 'No alerts match your search.')\n : t(\n 'bigconsole.alerts.list.empty',\n 'No alert rules yet. Create a disabled rule and preview its condition before enabling it.'\n )}\n </p>\n )}\n <p className=\"mt-3 text-xs text-text-muted\">\n {filtered.length} {t('bigconsole.alerts.list.count', 'rules shown')}\n </p>\n </Section>\n <AlertExecutionHistory\n owner={operations.owner}\n rules={rules}\n load={operations.history}\n refreshVersion={historyVersion}\n />\n </div>\n <div className=\"min-w-0\">\n {editing ? (\n <>\n <AlertRuleEditor\n draft={editing.draft}\n channels={operations.channels}\n channelError={operations.channelError}\n canUpdate={canUpdate}\n pending={pending}\n previewing={previewing}\n preview={preview?.result ?? null}\n previewError={previewError}\n previewStale={\n !!preview &&\n (preview.condition !== editing.draft.condition ||\n preview.conditionType !== editing.draft.conditionType ||\n sink.version > preview.result.version)\n }\n error={error}\n onChange={(draft) => {\n if (\n draft.condition !== editing.draft.condition ||\n draft.conditionType !== editing.draft.conditionType\n ) {\n previewRequest.current++;\n setPreviewError(null);\n setPreviewing(false);\n }\n setEditing({ ...editing, draft });\n }}\n onSave={() => void save()}\n onCancel={() => void cancel()}\n onPreview={() => void runPreview()}\n onReloadChannels={() => void operations.reloadChannels()}\n />\n {editing.draft.id && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void reloadRule()}\n disabled={pending || operations.refreshing}\n className=\"mt-3\"\n >\n {t('bigconsole.alerts.rule.reloadSaved', 'Reload saved rule')}\n </Button>\n )}\n </>\n ) : (\n <Section\n title={t('bigconsole.alerts.rule.title', 'Alert rule')}\n headingLevel={2}\n description={t(\n 'bigconsole.alerts.rule.select',\n 'Select a rule to inspect it, or create a new alert rule.'\n )}\n />\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
type TranslateFn = (key: string, fallback: string) => string;
|
|
2
2
|
export declare function resolveBackendErrorMessage(t: TranslateFn, error: unknown): string;
|
|
3
|
+
/**
|
|
4
|
+
* Every GraphQL `extensions.code` reachable from an error, in the shapes the
|
|
5
|
+
* fe-libs Apollo 4 client hands back:
|
|
6
|
+
*
|
|
7
|
+
* - `CombinedGraphQLErrors` (a `query()` resolved with `{ error }` under
|
|
8
|
+
* errorPolicy "all", or thrown under "none"): `error.errors[]`;
|
|
9
|
+
* - legacy Apollo 3 errors: `error.graphQLErrors[]`;
|
|
10
|
+
* - `ServerError` for a non-2xx answer sent as `application/json` — a subgraph
|
|
11
|
+
* that maps NOT_FOUND to HTTP 404 lands here, with the GraphQL body only in
|
|
12
|
+
* `error.bodyText` (Apollo 3 kept it parsed on `error.result`);
|
|
13
|
+
* - a bare GraphQL error: `error.extensions.code`;
|
|
14
|
+
* - any of those wrapped in `cause` / `error`.
|
|
15
|
+
*
|
|
16
|
+
* Returns `[]` when none is found. Never throws.
|
|
17
|
+
*/
|
|
18
|
+
export declare function graphQLErrorCodes(error: unknown): string[];
|
|
19
|
+
/** True when any GraphQL error reachable from `error` carries one of `codes`. */
|
|
20
|
+
export declare function hasGraphQLErrorCode(error: unknown, codes: ReadonlySet<string>): boolean;
|
|
3
21
|
export {};
|
|
4
22
|
//# sourceMappingURL=backendError.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backendError.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/utils/backendError.ts"],"names":[],"mappings":"AAqBA,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAgD7D,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAKjF"}
|
|
1
|
+
{"version":3,"file":"backendError.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/utils/backendError.ts"],"names":[],"mappings":"AAqBA,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAgD7D,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAKjF;AAuBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAiB1D;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAEvF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/bigconsole/utils/backendError.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return typeof e == "object" && !!e;
|
|
4
|
+
}
|
|
5
|
+
var t = 4;
|
|
6
|
+
function n(t) {
|
|
7
|
+
return Array.isArray(t) ? t.flatMap((t) => {
|
|
8
|
+
let n = e(t) && e(t.extensions) ? t.extensions.code : void 0;
|
|
9
|
+
return typeof n == "string" && n.length > 0 ? [n] : [];
|
|
10
|
+
}) : [];
|
|
11
|
+
}
|
|
12
|
+
function r(t) {
|
|
13
|
+
if (typeof t != "string" || t.length === 0) return [];
|
|
14
|
+
try {
|
|
15
|
+
let r = JSON.parse(t);
|
|
16
|
+
return e(r) ? n(r.errors) : [];
|
|
17
|
+
} catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function i(i) {
|
|
22
|
+
let a = /* @__PURE__ */ new Set(), o = (i, s) => {
|
|
23
|
+
if (!e(i) || s > t || a.has(i)) return [];
|
|
24
|
+
a.add(i);
|
|
25
|
+
let c = e(i.extensions) ? i.extensions.code : void 0;
|
|
26
|
+
return [
|
|
27
|
+
...n(i.errors),
|
|
28
|
+
...n(i.graphQLErrors),
|
|
29
|
+
...e(i.result) ? n(i.result.errors) : [],
|
|
30
|
+
...r(i.bodyText),
|
|
31
|
+
...typeof c == "string" && c.length > 0 ? [c] : [],
|
|
32
|
+
...o(i.cause, s + 1),
|
|
33
|
+
...o(i.error, s + 1)
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
return [...new Set(o(i, 0))];
|
|
37
|
+
}
|
|
38
|
+
function a(e, t) {
|
|
39
|
+
return i(e).some((e) => t.has(e));
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { i as graphQLErrorCodes, a as hasGraphQLErrorCode };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=backendError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backendError.js","names":[],"sources":["../../../src/bigconsole/utils/backendError.ts"],"sourcesContent":["/**\n * Localize a backend error by its stable `extensions.code`.\n *\n * The wspace-bigconsole-svc backend throws `BigConsoleError(code, message)` so\n * every failure carries a stable `extensions.code`. This helper pulls that code\n * off whatever error shape Apollo/graphql hands us and resolves it to a\n * localized string: `t('bigconsole.errors.<CODE>', <fallback>)`.\n *\n * Fallback order for the second `t()` arg (shown if the active locale hasn't\n * translated the code):\n * 1. our generic English from BACKEND_ERROR_MESSAGES[code]\n * 2. the raw server message (already interpolated with ids)\n * 3. a generic \"Something went wrong.\" catch-all\n *\n * Usage:\n * const { t } = useI18n();\n * try { await doThing(); }\n * catch (e) { toast.error(resolveBackendErrorMessage(t, e)); }\n */\nimport { BACKEND_ERROR_MESSAGES } from '../constants/backendErrors';\n\ntype TranslateFn = (key: string, fallback: string) => string;\n\ninterface CodedExtensions {\n code?: unknown;\n}\ninterface GraphQLErrorLike {\n message?: unknown;\n extensions?: CodedExtensions;\n}\ninterface ApolloErrorLike {\n message?: unknown;\n graphQLErrors?: GraphQLErrorLike[];\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null;\n}\n\n/** Extract the first `extensions.code` and a raw message from any error shape. */\nfunction extract(error: unknown): { code?: string; message?: string } {\n if (!isObject(error)) {\n return typeof error === 'string' ? { message: error } : {};\n }\n\n // Apollo: error.graphQLErrors[].extensions.code\n const apollo = error as ApolloErrorLike;\n const gqlErrors = Array.isArray(apollo.graphQLErrors) ? apollo.graphQLErrors : [];\n for (const gqlError of gqlErrors) {\n const code = gqlError?.extensions?.code;\n if (typeof code === 'string' && code.length > 0) {\n return {\n code,\n message: typeof gqlError.message === 'string' ? gqlError.message : undefined,\n };\n }\n }\n\n // Bare GraphQLError / BigConsoleError: error.extensions.code\n const direct = error as GraphQLErrorLike;\n const directCode = direct.extensions?.code;\n const message = typeof direct.message === 'string' ? direct.message : undefined;\n if (typeof directCode === 'string' && directCode.length > 0) {\n return { code: directCode, message };\n }\n\n return { message };\n}\n\nexport function resolveBackendErrorMessage(t: TranslateFn, error: unknown): string {\n const { code, message } = extract(error);\n const fallback = (code ? BACKEND_ERROR_MESSAGES[code] : undefined) ?? message ?? 'Something went wrong.';\n if (!code) return fallback;\n return t(`bigconsole.errors.${code}`, fallback);\n}\n\n/** How deep {@link graphQLErrorCodes} follows `cause` / `error` wrappers. */\nconst MAX_ERROR_DEPTH = 4;\n\nfunction codesFromErrorList(list: unknown): string[] {\n if (!Array.isArray(list)) return [];\n return list.flatMap((entry) => {\n const code = isObject(entry) && isObject(entry.extensions) ? entry.extensions.code : undefined;\n return typeof code === 'string' && code.length > 0 ? [code] : [];\n });\n}\n\nfunction codesFromBodyText(bodyText: unknown): string[] {\n if (typeof bodyText !== 'string' || bodyText.length === 0) return [];\n try {\n const parsed: unknown = JSON.parse(bodyText);\n return isObject(parsed) ? codesFromErrorList(parsed.errors) : [];\n } catch {\n return [];\n }\n}\n\n/**\n * Every GraphQL `extensions.code` reachable from an error, in the shapes the\n * fe-libs Apollo 4 client hands back:\n *\n * - `CombinedGraphQLErrors` (a `query()` resolved with `{ error }` under\n * errorPolicy \"all\", or thrown under \"none\"): `error.errors[]`;\n * - legacy Apollo 3 errors: `error.graphQLErrors[]`;\n * - `ServerError` for a non-2xx answer sent as `application/json` — a subgraph\n * that maps NOT_FOUND to HTTP 404 lands here, with the GraphQL body only in\n * `error.bodyText` (Apollo 3 kept it parsed on `error.result`);\n * - a bare GraphQL error: `error.extensions.code`;\n * - any of those wrapped in `cause` / `error`.\n *\n * Returns `[]` when none is found. Never throws.\n */\nexport function graphQLErrorCodes(error: unknown): string[] {\n const seen = new Set<unknown>();\n const visit = (value: unknown, depth: number): string[] => {\n if (!isObject(value) || depth > MAX_ERROR_DEPTH || seen.has(value)) return [];\n seen.add(value);\n const direct = isObject(value.extensions) ? value.extensions.code : undefined;\n return [\n ...codesFromErrorList(value.errors),\n ...codesFromErrorList(value.graphQLErrors),\n ...(isObject(value.result) ? codesFromErrorList(value.result.errors) : []),\n ...codesFromBodyText(value.bodyText),\n ...(typeof direct === 'string' && direct.length > 0 ? [direct] : []),\n ...visit(value.cause, depth + 1),\n ...visit(value.error, depth + 1),\n ];\n };\n return [...new Set(visit(error, 0))];\n}\n\n/** True when any GraphQL error reachable from `error` carries one of `codes`. */\nexport function hasGraphQLErrorCode(error: unknown, codes: ReadonlySet<string>): boolean {\n return graphQLErrorCodes(error).some((code) => codes.has(code));\n}\n"],"mappings":";AAmCA,SAAS,EAAS,GAA0C;AAC1D,QAAO,OAAO,KAAM,cAAY;;AAyClC,IAAM,IAAkB;AAExB,SAAS,EAAmB,GAAyB;AAEnD,QADK,MAAM,QAAQ,EAAK,GACjB,EAAK,SAAS,MAAU;EAC7B,IAAM,IAAO,EAAS,EAAM,IAAI,EAAS,EAAM,WAAW,GAAG,EAAM,WAAW,OAAO,KAAA;AACrF,SAAO,OAAO,KAAS,YAAY,EAAK,SAAS,IAAI,CAAC,EAAK,GAAG,EAAE;GAChE,GAJ+B,EAAE;;AAOrC,SAAS,EAAkB,GAA6B;AACtD,KAAI,OAAO,KAAa,YAAY,EAAS,WAAW,EAAG,QAAO,EAAE;AACpE,KAAI;EACF,IAAM,IAAkB,KAAK,MAAM,EAAS;AAC5C,SAAO,EAAS,EAAO,GAAG,EAAmB,EAAO,OAAO,GAAG,EAAE;SAC1D;AACN,SAAO,EAAE;;;AAmBb,SAAgB,EAAkB,GAA0B;CAC1D,IAAM,oBAAO,IAAI,KAAc,EACzB,KAAS,GAAgB,MAA4B;AACzD,MAAI,CAAC,EAAS,EAAM,IAAI,IAAQ,KAAmB,EAAK,IAAI,EAAM,CAAE,QAAO,EAAE;AAC7E,IAAK,IAAI,EAAM;EACf,IAAM,IAAS,EAAS,EAAM,WAAW,GAAG,EAAM,WAAW,OAAO,KAAA;AACpE,SAAO;GACL,GAAG,EAAmB,EAAM,OAAO;GACnC,GAAG,EAAmB,EAAM,cAAc;GAC1C,GAAI,EAAS,EAAM,OAAO,GAAG,EAAmB,EAAM,OAAO,OAAO,GAAG,EAAE;GACzE,GAAG,EAAkB,EAAM,SAAS;GACpC,GAAI,OAAO,KAAW,YAAY,EAAO,SAAS,IAAI,CAAC,EAAO,GAAG,EAAE;GACnE,GAAG,EAAM,EAAM,OAAO,IAAQ,EAAE;GAChC,GAAG,EAAM,EAAM,OAAO,IAAQ,EAAE;GACjC;;AAEH,QAAO,CAAC,GAAG,IAAI,IAAI,EAAM,GAAO,EAAE,CAAC,CAAC;;AAItC,SAAgB,EAAoB,GAAgB,GAAqC;AACvF,QAAO,EAAkB,EAAM,CAAC,MAAM,MAAS,EAAM,IAAI,EAAK,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflowOpen.d.ts","sourceRoot":"","sources":["../../src/bigconsole/workflowOpen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAAoC,KAAK,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"workflowOpen.d.ts","sourceRoot":"","sources":["../../src/bigconsole/workflowOpen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAAoC,KAAK,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAWtH;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;CAAoC,CAAC;AAEvE,oEAAoE;AACpE,eAAO,MAAM,gBAAgB;;;;CAA4C,CAAC;AAE1E,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D,uFAAuF;AACvF,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE;QACf,KAAK,EAAE,iBAAiB,CAAC,6BAA6B,EAAE;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACjF,SAAS,EAAE;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC;QACnC,WAAW,EAAE,cAAc,CAAC;KAC7B,KAAK,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,6BAA6B,GAAG,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACtF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,oBAAoB,CAEzE;AAED,0EAA0E;AAC1E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoB7G;AAED,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAID;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,MAAM,EACX,EAAE,YAAuC,EAAE,KAAoB,EAAE,GAAE,aAAkB,GACpF,OAAO,CAAC,kBAAkB,CAAC,CAK7B;AAED,wDAAwD;AACxD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,YAAY,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iDAAiD;IACjD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,GAAG,EACH,YAAY,EACZ,WAAW,EACX,SAAS,EACT,SAAS,GACV,EAAE,iBAAiB,GAAG,gBAAgB,CAMtC"}
|
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
import { WorkflowDefinitionExistsDocument as e } from "../generated/wspace-operations.js";
|
|
2
2
|
import { BOOTSTRAP_RETRY_DELAY_MS as t } from "./constants.js";
|
|
3
|
+
import { hasGraphQLErrorCode as n } from "./utils/backendError.js";
|
|
3
4
|
//#region src/bigconsole/workflowOpen.ts
|
|
4
|
-
var
|
|
5
|
-
function
|
|
5
|
+
var r = new Set(["NOT_FOUND"]), i = { createWorkflow: !0 }, a = { state: i };
|
|
6
|
+
function o(e) {
|
|
6
7
|
return typeof e == "object" && !!e && e.createWorkflow === !0;
|
|
7
8
|
}
|
|
8
|
-
function
|
|
9
|
+
function s(e) {
|
|
9
10
|
return { query: (t) => e.query(t) };
|
|
10
11
|
}
|
|
11
|
-
async function
|
|
12
|
+
async function c(t, i) {
|
|
12
13
|
try {
|
|
13
|
-
let
|
|
14
|
+
let a = await t.query({
|
|
14
15
|
query: e,
|
|
15
|
-
variables: { workflowKey:
|
|
16
|
+
variables: { workflowKey: i },
|
|
16
17
|
fetchPolicy: "network-only"
|
|
17
18
|
});
|
|
18
|
-
return
|
|
19
|
-
} catch {
|
|
20
|
-
return "error";
|
|
19
|
+
return a.error ? n(a.error, r) ? "absent" : "error" : a.data?.workflowDefinition ? "found" : "absent";
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return n(e, r) ? "absent" : "error";
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
var
|
|
24
|
-
async function
|
|
25
|
-
return await
|
|
24
|
+
var l = (e) => new Promise((t) => setTimeout(t, e));
|
|
25
|
+
async function u(e, n, { retryDelayMs: r = t, sleep: i = l } = {}) {
|
|
26
|
+
return await c(e, n) === "found" ? "found" : (await i(r), c(e, n));
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
+
function d({ key: e, createIntent: t, verifiedKey: n, absentKey: r, failedKey: i }) {
|
|
28
29
|
return t || n === e ? "builder" : r === e ? "not-found" : i === e ? "failed" : "checking";
|
|
29
30
|
}
|
|
30
31
|
//#endregion
|
|
31
|
-
export {
|
|
32
|
+
export { i as CREATE_WORKFLOW_STATE, a as NEW_WORKFLOW_NAV, d as decideWorkflowOpenView, o as isCreateIntent, s as toLookupClient, u as verifyWorkflowKey };
|
|
32
33
|
|
|
33
34
|
//# sourceMappingURL=workflowOpen.js.map
|