@burdenoff/microfe-bigconsole 2026.1104.3 → 2026.1104.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,27 +8,28 @@ import ne from "../hooks/useParserOperations.js";
8
8
  import { BIGCONSOLE_PERMISSIONS as r } from "../../constants/permissions.js";
9
9
  import { isDirty as re, shouldReseedForm as ie } from "../utils/formDirty.js";
10
10
  import { CacheTTLSelector as ae } from "../components/datasink/CacheTTLSelector.js";
11
+ import { expressionGateAllows as oe, expressionGateState as se, isEditAttemptKey as ce, parserTestSignature as le } from "../utils/parserTestGate.js";
11
12
  import { memo as i, useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
12
- import { useParams as oe } from "react-router";
13
- import { AccessDenied as se, PermissionButton as ce } from "@burdenoff/fe-libs/shared/components";
14
- import { usePermissions as le } from "@burdenoff/fe-libs/shared/providers/shell";
15
- import { AlertCircle as ue, ArrowLeft as de, CheckCircle2 as fe, ChevronDown as pe, ChevronRight as me, Code as he, Download as ge, Eye as _e, FileCode2 as ve, LayoutDashboard as ye, Loader2 as u, Play as be, Save as xe, Settings as Se, X as Ce } from "lucide-react";
16
- import { Button as d, PagePurpose as we, Stepper as Te } from "@burdenoff/fe-libs/ui";
17
- import { useUnsavedChanges as Ee } from "@burdenoff/fe-libs/shared/hooks";
18
- import { useI18n as De } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
19
- import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
13
+ import { useParams as ue } from "react-router";
14
+ import { AccessDenied as de, PermissionButton as fe } from "@burdenoff/fe-libs/shared/components";
15
+ import { usePermissions as pe } from "@burdenoff/fe-libs/shared/providers/shell";
16
+ import { AlertCircle as u, ArrowLeft as me, CheckCircle2 as he, ChevronDown as ge, ChevronRight as _e, Code as ve, Download as ye, Eye as be, FileCode2 as xe, LayoutDashboard as Se, Loader2 as d, Play as Ce, Save as we, Settings as Te, X as Ee } from "lucide-react";
17
+ import { Button as f, PagePurpose as De, Stepper as Oe } from "@burdenoff/fe-libs/ui";
18
+ import { useUnsavedChanges as ke } from "@burdenoff/fe-libs/shared/hooks";
19
+ import { useI18n as Ae } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
20
+ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
20
21
  //#region src/bigconsole/pages/ParserBuilderPage.tsx
21
- var h = "w-full min-w-0 min-h-control-md rounded-md border bg-bg-surface px-3 py-2.5 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-action-primary-bg motion-safe:transition-colors disabled:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-60";
22
- function g(e = !1, t = "") {
23
- return `${h} ${e ? "border-status-error-border" : "border-[var(--color-border-default)]"} ${t}`.trim();
22
+ var g = "w-full min-w-0 min-h-control-md rounded-md border bg-bg-surface px-3 py-2.5 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-action-primary-bg motion-safe:transition-colors disabled:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-60";
23
+ function _(e = !1, t = "") {
24
+ return `${g} ${e ? "border-status-error-border" : "border-[var(--color-border-default)]"} ${t}`.trim();
24
25
  }
25
- var _ = "block text-sm font-medium text-text-primary mb-2", v = "text-xs text-text-muted mt-1.5", y = 25, Oe = "default", ke = [
26
+ var v = "block text-sm font-medium text-text-primary mb-2", y = "text-xs text-text-muted mt-1.5", b = 25, je = "default", Me = [
26
27
  "details",
27
28
  "source",
28
29
  "expression",
29
30
  "review"
30
31
  ];
31
- function Ae(e) {
32
+ function Ne(e) {
32
33
  return [
33
34
  {
34
35
  key: "details",
@@ -52,14 +53,14 @@ function Ae(e) {
52
53
  }
53
54
  ];
54
55
  }
55
- function je(e) {
56
+ function Pe(e) {
56
57
  return e.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").substring(0, 64);
57
58
  }
58
- function Me(e, t) {
59
+ function Fe(e, t) {
59
60
  let n = {};
60
61
  return e.name.trim() ? e.name.length < 2 && (n.name = t("bigconsole.parsers.builder.validation.nameMinLength", "Name must be at least 2 characters")) : n.name = t("bigconsole.parsers.builder.validation.nameRequired", "Name is required"), e.outputKey.trim() ? /^[a-z0-9_]+$/.test(e.outputKey) || (n.outputKey = t("bigconsole.parsers.builder.validation.outputKeyInvalid", "Output key can only contain lowercase letters, numbers, and underscores")) : n.outputKey = t("bigconsole.parsers.builder.validation.outputKeyRequired", "Output key is required"), e.expression.trim() || (n.expression = t("bigconsole.parsers.builder.validation.expressionRequired", "Expression is required")), e.inputSinkKey.trim() || (n.inputSinkKey = t("bigconsole.parsers.builder.validation.inputSinkRequired", "Source DataSink is required")), e.ttl != null && e.ttl > 0 && (e.ttl < 30 || e.ttl > 86400) && (n.ttl = t("bigconsole.parsers.builder.validation.cacheDurationRange", "Cache duration must be between 30 and 86400 seconds")), n;
61
62
  }
62
- function Ne(e) {
63
+ function Ie(e) {
63
64
  return {
64
65
  jq: {
65
66
  name: e("bigconsole.parsers.builder.parserType.jq.name", "JQ"),
@@ -75,8 +76,8 @@ function Ne(e) {
75
76
  }
76
77
  };
77
78
  }
78
- var b = i(function() {
79
- let { parserId: i, consoleId: h } = oe(), b = e(), { t: x } = De(), Pe = s(() => Ae(x), [x]), S = s(() => Ne(x), [x]), C = Pe.length, [w, T] = l(0), [E, Fe] = l(Oe), Ie = h || E || Oe, D = i !== "new" && !!i, { hasPermission: Le, isLoading: Re } = le(), ze = Le(r.PARSER_READ), Be = Le(D ? r.PARSER_UPDATE : r.PARSER_CREATE), Ve = D ? r.PARSER_UPDATE : r.PARSER_CREATE, O = !h, [k, A] = l({
79
+ var x = i(function() {
80
+ let { parserId: i, consoleId: g } = ue(), x = e(), { t: S } = Ae(), Le = s(() => Ne(S), [S]), C = s(() => Ie(S), [S]), w = Le.length, [T, E] = l(0), [D, Re] = l(je), ze = g || D || je, O = i !== "new" && !!i, { hasPermission: Be, isLoading: Ve } = pe(), He = Be(r.PARSER_READ), Ue = Be(O ? r.PARSER_UPDATE : r.PARSER_CREATE), We = O ? r.PARSER_UPDATE : r.PARSER_CREATE, Ge = Be(r.PARSER_TEST), k = !g, [A, j] = l({
80
81
  name: "",
81
82
  outputKey: "",
82
83
  description: "",
@@ -84,533 +85,549 @@ var b = i(function() {
84
85
  expression: "",
85
86
  inputSinkKey: "",
86
87
  ttl: 900
87
- }), [j, He] = l(() => D ? null : k);
88
- Ee({
88
+ }), [M, Ke] = l(() => O ? null : A);
89
+ ke({
89
90
  id: "parser-editor",
90
- label: x("bigconsole.assistant.unsaved.parserEditor", "the parser editor"),
91
- dirty: re(k, j)
91
+ label: S("bigconsole.assistant.unsaved.parserEditor", "the parser editor"),
92
+ dirty: re(A, M)
92
93
  });
93
- let [M, N] = l({}), [Ue, We] = l(!1), [Ge, Ke] = l(!1), [qe, Je] = l(null), [P, F] = l("{\n \"data\": [\n {\"name\": \"Item 1\", \"count\": 10},\n {\"name\": \"Item 2\", \"count\": 20}\n ]\n}"), [Ye, I] = l(""), [L, R] = l(null), [Xe, Ze] = l(!1), [z, B] = l(null), [V, Qe] = l(!1), [H, $e] = l(null), [et, tt] = l(!1), U = c(k.inputSinkKey);
94
+ let [N, P] = l({}), [qe, Je] = l(!1), [Ye, Xe] = l(!1), [Ze, Qe] = l(null), [$e, F] = l("{\n \"data\": [\n {\"name\": \"Item 1\", \"count\": 10},\n {\"name\": \"Item 2\", \"count\": 20}\n ]\n}"), [et, I] = l(""), [L, R] = l(null), [tt, nt] = l(!1), [z, B] = l(null), [rt, it] = l(null), [at, ot] = l(null), [st, V] = l(!1), [H, ct] = l(!1), [U, lt] = l(null), [ut, dt] = l(!1), W = c(A.inputSinkKey);
94
95
  o(() => {
95
- U.current = k.inputSinkKey;
96
- }, [k.inputSinkKey]);
97
- let [W, nt] = l(!1), [rt, it] = l(null), [at, ot] = l(!1), [st, G] = l(null), [K, ct] = l(null), { loading: lt, error: ut, parsers: dt, fetchParser: ft, createParser: pt, updateParser: mt, testParserExpression: ht } = ne({
98
- consoleId: Ie || "",
96
+ W.current = A.inputSinkKey;
97
+ }, [A.inputSinkKey]);
98
+ let [G, ft] = l(!1), [pt, mt] = l(null), [ht, gt] = l(!1), [_t, K] = l(null), [q, vt] = l(null), { loading: yt, error: bt, parsers: xt, fetchParser: St, createParser: Ct, updateParser: wt, testParserExpression: Tt } = ne({
99
+ consoleId: ze || "",
99
100
  skipFetch: !0
100
- }), { dataSinks: q, fetchDataSinks: gt, getDataSinkData: J } = te({ skipFetch: !0 }), { dashboards: _t, fetchDashboards: vt, loading: yt } = ee(), Y = D ? dt.find((e) => e.id === i) : null;
101
+ }), { dataSinks: J, fetchDataSinks: Et, getDataSinkData: Y } = te({ skipFetch: !0 }), { dashboards: Dt, fetchDashboards: Ot, loading: kt } = ee(), X = O ? xt.find((e) => e.id === i) : null;
101
102
  o(() => {
102
- gt(), D && i && ft(i), O && vt();
103
+ Et(), O && i && St(i), k && Ot();
103
104
  }, [
104
- D,
105
- i,
106
- ft,
107
- gt,
108
105
  O,
109
- vt
106
+ i,
107
+ St,
108
+ Et,
109
+ k,
110
+ Ot
110
111
  ]);
111
- let bt = c(null), xt = c(k), St = c(j);
112
+ let At = c(null), jt = c(A), Mt = c(M);
112
113
  o(() => {
113
- xt.current = k, St.current = j;
114
- }, [k, j]), o(() => {
115
- if (Y && ie(bt.current, Y.id, xt.current, St.current)) {
116
- bt.current = Y.id;
114
+ jt.current = A, Mt.current = M;
115
+ }, [A, M]), o(() => {
116
+ if (X && ie(At.current, X.id, jt.current, Mt.current)) {
117
+ At.current = X.id;
117
118
  let e = {
118
- name: Y.name || "",
119
- outputKey: Y.outputKey || "",
120
- description: Y.description || "",
121
- type: Y.type,
122
- expression: Y.expression || "",
123
- inputSinkKey: Y.inputSinkKey || "",
124
- ttl: Y.ttl ?? null
119
+ name: X.name || "",
120
+ outputKey: X.outputKey || "",
121
+ description: X.description || "",
122
+ type: X.type,
123
+ expression: X.expression || "",
124
+ inputSinkKey: X.inputSinkKey || "",
125
+ ttl: X.ttl ?? null
125
126
  };
126
- A(e), He(e), We(!0), Y.consoleId && Fe(Y.consoleId);
127
+ j(e), Ke(e), Je(!0), it(e.expression.trim() ? le(e.type, e.expression) : null), X.consoleId && Re(X.consoleId);
127
128
  }
128
- }, [Y]);
129
- let X = s(() => q.find((e) => e.key === k.inputSinkKey)?.name || k.inputSinkKey, [q, k.inputSinkKey]), Ct = a((e) => {
129
+ }, [X]);
130
+ let Z = s(() => J.find((e) => e.key === A.inputSinkKey)?.name || A.inputSinkKey, [J, A.inputSinkKey]), Nt = a((e) => {
130
131
  let t = e.target.value;
131
- A((e) => ({
132
+ j((e) => ({
132
133
  ...e,
133
134
  name: t,
134
- outputKey: Ue ? e.outputKey : je(t)
135
- })), N((e) => ({
135
+ outputKey: qe ? e.outputKey : Pe(t)
136
+ })), P((e) => ({
136
137
  ...e,
137
138
  name: void 0
138
139
  }));
139
- }, [Ue]), wt = a((e) => {
140
+ }, [qe]), Pt = a((e) => {
140
141
  let t = e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, "");
141
- A((e) => ({
142
+ j((e) => ({
142
143
  ...e,
143
144
  outputKey: t
144
- })), We(!0), N((e) => ({
145
+ })), Je(!0), P((e) => ({
145
146
  ...e,
146
147
  outputKey: void 0
147
148
  }));
148
- }, []), Tt = a((e) => {
149
- A((t) => ({
149
+ }, []), Ft = a((e) => {
150
+ j((t) => ({
150
151
  ...t,
151
152
  description: e.target.value
152
153
  }));
153
- }, []), Et = a((e) => {
154
- A((t) => ({
154
+ }, []), It = a((e) => {
155
+ j((t) => ({
155
156
  ...t,
156
157
  type: e
157
- })), I(""), R(null);
158
- }, []), Dt = a((e) => {
159
- A((t) => ({
158
+ })), I(""), R(null), ot(null);
159
+ }, []), Lt = a((e) => {
160
+ j((t) => ({
160
161
  ...t,
161
162
  expression: e.target.value
162
- })), N((e) => ({
163
+ })), P((e) => ({
163
164
  ...e,
164
165
  expression: void 0
165
166
  }));
166
- }, []), Ot = a((e) => {
167
- A((t) => ({
167
+ }, []), Rt = a((e) => {
168
+ j((t) => ({
168
169
  ...t,
169
170
  inputSinkKey: e.target.value
170
- })), N((e) => ({
171
+ })), P((e) => ({
171
172
  ...e,
172
173
  inputSinkKey: void 0
173
- })), nt(!1), it(null), ct(null), G(null), V && (F(""), Qe(!1)), $e(null), I(""), R(null), B(null);
174
- }, [V]), kt = a((e) => {
175
- A((t) => ({
174
+ })), ft(!1), mt(null), vt(null), K(null), H && (F(""), ct(!1), V(!1)), lt(null), I(""), R(null), B(null);
175
+ }, [H]), zt = a((e) => {
176
+ j((t) => ({
176
177
  ...t,
177
178
  ttl: e
178
- })), N((e) => ({
179
+ })), P((e) => ({
179
180
  ...e,
180
181
  ttl: void 0
181
182
  }));
182
- }, []), At = a((e) => {
183
- Fe(e.target.value);
184
- }, []), jt = a((e) => {
183
+ }, []), Bt = a((e) => {
184
+ Re(e.target.value);
185
+ }, []), Vt = a((e) => {
185
186
  F(e.target.value);
186
- }, []), Mt = a(async () => {
187
- let e = k.inputSinkKey;
187
+ }, []), Ht = a((e) => {
188
+ H && ce(e) && V(!0);
189
+ }, [H]), Ut = a(() => {
190
+ H && V(!0);
191
+ }, [H]), Wt = a(async () => {
192
+ let e = A.inputSinkKey;
188
193
  if (e) {
189
- tt(!0);
194
+ dt(!0);
190
195
  try {
191
- let t = await J({ key: e }, { limit: y });
192
- if (U.current !== e) return;
193
- t?.raw !== void 0 && t?.raw !== null ? (F(JSON.stringify(t.raw, null, 2)), Qe(!0), $e({
196
+ let t = await Y({ key: e }, { limit: b });
197
+ if (W.current !== e) return;
198
+ t?.raw !== void 0 && t?.raw !== null ? (F(JSON.stringify(t.raw, null, 2)), ct(!0), V(!1), lt({
194
199
  total: t.totalCount ?? null,
195
200
  hasMore: t.hasMore ?? null,
196
- sinkName: X
197
- }), I(""), R(null), B(null)) : R(x("bigconsole.parsers.builder.errors.loadSampleFailed", "Could not load a sample from the selected DataSink."));
201
+ sinkName: Z
202
+ }), I(""), R(null), B(null)) : R(S("bigconsole.parsers.builder.errors.loadSampleFailed", "Could not load a sample from the selected DataSink."));
198
203
  } catch (t) {
199
- if (U.current !== e) return;
200
- R(t instanceof Error ? t.message : x("bigconsole.parsers.builder.errors.loadSampleDataFailed", "Failed to load sample data"));
204
+ if (W.current !== e) return;
205
+ R(t instanceof Error ? t.message : S("bigconsole.parsers.builder.errors.loadSampleDataFailed", "Failed to load sample data"));
201
206
  } finally {
202
- tt(!1);
207
+ dt(!1);
203
208
  }
204
209
  }
205
210
  }, [
206
- k.inputSinkKey,
207
- J,
208
- X,
209
- x
210
- ]), Nt = a(() => {
211
- F(""), Qe(!1), $e(null), B(null), I(""), R(null);
212
- }, []), Pt = a(async () => {
213
- if (W) {
214
- nt(!1);
211
+ A.inputSinkKey,
212
+ Y,
213
+ Z,
214
+ S
215
+ ]), Gt = a(() => {
216
+ F(""), ct(!1), V(!1), lt(null), B(null), I(""), R(null);
217
+ }, []), Kt = a(async () => {
218
+ if (G) {
219
+ ft(!1);
215
220
  return;
216
221
  }
217
- if (!k.inputSinkKey) {
218
- G(x("bigconsole.parsers.builder.errors.selectSourceFirst", "Please select a source DataSink first"));
222
+ if (!A.inputSinkKey) {
223
+ K(S("bigconsole.parsers.builder.errors.selectSourceFirst", "Please select a source DataSink first"));
219
224
  return;
220
225
  }
221
- nt(!0), ot(!0), G(null);
222
- let e = k.inputSinkKey;
226
+ ft(!0), gt(!0), K(null);
227
+ let e = A.inputSinkKey;
223
228
  try {
224
- let t = await J({ key: e }, { limit: y });
225
- if (U.current !== e) return;
226
- t?.raw !== void 0 && t?.raw !== null ? (it(t.raw), ct({
229
+ let t = await Y({ key: e }, { limit: b });
230
+ if (W.current !== e) return;
231
+ t?.raw !== void 0 && t?.raw !== null ? (mt(t.raw), vt({
227
232
  total: t.totalCount ?? null,
228
233
  hasMore: t.hasMore ?? null,
229
- sinkName: X
230
- })) : G(x("bigconsole.parsers.builder.errors.noDataInSink", "No data available in selected DataSink"));
234
+ sinkName: Z
235
+ })) : K(S("bigconsole.parsers.builder.errors.noDataInSink", "No data available in selected DataSink"));
231
236
  } catch (t) {
232
- if (U.current !== e) return;
233
- G(t instanceof Error ? t.message : x("bigconsole.parsers.builder.errors.loadDataFailed", "Failed to load data"));
237
+ if (W.current !== e) return;
238
+ K(t instanceof Error ? t.message : S("bigconsole.parsers.builder.errors.loadDataFailed", "Failed to load data"));
234
239
  } finally {
235
- ot(!1);
240
+ gt(!1);
236
241
  }
237
242
  }, [
238
- W,
239
- k.inputSinkKey,
240
- J,
241
- X,
242
- x
243
- ]), Ft = a(async () => {
244
- if (!k.expression.trim()) {
245
- R(x("bigconsole.parsers.builder.validation.expressionRequired", "Expression is required"));
243
+ G,
244
+ A.inputSinkKey,
245
+ Y,
246
+ Z,
247
+ S
248
+ ]), qt = a(async () => {
249
+ if (!A.expression.trim()) {
250
+ R(S("bigconsole.parsers.builder.validation.expressionRequired", "Expression is required"));
246
251
  return;
247
252
  }
248
253
  let e;
249
- if (V) e = {
250
- type: k.type,
251
- expression: k.expression,
252
- dataSinkKey: k.inputSinkKey,
253
- sampleLimit: y
254
+ if (H) e = {
255
+ type: A.type,
256
+ expression: A.expression,
257
+ dataSinkKey: A.inputSinkKey,
258
+ sampleLimit: b
254
259
  };
255
260
  else {
256
261
  let t;
257
262
  try {
258
- t = JSON.parse(P);
263
+ t = JSON.parse($e);
259
264
  } catch {
260
- R(x("bigconsole.parsers.builder.errors.invalidInputJson", "Input JSON is not valid JSON"));
265
+ R(S("bigconsole.parsers.builder.errors.invalidInputJson", "Input JSON is not valid JSON"));
261
266
  return;
262
267
  }
263
268
  e = {
264
- type: k.type,
265
- expression: k.expression,
269
+ type: A.type,
270
+ expression: A.expression,
266
271
  sampleData: t
267
272
  };
268
273
  }
269
- Ze(!0), R(null), I(""), B(null);
274
+ let t = le(A.type, A.expression);
275
+ nt(!0), R(null), I(""), B(null), it(null), ot(t);
270
276
  try {
271
- let t = await ht(e);
272
- t ? t.success ? (I(JSON.stringify(t.output, null, 2)), t.sampled && B({
273
- sampledRows: t.sampledRows ?? null,
274
- totalRows: t.totalRows ?? null
275
- })) : R(t.error || x("bigconsole.parsers.builder.errors.testFailed", "Test failed")) : R(x("bigconsole.parsers.builder.errors.testRequestFailed", "Test request failed — please try again."));
277
+ let n = await Tt(e);
278
+ n ? n.success ? (I(JSON.stringify(n.output, null, 2)), it(t), n.sampled && B({
279
+ sampledRows: n.sampledRows ?? null,
280
+ totalRows: n.totalRows ?? null
281
+ })) : R(n.error || S("bigconsole.parsers.builder.errors.testFailed", "Test failed")) : R(S("bigconsole.parsers.builder.errors.testRequestFailed", "Test request failed — please try again."));
276
282
  } catch (e) {
277
- R(e instanceof Error ? e.message : x("bigconsole.parsers.builder.errors.testFailed", "Test failed"));
283
+ R(e instanceof Error ? e.message : S("bigconsole.parsers.builder.errors.testFailed", "Test failed"));
278
284
  } finally {
279
- Ze(!1);
285
+ nt(!1);
280
286
  }
281
287
  }, [
282
- k.type,
283
- k.expression,
284
- k.inputSinkKey,
285
- P,
286
- V,
287
- ht,
288
- x
289
- ]), Z = a(() => {
290
- b(h ? `/dashboards/${h}/parsers` : "/parsers");
291
- }, [b, h]), It = a(async () => {
292
- Je(null);
293
- let e = Me(k, x);
288
+ A.type,
289
+ A.expression,
290
+ A.inputSinkKey,
291
+ $e,
292
+ H,
293
+ Tt,
294
+ S
295
+ ]), Q = a(() => {
296
+ x(g ? `/dashboards/${g}/parsers` : "/parsers");
297
+ }, [x, g]), Jt = se({
298
+ type: A.type,
299
+ expression: A.expression,
300
+ passedSignature: rt,
301
+ canTest: Ge
302
+ }), $ = oe(Jt), Yt = at !== null && at !== le(A.type, A.expression), Xt = a(async () => {
303
+ Qe(null);
304
+ let e = Fe(A, S);
294
305
  if (Object.keys(e).length > 0) {
295
- N(e), e.name || e.outputKey ? T(0) : e.inputSinkKey ? T(1) : e.expression && T(2);
306
+ P(e), e.name || e.outputKey ? E(0) : e.inputSinkKey ? E(1) : e.expression && E(2);
296
307
  return;
297
308
  }
298
- Ke(!0);
309
+ if (!$) {
310
+ E(2);
311
+ return;
312
+ }
313
+ Xe(!0);
299
314
  try {
300
- if (D && Y) {
301
- if (!await mt(Y.id, {
302
- name: k.name,
303
- description: k.description || void 0,
304
- expression: k.expression,
305
- inputSinkKey: k.inputSinkKey,
306
- outputKey: k.outputKey,
307
- ttl: k.ttl
308
- }, Y.version)) throw Error(x("bigconsole.parsers.builder.errors.updateFailed", "Failed to update parser"));
309
- } else if (!await pt({
310
- consoleId: Ie || "",
311
- name: k.name,
312
- type: k.type,
313
- expression: k.expression,
314
- inputSinkKey: k.inputSinkKey,
315
- outputKey: k.outputKey,
316
- description: k.description || void 0,
317
- ttl: k.ttl ?? void 0
318
- })) throw Error(x("bigconsole.parsers.builder.errors.createFailed", "Failed to create parser"));
319
- He(k), Z();
315
+ if (O && X) {
316
+ if (!await wt(X.id, {
317
+ name: A.name,
318
+ description: A.description || void 0,
319
+ expression: A.expression,
320
+ inputSinkKey: A.inputSinkKey,
321
+ outputKey: A.outputKey,
322
+ ttl: A.ttl
323
+ }, X.version)) throw Error(S("bigconsole.parsers.builder.errors.updateFailed", "Failed to update parser"));
324
+ } else if (!await Ct({
325
+ consoleId: ze || "",
326
+ name: A.name,
327
+ type: A.type,
328
+ expression: A.expression,
329
+ inputSinkKey: A.inputSinkKey,
330
+ outputKey: A.outputKey,
331
+ description: A.description || void 0,
332
+ ttl: A.ttl ?? void 0
333
+ })) throw Error(S("bigconsole.parsers.builder.errors.createFailed", "Failed to create parser"));
334
+ Ke(A), Q();
320
335
  } catch (e) {
321
- Je(e instanceof Error ? e.message : x("bigconsole.parsers.builder.errors.saveFailed", "Failed to save parser"));
336
+ Qe(e instanceof Error ? e.message : S("bigconsole.parsers.builder.errors.saveFailed", "Failed to save parser"));
322
337
  } finally {
323
- Ke(!1);
338
+ Xe(!1);
324
339
  }
325
340
  }, [
326
- k,
327
- D,
328
- Y,
329
- pt,
330
- mt,
331
- Ie,
332
- Z,
333
- x
334
- ]), Lt = s(() => k.name.trim().length >= 2 && k.expression.trim().length > 0 && k.inputSinkKey.trim().length > 0 && k.outputKey.trim().length > 0 && /^[a-z0-9_]+$/.test(k.outputKey), [
335
- k.name,
336
- k.expression,
337
- k.inputSinkKey,
338
- k.outputKey
339
- ]), Q = a((e) => {
340
- switch (ke[e]) {
341
- case "details": return k.name.trim().length >= 2 && k.outputKey.trim().length > 0 && /^[a-z0-9_]+$/.test(k.outputKey);
342
- case "source": return k.inputSinkKey.trim().length > 0;
343
- case "expression": return k.expression.trim().length > 0;
341
+ A,
342
+ $,
343
+ O,
344
+ X,
345
+ Ct,
346
+ wt,
347
+ ze,
348
+ Q,
349
+ S
350
+ ]), Zt = s(() => A.name.trim().length >= 2 && A.expression.trim().length > 0 && $ && A.inputSinkKey.trim().length > 0 && A.outputKey.trim().length > 0 && /^[a-z0-9_]+$/.test(A.outputKey), [
351
+ A.name,
352
+ A.expression,
353
+ $,
354
+ A.inputSinkKey,
355
+ A.outputKey
356
+ ]), Qt = a((e) => {
357
+ switch (Me[e]) {
358
+ case "details": return A.name.trim().length >= 2 && A.outputKey.trim().length > 0 && /^[a-z0-9_]+$/.test(A.outputKey);
359
+ case "source": return A.inputSinkKey.trim().length > 0;
360
+ case "expression": return $;
344
361
  default: return !0;
345
362
  }
346
363
  }, [
347
- k.name,
348
- k.outputKey,
349
- k.inputSinkKey,
350
- k.expression
351
- ]), Rt = a((e) => {
352
- let t = Math.max(0, Math.min(e, C - 1));
353
- if (t > w) {
354
- for (let e = w; e < t; e++) if (!Q(e)) return;
364
+ A.name,
365
+ A.outputKey,
366
+ A.inputSinkKey,
367
+ $
368
+ ]), $t = a((e) => {
369
+ let t = Math.max(0, Math.min(e, w - 1));
370
+ if (t > T) {
371
+ for (let e = T; e < t; e++) if (!Qt(e)) return;
355
372
  }
356
- T(t);
373
+ E(t);
357
374
  }, [
358
- w,
359
- Q,
360
- C
361
- ]), zt = a(() => {
362
- T((e) => Math.min(e + 1, C - 1));
363
- }, [C]), Bt = a(() => {
364
- T((e) => Math.max(e - 1, 0));
375
+ T,
376
+ Qt,
377
+ w
378
+ ]), en = a(() => {
379
+ E((e) => Math.min(e + 1, w - 1));
380
+ }, [w]), tn = a(() => {
381
+ E((e) => Math.max(e - 1, 0));
365
382
  }, []);
366
- if (lt && D || Re) return /* @__PURE__ */ p("div", {
383
+ if (yt && O || Ve) return /* @__PURE__ */ m("div", {
367
384
  className: "flex items-center justify-center min-h-[400px]",
368
- children: /* @__PURE__ */ p(u, { className: "w-8 h-8 text-text-secondary animate-spin" })
385
+ children: /* @__PURE__ */ m(d, { className: "w-8 h-8 text-text-secondary animate-spin" })
369
386
  });
370
- if (D && !ze) return /* @__PURE__ */ p(se, {
371
- title: x("bigconsole.parsers.builder.accessDenied.title", "Access Denied"),
372
- description: x("bigconsole.parsers.builder.accessDenied.description", "You don't have permission to view this parser.")
387
+ if (O && !He) return /* @__PURE__ */ m(de, {
388
+ title: S("bigconsole.parsers.builder.accessDenied.title", "Access Denied"),
389
+ description: S("bigconsole.parsers.builder.accessDenied.description", "You don't have permission to view this parser.")
373
390
  });
374
- if (ut) return /* @__PURE__ */ p("div", {
391
+ if (bt) return /* @__PURE__ */ m("div", {
375
392
  className: "p-card-padding",
376
- children: /* @__PURE__ */ p(t, {
393
+ children: /* @__PURE__ */ m(t, {
377
394
  tone: "danger",
378
395
  headingLevel: 2,
379
- title: x("bigconsole.parsers.builder.errors.loadParserFailed", "Failed to load Parser"),
396
+ title: S("bigconsole.parsers.builder.errors.loadParserFailed", "Failed to load Parser"),
380
397
  description: "The parser could not be fetched, so the form cannot be filled in.",
381
- icon: /* @__PURE__ */ p(ue, { className: "h-icon-md w-icon-md text-[var(--color-status-error-text)]" }),
382
- actions: /* @__PURE__ */ m(d, {
383
- onClick: Z,
398
+ icon: /* @__PURE__ */ m(u, { className: "h-icon-md w-icon-md text-[var(--color-status-error-text)]" }),
399
+ actions: /* @__PURE__ */ h(f, {
400
+ onClick: Q,
384
401
  variant: "secondary",
385
402
  size: "sm",
386
- children: [/* @__PURE__ */ p(de, { className: "w-4 h-4 mr-2" }), x("bigconsole.parsers.builder.header.backToParsers", "Back to Parsers")]
403
+ children: [/* @__PURE__ */ m(me, { className: "w-4 h-4 mr-2" }), S("bigconsole.parsers.builder.header.backToParsers", "Back to Parsers")]
387
404
  }),
388
405
  "data-testid": "parser-builder-load-error",
389
- children: /* @__PURE__ */ p("p", {
406
+ children: /* @__PURE__ */ m("p", {
390
407
  className: "font-mono text-xs break-words text-text-secondary",
391
- children: ut.message
408
+ children: bt.message
392
409
  })
393
410
  })
394
411
  });
395
- let Vt = S[k.type], Ht = w === C - 1, $ = /* @__PURE__ */ p("span", {
412
+ let nn = C[A.type], rn = T === w - 1, an = /* @__PURE__ */ m("span", {
396
413
  className: "text-xs font-medium text-text-muted",
397
- children: x("bigconsole.parsers.builder.header.stepCounter", "Step {{current}} of {{total}}", {
398
- current: w + 1,
399
- total: C
414
+ children: S("bigconsole.parsers.builder.header.stepCounter", "Step {{current}} of {{total}}", {
415
+ current: T + 1,
416
+ total: w
400
417
  })
401
418
  });
402
- return /* @__PURE__ */ p("div", {
419
+ return /* @__PURE__ */ m("div", {
403
420
  "data-tour": "bigconsole-parser-builder",
404
421
  className: "min-h-screen bg-bg-canvas",
405
- children: /* @__PURE__ */ p("div", {
422
+ children: /* @__PURE__ */ m("div", {
406
423
  className: "max-w-4xl mx-auto p-card-padding pb-10",
407
- children: /* @__PURE__ */ m(n, { children: [
408
- /* @__PURE__ */ m("div", {
424
+ children: /* @__PURE__ */ h(n, { children: [
425
+ /* @__PURE__ */ h("div", {
409
426
  className: "border-b border-[var(--color-border-subtle)] pb-form-gap",
410
427
  children: [
411
- /* @__PURE__ */ m(d, {
412
- onClick: Z,
428
+ /* @__PURE__ */ h(f, {
429
+ onClick: Q,
413
430
  variant: "ghost",
414
431
  size: "sm",
415
432
  className: "mb-4",
416
- children: [/* @__PURE__ */ p(de, { className: "w-4 h-4 mr-2" }), x("bigconsole.parsers.builder.header.backToParsers", "Back to Parsers")]
433
+ children: [/* @__PURE__ */ m(me, { className: "w-4 h-4 mr-2" }), S("bigconsole.parsers.builder.header.backToParsers", "Back to Parsers")]
417
434
  }),
418
- /* @__PURE__ */ p("h1", {
435
+ /* @__PURE__ */ m("h1", {
419
436
  className: "text-2xl font-bold text-text-primary sm:text-3xl",
420
- children: D ? x("bigconsole.parsers.builder.header.editTitle", "Edit Parser") : x("bigconsole.parsers.builder.header.createTitle", "Create Parser")
437
+ children: O ? S("bigconsole.parsers.builder.header.editTitle", "Edit Parser") : S("bigconsole.parsers.builder.header.createTitle", "Create Parser")
421
438
  }),
422
- /* @__PURE__ */ p("p", {
439
+ /* @__PURE__ */ m("p", {
423
440
  className: "text-sm text-text-secondary mt-1",
424
- children: x("bigconsole.parsers.builder.header.subtitle", "Transform data using JQ or JSONata expressions.")
441
+ children: S("bigconsole.parsers.builder.header.subtitle", "Transform data using JQ or JSONata expressions.")
425
442
  })
426
443
  ]
427
444
  }),
428
- /* @__PURE__ */ p(we, {
445
+ /* @__PURE__ */ m(De, {
429
446
  className: "max-w-[80ch]",
430
- children: x("bigconsole.parsers.builder.header.purpose", "A parser maps raw input into structured fields using a JQ or JSONata expression. Write the expression, run it against a sample to confirm the output, and save it once it produces the shape you need — then reuse it across pipelines to normalise any source.")
447
+ children: S("bigconsole.parsers.builder.header.purpose", "A parser maps raw input into structured fields using a JQ or JSONata expression. Write the expression, run it against a sample to confirm the output, and save it once it produces the shape you need — then reuse it across pipelines to normalise any source.")
431
448
  }),
432
- /* @__PURE__ */ p("div", {
449
+ /* @__PURE__ */ m("div", {
433
450
  className: "min-w-0 overflow-x-auto",
434
- children: /* @__PURE__ */ p(Te, {
435
- steps: Pe,
436
- active: w,
437
- onStepClick: Rt
451
+ children: /* @__PURE__ */ m(Oe, {
452
+ steps: Le,
453
+ active: T,
454
+ onStepClick: $t
438
455
  })
439
456
  }),
440
- qe && /* @__PURE__ */ p(t, {
457
+ Ze && /* @__PURE__ */ m(t, {
441
458
  tone: "danger",
442
459
  headingLevel: 2,
443
- title: x("bigconsole.parsers.builder.errors.saveParserFailed", "Failed to save Parser"),
444
- icon: /* @__PURE__ */ p(ue, { className: "h-icon-sm w-icon-sm text-[var(--color-status-error-text)]" }),
460
+ title: S("bigconsole.parsers.builder.errors.saveParserFailed", "Failed to save Parser"),
461
+ icon: /* @__PURE__ */ m(u, { className: "h-icon-sm w-icon-sm text-[var(--color-status-error-text)]" }),
445
462
  "data-testid": "parser-submit-error",
446
- children: /* @__PURE__ */ p("p", {
463
+ children: /* @__PURE__ */ m("p", {
447
464
  className: "font-mono text-xs break-words text-text-secondary",
448
- children: qe
465
+ children: Ze
449
466
  })
450
467
  }),
451
- /* @__PURE__ */ m("form", {
468
+ /* @__PURE__ */ h("form", {
452
469
  className: "flex flex-col gap-section-gap",
453
470
  onSubmit: (e) => {
454
- e.preventDefault(), Ht && It();
471
+ e.preventDefault(), rn && Xt();
455
472
  },
456
473
  children: [
457
- w === 0 && /* @__PURE__ */ m(t, {
474
+ T === 0 && /* @__PURE__ */ h(t, {
458
475
  emphasis: "primary",
459
476
  headingLevel: 2,
460
477
  title: "Basic information",
461
478
  description: "Essential details for your parser.",
462
- icon: /* @__PURE__ */ p(ve, { className: "h-icon-sm w-icon-sm" }),
463
- meta: $,
479
+ icon: /* @__PURE__ */ m(xe, { className: "h-icon-sm w-icon-sm" }),
480
+ meta: an,
464
481
  bodyClassName: "space-y-5",
465
482
  "data-testid": "parser-basic-information",
466
483
  children: [
467
- /* @__PURE__ */ m("div", {
484
+ /* @__PURE__ */ h("div", {
468
485
  className: "grid gap-5 sm:grid-cols-2",
469
- children: [/* @__PURE__ */ m("div", { children: [
470
- /* @__PURE__ */ m("label", {
486
+ children: [/* @__PURE__ */ h("div", { children: [
487
+ /* @__PURE__ */ h("label", {
471
488
  htmlFor: "name",
472
- className: _,
489
+ className: v,
473
490
  children: [
474
- x("bigconsole.parsers.builder.fields.name.label", "Name"),
491
+ S("bigconsole.parsers.builder.fields.name.label", "Name"),
475
492
  " ",
476
- /* @__PURE__ */ p("span", {
493
+ /* @__PURE__ */ m("span", {
477
494
  className: "text-status-error-text",
478
495
  children: "*"
479
496
  })
480
497
  ]
481
498
  }),
482
- /* @__PURE__ */ p("input", {
499
+ /* @__PURE__ */ m("input", {
483
500
  id: "name",
484
501
  type: "text",
485
- value: k.name,
486
- onChange: Ct,
487
- placeholder: x("bigconsole.parsers.builder.fields.name.placeholder", "e.g., User Analytics Parser"),
488
- className: g(!!M.name)
502
+ value: A.name,
503
+ onChange: Nt,
504
+ placeholder: S("bigconsole.parsers.builder.fields.name.placeholder", "e.g., User Analytics Parser"),
505
+ className: _(!!N.name)
489
506
  }),
490
- M.name && /* @__PURE__ */ p("p", {
507
+ N.name && /* @__PURE__ */ m("p", {
491
508
  className: "text-xs text-status-error-text mt-1.5",
492
- children: M.name
509
+ children: N.name
493
510
  })
494
- ] }), /* @__PURE__ */ m("div", { children: [
495
- /* @__PURE__ */ m("label", {
511
+ ] }), /* @__PURE__ */ h("div", { children: [
512
+ /* @__PURE__ */ h("label", {
496
513
  htmlFor: "outputKey",
497
- className: _,
514
+ className: v,
498
515
  children: [
499
- x("bigconsole.parsers.builder.fields.outputKey.label", "Output Key"),
516
+ S("bigconsole.parsers.builder.fields.outputKey.label", "Output Key"),
500
517
  " ",
501
- /* @__PURE__ */ p("span", {
518
+ /* @__PURE__ */ m("span", {
502
519
  className: "text-status-error-text",
503
520
  children: "*"
504
521
  })
505
522
  ]
506
523
  }),
507
- /* @__PURE__ */ p("input", {
524
+ /* @__PURE__ */ m("input", {
508
525
  id: "outputKey",
509
526
  type: "text",
510
- value: k.outputKey,
511
- onChange: wt,
527
+ value: A.outputKey,
528
+ onChange: Pt,
512
529
  placeholder: "user_analytics_parser",
513
- disabled: D,
514
- className: g(!!M.outputKey, "font-mono")
530
+ disabled: O,
531
+ className: _(!!N.outputKey, "font-mono")
515
532
  }),
516
- M.outputKey && /* @__PURE__ */ p("p", {
533
+ N.outputKey && /* @__PURE__ */ m("p", {
517
534
  className: "text-xs text-status-error-text mt-1.5",
518
- children: M.outputKey
535
+ children: N.outputKey
519
536
  }),
520
- !D && /* @__PURE__ */ p("p", {
521
- className: v,
522
- children: x("bigconsole.parsers.builder.fields.outputKey.helper", "Auto-generated from name. Customize if needed.")
537
+ !O && /* @__PURE__ */ m("p", {
538
+ className: y,
539
+ children: S("bigconsole.parsers.builder.fields.outputKey.helper", "Auto-generated from name. Customize if needed.")
523
540
  })
524
541
  ] })]
525
542
  }),
526
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
543
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("label", {
527
544
  htmlFor: "description",
528
- className: _,
529
- children: x("bigconsole.parsers.builder.fields.description.label", "Description")
530
- }), /* @__PURE__ */ p("textarea", {
545
+ className: v,
546
+ children: S("bigconsole.parsers.builder.fields.description.label", "Description")
547
+ }), /* @__PURE__ */ m("textarea", {
531
548
  id: "description",
532
- value: k.description,
533
- onChange: Tt,
534
- placeholder: x("bigconsole.parsers.builder.fields.description.placeholder", "Describe what this parser does..."),
549
+ value: A.description,
550
+ onChange: Ft,
551
+ placeholder: S("bigconsole.parsers.builder.fields.description.placeholder", "Describe what this parser does..."),
535
552
  rows: 3,
536
- className: g(!1, "resize-y")
553
+ className: _(!1, "resize-y")
537
554
  })] }),
538
- O && /* @__PURE__ */ m("div", { children: [
539
- /* @__PURE__ */ m("label", {
555
+ k && /* @__PURE__ */ h("div", { children: [
556
+ /* @__PURE__ */ h("label", {
540
557
  htmlFor: "dashboard",
541
- className: `${_} flex items-center gap-2`,
542
- children: [/* @__PURE__ */ p(ye, {
558
+ className: `${v} flex items-center gap-2`,
559
+ children: [/* @__PURE__ */ m(Se, {
543
560
  "aria-hidden": "true",
544
561
  className: "w-4 h-4"
545
- }), x("bigconsole.parsers.builder.fields.dashboard.label", "Dashboard Scope")]
562
+ }), S("bigconsole.parsers.builder.fields.dashboard.label", "Dashboard Scope")]
546
563
  }),
547
- /* @__PURE__ */ m("select", {
564
+ /* @__PURE__ */ h("select", {
548
565
  id: "dashboard",
549
- value: E,
550
- onChange: At,
551
- disabled: yt || D,
552
- className: g(),
553
- children: [/* @__PURE__ */ p("option", {
566
+ value: D,
567
+ onChange: Bt,
568
+ disabled: kt || O,
569
+ className: _(),
570
+ children: [/* @__PURE__ */ m("option", {
554
571
  value: "default",
555
- children: x("bigconsole.parsers.builder.fields.dashboard.globalOption", "Global (available everywhere)")
556
- }), _t.map((e) => /* @__PURE__ */ p("option", {
572
+ children: S("bigconsole.parsers.builder.fields.dashboard.globalOption", "Global (available everywhere)")
573
+ }), Dt.map((e) => /* @__PURE__ */ m("option", {
557
574
  value: e.id,
558
575
  children: e.name
559
576
  }, e.id))]
560
577
  }),
561
- /* @__PURE__ */ p("p", {
562
- className: v,
563
- children: D ? x("bigconsole.parsers.builder.fields.dashboard.helperLocked", "Dashboard scope cannot be changed after creation.") : E === "default" ? x("bigconsole.parsers.builder.fields.dashboard.helperGlobal", "Global parsers are available across all dashboards.") : x("bigconsole.parsers.builder.fields.dashboard.helperScoped", "This parser will only be available in the selected dashboard.")
578
+ /* @__PURE__ */ m("p", {
579
+ className: y,
580
+ children: O ? S("bigconsole.parsers.builder.fields.dashboard.helperLocked", "Dashboard scope cannot be changed after creation.") : D === "default" ? S("bigconsole.parsers.builder.fields.dashboard.helperGlobal", "Global parsers are available across all dashboards.") : S("bigconsole.parsers.builder.fields.dashboard.helperScoped", "This parser will only be available in the selected dashboard.")
564
581
  })
565
582
  ] })
566
583
  ]
567
584
  }),
568
- w === 1 && /* @__PURE__ */ m(t, {
585
+ T === 1 && /* @__PURE__ */ h(t, {
569
586
  emphasis: "primary",
570
587
  headingLevel: 2,
571
588
  title: "Parser configuration",
572
589
  description: "Pick the language and point it at a source.",
573
- icon: /* @__PURE__ */ p(he, { className: "h-icon-sm w-icon-sm" }),
574
- meta: $,
590
+ icon: /* @__PURE__ */ m(ve, { className: "h-icon-sm w-icon-sm" }),
591
+ meta: an,
575
592
  bodyClassName: "space-y-5",
576
593
  "data-testid": "parser-configuration",
577
- children: [/* @__PURE__ */ m("fieldset", {
594
+ children: [/* @__PURE__ */ h("fieldset", {
578
595
  className: "min-w-0 border-0 p-0 m-0",
579
- children: [/* @__PURE__ */ m("legend", {
596
+ children: [/* @__PURE__ */ h("legend", {
580
597
  className: "mb-3 text-sm font-medium text-text-primary",
581
598
  children: [
582
- x("bigconsole.parsers.builder.fields.parserType.label", "Parser Type"),
599
+ S("bigconsole.parsers.builder.fields.parserType.label", "Parser Type"),
583
600
  " ",
584
- /* @__PURE__ */ p("span", {
601
+ /* @__PURE__ */ m("span", {
585
602
  className: "text-status-error-text",
586
603
  children: "*"
587
604
  })
588
605
  ]
589
- }), /* @__PURE__ */ p("div", {
606
+ }), /* @__PURE__ */ m("div", {
590
607
  className: "space-y-2",
591
- children: Object.keys(S).map((e) => {
592
- let t = S[e];
593
- return /* @__PURE__ */ m("label", {
608
+ children: Object.keys(C).map((e) => {
609
+ let t = C[e];
610
+ return /* @__PURE__ */ h("label", {
594
611
  className: `
595
612
  flex items-start gap-3 p-3
596
613
  rounded-md border
597
614
  cursor-pointer
598
615
  motion-safe:transition-colors
599
- ${k.type === e ? "border-action-primary-bg bg-action-primary-bg/5" : "border-transparent bg-bg-sunken hover:border-[var(--color-border-subtle)]"}
616
+ ${A.type === e ? "border-action-primary-bg bg-action-primary-bg/5" : "border-transparent bg-bg-sunken hover:border-[var(--color-border-subtle)]"}
600
617
  `,
601
- children: [/* @__PURE__ */ p("input", {
618
+ children: [/* @__PURE__ */ m("input", {
602
619
  type: "radio",
603
620
  name: "parserType",
604
621
  value: e,
605
- checked: k.type === e,
606
- onChange: () => Et(e),
622
+ checked: A.type === e,
623
+ onChange: () => It(e),
607
624
  className: "mt-1 w-4 h-4 text-action-primary-bg"
608
- }), /* @__PURE__ */ m("span", {
625
+ }), /* @__PURE__ */ h("span", {
609
626
  className: "min-w-0",
610
- children: [/* @__PURE__ */ p("span", {
627
+ children: [/* @__PURE__ */ m("span", {
611
628
  className: "block text-sm font-medium text-text-primary",
612
629
  children: t.name
613
- }), /* @__PURE__ */ p("span", {
630
+ }), /* @__PURE__ */ m("span", {
614
631
  className: "mt-0.5 block text-xs text-text-secondary",
615
632
  children: t.description
616
633
  })]
@@ -618,57 +635,57 @@ var b = i(function() {
618
635
  }, e);
619
636
  })
620
637
  })]
621
- }), /* @__PURE__ */ m("div", { children: [
622
- /* @__PURE__ */ m("label", {
638
+ }), /* @__PURE__ */ h("div", { children: [
639
+ /* @__PURE__ */ h("label", {
623
640
  htmlFor: "inputSinkKey",
624
- className: _,
641
+ className: v,
625
642
  children: [
626
- x("bigconsole.parsers.builder.fields.sourceDataSink.label", "Source DataSink"),
643
+ S("bigconsole.parsers.builder.fields.sourceDataSink.label", "Source DataSink"),
627
644
  " ",
628
- /* @__PURE__ */ p("span", {
645
+ /* @__PURE__ */ m("span", {
629
646
  className: "text-status-error-text",
630
647
  children: "*"
631
648
  })
632
649
  ]
633
650
  }),
634
- /* @__PURE__ */ m("select", {
651
+ /* @__PURE__ */ h("select", {
635
652
  id: "inputSinkKey",
636
- value: k.inputSinkKey,
637
- onChange: Ot,
638
- className: g(!!M.inputSinkKey),
639
- children: [/* @__PURE__ */ p("option", {
653
+ value: A.inputSinkKey,
654
+ onChange: Rt,
655
+ className: _(!!N.inputSinkKey),
656
+ children: [/* @__PURE__ */ m("option", {
640
657
  value: "",
641
- children: x("bigconsole.parsers.builder.fields.sourceDataSink.placeholder", "Select a DataSink...")
642
- }), q.map((e) => /* @__PURE__ */ p("option", {
658
+ children: S("bigconsole.parsers.builder.fields.sourceDataSink.placeholder", "Select a DataSink...")
659
+ }), J.map((e) => /* @__PURE__ */ m("option", {
643
660
  value: e.key,
644
661
  children: e.name || e.key
645
662
  }, e.id))]
646
663
  }),
647
- M.inputSinkKey && /* @__PURE__ */ p("p", {
664
+ N.inputSinkKey && /* @__PURE__ */ m("p", {
648
665
  className: "text-xs text-status-error-text mt-1.5",
649
- children: M.inputSinkKey
666
+ children: N.inputSinkKey
650
667
  }),
651
- q.length === 0 ? /* @__PURE__ */ p("p", {
652
- className: v,
653
- children: x("bigconsole.parsers.builder.fields.sourceDataSink.emptyState", "No DataSinks yet — create one first, then return here to build a parser for it.")
654
- }) : /* @__PURE__ */ p("p", {
655
- className: v,
668
+ J.length === 0 ? /* @__PURE__ */ m("p", {
669
+ className: y,
670
+ children: S("bigconsole.parsers.builder.fields.sourceDataSink.emptyState", "No DataSinks yet — create one first, then return here to build a parser for it.")
671
+ }) : /* @__PURE__ */ m("p", {
672
+ className: y,
656
673
  children: "Select the data source for this parser to transform."
657
674
  }),
658
- k.inputSinkKey && /* @__PURE__ */ m("div", {
675
+ A.inputSinkKey && /* @__PURE__ */ h("div", {
659
676
  className: "mt-3",
660
- children: [/* @__PURE__ */ m("button", {
677
+ children: [/* @__PURE__ */ h("button", {
661
678
  type: "button",
662
- onClick: Pt,
663
- "aria-expanded": W,
679
+ onClick: Kt,
680
+ "aria-expanded": G,
664
681
  "aria-controls": "parser-data-preview",
665
682
  className: "inline-flex min-h-control-md items-center gap-2 rounded-md text-sm text-action-primary-bg hover:text-action-primary-bgHover motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
666
683
  children: [
667
- p(W ? pe : me, { className: "w-4 h-4" }),
668
- /* @__PURE__ */ p(_e, { className: "w-4 h-4" }),
669
- x("bigconsole.parsers.builder.dataPreview.toggle", "Show Data Preview")
684
+ m(G ? ge : _e, { className: "w-4 h-4" }),
685
+ /* @__PURE__ */ m(be, { className: "w-4 h-4" }),
686
+ S("bigconsole.parsers.builder.dataPreview.toggle", "Show Data Preview")
670
687
  ]
671
- }), W && /* @__PURE__ */ p(t, {
688
+ }), G && /* @__PURE__ */ m(t, {
672
689
  id: "parser-data-preview",
673
690
  emphasis: "muted",
674
691
  padding: "compact",
@@ -677,265 +694,301 @@ var b = i(function() {
677
694
  description: "A slice of the payload stored on the selected DataSink.",
678
695
  className: "mt-3",
679
696
  "data-testid": "parser-data-preview",
680
- children: at ? /* @__PURE__ */ m("div", {
697
+ children: ht ? /* @__PURE__ */ h("div", {
681
698
  className: "flex items-center justify-center p-4",
682
- children: [/* @__PURE__ */ p(u, { className: "w-5 h-5 text-text-secondary animate-spin" }), /* @__PURE__ */ p("span", {
699
+ children: [/* @__PURE__ */ m(d, { className: "w-5 h-5 text-text-secondary animate-spin" }), /* @__PURE__ */ m("span", {
683
700
  className: "ml-2 text-sm text-text-secondary",
684
- children: x("bigconsole.parsers.builder.dataPreview.loading", "Loading sample…")
701
+ children: S("bigconsole.parsers.builder.dataPreview.loading", "Loading sample…")
685
702
  })]
686
- }) : st ? /* @__PURE__ */ p("p", {
703
+ }) : _t ? /* @__PURE__ */ m("p", {
687
704
  className: "text-sm text-status-error-text",
688
- children: st
689
- }) : rt ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("pre", {
705
+ children: _t
706
+ }) : pt ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("pre", {
690
707
  className: "max-h-48 min-w-0 overflow-auto rounded-md bg-bg-canvas p-3 font-mono text-xs text-text-primary",
691
- children: JSON.stringify(rt, null, 2)
692
- }), K && /* @__PURE__ */ m("p", {
693
- className: v,
708
+ children: JSON.stringify(pt, null, 2)
709
+ }), q && /* @__PURE__ */ h("p", {
710
+ className: y,
694
711
  children: [
695
- x("bigconsole.parsers.builder.dataPreview.previewingSample", "Previewing a sample"),
696
- K.total == null ? "" : x("bigconsole.parsers.builder.dataPreview.rowRange", " (first {{shown}} of {{total}} rows)", {
697
- shown: Math.min(y, K.total),
698
- total: K.total
712
+ S("bigconsole.parsers.builder.dataPreview.previewingSample", "Previewing a sample"),
713
+ q.total == null ? "" : S("bigconsole.parsers.builder.dataPreview.rowRange", " (first {{shown}} of {{total}} rows)", {
714
+ shown: Math.min(b, q.total),
715
+ total: q.total
699
716
  }),
700
717
  " · ",
701
- K.sinkName
718
+ q.sinkName
702
719
  ]
703
- })] }) : /* @__PURE__ */ p("p", {
720
+ })] }) : /* @__PURE__ */ m("p", {
704
721
  className: "text-center text-sm text-text-secondary",
705
- children: x("bigconsole.parsers.builder.dataPreview.noData", "No data available")
722
+ children: S("bigconsole.parsers.builder.dataPreview.noData", "No data available")
706
723
  })
707
724
  })]
708
725
  })
709
726
  ] })]
710
727
  }),
711
- w === 2 && /* @__PURE__ */ m(t, {
728
+ T === 2 && /* @__PURE__ */ h(t, {
712
729
  emphasis: "primary",
713
730
  headingLevel: 2,
714
731
  title: "Test expression",
715
732
  description: "Write the expression, then run it against sample data before you save.",
716
- icon: /* @__PURE__ */ p(be, { className: "h-icon-sm w-icon-sm" }),
717
- meta: $,
733
+ icon: /* @__PURE__ */ m(Ce, { className: "h-icon-sm w-icon-sm" }),
734
+ meta: an,
718
735
  bodyClassName: "space-y-5",
719
736
  "data-testid": "parser-test-expression",
720
737
  children: [
721
- /* @__PURE__ */ m("div", { children: [
722
- /* @__PURE__ */ m("label", {
738
+ /* @__PURE__ */ h("div", { children: [
739
+ /* @__PURE__ */ h("label", {
723
740
  htmlFor: "expression",
724
- className: _,
741
+ className: v,
725
742
  children: [
726
- x("bigconsole.parsers.builder.fields.expression.label", "Expression"),
743
+ S("bigconsole.parsers.builder.fields.expression.label", "Expression"),
727
744
  " ",
728
- /* @__PURE__ */ p("span", {
745
+ /* @__PURE__ */ m("span", {
729
746
  className: "text-status-error-text",
730
747
  children: "*"
731
748
  })
732
749
  ]
733
750
  }),
734
- /* @__PURE__ */ p("textarea", {
751
+ /* @__PURE__ */ m("textarea", {
735
752
  id: "expression",
736
- value: k.expression,
737
- onChange: Dt,
738
- placeholder: Vt.placeholder,
753
+ value: A.expression,
754
+ onChange: Lt,
755
+ placeholder: nn.placeholder,
739
756
  rows: 8,
740
- className: g(!!M.expression, "font-mono resize-y min-h-[12rem]")
757
+ className: _(!!N.expression, "font-mono resize-y min-h-[12rem]")
741
758
  }),
742
- M.expression && /* @__PURE__ */ p("p", {
759
+ N.expression && /* @__PURE__ */ m("p", {
743
760
  className: "text-xs text-status-error-text mt-1.5",
744
- children: M.expression
761
+ children: N.expression
745
762
  }),
746
- /* @__PURE__ */ p("p", {
747
- className: v,
748
- children: x("bigconsole.parsers.builder.fields.expression.example", "Example: {{example}}", { example: Vt.example })
763
+ /* @__PURE__ */ m("p", {
764
+ className: y,
765
+ children: S("bigconsole.parsers.builder.fields.expression.example", "Example: {{example}}", { example: nn.example })
749
766
  })
750
767
  ] }),
751
- /* @__PURE__ */ m("div", { children: [
752
- /* @__PURE__ */ m("div", {
768
+ /* @__PURE__ */ h("div", { children: [
769
+ /* @__PURE__ */ h("div", {
753
770
  className: "mb-2 flex flex-wrap items-center justify-between gap-control-gap",
754
- children: [/* @__PURE__ */ m("label", {
771
+ children: [/* @__PURE__ */ h("label", {
755
772
  htmlFor: "test-input",
756
- className: `${_} mb-0 flex flex-wrap items-center gap-2`,
757
- children: [x("bigconsole.parsers.builder.test.inputJsonLabel", "Input JSON"), /* @__PURE__ */ p("span", {
758
- className: `rounded border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${V ? "text-action-primary-bg bg-action-primary-bg/10 border-action-primary-bg/30" : "text-text-secondary bg-bg-sunken border-[var(--color-border-subtle)]"}`,
759
- children: V ? x("bigconsole.parsers.builder.test.referenceMode", "Reference mode") : x("bigconsole.parsers.builder.test.sampleMode", "Sample mode")
773
+ className: `${v} mb-0 flex flex-wrap items-center gap-2`,
774
+ children: [S("bigconsole.parsers.builder.test.inputJsonLabel", "Input JSON"), /* @__PURE__ */ m("span", {
775
+ className: `rounded border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${H ? "text-action-primary-bg bg-action-primary-bg/10 border-action-primary-bg/30" : "text-text-secondary bg-bg-sunken border-[var(--color-border-subtle)]"}`,
776
+ children: H ? S("bigconsole.parsers.builder.test.referenceMode", "Reference mode") : S("bigconsole.parsers.builder.test.sampleMode", "Sample mode")
760
777
  })]
761
- }), /* @__PURE__ */ m("div", {
778
+ }), /* @__PURE__ */ h("div", {
762
779
  className: "flex flex-wrap items-center gap-2",
763
- children: [k.inputSinkKey && !V && /* @__PURE__ */ m("button", {
780
+ children: [A.inputSinkKey && !H && /* @__PURE__ */ h("button", {
764
781
  type: "button",
765
- onClick: Mt,
766
- disabled: et,
782
+ onClick: Wt,
783
+ disabled: ut,
767
784
  className: "inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border border-action-primary-bg px-2.5 py-1.5 text-xs font-semibold text-action-primary-bg hover:bg-action-primary-bg/10 motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface disabled:opacity-50 disabled:cursor-not-allowed",
768
- children: [et ? /* @__PURE__ */ p(u, { className: "w-3.5 h-3.5 animate-spin" }) : /* @__PURE__ */ p(ge, { className: "w-3.5 h-3.5" }), x("bigconsole.parsers.builder.actions.loadSample", "Load Sample")]
769
- }), V && /* @__PURE__ */ m("button", {
785
+ children: [ut ? /* @__PURE__ */ m(d, { className: "w-3.5 h-3.5 animate-spin" }) : /* @__PURE__ */ m(ye, { className: "w-3.5 h-3.5" }), S("bigconsole.parsers.builder.actions.loadSample", "Load Sample")]
786
+ }), H && /* @__PURE__ */ h("button", {
770
787
  type: "button",
771
- onClick: Nt,
788
+ onClick: Gt,
772
789
  className: "inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border border-[var(--color-border-default)] px-2.5 py-1.5 text-xs font-semibold text-text-primary hover:bg-bg-sunken motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
773
- children: [/* @__PURE__ */ p(Ce, { className: "w-3.5 h-3.5" }), x("bigconsole.parsers.builder.actions.clear", "Clear")]
790
+ children: [/* @__PURE__ */ m(Ee, { className: "w-3.5 h-3.5" }), S("bigconsole.parsers.builder.actions.clear", "Clear")]
774
791
  })]
775
792
  })]
776
793
  }),
777
- /* @__PURE__ */ p("textarea", {
794
+ /* @__PURE__ */ m("textarea", {
778
795
  id: "test-input",
779
- value: P,
780
- onChange: jt,
781
- readOnly: V,
782
- placeholder: x("bigconsole.parsers.builder.test.inputPlaceholder", "Type sample JSON to test against it — or Load a sample from the source…"),
796
+ value: $e,
797
+ onChange: Vt,
798
+ onKeyDown: Ht,
799
+ onPaste: Ut,
800
+ readOnly: H,
801
+ "aria-describedby": H ? "test-input-locked-hint" : void 0,
802
+ placeholder: S("bigconsole.parsers.builder.test.inputPlaceholder", "Type sample JSON to test against it — or Load a sample from the source…"),
783
803
  rows: 8,
784
- className: g(!1, `font-mono leading-relaxed resize-y ${V ? "bg-bg-sunken opacity-80 cursor-not-allowed" : ""}`)
804
+ className: _(!1, `font-mono leading-relaxed resize-y ${H ? "bg-bg-sunken opacity-80 cursor-not-allowed" : ""}`)
785
805
  }),
786
- V && H ? /* @__PURE__ */ m("p", {
787
- className: v,
806
+ H && st && /* @__PURE__ */ h("p", {
807
+ role: "status",
808
+ "data-testid": "parser-test-input-locked-notice",
809
+ className: "mt-2 flex items-start gap-1.5 rounded-md border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bgSubtle)] px-2.5 py-1.5 text-xs text-[var(--color-status-warning-text)]",
810
+ children: [/* @__PURE__ */ m(u, {
811
+ className: "mt-0.5 h-3.5 w-3.5 shrink-0",
812
+ "aria-hidden": "true"
813
+ }), S("bigconsole.parsers.builder.test.lockedNotice", "This sample is read-only in Reference mode — tests run against the source sink. Press Clear to type your own test input.")]
814
+ }),
815
+ H && U ? /* @__PURE__ */ h("p", {
816
+ id: "test-input-locked-hint",
817
+ className: y,
788
818
  children: [
789
- x("bigconsole.parsers.builder.test.loadedSample", "Loaded a small sample"),
790
- H.total == null ? "" : x("bigconsole.parsers.builder.dataPreview.rowRange", " (first {{shown}} of {{total}} rows)", {
791
- shown: Math.min(y, H.total),
792
- total: H.total
819
+ S("bigconsole.parsers.builder.test.loadedSample", "Loaded a small sample"),
820
+ U.total == null ? "" : S("bigconsole.parsers.builder.dataPreview.rowRange", " (first {{shown}} of {{total}} rows)", {
821
+ shown: Math.min(b, U.total),
822
+ total: U.total
793
823
  }),
794
824
  " ",
795
- x("bigconsole.parsers.builder.test.loadedSampleFrom", "from {{sinkName}} · locked — press Clear to edit.", { sinkName: H.sinkName })
825
+ S("bigconsole.parsers.builder.test.loadedSampleFrom", "from {{sinkName}} · locked — press Clear to edit.", { sinkName: U.sinkName })
796
826
  ]
797
- }) : /* @__PURE__ */ p("p", {
798
- className: v,
799
- children: x("bigconsole.parsers.builder.test.inputHelper", "Type sample JSON to test against it, or Load a sample from the source.")
827
+ }) : /* @__PURE__ */ m("p", {
828
+ className: y,
829
+ children: S("bigconsole.parsers.builder.test.inputHelper", "Type sample JSON to test against it, or Load a sample from the source.")
800
830
  })
801
831
  ] }),
802
- /* @__PURE__ */ p(ce, {
832
+ /* @__PURE__ */ m(fe, {
803
833
  permission: r.PARSER_TEST,
804
834
  deniedBehavior: "disable",
805
- children: /* @__PURE__ */ p(d, {
835
+ children: /* @__PURE__ */ m(f, {
806
836
  type: "button",
807
- onClick: Ft,
808
- disabled: Xe || !k.expression.trim(),
837
+ onClick: qt,
838
+ disabled: tt || !A.expression.trim(),
809
839
  variant: "default",
810
840
  className: "w-full",
811
- children: Xe ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(u, { className: "w-4 h-4 mr-2 animate-spin" }), x("bigconsole.parsers.builder.actions.testing", "Testing...")] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(be, { className: "w-4 h-4 mr-2" }), x("bigconsole.parsers.builder.actions.runTest", "Run Test")] })
841
+ children: tt ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(d, { className: "w-4 h-4 mr-2 animate-spin" }), S("bigconsole.parsers.builder.actions.testing", "Testing...")] }) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(Ce, { className: "w-4 h-4 mr-2" }), S("bigconsole.parsers.builder.actions.runTest", "Run Test")] })
812
842
  })
813
843
  }),
814
- (Ye || L) && /* @__PURE__ */ m(t, {
844
+ Jt === "untested" && !tt && /* @__PURE__ */ m("p", {
845
+ className: y,
846
+ role: "status",
847
+ "data-testid": "parser-test-gate",
848
+ children: L && !Yt ? S("bigconsole.parsers.builder.test.gateFailed", "The test failed. Fix the expression and run the test again to continue.") : S("bigconsole.parsers.builder.test.gateUntested", "Run a passing test of this expression to continue.")
849
+ }),
850
+ Jt === "untestable" && /* @__PURE__ */ h("p", {
851
+ role: "status",
852
+ "data-testid": "parser-test-gate",
853
+ className: "flex items-start gap-1.5 rounded-md border border-[var(--color-status-warning-border)] bg-[var(--color-status-warning-bgSubtle)] px-2.5 py-1.5 text-xs text-[var(--color-status-warning-text)]",
854
+ children: [/* @__PURE__ */ m(u, {
855
+ className: "mt-0.5 h-3.5 w-3.5 shrink-0",
856
+ "aria-hidden": "true"
857
+ }), S("bigconsole.parsers.builder.test.gateUntestable", "You don’t have permission to run tests, so this expression has not been tested. Ask someone who can to test it before dashboards rely on it.")]
858
+ }),
859
+ (et || L) && /* @__PURE__ */ h(t, {
815
860
  emphasis: "muted",
816
861
  padding: "compact",
817
862
  headingLevel: 3,
818
863
  tone: L ? "danger" : "success",
819
- title: L ? x("bigconsole.parsers.builder.test.errorOutputLabel", "Error Output") : x("bigconsole.parsers.builder.test.outputLabel", "Output"),
820
- meta: L ? /* @__PURE__ */ m("span", {
864
+ title: L ? S("bigconsole.parsers.builder.test.errorOutputLabel", "Error Output") : S("bigconsole.parsers.builder.test.outputLabel", "Output"),
865
+ meta: L ? /* @__PURE__ */ h("span", {
821
866
  className: "inline-flex items-center gap-1 text-xs text-[var(--color-status-error-text)]",
822
867
  children: [
823
- /* @__PURE__ */ p(ue, { className: "w-3 h-3" }),
868
+ /* @__PURE__ */ m(u, { className: "w-3 h-3" }),
824
869
  " ",
825
- x("bigconsole.parsers.builder.test.failed", "Failed")
870
+ S("bigconsole.parsers.builder.test.failed", "Failed")
826
871
  ]
827
- }) : /* @__PURE__ */ m("span", {
872
+ }) : /* @__PURE__ */ h("span", {
828
873
  className: "inline-flex items-center gap-1 text-xs text-status-success-text",
829
874
  children: [
830
- /* @__PURE__ */ p(fe, { className: "w-3 h-3" }),
875
+ /* @__PURE__ */ m(he, { className: "w-3 h-3" }),
831
876
  " ",
832
- x("bigconsole.parsers.builder.test.passed", "Passed")
877
+ S("bigconsole.parsers.builder.test.passed", "Passed")
833
878
  ]
834
879
  }),
835
880
  "data-testid": "parser-test-output",
836
- children: [/* @__PURE__ */ p("pre", {
837
- className: "max-h-[150px] min-w-0 overflow-auto rounded-md bg-bg-canvas px-3 py-2.5 font-mono text-xs leading-relaxed text-text-primary",
838
- children: L || Ye
839
- }), z && !L && /* @__PURE__ */ m("p", {
840
- className: v,
841
- children: [
842
- x("bigconsole.parsers.builder.test.testedSample", "Tested a sample"),
843
- z.sampledRows != null && z.totalRows != null ? x("bigconsole.parsers.builder.dataPreview.rowRange", " (first {{shown}} of {{total}} rows)", {
844
- shown: z.sampledRows,
845
- total: z.totalRows
846
- }) : "",
847
- x("bigconsole.parsers.builder.test.testedSampleNote", " — a saved parser runs over the full source, so results may differ.")
848
- ]
849
- })]
881
+ children: [
882
+ Yt && /* @__PURE__ */ m("p", {
883
+ className: `${y} mb-2`,
884
+ "data-testid": "parser-test-output-stale",
885
+ children: S("bigconsole.parsers.builder.test.staleResult", "This result is from an earlier version of the expression. Run the test again.")
886
+ }),
887
+ /* @__PURE__ */ m("pre", {
888
+ className: "max-h-[150px] min-w-0 overflow-auto rounded-md bg-bg-canvas px-3 py-2.5 font-mono text-xs leading-relaxed text-text-primary",
889
+ children: L || et
890
+ }),
891
+ z && !L && /* @__PURE__ */ h("p", {
892
+ className: y,
893
+ children: [
894
+ S("bigconsole.parsers.builder.test.testedSample", "Tested a sample"),
895
+ z.sampledRows != null && z.totalRows != null ? S("bigconsole.parsers.builder.dataPreview.rowRange", " (first {{shown}} of {{total}} rows)", {
896
+ shown: z.sampledRows,
897
+ total: z.totalRows
898
+ }) : "",
899
+ S("bigconsole.parsers.builder.test.testedSampleNote", " — a saved parser runs over the full source, so results may differ.")
900
+ ]
901
+ })
902
+ ]
850
903
  }),
851
- !Ye && !L && /* @__PURE__ */ p(t, {
904
+ !et && !L && /* @__PURE__ */ m(t, {
852
905
  emphasis: "muted",
853
906
  padding: "compact",
854
907
  headingLevel: 3,
855
908
  title: "No run yet",
856
909
  "data-testid": "parser-test-empty",
857
- children: /* @__PURE__ */ m("p", {
910
+ children: /* @__PURE__ */ h("p", {
858
911
  className: "text-xs leading-relaxed text-text-secondary",
859
912
  children: [
860
- /* @__PURE__ */ p("strong", { children: x("bigconsole.parsers.builder.test.tipLabel", "Tip:") }),
913
+ /* @__PURE__ */ m("strong", { children: S("bigconsole.parsers.builder.test.tipLabel", "Tip:") }),
861
914
  " ",
862
- x("bigconsole.parsers.builder.test.tipBody", "write your expression and click “Run Test” to see the transformation.")
915
+ S("bigconsole.parsers.builder.test.tipBody", "write your expression and click “Run Test” to see the transformation.")
863
916
  ]
864
917
  })
865
918
  })
866
919
  ]
867
920
  }),
868
- w === 3 && /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(t, {
921
+ T === 3 && /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(t, {
869
922
  emphasis: "primary",
870
923
  headingLevel: 2,
871
- title: x("bigconsole.parsers.builder.review.cacheDurationLabel", "Cache Duration"),
872
- description: x("bigconsole.parsers.builder.review.cacheDurationHelper", "How long should data be cached before refreshing?"),
873
- icon: /* @__PURE__ */ p(Se, { className: "h-icon-sm w-icon-sm" }),
874
- meta: $,
924
+ title: S("bigconsole.parsers.builder.review.cacheDurationLabel", "Cache Duration"),
925
+ description: S("bigconsole.parsers.builder.review.cacheDurationHelper", "How long should data be cached before refreshing?"),
926
+ icon: /* @__PURE__ */ m(Te, { className: "h-icon-sm w-icon-sm" }),
927
+ meta: an,
875
928
  "data-testid": "parser-advanced-settings",
876
- children: /* @__PURE__ */ p(ae, {
877
- value: k.ttl,
878
- onChange: kt,
879
- error: M.ttl,
929
+ children: /* @__PURE__ */ m(ae, {
930
+ value: A.ttl,
931
+ onChange: zt,
932
+ error: N.ttl,
880
933
  hideLabel: !0
881
934
  })
882
- }), /* @__PURE__ */ p(t, {
935
+ }), /* @__PURE__ */ m(t, {
883
936
  emphasis: "muted",
884
937
  headingLevel: 2,
885
- title: x("bigconsole.parsers.builder.review.label", "Review"),
938
+ title: S("bigconsole.parsers.builder.review.label", "Review"),
886
939
  description: "Check these details before you save.",
887
940
  "data-testid": "parser-review",
888
- children: /* @__PURE__ */ p("div", {
941
+ children: /* @__PURE__ */ m("div", {
889
942
  className: "overflow-hidden rounded-lg border border-[var(--color-border-subtle)]",
890
943
  children: [
891
- [x("bigconsole.parsers.builder.review.name", "Name"), k.name || "—"],
892
- [x("bigconsole.parsers.builder.review.outputKey", "Output Key"), k.outputKey || "—"],
893
- [x("bigconsole.parsers.builder.review.scope", "Scope"), O ? E === "default" ? x("bigconsole.parsers.builder.review.scopeGlobal", "Global") : _t.find((e) => e.id === E)?.name || E : x("bigconsole.parsers.builder.review.scopeDashboard", "Dashboard")],
894
- [x("bigconsole.parsers.builder.review.type", "Type"), S[k.type].name],
895
- [x("bigconsole.parsers.builder.review.source", "Source"), X || "—"]
896
- ].map(([e, t]) => /* @__PURE__ */ m("div", {
944
+ [S("bigconsole.parsers.builder.review.name", "Name"), A.name || "—"],
945
+ [S("bigconsole.parsers.builder.review.outputKey", "Output Key"), A.outputKey || "—"],
946
+ [S("bigconsole.parsers.builder.review.scope", "Scope"), k ? D === "default" ? S("bigconsole.parsers.builder.review.scopeGlobal", "Global") : Dt.find((e) => e.id === D)?.name || D : S("bigconsole.parsers.builder.review.scopeDashboard", "Dashboard")],
947
+ [S("bigconsole.parsers.builder.review.type", "Type"), C[A.type].name],
948
+ [S("bigconsole.parsers.builder.review.source", "Source"), Z || "—"]
949
+ ].map(([e, t]) => /* @__PURE__ */ h("div", {
897
950
  className: "flex flex-wrap items-center justify-between gap-3 border-b border-[var(--color-border-subtle)] px-4 py-2.5 text-sm last:border-b-0",
898
- children: [/* @__PURE__ */ p("span", {
951
+ children: [/* @__PURE__ */ m("span", {
899
952
  className: "text-text-secondary",
900
953
  children: e
901
- }), /* @__PURE__ */ p("span", {
954
+ }), /* @__PURE__ */ m("span", {
902
955
  className: "min-w-0 break-words text-right font-medium text-text-primary",
903
956
  children: t
904
957
  })]
905
958
  }, e))
906
959
  })
907
960
  })] }),
908
- /* @__PURE__ */ m("div", {
961
+ /* @__PURE__ */ h("div", {
909
962
  className: "sticky bottom-0 z-10 flex flex-col-reverse gap-control-gap border-t border-[var(--color-border-subtle)] bg-bg-canvas py-form-gap sm:flex-row sm:items-center sm:justify-between",
910
- children: [w === 0 ? /* @__PURE__ */ p(d, {
963
+ children: [T === 0 ? /* @__PURE__ */ m(f, {
911
964
  type: "button",
912
- onClick: Z,
965
+ onClick: Q,
913
966
  variant: "secondary",
914
967
  className: "w-full sm:w-auto",
915
- children: x("bigconsole.parsers.builder.actions.cancel", "Cancel")
916
- }) : /* @__PURE__ */ m(d, {
968
+ children: S("bigconsole.parsers.builder.actions.cancel", "Cancel")
969
+ }) : /* @__PURE__ */ h(f, {
917
970
  type: "button",
918
- onClick: Bt,
971
+ onClick: tn,
919
972
  variant: "secondary",
920
973
  className: "w-full sm:w-auto",
921
- children: [/* @__PURE__ */ p(de, { className: "w-4 h-4 mr-2" }), x("bigconsole.parsers.builder.actions.back", "Back")]
922
- }), Ht ? /* @__PURE__ */ p(ce, {
923
- permission: Ve,
974
+ children: [/* @__PURE__ */ m(me, { className: "w-4 h-4 mr-2" }), S("bigconsole.parsers.builder.actions.back", "Back")]
975
+ }), rn ? /* @__PURE__ */ m(fe, {
976
+ permission: We,
924
977
  deniedBehavior: "disable",
925
- children: /* @__PURE__ */ p(d, {
978
+ children: /* @__PURE__ */ m(f, {
926
979
  type: "submit",
927
- disabled: !Lt || Ge || !Be,
980
+ disabled: !Zt || Ye || !Ue,
928
981
  variant: "default",
929
982
  className: "w-full sm:w-auto",
930
- children: Ge ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(u, { className: "w-4 h-4 mr-2 animate-spin" }), x("bigconsole.parsers.builder.actions.saving", "Saving...")] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(xe, { className: "w-4 h-4 mr-2" }), D ? x("bigconsole.parsers.builder.actions.saveChanges", "Save Changes") : x("bigconsole.parsers.builder.actions.createParser", "Create Parser")] })
983
+ children: Ye ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(d, { className: "w-4 h-4 mr-2 animate-spin" }), S("bigconsole.parsers.builder.actions.saving", "Saving...")] }) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(we, { className: "w-4 h-4 mr-2" }), O ? S("bigconsole.parsers.builder.actions.saveChanges", "Save Changes") : S("bigconsole.parsers.builder.actions.createParser", "Create Parser")] })
931
984
  })
932
- }) : /* @__PURE__ */ m(d, {
985
+ }) : /* @__PURE__ */ h(f, {
933
986
  type: "button",
934
- onClick: zt,
935
- disabled: !Q(w),
987
+ onClick: en,
988
+ disabled: !Qt(T),
936
989
  variant: "default",
937
990
  className: "w-full sm:w-auto",
938
- children: [x("bigconsole.parsers.builder.actions.next", "Next"), /* @__PURE__ */ p(me, { className: "w-4 h-4 ml-2" })]
991
+ children: [S("bigconsole.parsers.builder.actions.next", "Next"), /* @__PURE__ */ m(_e, { className: "w-4 h-4 ml-2" })]
939
992
  })]
940
993
  })
941
994
  ]
@@ -945,4 +998,4 @@ var b = i(function() {
945
998
  });
946
999
  });
947
1000
  //#endregion
948
- export { b as ParserBuilderPage, b as default };
1001
+ export { x as ParserBuilderPage, x as default };