@burdenoff/microfe-bigconsole 2026.730.7 → 2026.731.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,20 +4,47 @@ import t from "../hooks/useDashboardOperations.js";
4
4
  import ee from "../hooks/useDataSinkOperations.js";
5
5
  import te from "../hooks/useParserOperations.js";
6
6
  import ne from "../components/datasink/CacheTTLSelector.js";
7
- import { memo as n, useCallback as r, useEffect as i, useMemo as re, useState as a } from "react";
7
+ import { memo as n, useCallback as r, useEffect as i, useMemo as a, useRef as re, useState as o } from "react";
8
8
  import { useParams as ie } from "react-router-dom";
9
- import { AlertCircle as o, ArrowLeft as ae, CheckCircle2 as oe, ChevronDown as se, ChevronRight as ce, Code as le, Eye as ue, FileCode2 as de, LayoutDashboard as fe, Loader2 as s, Play as c, Save as pe, Settings as me } from "lucide-react";
10
- import { Button as l, Card as u, CardContent as d, CardHeader as f, CardTitle as p, GlassCard as he, PagePurpose as ge } from "@burdenoff/fe-libs/ui";
11
- import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
9
+ import { AlertCircle as s, ArrowLeft as ae, CheckCircle2 as oe, ChevronDown as se, ChevronRight as ce, Code as le, Download as ue, Eye as de, FileCode2 as fe, LayoutDashboard as pe, Loader2 as c, Play as l, Save as me, Settings as he, X as ge } from "lucide-react";
10
+ import { Button as u, CardContent as _e, CardHeader as ve, CardTitle as ye, GlassCard as be, PagePurpose as xe, Stepper as Se } from "@burdenoff/fe-libs/ui";
11
+ import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
12
12
  //#region src/bigconsole/pages/ParserBuilderPage.tsx
13
- function _e(e) {
13
+ var m = 25, Ce = "default", we = [
14
+ "details",
15
+ "source",
16
+ "expression",
17
+ "review"
18
+ ], h = [
19
+ {
20
+ key: "details",
21
+ label: "Details",
22
+ description: "Name & scope"
23
+ },
24
+ {
25
+ key: "source",
26
+ label: "Source & Type",
27
+ description: "Engine & data"
28
+ },
29
+ {
30
+ key: "expression",
31
+ label: "Expression & Test",
32
+ description: "Transform & verify"
33
+ },
34
+ {
35
+ key: "review",
36
+ label: "Cache & Review",
37
+ description: "Finish up"
38
+ }
39
+ ];
40
+ function Te(e) {
14
41
  return e.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").substring(0, 64);
15
42
  }
16
- function ve(e) {
43
+ function Ee(e) {
17
44
  let t = {};
18
45
  return e.name.trim() ? e.name.length < 2 && (t.name = "Name must be at least 2 characters") : t.name = "Name is required", e.outputKey.trim() ? /^[a-z0-9_]+$/.test(e.outputKey) || (t.outputKey = "Output key can only contain lowercase letters, numbers, and underscores") : t.outputKey = "Output key is required", e.expression.trim() || (t.expression = "Expression is required"), e.inputSinkKey.trim() || (t.inputSinkKey = "Source DataSink is required"), e.ttl != null && e.ttl > 0 && (e.ttl < 30 || e.ttl > 86400) && (t.ttl = "Cache duration must be between 30 and 86400 seconds"), t;
19
46
  }
20
- var _ = {
47
+ var g = {
21
48
  jq: {
22
49
  name: "JQ",
23
50
  description: "Lightweight JSON processor - fast and efficient for simple transformations",
@@ -30,8 +57,8 @@ var _ = {
30
57
  placeholder: "$sum(data[*].value)",
31
58
  example: "$sum(data.values) - Calculate sum of values"
32
59
  }
33
- }, v = "default", y = n(function() {
34
- let { parserId: n, consoleId: y } = ie(), b = e(), [x, S] = a(v), C = y || x || v, w = n !== "new" && !!n, T = !y, [E, D] = a({
60
+ }, _ = "w-full px-3 py-2.5 text-sm text-text-primary bg-bg-surface border rounded-md placeholder:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg transition-all", v = n(function() {
61
+ let { parserId: n, consoleId: v } = ie(), De = e(), [y, b] = o(0), [x, Oe] = o(Ce), S = v || x || Ce, C = n !== "new" && !!n, w = !v, [T, E] = o({
35
62
  name: "",
36
63
  outputKey: "",
37
64
  description: "",
@@ -39,690 +66,752 @@ var _ = {
39
66
  expression: "",
40
67
  inputSinkKey: "",
41
68
  ttl: 900
42
- }), [O, k] = a({}), [A, j] = a(!1), [M, N] = a(!1), [P, F] = a(null), [I, L] = a("{\n \"data\": [\n {\"name\": \"Item 1\", \"count\": 10},\n {\"name\": \"Item 2\", \"count\": 20}\n ]\n}"), [R, z] = a(""), [B, V] = a(null), [H, U] = a(!1), [W, G] = a(!1), [K, ye] = a(null), [be, q] = a(!1), [J, Y] = a(null), { loading: xe, error: Se, parsers: Ce, fetchParser: X, createParser: Z, updateParser: we, testParserExpression: Te } = te({
43
- consoleId: C || "",
69
+ }), [D, O] = o({}), [k, ke] = o(!1), [Ae, je] = o(!1), [Me, Ne] = o(null), [A, j] = o("{\n \"data\": [\n {\"name\": \"Item 1\", \"count\": 10},\n {\"name\": \"Item 2\", \"count\": 20}\n ]\n}"), [M, N] = o(""), [P, F] = o(null), [Pe, Fe] = o(!1), [I, L] = o(null), [R, z] = o(!1), [B, V] = o(null), [Ie, Le] = o(!1), H = re(T.inputSinkKey);
70
+ i(() => {
71
+ H.current = T.inputSinkKey;
72
+ }, [T.inputSinkKey]);
73
+ let [U, W] = o(!1), [Re, ze] = o(null), [Be, Ve] = o(!1), [He, G] = o(null), [K, Ue] = o(null), { loading: We, error: Ge, parsers: Ke, fetchParser: qe, createParser: Je, updateParser: Ye, testParserExpression: Xe } = te({
74
+ consoleId: S || "",
44
75
  skipFetch: !0
45
- }), { dataSinks: Ee, fetchDataSinks: De, getDataSinkData: Q } = ee({ skipFetch: !0 }), { dashboards: Oe, fetchDashboards: ke, loading: Ae } = t(), $ = w ? Ce.find((e) => e.id === n) : null;
76
+ }), { dataSinks: q, fetchDataSinks: Ze, getDataSinkData: J } = ee({ skipFetch: !0 }), { dashboards: Qe, fetchDashboards: $e, loading: et } = t(), Y = C ? Ke.find((e) => e.id === n) : null;
46
77
  i(() => {
47
- De(), w && n && X(n), T && ke();
78
+ Ze(), C && n && qe(n), w && $e();
48
79
  }, [
49
- w,
80
+ C,
50
81
  n,
51
- X,
52
- De,
53
- T,
54
- ke
82
+ qe,
83
+ Ze,
84
+ w,
85
+ $e
55
86
  ]), i(() => {
56
- $ && (D({
57
- name: $.name || "",
58
- outputKey: $.outputKey || "",
59
- description: $.description || "",
60
- type: $.type,
61
- expression: $.expression || "",
62
- inputSinkKey: $.inputSinkKey || "",
63
- ttl: $.ttl ?? null
64
- }), j(!0), $.consoleId && S($.consoleId));
65
- }, [$]);
66
- let je = r((e) => {
87
+ Y && (E({
88
+ name: Y.name || "",
89
+ outputKey: Y.outputKey || "",
90
+ description: Y.description || "",
91
+ type: Y.type,
92
+ expression: Y.expression || "",
93
+ inputSinkKey: Y.inputSinkKey || "",
94
+ ttl: Y.ttl ?? null
95
+ }), ke(!0), Y.consoleId && Oe(Y.consoleId));
96
+ }, [Y]);
97
+ let X = a(() => q.find((e) => e.key === T.inputSinkKey)?.name || T.inputSinkKey, [q, T.inputSinkKey]), tt = r((e) => {
67
98
  let t = e.target.value;
68
- D((e) => ({
99
+ E((e) => ({
69
100
  ...e,
70
101
  name: t,
71
- outputKey: A ? e.outputKey : _e(t)
72
- })), k((e) => ({
102
+ outputKey: k ? e.outputKey : Te(t)
103
+ })), O((e) => ({
73
104
  ...e,
74
105
  name: void 0
75
106
  }));
76
- }, [A]), Me = r((e) => {
107
+ }, [k]), nt = r((e) => {
77
108
  let t = e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, "");
78
- D((e) => ({
109
+ E((e) => ({
79
110
  ...e,
80
111
  outputKey: t
81
- })), j(!0), k((e) => ({
112
+ })), ke(!0), O((e) => ({
82
113
  ...e,
83
114
  outputKey: void 0
84
115
  }));
85
- }, []), Ne = r((e) => {
86
- D((t) => ({
116
+ }, []), rt = r((e) => {
117
+ E((t) => ({
87
118
  ...t,
88
119
  description: e.target.value
89
120
  }));
90
- }, []), Pe = r((e) => {
91
- D((t) => ({
121
+ }, []), it = r((e) => {
122
+ E((t) => ({
92
123
  ...t,
93
124
  type: e
94
- })), z(""), V(null);
95
- }, []), Fe = r((e) => {
96
- D((t) => ({
125
+ })), N(""), F(null);
126
+ }, []), at = r((e) => {
127
+ E((t) => ({
97
128
  ...t,
98
129
  expression: e.target.value
99
- })), k((e) => ({
130
+ })), O((e) => ({
100
131
  ...e,
101
132
  expression: void 0
102
133
  }));
103
- }, []), Ie = r((e) => {
104
- D((t) => ({
134
+ }, []), ot = r((e) => {
135
+ E((t) => ({
105
136
  ...t,
106
137
  inputSinkKey: e.target.value
107
- })), k((e) => ({
138
+ })), O((e) => ({
108
139
  ...e,
109
140
  inputSinkKey: void 0
110
- }));
111
- }, []), Le = r((e) => {
112
- D((t) => ({
141
+ })), W(!1), ze(null), Ue(null), G(null), R && (j(""), z(!1)), V(null), N(""), F(null), L(null);
142
+ }, [R]), st = r((e) => {
143
+ E((t) => ({
113
144
  ...t,
114
145
  ttl: e
115
- })), k((e) => ({
146
+ })), O((e) => ({
116
147
  ...e,
117
148
  ttl: void 0
118
149
  }));
119
- }, []), Re = r((e) => {
120
- S(e.target.value);
121
- }, []), ze = r(async () => {
122
- if (E.inputSinkKey) try {
123
- let e = await Q({ key: E.inputSinkKey });
124
- e?.raw && L(JSON.stringify(e.raw, null, 2));
125
- } catch {}
126
- }, [E.inputSinkKey, Q]), Be = r(async () => {
127
- if (W) {
128
- G(!1);
150
+ }, []), ct = r((e) => {
151
+ Oe(e.target.value);
152
+ }, []), lt = r((e) => {
153
+ j(e.target.value);
154
+ }, []), ut = r(async () => {
155
+ let e = T.inputSinkKey;
156
+ if (e) {
157
+ Le(!0);
158
+ try {
159
+ let t = await J({ key: e }, { limit: m });
160
+ if (H.current !== e) return;
161
+ t?.raw !== void 0 && t?.raw !== null ? (j(JSON.stringify(t.raw, null, 2)), z(!0), V({
162
+ total: t.totalCount ?? null,
163
+ hasMore: t.hasMore ?? null,
164
+ sinkName: X
165
+ }), N(""), F(null), L(null)) : F("Could not load a sample from the selected DataSink.");
166
+ } catch (t) {
167
+ if (H.current !== e) return;
168
+ F(t instanceof Error ? t.message : "Failed to load sample data");
169
+ } finally {
170
+ Le(!1);
171
+ }
172
+ }
173
+ }, [
174
+ T.inputSinkKey,
175
+ J,
176
+ X
177
+ ]), dt = r(() => {
178
+ j(""), z(!1), V(null), L(null), N(""), F(null);
179
+ }, []), ft = r(async () => {
180
+ if (U) {
181
+ W(!1);
129
182
  return;
130
183
  }
131
- if (!E.inputSinkKey) {
132
- Y("Please select a source DataSink first");
184
+ if (!T.inputSinkKey) {
185
+ G("Please select a source DataSink first");
133
186
  return;
134
187
  }
135
- G(!0), q(!0), Y(null);
188
+ W(!0), Ve(!0), G(null);
189
+ let e = T.inputSinkKey;
136
190
  try {
137
- let e = await Q({ key: E.inputSinkKey });
138
- e?.raw ? ye(e.raw) : Y("No data available in selected DataSink");
139
- } catch (e) {
140
- Y(e instanceof Error ? e.message : "Failed to load data");
191
+ let t = await J({ key: e }, { limit: m });
192
+ if (H.current !== e) return;
193
+ t?.raw !== void 0 && t?.raw !== null ? (ze(t.raw), Ue({
194
+ total: t.totalCount ?? null,
195
+ hasMore: t.hasMore ?? null,
196
+ sinkName: X
197
+ })) : G("No data available in selected DataSink");
198
+ } catch (t) {
199
+ if (H.current !== e) return;
200
+ G(t instanceof Error ? t.message : "Failed to load data");
141
201
  } finally {
142
- q(!1);
202
+ Ve(!1);
143
203
  }
144
204
  }, [
145
- W,
146
- E.inputSinkKey,
147
- Q
148
- ]), Ve = r(async () => {
149
- if (!E.expression.trim()) {
150
- V("Expression is required");
205
+ U,
206
+ T.inputSinkKey,
207
+ J,
208
+ X
209
+ ]), pt = r(async () => {
210
+ if (!T.expression.trim()) {
211
+ F("Expression is required");
151
212
  return;
152
213
  }
153
- U(!0), V(null), z("");
214
+ let e;
215
+ if (R) e = {
216
+ type: T.type,
217
+ expression: T.expression,
218
+ dataSinkKey: T.inputSinkKey,
219
+ sampleLimit: m
220
+ };
221
+ else {
222
+ let t;
223
+ try {
224
+ t = JSON.parse(A);
225
+ } catch {
226
+ F("Input JSON is not valid JSON");
227
+ return;
228
+ }
229
+ e = {
230
+ type: T.type,
231
+ expression: T.expression,
232
+ sampleData: t
233
+ };
234
+ }
235
+ Fe(!0), F(null), N(""), L(null);
154
236
  try {
155
- let e = await Te({
156
- type: E.type,
157
- expression: E.expression,
158
- sampleData: JSON.parse(I)
159
- });
160
- e && (e.success ? z(JSON.stringify(e.output, null, 2)) : V(e.error || "Test failed"));
237
+ let t = await Xe(e);
238
+ t ? t.success ? (N(JSON.stringify(t.output, null, 2)), t.sampled && L({
239
+ sampledRows: t.sampledRows ?? null,
240
+ totalRows: t.totalRows ?? null
241
+ })) : F(t.error || "Test failed") : F("Test request failed — please try again.");
161
242
  } catch (e) {
162
- V(e instanceof Error ? e.message : "Test failed");
243
+ F(e instanceof Error ? e.message : "Test failed");
163
244
  } finally {
164
- U(!1);
245
+ Fe(!1);
165
246
  }
166
247
  }, [
167
- E.type,
168
- E.expression,
169
- I,
170
- Te
171
- ]), He = r(() => {
172
- b(y ? `/dashboards/${y}/parsers` : "/parsers");
173
- }, [b, y]), Ue = r(async (e) => {
174
- e.preventDefault(), F(null);
175
- let t = ve(E);
176
- if (Object.keys(t).length > 0) {
177
- k(t);
248
+ T.type,
249
+ T.expression,
250
+ T.inputSinkKey,
251
+ A,
252
+ R,
253
+ Xe
254
+ ]), Z = r(() => {
255
+ De(v ? `/dashboards/${v}/parsers` : "/parsers");
256
+ }, [De, v]), mt = r(async () => {
257
+ Ne(null);
258
+ let e = Ee(T);
259
+ if (Object.keys(e).length > 0) {
260
+ O(e), e.name || e.outputKey ? b(0) : e.inputSinkKey ? b(1) : e.expression && b(2);
178
261
  return;
179
262
  }
180
- N(!0);
263
+ je(!0);
181
264
  try {
182
- if (w && $) {
183
- if (!await we($.id, {
184
- name: E.name,
185
- description: E.description || void 0,
186
- expression: E.expression,
187
- inputSinkKey: E.inputSinkKey,
188
- outputKey: E.outputKey,
189
- ttl: E.ttl
190
- }, $.version)) throw Error("Failed to update parser");
191
- } else if (!await Z({
192
- consoleId: C || "",
193
- name: E.name,
194
- type: E.type,
195
- expression: E.expression,
196
- inputSinkKey: E.inputSinkKey,
197
- outputKey: E.outputKey,
198
- description: E.description || void 0,
199
- ttl: E.ttl || void 0
265
+ if (C && Y) {
266
+ if (!await Ye(Y.id, {
267
+ name: T.name,
268
+ description: T.description || void 0,
269
+ expression: T.expression,
270
+ inputSinkKey: T.inputSinkKey,
271
+ outputKey: T.outputKey,
272
+ ttl: T.ttl
273
+ }, Y.version)) throw Error("Failed to update parser");
274
+ } else if (!await Je({
275
+ consoleId: S || "",
276
+ name: T.name,
277
+ type: T.type,
278
+ expression: T.expression,
279
+ inputSinkKey: T.inputSinkKey,
280
+ outputKey: T.outputKey,
281
+ description: T.description || void 0,
282
+ ttl: T.ttl ?? void 0
200
283
  })) throw Error("Failed to create parser");
201
- b(y ? `/dashboards/${y}/parsers` : "/parsers");
284
+ Z();
202
285
  } catch (e) {
203
- F(e instanceof Error ? e.message : "Failed to save parser");
286
+ Ne(e instanceof Error ? e.message : "Failed to save parser");
204
287
  } finally {
205
- N(!1);
288
+ je(!1);
206
289
  }
207
290
  }, [
208
- E,
209
- w,
210
- $,
211
- Z,
212
- we,
213
- b,
291
+ T,
214
292
  C,
215
- y
216
- ]), We = re(() => E.name.trim().length >= 2 && E.expression.trim().length > 0 && E.inputSinkKey.trim().length > 0 && E.outputKey.trim().length > 0, [
217
- E.name,
218
- E.expression,
219
- E.inputSinkKey,
220
- E.outputKey
221
- ]);
222
- if (xe && w) return /* @__PURE__ */ h("div", {
293
+ Y,
294
+ Je,
295
+ Ye,
296
+ S,
297
+ Z
298
+ ]), ht = a(() => T.name.trim().length >= 2 && T.expression.trim().length > 0 && T.inputSinkKey.trim().length > 0 && T.outputKey.trim().length > 0 && /^[a-z0-9_]+$/.test(T.outputKey), [
299
+ T.name,
300
+ T.expression,
301
+ T.inputSinkKey,
302
+ T.outputKey
303
+ ]), Q = r((e) => {
304
+ switch (we[e]) {
305
+ case "details": return T.name.trim().length >= 2 && T.outputKey.trim().length > 0 && /^[a-z0-9_]+$/.test(T.outputKey);
306
+ case "source": return T.inputSinkKey.trim().length > 0;
307
+ case "expression": return T.expression.trim().length > 0;
308
+ default: return !0;
309
+ }
310
+ }, [
311
+ T.name,
312
+ T.outputKey,
313
+ T.inputSinkKey,
314
+ T.expression
315
+ ]), gt = r((e) => {
316
+ let t = Math.max(0, Math.min(e, h.length - 1));
317
+ if (t > y) {
318
+ for (let e = y; e < t; e++) if (!Q(e)) return;
319
+ }
320
+ b(t);
321
+ }, [y, Q]), _t = r(() => {
322
+ b((e) => Math.min(e + 1, h.length - 1));
323
+ }, []), vt = r(() => {
324
+ b((e) => Math.max(e - 1, 0));
325
+ }, []);
326
+ if (We && C) return /* @__PURE__ */ f("div", {
223
327
  className: "flex items-center justify-center min-h-[400px]",
224
- children: /* @__PURE__ */ h(s, { className: "w-8 h-8 text-text-secondary animate-spin" })
328
+ children: /* @__PURE__ */ f(c, { className: "w-8 h-8 text-text-secondary animate-spin" })
225
329
  });
226
- if (Se) return /* @__PURE__ */ h("div", {
330
+ if (Ge) return /* @__PURE__ */ f("div", {
227
331
  className: "flex items-center justify-center min-h-[400px] p-card-padding",
228
- children: /* @__PURE__ */ g("div", {
332
+ children: /* @__PURE__ */ p("div", {
229
333
  className: "text-center",
230
334
  children: [
231
- /* @__PURE__ */ h(o, { className: "w-12 h-12 text-status-error-text mx-auto mb-4" }),
232
- /* @__PURE__ */ h("p", {
335
+ /* @__PURE__ */ f(s, { className: "w-12 h-12 text-status-error-text mx-auto mb-4" }),
336
+ /* @__PURE__ */ f("p", {
233
337
  className: "text-status-error-text text-body-sm font-medium mb-2",
234
338
  children: "Failed to load Parser"
235
339
  }),
236
- /* @__PURE__ */ h("p", {
340
+ /* @__PURE__ */ f("p", {
237
341
  className: "text-text-tertiary text-body-xs",
238
- children: Se.message
342
+ children: Ge.message
239
343
  })
240
344
  ]
241
345
  })
242
346
  });
243
- let Ge = _[E.type];
244
- return /* @__PURE__ */ h("div", {
347
+ let $ = g[T.type], yt = y === h.length - 1;
348
+ return /* @__PURE__ */ f("div", {
245
349
  className: "min-h-screen bg-bg-canvas",
246
- children: /* @__PURE__ */ g("div", {
247
- className: "max-w-7xl mx-auto p-card-padding",
350
+ children: /* @__PURE__ */ p("div", {
351
+ className: "max-w-4xl mx-auto p-card-padding pb-10",
248
352
  children: [
249
- /* @__PURE__ */ g("div", {
353
+ /* @__PURE__ */ p("div", {
250
354
  className: "mb-6",
251
355
  children: [
252
- /* @__PURE__ */ g(l, {
253
- onClick: He,
356
+ /* @__PURE__ */ p(u, {
357
+ onClick: Z,
254
358
  variant: "ghost",
255
359
  size: "sm",
256
360
  className: "mb-4",
257
- children: [/* @__PURE__ */ h(ae, { className: "w-4 h-4 mr-2" }), "Back to Parsers"]
361
+ children: [/* @__PURE__ */ f(ae, { className: "w-4 h-4 mr-2" }), "Back to Parsers"]
258
362
  }),
259
- /* @__PURE__ */ h("h1", {
363
+ /* @__PURE__ */ f("h1", {
260
364
  className: "text-heading-h1 font-bold text-text-primary",
261
- children: w ? "Edit Parser" : "Create Parser"
365
+ children: C ? "Edit Parser" : "Create Parser"
262
366
  }),
263
- /* @__PURE__ */ h("p", {
367
+ /* @__PURE__ */ f("p", {
264
368
  className: "text-body-sm text-text-secondary mt-1",
265
- children: w ? "Update the parser configuration and test your changes." : "Transform data using JQ or JSONata expressions."
369
+ children: "Transform data using JQ or JSONata expressions."
266
370
  })
267
371
  ]
268
372
  }),
269
- /* @__PURE__ */ h(ge, {
373
+ /* @__PURE__ */ f(xe, {
270
374
  className: "mb-6",
271
- children: "A parser maps raw input into structured fields using a JQ or JSONata expression. Write the expression here, 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."
375
+ children: "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."
272
376
  }),
273
- P && /* @__PURE__ */ g("div", {
377
+ /* @__PURE__ */ f("div", {
378
+ className: "mb-6",
379
+ children: /* @__PURE__ */ f(Se, {
380
+ steps: h,
381
+ active: y,
382
+ onStepClick: gt
383
+ })
384
+ }),
385
+ Me && /* @__PURE__ */ p("div", {
274
386
  className: "mb-6 p-4 bg-status-error-bg/10 border border-status-error-border/30 rounded-lg flex items-start gap-3",
275
- children: [/* @__PURE__ */ h(o, { className: "w-5 h-5 text-status-error-text flex-shrink-0 mt-0.5" }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
387
+ children: [/* @__PURE__ */ f(s, { className: "w-5 h-5 text-status-error-text flex-shrink-0 mt-0.5" }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("p", {
276
388
  className: "text-sm font-medium text-status-error-text",
277
389
  children: "Failed to save Parser"
278
- }), /* @__PURE__ */ h("p", {
390
+ }), /* @__PURE__ */ f("p", {
279
391
  className: "text-xs text-status-error-text/80 mt-1",
280
- children: P
392
+ children: Me
281
393
  })] })]
282
394
  }),
283
- /* @__PURE__ */ g("form", {
284
- onSubmit: Ue,
285
- children: [/* @__PURE__ */ g("div", {
286
- className: "grid gap-6 lg:grid-cols-3",
395
+ /* @__PURE__ */ p(be, {
396
+ treatment: "glass",
397
+ glow: !0,
398
+ children: [/* @__PURE__ */ f(ve, {
399
+ className: "pb-4",
400
+ children: /* @__PURE__ */ p("div", {
401
+ className: "flex items-center gap-3",
402
+ children: [/* @__PURE__ */ p("div", {
403
+ className: "w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
404
+ children: [
405
+ y === 0 && /* @__PURE__ */ f(fe, { className: "w-4 h-4 text-action-primary-bg" }),
406
+ y === 1 && /* @__PURE__ */ f(le, { className: "w-4 h-4 text-action-primary-bg" }),
407
+ y === 2 && /* @__PURE__ */ f(l, { className: "w-4 h-4 text-action-primary-bg" }),
408
+ y === 3 && /* @__PURE__ */ f(he, { className: "w-4 h-4 text-action-primary-bg" })
409
+ ]
410
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("p", {
411
+ className: "text-xs text-text-tertiary",
412
+ children: [
413
+ "Step ",
414
+ y + 1,
415
+ " of ",
416
+ h.length
417
+ ]
418
+ }), /* @__PURE__ */ f(ye, {
419
+ className: "text-base",
420
+ children: h[y].label
421
+ })] })]
422
+ })
423
+ }), /* @__PURE__ */ p(_e, {
424
+ className: "space-y-5",
287
425
  children: [
288
- /* @__PURE__ */ h("div", {
289
- className: "space-y-6",
290
- children: /* @__PURE__ */ g(u, { children: [/* @__PURE__ */ h(f, {
291
- className: "pb-4",
292
- children: /* @__PURE__ */ g("div", {
293
- className: "flex items-center gap-3",
294
- children: [/* @__PURE__ */ h("div", {
295
- className: "w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
296
- children: /* @__PURE__ */ h(de, { className: "w-4 h-4 text-action-primary-bg" })
297
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h(p, {
298
- className: "text-base",
299
- children: "Basic Information"
300
- }), /* @__PURE__ */ h("p", {
301
- className: "text-xs text-text-secondary mt-0.5",
302
- children: "Essential details for your parser"
303
- })] })]
304
- })
305
- }), /* @__PURE__ */ g(d, {
306
- className: "space-y-5",
307
- children: [
308
- /* @__PURE__ */ g("div", { children: [
309
- /* @__PURE__ */ g("label", {
426
+ y === 0 && /* @__PURE__ */ p("div", {
427
+ className: "space-y-5",
428
+ children: [
429
+ /* @__PURE__ */ p("div", {
430
+ className: "grid gap-5 sm:grid-cols-2",
431
+ children: [/* @__PURE__ */ p("div", { children: [
432
+ /* @__PURE__ */ p("label", {
310
433
  htmlFor: "name",
311
434
  className: "block text-sm font-medium text-text-primary mb-2",
312
- children: ["Name ", /* @__PURE__ */ h("span", {
435
+ children: ["Name ", /* @__PURE__ */ f("span", {
313
436
  className: "text-status-error-text",
314
437
  children: "*"
315
438
  })]
316
439
  }),
317
- /* @__PURE__ */ h("input", {
440
+ /* @__PURE__ */ f("input", {
318
441
  id: "name",
319
442
  type: "text",
320
- value: E.name,
321
- onChange: je,
443
+ value: T.name,
444
+ onChange: tt,
322
445
  placeholder: "e.g., User Analytics Parser",
323
- className: `
324
- w-full px-3 py-2.5
325
- text-sm text-text-primary
326
- bg-bg-surface
327
- border ${O.name ? "border-status-error-border" : "border-border-default"}
328
- rounded-md
329
- placeholder:text-text-tertiary
330
- focus:outline-none focus:ring-2 focus:ring-action-primary-bg
331
- transition-all
332
- `
446
+ className: `${_} ${D.name ? "border-status-error-border" : "border-border-default"}`
333
447
  }),
334
- O.name && /* @__PURE__ */ h("p", {
448
+ D.name && /* @__PURE__ */ f("p", {
335
449
  className: "text-xs text-status-error-text mt-1.5",
336
- children: O.name
450
+ children: D.name
337
451
  })
338
- ] }),
339
- /* @__PURE__ */ g("div", { children: [
340
- /* @__PURE__ */ g("label", {
452
+ ] }), /* @__PURE__ */ p("div", { children: [
453
+ /* @__PURE__ */ p("label", {
341
454
  htmlFor: "outputKey",
342
455
  className: "block text-sm font-medium text-text-primary mb-2",
343
- children: ["Output Key ", /* @__PURE__ */ h("span", {
456
+ children: ["Output Key ", /* @__PURE__ */ f("span", {
344
457
  className: "text-status-error-text",
345
458
  children: "*"
346
459
  })]
347
460
  }),
348
- /* @__PURE__ */ h("input", {
461
+ /* @__PURE__ */ f("input", {
349
462
  id: "outputKey",
350
463
  type: "text",
351
- value: E.outputKey,
352
- onChange: Me,
464
+ value: T.outputKey,
465
+ onChange: nt,
353
466
  placeholder: "user_analytics_parser",
354
- disabled: w,
355
- className: `
356
- w-full px-3 py-2.5
357
- text-sm text-text-primary font-mono
358
- bg-bg-surface
359
- border ${O.outputKey ? "border-status-error-border" : "border-border-default"}
360
- rounded-md
361
- placeholder:text-text-tertiary
362
- focus:outline-none focus:ring-2 focus:ring-action-primary-bg
363
- disabled:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-60
364
- transition-all
365
- `
467
+ disabled: C,
468
+ className: `${_} font-mono ${D.outputKey ? "border-status-error-border" : "border-border-default"} disabled:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-60`
366
469
  }),
367
- O.outputKey && /* @__PURE__ */ h("p", {
470
+ D.outputKey && /* @__PURE__ */ f("p", {
368
471
  className: "text-xs text-status-error-text mt-1.5",
369
- children: O.outputKey
472
+ children: D.outputKey
370
473
  }),
371
- !w && /* @__PURE__ */ h("p", {
474
+ !C && /* @__PURE__ */ f("p", {
372
475
  className: "text-xs text-text-tertiary mt-1.5",
373
476
  children: "Auto-generated from name. Customize if needed."
374
477
  })
375
- ] }),
376
- /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
377
- htmlFor: "description",
478
+ ] })]
479
+ }),
480
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
481
+ htmlFor: "description",
482
+ className: "block text-sm font-medium text-text-primary mb-2",
483
+ children: "Description"
484
+ }), /* @__PURE__ */ f("textarea", {
485
+ id: "description",
486
+ value: T.description,
487
+ onChange: rt,
488
+ placeholder: "Describe what this parser does...",
489
+ rows: 2,
490
+ className: `${_} border-border-default resize-y`
491
+ })] }),
492
+ w && /* @__PURE__ */ p("div", { children: [
493
+ /* @__PURE__ */ f("label", {
494
+ htmlFor: "dashboard",
378
495
  className: "block text-sm font-medium text-text-primary mb-2",
379
- children: "Description"
380
- }), /* @__PURE__ */ h("textarea", {
381
- id: "description",
382
- value: E.description,
383
- onChange: Ne,
384
- placeholder: "Describe what this parser does...",
385
- rows: 3,
386
- className: "\n w-full px-3 py-2.5\n text-sm text-text-primary\n bg-bg-surface\n border border-border-default\n rounded-md\n placeholder:text-text-tertiary\n focus:outline-none focus:ring-2 focus:ring-action-primary-bg\n resize-none\n transition-all\n "
387
- })] }),
388
- T && /* @__PURE__ */ g("div", { children: [
389
- /* @__PURE__ */ h("label", {
390
- htmlFor: "dashboard",
391
- className: "block text-sm font-medium text-text-primary mb-2",
392
- children: /* @__PURE__ */ g("div", {
393
- className: "flex items-center gap-2",
394
- children: [/* @__PURE__ */ h(fe, { className: "w-4 h-4" }), "Dashboard Scope"]
395
- })
396
- }),
397
- /* @__PURE__ */ g("select", {
398
- id: "dashboard",
399
- value: x,
400
- onChange: Re,
401
- disabled: Ae || w,
402
- className: "\n w-full px-3 py-2.5\n text-sm text-text-primary\n bg-bg-surface\n border border-border-default\n rounded-md\n focus:outline-none focus:ring-2 focus:ring-action-primary-bg\n disabled:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-60\n transition-all\n ",
403
- children: [/* @__PURE__ */ h("option", {
404
- value: "default",
405
- children: "Global (available everywhere)"
406
- }), Oe.map((e) => /* @__PURE__ */ h("option", {
407
- value: e.id,
408
- children: e.name
409
- }, e.id))]
410
- }),
411
- /* @__PURE__ */ h("p", {
412
- className: "text-xs text-text-tertiary mt-1.5",
413
- children: w ? "Dashboard scope cannot be changed after creation." : x === "default" ? "Global parsers are available across all dashboards." : "This parser will only be available in the selected dashboard."
496
+ children: /* @__PURE__ */ p("span", {
497
+ className: "flex items-center gap-2",
498
+ children: [/* @__PURE__ */ f(pe, { className: "w-4 h-4" }), "Dashboard Scope"]
414
499
  })
415
- ] })
416
- ]
417
- })] })
500
+ }),
501
+ /* @__PURE__ */ p("select", {
502
+ id: "dashboard",
503
+ value: x,
504
+ onChange: ct,
505
+ disabled: et || C,
506
+ className: `${_} border-border-default disabled:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-60`,
507
+ children: [/* @__PURE__ */ f("option", {
508
+ value: "default",
509
+ children: "Global (available everywhere)"
510
+ }), Qe.map((e) => /* @__PURE__ */ f("option", {
511
+ value: e.id,
512
+ children: e.name
513
+ }, e.id))]
514
+ }),
515
+ /* @__PURE__ */ f("p", {
516
+ className: "text-xs text-text-tertiary mt-1.5",
517
+ children: C ? "Dashboard scope cannot be changed after creation." : x === "default" ? "Global parsers are available across all dashboards." : "This parser will only be available in the selected dashboard."
518
+ })
519
+ ] })
520
+ ]
418
521
  }),
419
- /* @__PURE__ */ h("div", {
420
- className: "space-y-6",
421
- children: /* @__PURE__ */ g(he, {
422
- treatment: "glass",
423
- glow: !0,
424
- children: [/* @__PURE__ */ h(f, {
425
- className: "pb-4",
426
- children: /* @__PURE__ */ g("div", {
427
- className: "flex items-center gap-3",
428
- children: [/* @__PURE__ */ h("div", {
429
- className: "w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
430
- children: /* @__PURE__ */ h(le, { className: "w-4 h-4 text-action-primary-bg" })
431
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h(p, {
432
- className: "text-base",
433
- children: "Parser Configuration"
434
- }), /* @__PURE__ */ h("p", {
522
+ y === 1 && /* @__PURE__ */ p("div", {
523
+ className: "space-y-5",
524
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("label", {
525
+ className: "block text-sm font-medium text-text-primary mb-3",
526
+ children: ["Parser Type ", /* @__PURE__ */ f("span", {
527
+ className: "text-status-error-text",
528
+ children: "*"
529
+ })]
530
+ }), /* @__PURE__ */ f("div", {
531
+ className: "grid gap-2 sm:grid-cols-2",
532
+ children: Object.keys(g).map((e) => {
533
+ let t = g[e];
534
+ return /* @__PURE__ */ p("label", {
535
+ className: `flex items-start gap-3 p-3 border rounded-md cursor-pointer transition-colors ${T.type === e ? "border-action-primary-bg bg-action-primary-bg/5" : "border-border-default hover:bg-bg-sunken"}`,
536
+ children: [/* @__PURE__ */ f("input", {
537
+ type: "radio",
538
+ name: "parserType",
539
+ value: e,
540
+ checked: T.type === e,
541
+ onChange: () => it(e),
542
+ className: "mt-1 w-4 h-4 text-action-primary-bg"
543
+ }), /* @__PURE__ */ p("span", { children: [/* @__PURE__ */ f("span", {
544
+ className: "text-sm font-medium text-text-primary",
545
+ children: t.name
546
+ }), /* @__PURE__ */ f("p", {
435
547
  className: "text-xs text-text-secondary mt-0.5",
436
- children: "Configure parser type and data source"
548
+ children: t.description
437
549
  })] })]
438
- })
439
- }), /* @__PURE__ */ g(d, {
440
- className: "space-y-5",
441
- children: [
442
- /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ g("label", {
443
- className: "block text-sm font-medium text-text-primary mb-3",
444
- children: ["Parser Type ", /* @__PURE__ */ h("span", {
445
- className: "text-status-error-text",
446
- children: "*"
550
+ }, e);
551
+ })
552
+ })] }), /* @__PURE__ */ p("div", { children: [
553
+ /* @__PURE__ */ p("label", {
554
+ htmlFor: "inputSinkKey",
555
+ className: "block text-sm font-medium text-text-primary mb-2",
556
+ children: ["Source DataSink ", /* @__PURE__ */ f("span", {
557
+ className: "text-status-error-text",
558
+ children: "*"
559
+ })]
560
+ }),
561
+ /* @__PURE__ */ p("select", {
562
+ id: "inputSinkKey",
563
+ value: T.inputSinkKey,
564
+ onChange: ot,
565
+ className: `${_} ${D.inputSinkKey ? "border-status-error-border" : "border-border-default"}`,
566
+ children: [/* @__PURE__ */ f("option", {
567
+ value: "",
568
+ children: "Select a DataSink..."
569
+ }), q.map((e) => /* @__PURE__ */ f("option", {
570
+ value: e.key,
571
+ children: e.name || e.key
572
+ }, e.id))]
573
+ }),
574
+ D.inputSinkKey && /* @__PURE__ */ f("p", {
575
+ className: "text-xs text-status-error-text mt-1.5",
576
+ children: D.inputSinkKey
577
+ }),
578
+ q.length === 0 && /* @__PURE__ */ f("p", {
579
+ className: "text-xs text-text-tertiary mt-1.5",
580
+ children: "No DataSinks yet — create one first, then return here to build a parser for it."
581
+ }),
582
+ T.inputSinkKey && /* @__PURE__ */ p("div", {
583
+ className: "mt-3",
584
+ children: [/* @__PURE__ */ p("button", {
585
+ type: "button",
586
+ onClick: ft,
587
+ className: "inline-flex items-center gap-2 text-sm text-action-primary-bg hover:text-action-primary-bgHover transition-colors",
588
+ children: [
589
+ f(U ? se : ce, { className: "w-4 h-4" }),
590
+ /* @__PURE__ */ f(de, { className: "w-4 h-4" }),
591
+ "Show Data Preview"
592
+ ]
593
+ }), U && /* @__PURE__ */ f("div", {
594
+ className: "mt-3 border border-border-default rounded-md overflow-hidden",
595
+ children: Be ? /* @__PURE__ */ p("div", {
596
+ className: "p-4 flex items-center justify-center",
597
+ children: [/* @__PURE__ */ f(c, { className: "w-5 h-5 text-text-secondary animate-spin" }), /* @__PURE__ */ f("span", {
598
+ className: "ml-2 text-sm text-text-secondary",
599
+ children: "Loading sample…"
447
600
  })]
448
- }), /* @__PURE__ */ h("div", {
449
- className: "space-y-2",
450
- children: Object.keys(_).map((e) => {
451
- let t = _[e];
452
- return /* @__PURE__ */ g("label", {
453
- className: `
454
- flex items-start gap-3 p-3
455
- border rounded-md
456
- cursor-pointer
457
- ${E.type === e ? "border-action-primary-bg bg-action-primary-bg/5" : "border-border-default hover:bg-bg-sunken"}
458
- transition-colors
459
- `,
460
- children: [/* @__PURE__ */ h("input", {
461
- type: "radio",
462
- name: "parserType",
463
- value: e,
464
- checked: E.type === e,
465
- onChange: () => Pe(e),
466
- className: "mt-1 w-4 h-4 text-action-primary-bg"
467
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("span", {
468
- className: "text-sm font-medium text-text-primary",
469
- children: t.name
470
- }), /* @__PURE__ */ h("p", {
471
- className: "text-xs text-text-secondary mt-0.5",
472
- children: t.description
473
- })] })]
474
- }, e);
601
+ }) : He ? /* @__PURE__ */ f("div", {
602
+ className: "p-4 bg-status-error-bg/5",
603
+ children: /* @__PURE__ */ f("p", {
604
+ className: "text-sm text-status-error-text",
605
+ children: He
475
606
  })
476
- })] }),
477
- /* @__PURE__ */ g("div", { children: [
478
- /* @__PURE__ */ g("label", {
479
- htmlFor: "inputSinkKey",
480
- className: "block text-sm font-medium text-text-primary mb-2",
481
- children: ["Source DataSink ", /* @__PURE__ */ h("span", {
482
- className: "text-status-error-text",
483
- children: "*"
607
+ }) : Re ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("pre", {
608
+ className: "p-3 text-xs font-mono bg-bg-sunken text-text-primary overflow-auto max-h-48",
609
+ children: JSON.stringify(Re, null, 2)
610
+ }), K && /* @__PURE__ */ p("p", {
611
+ className: "px-3 py-2 text-xs text-text-tertiary border-t border-border-default",
612
+ children: [
613
+ "Previewing a sample",
614
+ K.total == null ? "" : ` (first ${Math.min(m, K.total)} of ${K.total} rows)`,
615
+ " · ",
616
+ K.sinkName
617
+ ]
618
+ })] }) : /* @__PURE__ */ f("div", {
619
+ className: "p-4 text-sm text-text-secondary text-center",
620
+ children: "No data available"
621
+ })
622
+ })]
623
+ })
624
+ ] })]
625
+ }),
626
+ y === 2 && /* @__PURE__ */ p("div", {
627
+ className: "space-y-5",
628
+ children: [
629
+ /* @__PURE__ */ p("div", { children: [
630
+ /* @__PURE__ */ p("label", {
631
+ htmlFor: "expression",
632
+ className: "block text-sm font-medium text-text-primary mb-2",
633
+ children: ["Expression ", /* @__PURE__ */ f("span", {
634
+ className: "text-status-error-text",
635
+ children: "*"
636
+ })]
637
+ }),
638
+ /* @__PURE__ */ f("textarea", {
639
+ id: "expression",
640
+ value: T.expression,
641
+ onChange: at,
642
+ placeholder: $.placeholder,
643
+ rows: 8,
644
+ className: `${_} font-mono resize-y ${D.expression ? "border-status-error-border" : "border-border-default"}`
645
+ }),
646
+ D.expression && /* @__PURE__ */ f("p", {
647
+ className: "text-xs text-status-error-text mt-1.5",
648
+ children: D.expression
649
+ }),
650
+ /* @__PURE__ */ p("p", {
651
+ className: "text-xs text-text-tertiary mt-1.5",
652
+ children: ["Example: ", $.example]
653
+ })
654
+ ] }),
655
+ /* @__PURE__ */ f(u, {
656
+ type: "button",
657
+ onClick: pt,
658
+ disabled: Pe || !T.expression.trim(),
659
+ variant: "default",
660
+ className: "w-full",
661
+ children: Pe ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(c, { className: "w-4 h-4 mr-2 animate-spin" }), "Testing..."] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(l, { className: "w-4 h-4 mr-2" }), "Run Test"] })
662
+ }),
663
+ /* @__PURE__ */ p("div", {
664
+ className: "grid gap-4 md:grid-cols-2",
665
+ children: [/* @__PURE__ */ p("div", { children: [
666
+ /* @__PURE__ */ p("div", {
667
+ className: "flex items-center justify-between mb-2",
668
+ children: [/* @__PURE__ */ p("label", {
669
+ className: "text-sm font-medium text-text-primary",
670
+ children: ["Input JSON", /* @__PURE__ */ f("span", {
671
+ className: `ml-2 text-[10px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded border align-middle ${R ? "text-action-primary-bg bg-action-primary-bg/10 border-action-primary-bg/30" : "text-text-secondary bg-bg-sunken border-border-default"}`,
672
+ children: R ? "Reference mode" : "Sample mode"
484
673
  })]
485
- }),
486
- /* @__PURE__ */ g("div", {
487
- className: "flex gap-2",
488
- children: [/* @__PURE__ */ g("select", {
489
- id: "inputSinkKey",
490
- value: E.inputSinkKey,
491
- onChange: Ie,
492
- className: `
493
- flex-1 px-3 py-2.5
494
- text-sm text-text-primary
495
- bg-bg-surface
496
- border ${O.inputSinkKey ? "border-status-error-border" : "border-border-default"}
497
- rounded-md
498
- focus:outline-none focus:ring-2 focus:ring-action-primary-bg
499
- transition-all
500
- `,
501
- children: [/* @__PURE__ */ h("option", {
502
- value: "",
503
- children: "Select a DataSink..."
504
- }), Ee.map((e) => /* @__PURE__ */ h("option", {
505
- value: e.key,
506
- children: e.name || e.key
507
- }, e.id))]
508
- }), E.inputSinkKey && /* @__PURE__ */ h("button", {
674
+ }), /* @__PURE__ */ p("div", {
675
+ className: "flex items-center gap-2",
676
+ children: [T.inputSinkKey && !R && /* @__PURE__ */ p("button", {
509
677
  type: "button",
510
- onClick: ze,
511
- className: "px-3 py-2.5 text-sm font-medium text-action-primary-bg border border-action-primary-bg rounded-md hover:bg-action-primary-bg/10 transition-colors whitespace-nowrap",
512
- children: "Load Sample"
513
- })]
514
- }),
515
- O.inputSinkKey && /* @__PURE__ */ h("p", {
516
- className: "text-xs text-status-error-text mt-1.5",
517
- children: O.inputSinkKey
518
- }),
519
- /* @__PURE__ */ h("p", {
520
- className: "text-xs text-text-tertiary mt-1.5",
521
- children: "Select the data source for this parser to transform."
522
- }),
523
- E.inputSinkKey && /* @__PURE__ */ g("div", {
524
- className: "mt-3",
525
- children: [/* @__PURE__ */ g("button", {
678
+ onClick: ut,
679
+ disabled: Ie,
680
+ className: "inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-semibold text-action-primary-bg border border-action-primary-bg rounded-md hover:bg-action-primary-bg/10 transition-colors disabled:opacity-50",
681
+ children: [Ie ? /* @__PURE__ */ f(c, { className: "w-3.5 h-3.5 animate-spin" }) : /* @__PURE__ */ f(ue, { className: "w-3.5 h-3.5" }), "Load Sample"]
682
+ }), R && /* @__PURE__ */ p("button", {
526
683
  type: "button",
527
- onClick: Be,
528
- className: "inline-flex items-center gap-2 text-sm text-action-primary-bg hover:text-action-primary-bgHover transition-colors",
529
- children: [
530
- h(W ? se : ce, { className: "w-4 h-4" }),
531
- /* @__PURE__ */ h(ue, { className: "w-4 h-4" }),
532
- "Show Data Preview"
533
- ]
534
- }), W && /* @__PURE__ */ h("div", {
535
- className: "mt-3 border border-border-default rounded-md overflow-hidden",
536
- children: be ? /* @__PURE__ */ g("div", {
537
- className: "p-4 flex items-center justify-center",
538
- children: [/* @__PURE__ */ h(s, { className: "w-5 h-5 text-text-secondary animate-spin" }), /* @__PURE__ */ h("span", {
539
- className: "ml-2 text-sm text-text-secondary",
540
- children: "Loading data..."
541
- })]
542
- }) : J ? /* @__PURE__ */ h("div", {
543
- className: "p-4 bg-status-error-bg/5",
544
- children: /* @__PURE__ */ h("p", {
545
- className: "text-sm text-status-error-text",
546
- children: J
547
- })
548
- }) : K ? /* @__PURE__ */ h("pre", {
549
- className: "p-3 text-xs font-mono bg-bg-sunken text-text-primary overflow-auto max-h-48",
550
- children: JSON.stringify(K, null, 2)
551
- }) : /* @__PURE__ */ h("div", {
552
- className: "p-4 text-sm text-text-secondary text-center",
553
- children: "No data available"
554
- })
684
+ onClick: dt,
685
+ className: "inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-semibold text-text-primary border border-border-default rounded-md hover:bg-bg-sunken transition-colors",
686
+ children: [/* @__PURE__ */ f(ge, { className: "w-3.5 h-3.5" }), "Clear"]
555
687
  })]
556
- })
557
- ] }),
558
- /* @__PURE__ */ g("div", { children: [
559
- /* @__PURE__ */ g("label", {
560
- htmlFor: "expression",
561
- className: "block text-sm font-medium text-text-primary mb-2",
562
- children: ["Expression ", /* @__PURE__ */ h("span", {
563
- className: "text-status-error-text",
564
- children: "*"
565
- })]
566
- }),
567
- /* @__PURE__ */ h("textarea", {
568
- id: "expression",
569
- value: E.expression,
570
- onChange: Fe,
571
- placeholder: Ge.placeholder,
572
- rows: 8,
573
- className: `
574
- w-full px-3 py-2.5
575
- text-sm text-text-primary font-mono
576
- bg-bg-surface
577
- border ${O.expression ? "border-status-error-border" : "border-border-default"}
578
- rounded-md
579
- placeholder:text-text-tertiary
580
- focus:outline-none focus:ring-2 focus:ring-action-primary-bg
581
- resize-none
582
- transition-all
583
- `
584
- }),
585
- O.expression && /* @__PURE__ */ h("p", {
586
- className: "text-xs text-status-error-text mt-1.5",
587
- children: O.expression
588
- }),
589
- /* @__PURE__ */ g("p", {
590
- className: "text-xs text-text-tertiary mt-1.5",
591
- children: ["Example: ", Ge.example]
592
- })
593
- ] })
594
- ]
595
- })]
596
- })
597
- }),
598
- /* @__PURE__ */ g("div", {
599
- className: "space-y-6",
600
- children: [/* @__PURE__ */ g(u, { children: [/* @__PURE__ */ h(f, {
601
- className: "pb-4",
602
- children: /* @__PURE__ */ g("div", {
603
- className: "flex items-center gap-3",
604
- children: [/* @__PURE__ */ h("div", {
605
- className: "w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
606
- children: /* @__PURE__ */ h(c, { className: "w-4 h-4 text-action-primary-bg" })
607
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h(p, {
608
- className: "text-base",
609
- children: "Test Expression"
610
- }), /* @__PURE__ */ h("p", {
611
- className: "text-xs text-text-secondary mt-0.5",
612
- children: "Test your parser with sample data"
613
- })] })]
614
- })
615
- }), /* @__PURE__ */ g(d, {
616
- className: "space-y-5",
617
- children: [
618
- /* @__PURE__ */ g("div", { children: [
619
- /* @__PURE__ */ h("label", {
620
- className: "block text-sm font-medium text-text-primary mb-2",
621
- children: "Input JSON"
688
+ })]
622
689
  }),
623
- /* @__PURE__ */ h("textarea", {
624
- value: I,
625
- onChange: (e) => L(e.target.value),
626
- placeholder: "{\"data\": [{\"name\": \"test\", \"value\": 123}]}",
627
- rows: 6,
628
- className: "\n w-full px-3 py-2.5\n text-xs text-text-primary font-mono leading-relaxed\n bg-bg-surface\n border border-border-default\n rounded-md\n placeholder:text-text-tertiary\n focus:outline-none focus:ring-2 focus:ring-action-primary-bg\n resize-none\n transition-all\n "
690
+ /* @__PURE__ */ f("textarea", {
691
+ value: A,
692
+ onChange: lt,
693
+ readOnly: R,
694
+ placeholder: "Type sample JSON to test against it — or Load a sample from the source…",
695
+ rows: 8,
696
+ className: `${_} text-xs font-mono leading-relaxed resize-y border-border-default ${R ? "bg-bg-sunken opacity-80 cursor-not-allowed" : ""}`
629
697
  }),
630
- /* @__PURE__ */ h("p", {
698
+ R && B ? /* @__PURE__ */ p("p", {
631
699
  className: "text-xs text-text-tertiary mt-1.5",
632
- children: "Paste test data or load from a DataSink above."
700
+ children: [
701
+ "Loaded a small sample",
702
+ B.total == null ? "" : ` (first ${Math.min(m, B.total)} of ${B.total} rows)`,
703
+ " ",
704
+ "from ",
705
+ B.sinkName,
706
+ " · locked — press Clear to edit."
707
+ ]
708
+ }) : /* @__PURE__ */ f("p", {
709
+ className: "text-xs text-text-tertiary mt-1.5",
710
+ children: "Type sample JSON to test against it, or Load a sample from the source."
633
711
  })
634
- ] }),
635
- /* @__PURE__ */ h(l, {
636
- type: "button",
637
- onClick: Ve,
638
- disabled: H || !E.expression.trim(),
639
- variant: "default",
640
- className: "w-full",
641
- children: H ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(s, { className: "w-4 h-4 mr-2 animate-spin" }), "Testing..."] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(c, { className: "w-4 h-4 mr-2" }), "Run Test"] })
642
- }),
643
- (R || B) && /* @__PURE__ */ g("div", {
644
- className: "pt-4 border-t border-border-default",
645
- children: [/* @__PURE__ */ g("div", {
712
+ ] }), /* @__PURE__ */ p("div", { children: [
713
+ /* @__PURE__ */ p("div", {
646
714
  className: "flex items-center justify-between mb-2",
647
- children: [/* @__PURE__ */ h("label", {
648
- className: "block text-sm font-medium text-text-primary",
649
- children: B ? "Error Output" : "Success Output"
650
- }), B ? /* @__PURE__ */ g("span", {
715
+ children: [/* @__PURE__ */ f("label", {
716
+ className: "text-sm font-medium text-text-primary",
717
+ children: P ? "Error Output" : "Output"
718
+ }), (M || P) && (P ? /* @__PURE__ */ p("span", {
651
719
  className: "text-xs px-2 py-1 bg-status-error-bg/10 text-status-error-text rounded flex items-center gap-1",
652
- children: [/* @__PURE__ */ h(o, { className: "w-3 h-3" }), " Failed"]
653
- }) : /* @__PURE__ */ g("span", {
720
+ children: [/* @__PURE__ */ f(s, { className: "w-3 h-3" }), " Failed"]
721
+ }) : /* @__PURE__ */ p("span", {
654
722
  className: "text-xs px-2 py-1 bg-status-success-bg/10 text-status-success-text rounded flex items-center gap-1",
655
- children: [/* @__PURE__ */ h(oe, { className: "w-3 h-3" }), " Passed"]
656
- })]
657
- }), /* @__PURE__ */ h("pre", {
658
- className: `
659
- w-full px-3 py-2.5
660
- text-xs font-mono leading-relaxed
661
- ${B ? "bg-status-error-bg/5 text-status-error-text border-status-error-border/30" : "bg-status-success-bg/5 text-text-primary border-status-success-border/30"}
662
- border
663
- rounded-md
664
- overflow-auto
665
- max-h-[150px]
666
- `,
667
- children: B || R
668
- })]
669
- }),
670
- !R && !B && /* @__PURE__ */ h("div", {
671
- className: "p-3 bg-bg-sunken rounded-md border border-border-default",
672
- children: /* @__PURE__ */ g("p", {
673
- className: "text-xs text-text-secondary leading-relaxed",
674
- children: [/* @__PURE__ */ h("strong", { children: "Tip:" }), " Write your expression and click “Run Test” to see the transformation in real-time."]
723
+ children: [/* @__PURE__ */ f(oe, { className: "w-3 h-3" }), " Passed"]
724
+ }))]
725
+ }),
726
+ M || P ? /* @__PURE__ */ f("pre", {
727
+ className: `w-full px-3 py-2.5 text-xs font-mono leading-relaxed border rounded-md overflow-auto max-h-[220px] resize-y ${P ? "bg-status-error-bg/5 text-status-error-text border-status-error-border/30" : "bg-status-success-bg/5 text-text-primary border-status-success-border/30"}`,
728
+ children: P || M
729
+ }) : /* @__PURE__ */ f("div", {
730
+ className: "p-3 bg-bg-sunken rounded-md border border-border-default",
731
+ children: /* @__PURE__ */ p("p", {
732
+ className: "text-xs text-text-secondary leading-relaxed",
733
+ children: [/* @__PURE__ */ f("strong", { children: "Tip:" }), " write your expression and click “Run Test” to see the transformation."]
734
+ })
735
+ }),
736
+ I && !P && /* @__PURE__ */ p("p", {
737
+ className: "text-xs text-text-tertiary mt-1.5",
738
+ children: [
739
+ "Tested a sample",
740
+ I.sampledRows != null && I.totalRows != null ? ` (first ${I.sampledRows} of ${I.totalRows} rows)` : "",
741
+ " a saved parser runs over the full source, so results may differ."
742
+ ]
675
743
  })
676
- })
677
- ]
678
- })] }), /* @__PURE__ */ g(u, { children: [/* @__PURE__ */ h(f, {
679
- className: "pb-4",
680
- children: /* @__PURE__ */ g("div", {
681
- className: "flex items-center gap-3",
682
- children: [/* @__PURE__ */ h("div", {
683
- className: "w-8 h-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
684
- children: /* @__PURE__ */ h(me, { className: "w-4 h-4 text-action-primary-bg" })
685
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h(p, {
686
- className: "text-base",
687
- children: "Advanced Settings"
688
- }), /* @__PURE__ */ h("p", {
689
- className: "text-xs text-text-secondary mt-0.5",
690
- children: "Cache configuration"
691
- })] })]
744
+ ] })]
692
745
  })
693
- }), /* @__PURE__ */ h(d, {
694
- className: "space-y-5",
695
- children: /* @__PURE__ */ g("div", { children: [
696
- /* @__PURE__ */ h("label", {
697
- className: "block text-sm font-medium text-text-primary mb-3",
698
- children: "Cache Duration"
699
- }),
700
- /* @__PURE__ */ h(ne, {
701
- value: E.ttl,
702
- onChange: Le,
703
- error: O.ttl
704
- }),
705
- /* @__PURE__ */ h("p", {
706
- className: "text-xs text-text-tertiary mt-2",
707
- children: "Select a preset or enter a custom duration (30-86400 seconds)."
708
- })
709
- ] })
746
+ ]
747
+ }),
748
+ y === 3 && /* @__PURE__ */ p("div", {
749
+ className: "space-y-6",
750
+ children: [/* @__PURE__ */ p("div", { children: [
751
+ /* @__PURE__ */ f("label", {
752
+ className: "block text-sm font-medium text-text-primary mb-1",
753
+ children: "Cache Duration"
754
+ }),
755
+ /* @__PURE__ */ f("p", {
756
+ className: "text-xs text-text-tertiary mb-3",
757
+ children: "How long should data be cached before refreshing?"
758
+ }),
759
+ /* @__PURE__ */ f(ne, {
760
+ value: T.ttl,
761
+ onChange: st,
762
+ error: D.ttl,
763
+ hideLabel: !0
764
+ })
765
+ ] }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
766
+ className: "block text-sm font-medium text-text-primary mb-2",
767
+ children: "Review"
768
+ }), /* @__PURE__ */ f("div", {
769
+ className: "border border-border-default rounded-lg overflow-hidden",
770
+ children: [
771
+ ["Name", T.name || "—"],
772
+ ["Output Key", T.outputKey || "—"],
773
+ ["Scope", w ? x === "default" ? "Global" : Qe.find((e) => e.id === x)?.name || x : "Dashboard"],
774
+ ["Type", g[T.type].name],
775
+ ["Source", X || "—"]
776
+ ].map(([e, t]) => /* @__PURE__ */ p("div", {
777
+ className: "flex items-center justify-between gap-3 px-4 py-2.5 text-sm border-b border-border-default last:border-b-0",
778
+ children: [/* @__PURE__ */ f("span", {
779
+ className: "text-text-secondary",
780
+ children: e
781
+ }), /* @__PURE__ */ f("span", {
782
+ className: "font-medium text-text-primary text-right break-words",
783
+ children: t
784
+ })]
785
+ }, e))
710
786
  })] })]
711
787
  })
712
788
  ]
713
- }), /* @__PURE__ */ g("div", {
714
- className: "flex items-center justify-end gap-4 pt-6 mt-6 border-t border-border-default",
715
- children: [/* @__PURE__ */ h(l, {
716
- type: "button",
717
- onClick: He,
718
- variant: "secondary",
719
- children: "Cancel"
720
- }), /* @__PURE__ */ h(l, {
721
- type: "submit",
722
- disabled: !We || M,
723
- variant: "default",
724
- children: M ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(s, { className: "w-4 h-4 mr-2 animate-spin" }), "Saving..."] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(pe, { className: "w-4 h-4 mr-2" }), w ? "Save Changes" : "Create Parser"] })
725
- })]
789
+ })]
790
+ }),
791
+ /* @__PURE__ */ p("div", {
792
+ className: "flex items-center justify-between gap-4 pt-6 mt-6 border-t border-border-default",
793
+ children: [y === 0 ? /* @__PURE__ */ f(u, {
794
+ type: "button",
795
+ onClick: Z,
796
+ variant: "secondary",
797
+ children: "Cancel"
798
+ }) : /* @__PURE__ */ p(u, {
799
+ type: "button",
800
+ onClick: vt,
801
+ variant: "secondary",
802
+ children: [/* @__PURE__ */ f(ae, { className: "w-4 h-4 mr-2" }), "Back"]
803
+ }), yt ? /* @__PURE__ */ f(u, {
804
+ type: "button",
805
+ onClick: mt,
806
+ disabled: !ht || Ae,
807
+ variant: "default",
808
+ children: Ae ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(c, { className: "w-4 h-4 mr-2 animate-spin" }), "Saving..."] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(me, { className: "w-4 h-4 mr-2" }), C ? "Save Changes" : "Create Parser"] })
809
+ }) : /* @__PURE__ */ p(u, {
810
+ type: "button",
811
+ onClick: _t,
812
+ disabled: !Q(y),
813
+ variant: "default",
814
+ children: ["Next", /* @__PURE__ */ f(ce, { className: "w-4 h-4 ml-2" })]
726
815
  })]
727
816
  })
728
817
  ]
@@ -730,6 +819,6 @@ var _ = {
730
819
  });
731
820
  });
732
821
  //#endregion
733
- export { y as ParserBuilderPage, y as default };
822
+ export { v as ParserBuilderPage, v as default };
734
823
 
735
824
  //# sourceMappingURL=ParserBuilderPage.js.map