@nice2dev/ui-forms 1.1.9 → 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,18 +1,2446 @@
1
- import { N as s, a as o, b as i, c as m, d as r, e as c, f as t, g as d, h as n, i as h, j as F, k as N, s as f, v as l, l as S } from "./index-gnCoC9VA.js";
1
+ import { jsx as e, jsxs as u } from "react/jsx-runtime";
2
+ import { useNiceTranslation as ze } from "@nice2dev/i18n";
3
+ import { useControllableState as le, NiceIcon as z, NiceDataGrid as fe, useNiceTranslation as Z, evaluateValidation as Ee, NiceTutorialButton as se, resolveTutorial as ce, NiceTooltip as X, NiceForm as Je, useNiceAI as Ue, useFormGeneration as He, NiceScriptRunner as we, NiceLifecycleHooksEditor as ke, NiceRevisionHistory as Se, NiceConsole as Te, NiceLogConsole as Fe, NiceBadge as ae, NiceValidationBuilder as Ge, NiceButton as te, NiceTabs as We, NiceCheckbox as Ye, NiceSelect as Qe, NiceTextInput as Xe, NiceAccessManager as Ze, NiceViewEditor as et, NiceWorkflowDesigner as tt, NiceDataSourceBuilder as it } from "@nice2dev/ui";
4
+ import nt, { useState as K, forwardRef as ee, useMemo as P, useEffect as oe, useCallback as Q, useImperativeHandle as at } from "react";
5
+ import { useNiceTranslation as ot, useControllableState as rt, NiceTutorialButton as lt, resolveTutorial as st, NiceIcon as be } from "@nice2dev/ui-core";
6
+ function Bt(t) {
7
+ var l, o;
8
+ const r = {
9
+ text: "text",
10
+ email: "email",
11
+ password: "password",
12
+ phone: "phone",
13
+ url: "url",
14
+ textarea: "textarea",
15
+ number: "number",
16
+ date: "date",
17
+ datetime: "datetime",
18
+ time: "time",
19
+ select: "select",
20
+ multiselect: "tags",
21
+ checkbox: "checkbox",
22
+ toggle: "toggle",
23
+ radio: "radio",
24
+ slider: "slider",
25
+ rating: "rating",
26
+ color: "color",
27
+ file: "file",
28
+ image: "file"
29
+ }, a = [];
30
+ for (const i of t.sections)
31
+ for (const n of i.fields)
32
+ n.type === "heading" || n.type === "paragraph" || n.type === "divider" || n.type === "spacer" || n.type === "section" || a.push({
33
+ field: n.name,
34
+ label: n.label || n.name,
35
+ type: r[n.type] || "text",
36
+ placeholder: n.placeholder,
37
+ hint: n.helpText,
38
+ defaultValue: n.defaultValue,
39
+ required: n.required || ((l = n.validations) == null ? void 0 : l.some((c) => c.type === "required")),
40
+ disabled: n.disabled,
41
+ readOnly: n.readonly,
42
+ group: i.title,
43
+ options: (o = n.options) == null ? void 0 : o.map(
44
+ (c) => typeof c == "string" ? { label: c, value: c } : { label: c.label, value: c.value }
45
+ )
46
+ });
47
+ return a;
48
+ }
49
+ function ve(t) {
50
+ var a;
51
+ const r = {
52
+ text: "NiceTextInput",
53
+ textarea: "NiceTextArea",
54
+ number: "NiceNumberInput",
55
+ email: "NiceTextInput",
56
+ password: "NicePasswordInput",
57
+ date: "NiceDateTimePicker",
58
+ datetime: "NiceDateTimePicker",
59
+ time: "NiceDateTimePicker",
60
+ select: "NiceSelect",
61
+ multiselect: "NiceTagBox",
62
+ checkbox: "NiceCheckbox",
63
+ toggle: "NiceToggle",
64
+ radio: "NiceRadioGroup",
65
+ slider: "NiceSlider",
66
+ rating: "NiceRating",
67
+ color: "NiceColorPicker"
68
+ };
69
+ return {
70
+ dataField: t.name,
71
+ label: { text: t.label },
72
+ editorType: r[t.type] || "NiceTextInput",
73
+ editorOptions: {
74
+ placeholder: t.placeholder,
75
+ disabled: t.disabled,
76
+ readOnly: t.readonly,
77
+ ...t.props
78
+ },
79
+ colSpan: Math.ceil((t.colSpan || 12) / 6),
80
+ validationRules: (a = t.validations) == null ? void 0 : a.map((l) => ({
81
+ type: l.type,
82
+ message: l.message,
83
+ ...l.value !== void 0 ? { [l.type]: l.value } : {}
84
+ })),
85
+ helpText: t.helpText
86
+ };
87
+ }
88
+ function zt(t) {
89
+ const r = [];
90
+ for (const a of t.sections)
91
+ a.title ? r.push({
92
+ itemType: "group",
93
+ caption: a.title,
94
+ colCount: a.columns || 2,
95
+ items: a.fields.map(ve)
96
+ }) : r.push(...a.fields.map(ve));
97
+ return r;
98
+ }
99
+ function Jt(t) {
100
+ const r = [];
101
+ t.version || r.push("Missing schema version"), t.id || r.push("Missing form ID"), (!t.sections || t.sections.length === 0) && r.push("Form must have at least one section");
102
+ const a = /* @__PURE__ */ new Set();
103
+ for (const l of t.sections || [])
104
+ for (const o of l.fields || [])
105
+ o.id || r.push(`Field missing ID: ${o.name}`), o.name || r.push(`Field missing name: ${o.id}`), a.has(o.name) && r.push(`Duplicate field name: ${o.name}`), a.add(o.name);
106
+ return { valid: r.length === 0, errors: r };
107
+ }
108
+ function _e(t) {
109
+ const { value: r, onChange: a, readOnly: l } = t, [o, i] = K(() => {
110
+ try {
111
+ return r === void 0 ? "" : JSON.stringify(r, null, 2);
112
+ } catch {
113
+ return "";
114
+ }
115
+ }), [n, c] = K(null);
116
+ return nt.useEffect(() => {
117
+ try {
118
+ i(r === void 0 ? "" : JSON.stringify(r, null, 2));
119
+ } catch {
120
+ }
121
+ }, [JSON.stringify(r)]), /* @__PURE__ */ u("div", { className: "nice-schema-form__json-field", children: [
122
+ /* @__PURE__ */ e(
123
+ "textarea",
124
+ {
125
+ className: "nice-schema-form__json-textarea",
126
+ value: o,
127
+ readOnly: l,
128
+ spellCheck: !1,
129
+ rows: Math.min(12, Math.max(3, o.split(`
130
+ `).length)),
131
+ onChange: (f) => {
132
+ const p = f.target.value;
133
+ i(p);
134
+ const y = p.trim();
135
+ if (y === "") {
136
+ c(null), a(void 0);
137
+ return;
138
+ }
139
+ try {
140
+ a(JSON.parse(y)), c(null);
141
+ } catch (s) {
142
+ c(s instanceof Error ? s.message : "Invalid JSON");
143
+ }
144
+ }
145
+ }
146
+ ),
147
+ n && /* @__PURE__ */ e("div", { className: "nice-schema-form__json-error", children: n })
148
+ ] });
149
+ }
150
+ function ct(t) {
151
+ switch (t) {
152
+ case "email":
153
+ return "email";
154
+ case "uri":
155
+ case "url":
156
+ return "url";
157
+ case "date":
158
+ return "date";
159
+ case "date-time":
160
+ return "datetime";
161
+ case "time":
162
+ return "time";
163
+ case "color":
164
+ return "color";
165
+ case "password":
166
+ return "password";
167
+ case "phone":
168
+ return "phone";
169
+ case "data-url":
170
+ return "file";
171
+ default:
172
+ return "text";
173
+ }
174
+ }
175
+ function dt(t, r, a, l = {}) {
176
+ const o = {
177
+ field: t,
178
+ label: r.title ?? t,
179
+ required: a,
180
+ hint: r.description,
181
+ defaultValue: r.default
182
+ };
183
+ if (r.enum && r.enum.length > 0)
184
+ return {
185
+ ...o,
186
+ type: "select",
187
+ options: r.enum.map((i) => ({ label: String(i), value: i }))
188
+ };
189
+ switch (r.type) {
190
+ case "number":
191
+ case "integer":
192
+ return { ...o, type: "number" };
193
+ case "boolean":
194
+ return { ...o, type: "checkbox" };
195
+ case "string":
196
+ return { ...o, type: ct(r.format) };
197
+ case "array": {
198
+ const i = r.items;
199
+ if (i != null && i.enum && i.enum.length > 0)
200
+ return {
201
+ ...o,
202
+ type: "tags",
203
+ options: i.enum.map((n) => ({ label: String(n), value: String(n) }))
204
+ };
205
+ if ((i == null ? void 0 : i.type) === "object" && i.properties && l.renderArrayField) {
206
+ const n = l.renderArrayField;
207
+ return {
208
+ ...o,
209
+ render: (c, f) => n(
210
+ c ?? [],
211
+ f,
212
+ i,
213
+ o.label
214
+ )
215
+ };
216
+ }
217
+ return (i == null ? void 0 : i.type) === "string" || (i == null ? void 0 : i.type) === "number" || (i == null ? void 0 : i.type) === "integer" ? { ...o, type: "tags" } : {
218
+ ...o,
219
+ render: (n, c) => /* @__PURE__ */ e(_e, { value: n, onChange: c })
220
+ };
221
+ }
222
+ case "object":
223
+ if (l.renderObjectField) {
224
+ const i = l.renderObjectField;
225
+ return {
226
+ ...o,
227
+ render: (n, c) => i(
228
+ n ?? {},
229
+ c,
230
+ r,
231
+ o.label
232
+ )
233
+ };
234
+ }
235
+ return {
236
+ ...o,
237
+ render: (i, n) => /* @__PURE__ */ e(_e, { value: i, onChange: n })
238
+ };
239
+ default:
240
+ return { ...o, type: "text" };
241
+ }
242
+ }
243
+ function xe(t, r = {}) {
244
+ const { uiSchema: a, renderArrayField: l, renderObjectField: o } = r, i = { renderArrayField: l, renderObjectField: o }, n = t.properties ?? {}, c = new Set(t.required ?? []);
245
+ return Object.keys(n).map((f) => {
246
+ const p = dt(f, n[f], c.has(f), i);
247
+ return a != null && a[f] ? { ...p, ...a[f] } : p;
248
+ });
249
+ }
250
+ const ut = {
251
+ text: "text",
252
+ textarea: "textarea",
253
+ number: "number",
254
+ email: "email",
255
+ password: "password",
256
+ phone: "phone",
257
+ url: "url",
258
+ date: "date",
259
+ datetime: "datetime",
260
+ time: "time",
261
+ select: "select",
262
+ multiselect: "tags",
263
+ checkbox: "checkbox",
264
+ toggle: "toggle",
265
+ radio: "radio",
266
+ slider: "slider",
267
+ rating: "rating",
268
+ color: "color"
269
+ };
270
+ function Ce(t, r = {}) {
271
+ var o, i;
272
+ const { uiSchema: a } = r, l = [];
273
+ for (const n of t) {
274
+ if (n.type === "section" && n.children) {
275
+ for (const p of Ce(n.children, r))
276
+ l.push(n.label ? { ...p, group: n.label } : p);
277
+ continue;
278
+ }
279
+ const c = ut[n.type];
280
+ if (!c)
281
+ continue;
282
+ const f = {
283
+ field: n.name,
284
+ label: n.label,
285
+ type: c,
286
+ required: n.required || ((o = n.validations) == null ? void 0 : o.some((p) => p.type === "required")),
287
+ placeholder: n.placeholder,
288
+ hint: n.helpText,
289
+ defaultValue: n.defaultValue,
290
+ disabled: n.disabled,
291
+ readOnly: n.readonly,
292
+ options: (i = n.options) == null ? void 0 : i.map(
293
+ (p) => typeof p == "string" ? { label: p, value: p } : { label: p.label, value: p.value }
294
+ )
295
+ };
296
+ l.push(a != null && a[n.name] ? { ...f, ...a[n.name] } : f);
297
+ }
298
+ return l;
299
+ }
300
+ function Ne(t) {
301
+ return t == null || t === "" || Array.isArray(t) && t.length === 0;
302
+ }
303
+ function Ie(t, r) {
304
+ const a = [], l = r.properties ?? {}, o = new Set(r.required ?? []);
305
+ for (const i of Object.keys(l)) {
306
+ const n = l[i], c = t[i];
307
+ if (o.has(i) && Ne(c)) {
308
+ a.push({ field: i, message: `${n.title ?? i} is required` });
309
+ continue;
310
+ }
311
+ if (!Ne(c) && (n.enum && !n.enum.includes(c) && a.push({
312
+ field: i,
313
+ message: `${n.title ?? i} must be one of: ${n.enum.join(", ")}`
314
+ }), (n.type === "number" || n.type === "integer") && typeof c == "number" && (n.minimum !== void 0 && c < n.minimum && a.push({ field: i, message: `${n.title ?? i} must be ≥ ${n.minimum}` }), n.maximum !== void 0 && c > n.maximum && a.push({ field: i, message: `${n.title ?? i} must be ≤ ${n.maximum}` })), n.type === "string" && typeof c == "string" && (n.minLength !== void 0 && c.length < n.minLength && a.push({
315
+ field: i,
316
+ message: `${n.title ?? i} must be at least ${n.minLength} chars`
317
+ }), n.maxLength !== void 0 && c.length > n.maxLength && a.push({
318
+ field: i,
319
+ message: `${n.title ?? i} must be at most ${n.maxLength} chars`
320
+ }), n.pattern)))
321
+ try {
322
+ new RegExp(n.pattern).test(c) || a.push({ field: i, message: `${n.title ?? i} has an invalid format` });
323
+ } catch {
324
+ }
325
+ }
326
+ return a;
327
+ }
328
+ const ue = "__nafRid";
329
+ function mt(t) {
330
+ return Array.isArray(t) ? `[${t.length}]` : t && typeof t == "object" ? "{…}" : t == null ? "" : String(t);
331
+ }
332
+ const pt = ee(
333
+ function(r, a) {
334
+ const {
335
+ value: l,
336
+ defaultValue: o,
337
+ onChange: i,
338
+ itemSchema: n,
339
+ title: c,
340
+ readOnly: f = !1,
341
+ columns: p,
342
+ className: y,
343
+ style: s,
344
+ "data-testid": h
345
+ } = r, [F, O] = le({
346
+ value: l,
347
+ defaultValue: o,
348
+ fallbackValue: [],
349
+ onChange: i,
350
+ componentName: "NiceArrayField"
351
+ }), D = n.properties ?? {}, A = P(() => (p ?? Object.keys(D)).map((I) => {
352
+ const v = D[I] ?? {}, k = { field: I, header: v.title ?? I };
353
+ return v.type === "boolean" ? (k.render = (j) => j ? /* @__PURE__ */ e(z, { name: "check", size: 14, title: "true" }) : "", k.align = "center") : (v.type === "array" || v.type === "object") && (k.render = (j) => mt(j)), k;
354
+ }), [n, p]), C = P(
355
+ () => xe(n),
356
+ [n]
357
+ ), w = P(() => F.map((M, I) => ({ ...M, [ue]: String(I) })), [F]), $ = (M) => {
358
+ const { [ue]: I, ...v } = M;
359
+ return v;
360
+ }, J = "nice-array-field" + (y ? ` ${y}` : "");
361
+ return /* @__PURE__ */ e("div", { ref: a, className: J, style: s, "data-testid": h, children: /* @__PURE__ */ e(
362
+ fe,
363
+ {
364
+ data: w,
365
+ keyField: ue,
366
+ columns: A,
367
+ editMode: "popup",
368
+ formItems: C,
369
+ editFormTitle: c ? `${c} — item` : "Edit item",
370
+ emptyText: `No items${c ? ` in ${c}` : ""}`,
371
+ compact: !0,
372
+ onRowAdd: f ? void 0 : (M) => O([...F, $(M)]),
373
+ onRowEdit: f ? void 0 : (M, I) => {
374
+ const v = Number(M);
375
+ O(
376
+ F.map(
377
+ (k, j) => j === v ? $(I) : k
378
+ )
379
+ );
380
+ },
381
+ onRowDelete: f ? void 0 : (M) => {
382
+ const I = Number(M);
383
+ O(F.filter((v, k) => k !== I));
384
+ }
385
+ }
386
+ ) });
387
+ }
388
+ ), ht = [
389
+ {
390
+ target: ".nice-schema-form",
391
+ titleKey: "tutorial.schemaForm.intro.title",
392
+ title: "Schema form",
393
+ contentKey: "tutorial.schemaForm.intro.content",
394
+ content: "This form is generated from a schema. Required fields and validation errors are flagged; use the JSON toggle for raw editing.",
395
+ placement: "auto"
396
+ },
397
+ {
398
+ target: '[data-tour="sf-viewtoggle"]',
399
+ titleKey: "tutorial.schemaForm.viewToggle.title",
400
+ title: "Form ⇄ JSON",
401
+ contentKey: "tutorial.schemaForm.viewToggle.content",
402
+ content: "Switch between the visual form and the raw JSON value — handy for power users and copy/paste.",
403
+ placement: "bottom"
404
+ },
405
+ {
406
+ target: ".nice-schema-form",
407
+ titleKey: "tutorial.schemaForm.validation.title",
408
+ title: "Live validation",
409
+ contentKey: "tutorial.schemaForm.validation.content",
410
+ content: "Values are validated against the schema as you type; any problems are listed below the form.",
411
+ placement: "auto"
412
+ }
413
+ ];
414
+ function ft(t) {
415
+ const r = [], a = (l) => {
416
+ for (const o of l) {
417
+ if (o.type === "section" && o.children) {
418
+ a(o.children);
419
+ continue;
420
+ }
421
+ o.required && r.push({ id: `${o.name}-required`, field: o.name, op: "required" });
422
+ for (const i of o.validations ?? [])
423
+ r.push({
424
+ id: `${o.name}-${i.type}`,
425
+ field: o.name,
426
+ op: i.type,
427
+ value: typeof i.value == "boolean" ? void 0 : i.value,
428
+ message: i.message ?? (i.type === "required" ? `${o.label ?? o.name} is required` : void 0)
429
+ });
430
+ }
431
+ };
432
+ return a(t), r;
433
+ }
434
+ function yt(t, r) {
435
+ return Ee(ft(t), r).filter((a) => a.severity === "error").map((a) => ({ field: a.field, message: a.message }));
436
+ }
437
+ const de = ee(
438
+ function(r, a) {
439
+ const {
440
+ schema: l,
441
+ fields: o,
442
+ uiSchema: i,
443
+ value: n,
444
+ defaultValue: c,
445
+ onChange: f,
446
+ onValidate: p,
447
+ showJsonView: y = !1,
448
+ columns: s = 1,
449
+ labelPosition: h = "top",
450
+ readOnly: F = !1,
451
+ liveValidation: O = !0,
452
+ validationRules: D,
453
+ tutorial: A,
454
+ className: C,
455
+ style: w,
456
+ id: $,
457
+ "data-testid": J
458
+ } = r, { t: M } = Z(), [I, v] = le({
459
+ value: n,
460
+ defaultValue: c,
461
+ fallbackValue: {},
462
+ onChange: f,
463
+ componentName: "NiceSchemaForm"
464
+ }), [k, j] = K(!1), [U, L] = K(""), [S, H] = K(null), N = P(() => l ? xe(l, {
465
+ uiSchema: i,
466
+ // Inject the structured array editor (avoids an import cycle in the converter).
467
+ renderArrayField: (E, g, x, R) => /* @__PURE__ */ e(
468
+ pt,
469
+ {
470
+ value: E,
471
+ onChange: g,
472
+ itemSchema: x,
473
+ title: R,
474
+ readOnly: F
475
+ }
476
+ )
477
+ }) : o ? Ce(o, { uiSchema: i }) : [], [l, o, i, F]), q = P(() => {
478
+ const E = l ? Ie(I, l) : o ? yt(o, I) : [];
479
+ if (D != null && D.length) {
480
+ const g = Ee(D, I).filter((x) => x.severity === "error").map((x) => ({ field: x.field, message: x.message }));
481
+ return [...E, ...g];
482
+ }
483
+ return E;
484
+ }, [l, o, I, D]);
485
+ oe(() => {
486
+ p == null || p(q);
487
+ }, [q, p]), oe(() => {
488
+ if (k)
489
+ try {
490
+ L(JSON.stringify(I, null, 2)), H(null);
491
+ } catch {
492
+ }
493
+ }, [k, I]);
494
+ const m = (E, g) => {
495
+ v({ ...I, [E]: g });
496
+ }, _ = "nice-schema-form" + (C ? ` ${C}` : "");
497
+ return /* @__PURE__ */ u("div", { ref: a, id: $, className: _, style: w, "data-testid": J, children: [
498
+ A && /* @__PURE__ */ e("div", { className: "nice-schema-form__tutorial", children: /* @__PURE__ */ e(se, { steps: ce(A, ht) }) }),
499
+ y && /* @__PURE__ */ u("div", { className: "nice-schema-form__toolbar", "data-tour": "sf-viewtoggle", children: [
500
+ /* @__PURE__ */ e(
501
+ "button",
502
+ {
503
+ type: "button",
504
+ className: "nice-schema-form__tab" + (k ? "" : " nice-schema-form__tab--active"),
505
+ onClick: () => j(!1),
506
+ children: M("schemaForm.tab.form", "Form")
507
+ }
508
+ ),
509
+ /* @__PURE__ */ e(
510
+ X,
511
+ {
512
+ content: M("schemaForm.tab.json.help", "Edit the raw JSON value directly"),
513
+ children: /* @__PURE__ */ e(
514
+ "button",
515
+ {
516
+ type: "button",
517
+ className: "nice-schema-form__tab" + (k ? " nice-schema-form__tab--active" : ""),
518
+ onClick: () => j(!0),
519
+ children: M("schemaForm.tab.json", "JSON")
520
+ }
521
+ )
522
+ }
523
+ )
524
+ ] }),
525
+ k ? /* @__PURE__ */ u("div", { className: "nice-schema-form__json", children: [
526
+ /* @__PURE__ */ e(
527
+ "textarea",
528
+ {
529
+ className: "nice-schema-form__json-textarea",
530
+ value: U,
531
+ readOnly: F,
532
+ spellCheck: !1,
533
+ rows: Math.min(24, Math.max(6, U.split(`
534
+ `).length)),
535
+ onChange: (E) => {
536
+ const g = E.target.value;
537
+ L(g);
538
+ try {
539
+ const x = JSON.parse(g);
540
+ H(null), v(x);
541
+ } catch (x) {
542
+ H(
543
+ x instanceof Error ? x.message : M("schemaForm.invalidJson", "Invalid JSON")
544
+ );
545
+ }
546
+ }
547
+ }
548
+ ),
549
+ S && /* @__PURE__ */ e("div", { className: "nice-schema-form__json-error", children: S })
550
+ ] }) : /* @__PURE__ */ e(
551
+ Je,
552
+ {
553
+ items: N,
554
+ data: I,
555
+ onFieldChange: m,
556
+ columns: s,
557
+ labelPosition: h,
558
+ readOnly: F
559
+ }
560
+ ),
561
+ O && q.length > 0 && /* @__PURE__ */ e("ul", { className: "nice-schema-form__errors", role: "alert", children: q.map((E, g) => /* @__PURE__ */ e("li", { className: "nice-schema-form__error", children: E.message }, `${E.field}-${g}`)) })
562
+ ] });
563
+ }
564
+ ), gt = [
565
+ { name: "Contact Form", description: "A simple contact form with name, email, and message" },
566
+ {
567
+ name: "Registration Form",
568
+ description: "User registration with username, email, password, and profile info"
569
+ },
570
+ {
571
+ name: "Survey Form",
572
+ description: "Customer satisfaction survey with rating and feedback fields"
573
+ },
574
+ {
575
+ name: "Order Form",
576
+ description: "Product order form with shipping address and payment details"
577
+ },
578
+ {
579
+ name: "Job Application",
580
+ description: "Job application with personal info, experience, and file uploads"
581
+ },
582
+ { name: "Event Registration", description: "Event sign-up with attendee info and preferences" }
583
+ ];
584
+ function bt(t) {
585
+ return {
586
+ text: "text",
587
+ string: "text",
588
+ textarea: "textarea",
589
+ number: "number",
590
+ integer: "number",
591
+ email: "email",
592
+ password: "password",
593
+ phone: "phone",
594
+ tel: "phone",
595
+ url: "url",
596
+ date: "date",
597
+ datetime: "datetime",
598
+ time: "time",
599
+ select: "select",
600
+ dropdown: "select",
601
+ multiselect: "multiselect",
602
+ checkbox: "checkbox",
603
+ boolean: "checkbox",
604
+ toggle: "toggle",
605
+ switch: "toggle",
606
+ radio: "radio",
607
+ slider: "slider",
608
+ range: "slider",
609
+ rating: "rating",
610
+ stars: "rating",
611
+ color: "color",
612
+ file: "file",
613
+ upload: "file",
614
+ signature: "signature"
615
+ }[t.toLowerCase()] || "text";
616
+ }
617
+ function vt(t) {
618
+ return t.map((r, a) => {
619
+ var l;
620
+ return {
621
+ id: `field_${Date.now()}_${a}`,
622
+ type: bt(r.type),
623
+ label: r.label,
624
+ name: r.field,
625
+ placeholder: r.placeholder,
626
+ helperText: r.helpText,
627
+ required: r.required,
628
+ options: (l = r.options) == null ? void 0 : l.map((o, i) => ({
629
+ value: o.toLowerCase().replace(/\s+/g, "_"),
630
+ label: o
631
+ })),
632
+ validation: r.required ? [{ type: "required", message: `${r.label} is required` }] : [],
633
+ width: "100%",
634
+ order: a
635
+ };
636
+ });
637
+ }
638
+ const Ut = ee(
639
+ function(r, a) {
640
+ const {
641
+ enableAI: l = !0,
642
+ aiModel: o,
643
+ enableGenerate: i = !0,
644
+ enableSuggestions: n = !0,
645
+ onGenerate: c,
646
+ showAIToolbar: f = !0,
647
+ templates: p = gt,
648
+ fields: y,
649
+ onChange: s
650
+ } = r, [h, F] = K(!1), [O, D] = K(""), [A, C] = K([]), [w, $] = K(y || []), [J, M] = K(!1), [I, v] = K({}), { t: k } = ze(), j = Ue(), { generateForm: U, isLoading: L } = He(), S = l && j.isConfigured, H = Q(
651
+ async (g) => {
652
+ if (!S || !i || !g.trim())
653
+ return [];
654
+ try {
655
+ const x = await U(g);
656
+ return C(x), c == null || c(g, x), x;
657
+ } catch {
658
+ return [];
659
+ }
660
+ },
661
+ [S, i, U, c]
662
+ ), N = Q(
663
+ (g) => {
664
+ const x = vt(g);
665
+ $((R) => [...R, ...x]), s == null || s([...w, ...x]), F(!1), C([]), D("");
666
+ },
667
+ [s]
668
+ ), q = Q(() => w, [w]), m = Q(() => {
669
+ $([]), s == null || s([]);
670
+ }, [s]), _ = (g) => {
671
+ D(g.description), M(!1), H(g.description);
672
+ };
673
+ at(a, () => ({
674
+ generateForm: H,
675
+ getFields: q,
676
+ applyFields: N,
677
+ clearFields: m
678
+ }));
679
+ const E = (g) => ({
680
+ text: "edit",
681
+ textarea: "file",
682
+ number: "hash",
683
+ email: "mail",
684
+ password: "lock",
685
+ phone: "phone",
686
+ date: "calendar",
687
+ select: "list",
688
+ checkbox: "check",
689
+ toggle: "settings",
690
+ radio: "circle",
691
+ file: "paperclip",
692
+ rating: "star"
693
+ })[g] || "edit";
694
+ return /* @__PURE__ */ u("div", { className: "nice-form-builder-ai", "data-testid": r["data-testid"], children: [
695
+ f && S && /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__toolbar", children: [
696
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__toolbar-left", children: [
697
+ /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__badge", children: "AI" }),
698
+ L && /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__loading", children: k("formBuilderAI.generating", "Generating...") })
699
+ ] }),
700
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__toolbar-right", children: [
701
+ i && /* @__PURE__ */ u(
702
+ "button",
703
+ {
704
+ type: "button",
705
+ className: "nice-form-builder-ai__btn",
706
+ onClick: () => F(!0),
707
+ disabled: L,
708
+ children: [
709
+ /* @__PURE__ */ e(z, { name: "zap", size: "sm" }),
710
+ " ",
711
+ k("formBuilderAI.generateForm", "Generate Form")
712
+ ]
713
+ }
714
+ ),
715
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__templates-dropdown", children: [
716
+ /* @__PURE__ */ u(
717
+ "button",
718
+ {
719
+ type: "button",
720
+ className: "nice-form-builder-ai__btn nice-form-builder-ai__btn--secondary",
721
+ onClick: () => M(!J),
722
+ children: [
723
+ /* @__PURE__ */ e(z, { name: "list", size: "sm" }),
724
+ " ",
725
+ k("formBuilderAI.templates", "Templates"),
726
+ " ",
727
+ /* @__PURE__ */ e(z, { name: "chevron-down", size: "sm" })
728
+ ]
729
+ }
730
+ ),
731
+ J && /* @__PURE__ */ e("div", { className: "nice-form-builder-ai__templates-menu", children: p.map((g, x) => /* @__PURE__ */ u(
732
+ "button",
733
+ {
734
+ type: "button",
735
+ className: "nice-form-builder-ai__template-item",
736
+ onClick: () => _(g),
737
+ children: [
738
+ /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__template-name", children: g.name }),
739
+ /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__template-desc", children: g.description })
740
+ ]
741
+ },
742
+ x
743
+ )) })
744
+ ] })
745
+ ] })
746
+ ] }),
747
+ /* @__PURE__ */ e("div", { className: "nice-form-builder-ai__builder-wrapper", children: /* @__PURE__ */ e(
748
+ de,
749
+ {
750
+ fields: w,
751
+ value: I,
752
+ onChange: v,
753
+ columns: 1
754
+ }
755
+ ) }),
756
+ h && /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__panel", children: [
757
+ /* @__PURE__ */ e(
758
+ "div",
759
+ {
760
+ className: "nice-form-builder-ai__panel-overlay",
761
+ onClick: () => F(!1)
762
+ }
763
+ ),
764
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__panel-content", children: [
765
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__panel-header", children: [
766
+ /* @__PURE__ */ u("h4", { children: [
767
+ /* @__PURE__ */ e(z, { name: "zap", size: "sm" }),
768
+ " ",
769
+ k("formBuilderAI.generateFormTitle", "Generate Form with AI")
770
+ ] }),
771
+ /* @__PURE__ */ e(
772
+ "button",
773
+ {
774
+ type: "button",
775
+ className: "nice-form-builder-ai__panel-close",
776
+ onClick: () => {
777
+ F(!1), C([]), D("");
778
+ },
779
+ "aria-label": "Close",
780
+ children: /* @__PURE__ */ e(z, { name: "close", size: "sm" })
781
+ }
782
+ )
783
+ ] }),
784
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__panel-body", children: [
785
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__prompt-section", children: [
786
+ /* @__PURE__ */ e("label", { className: "nice-form-builder-ai__label", children: k("formBuilderAI.describeForm", "Describe the form you want to create:") }),
787
+ /* @__PURE__ */ e(
788
+ "textarea",
789
+ {
790
+ className: "nice-form-builder-ai__textarea",
791
+ placeholder: k(
792
+ "formBuilderAI.promptPlaceholder",
793
+ 'e.g., "A contact form with name, email, phone, subject dropdown, and message textarea"'
794
+ ),
795
+ value: O,
796
+ onChange: (g) => D(g.target.value),
797
+ rows: 3
798
+ }
799
+ ),
800
+ /* @__PURE__ */ e(
801
+ "button",
802
+ {
803
+ type: "button",
804
+ className: "nice-form-builder-ai__generate-btn",
805
+ onClick: () => H(O),
806
+ disabled: L || !O.trim(),
807
+ children: L ? k("formBuilderAI.generating", "Generating...") : k("formBuilderAI.generate", "Generate")
808
+ }
809
+ )
810
+ ] }),
811
+ A.length > 0 && /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__preview-section", children: [
812
+ /* @__PURE__ */ u("h5", { children: [
813
+ k("formBuilderAI.preview", "Preview"),
814
+ " (",
815
+ A.length,
816
+ " ",
817
+ k("formBuilderAI.fields", "fields"),
818
+ ")"
819
+ ] }),
820
+ /* @__PURE__ */ e("div", { className: "nice-form-builder-ai__fields-preview", children: A.map((g, x) => /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__field-preview", children: [
821
+ /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__field-icon", children: /* @__PURE__ */ e(z, { name: E(g.type), size: "sm" }) }),
822
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__field-info", children: [
823
+ /* @__PURE__ */ u("span", { className: "nice-form-builder-ai__field-label", children: [
824
+ g.label,
825
+ g.required && /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__required", children: "*" })
826
+ ] }),
827
+ /* @__PURE__ */ e("span", { className: "nice-form-builder-ai__field-type", children: g.type })
828
+ ] }),
829
+ g.options && /* @__PURE__ */ u("span", { className: "nice-form-builder-ai__field-options", children: [
830
+ g.options.length,
831
+ " options"
832
+ ] })
833
+ ] }, x)) })
834
+ ] })
835
+ ] }),
836
+ /* @__PURE__ */ u("div", { className: "nice-form-builder-ai__panel-footer", children: [
837
+ /* @__PURE__ */ u(
838
+ "button",
839
+ {
840
+ type: "button",
841
+ className: "nice-form-builder-ai__apply-btn",
842
+ onClick: () => N(A),
843
+ disabled: A.length === 0 || L,
844
+ children: [
845
+ /* @__PURE__ */ e(z, { name: "check", size: "sm" }),
846
+ " ",
847
+ k("formBuilderAI.addToForm", "Add to Form")
848
+ ]
849
+ }
850
+ ),
851
+ /* @__PURE__ */ e(
852
+ "button",
853
+ {
854
+ type: "button",
855
+ className: "nice-form-builder-ai__cancel-btn",
856
+ onClick: () => {
857
+ F(!1), C([]), D("");
858
+ },
859
+ children: k("formBuilderAI.cancel", "Cancel")
860
+ }
861
+ )
862
+ ] })
863
+ ] })
864
+ ] })
865
+ ] });
866
+ }
867
+ ), _t = {
868
+ text: { type: "string" },
869
+ textarea: { type: "string" },
870
+ password: { type: "string", format: "password" },
871
+ phone: { type: "string", format: "phone" },
872
+ url: { type: "string", format: "uri" },
873
+ email: { type: "string", format: "email" },
874
+ date: { type: "string", format: "date" },
875
+ datetime: { type: "string", format: "date-time" },
876
+ time: { type: "string", format: "time" },
877
+ color: { type: "string", format: "color" },
878
+ number: { type: "number" },
879
+ slider: { type: "number" },
880
+ rating: { type: "integer" },
881
+ checkbox: { type: "boolean" },
882
+ toggle: { type: "boolean" },
883
+ select: { type: "string" },
884
+ radio: { type: "string" },
885
+ multiselect: { type: "array", items: { type: "string" } },
886
+ file: { type: "string", format: "data-url" },
887
+ signature: { type: "string", format: "data-url" },
888
+ richtext: { type: "string" },
889
+ markdown: { type: "string" },
890
+ code: { type: "string" },
891
+ image: { type: "string", format: "uri" }
892
+ };
893
+ function Nt(t, r) {
894
+ if (r)
895
+ for (const a of r)
896
+ switch (a.type) {
897
+ case "minLength":
898
+ typeof a.value == "number" && (t.minLength = a.value);
899
+ break;
900
+ case "maxLength":
901
+ typeof a.value == "number" && (t.maxLength = a.value);
902
+ break;
903
+ case "min":
904
+ typeof a.value == "number" && (t.minimum = a.value);
905
+ break;
906
+ case "max":
907
+ typeof a.value == "number" && (t.maximum = a.value);
908
+ break;
909
+ case "pattern":
910
+ typeof a.value == "string" && (t.pattern = a.value);
911
+ break;
912
+ case "email":
913
+ t.format = "email";
914
+ break;
915
+ case "url":
916
+ t.format = "uri";
917
+ break;
918
+ }
919
+ }
920
+ function Et(t) {
921
+ if (t.type === "heading" || t.type === "paragraph" || t.type === "divider" || t.type === "spacer")
922
+ return null;
923
+ const r = _t[t.type];
924
+ if (!r)
925
+ return null;
926
+ const a = { ...r };
927
+ return t.label && (a.title = t.label), t.helpText && (a.description = t.helpText), t.defaultValue !== void 0 && (a.default = t.defaultValue), t.options && (t.type === "select" || t.type === "radio") && (a.enum = t.options.map((l) => typeof l == "string" ? l : l.value)), t.options && t.type === "multiselect" && (a.items = {
928
+ type: "string",
929
+ enum: t.options.map((l) => typeof l == "string" ? l : String(l.value))
930
+ }), Nt(a, t.validations), a;
931
+ }
932
+ function Ht(t) {
933
+ const r = {}, a = [], l = (i) => {
934
+ var n;
935
+ for (const c of i) {
936
+ if (c.type === "section" && c.children) {
937
+ l(c.children);
938
+ continue;
939
+ }
940
+ const f = Et(c);
941
+ f && (r[c.name] = f, (c.required || (n = c.validations) != null && n.some((p) => p.type === "required")) && a.push(c.name));
942
+ }
943
+ };
944
+ for (const i of t.sections)
945
+ l(i.fields);
946
+ const o = {
947
+ $schema: "http://json-schema.org/draft-07/schema#",
948
+ $id: t.id,
949
+ type: "object",
950
+ title: t.title,
951
+ description: t.description,
952
+ properties: r,
953
+ additionalProperties: !1
954
+ };
955
+ return a.length > 0 && (o.required = a), o;
956
+ }
957
+ const wt = [
958
+ {
959
+ target: ".nice-manifest-editor",
960
+ titleKey: "tutorial.manifestEditor.intro.title",
961
+ title: "Manifest editor",
962
+ contentKey: "tutorial.manifestEditor.intro.content",
963
+ content: "Edit the manifest in schema-driven sections. Toggle Form ⇄ JSON per section; validation appears in the status bar.",
964
+ placement: "auto"
965
+ },
966
+ {
967
+ target: ".nice-manifest-editor__pane",
968
+ titleKey: "tutorial.manifestEditor.sections.title",
969
+ title: "Sections",
970
+ contentKey: "tutorial.manifestEditor.sections.content",
971
+ content: "The manifest is split into schema-driven sections — switch between them using the tabs at the top.",
972
+ placement: "auto"
973
+ },
974
+ {
975
+ target: ".nice-manifest-editor__pane",
976
+ titleKey: "tutorial.manifestEditor.json.title",
977
+ title: "Form ⇄ JSON",
978
+ contentKey: "tutorial.manifestEditor.json.content",
979
+ content: "Each section can be edited as a visual form or as raw JSON — use the toggle inside the section.",
980
+ placement: "auto"
981
+ }
982
+ ];
983
+ function Gt(t) {
984
+ return t;
985
+ }
986
+ const Wt = ee(
987
+ function(r, a) {
988
+ var x;
989
+ const {
990
+ value: l,
991
+ defaultValue: o,
992
+ sections: i,
993
+ onChange: n,
994
+ jsonView: c = !0,
995
+ scriptRunner: f,
996
+ triggers: p,
997
+ bindings: y = [],
998
+ handlers: s,
999
+ onBindingsChange: h,
1000
+ revisions: F,
1001
+ onRollback: O,
1002
+ loadContent: D,
1003
+ logs: A,
1004
+ onClearLogs: C,
1005
+ extraTabs: w,
1006
+ validate: $,
1007
+ theme: J = "light",
1008
+ height: M = 560,
1009
+ tutorial: I,
1010
+ className: v,
1011
+ style: k,
1012
+ id: j,
1013
+ "data-testid": U
1014
+ } = r, { t: L } = Z(), [S, H] = le({
1015
+ value: l,
1016
+ defaultValue: o,
1017
+ fallbackValue: {},
1018
+ onChange: n,
1019
+ componentName: "NiceManifestEditor"
1020
+ }), N = P(() => {
1021
+ const R = i.map((G) => ({
1022
+ key: `section:${G.id}`,
1023
+ label: G.title,
1024
+ icon: G.icon,
1025
+ content: /* @__PURE__ */ e("div", { className: "nice-manifest-editor__pane", children: /* @__PURE__ */ e(
1026
+ de,
1027
+ {
1028
+ schema: G.schema,
1029
+ fields: G.fields,
1030
+ uiSchema: G.uiSchema,
1031
+ value: S,
1032
+ onChange: H,
1033
+ showJsonView: c
1034
+ }
1035
+ ) })
1036
+ }));
1037
+ return f && R.push({
1038
+ key: "scripts",
1039
+ label: L("manifestEditor.tab.scripts", "Scripts"),
1040
+ content: /* @__PURE__ */ e("div", { className: "nice-manifest-editor__pane", children: /* @__PURE__ */ e(we, { ...f }) })
1041
+ }), p && p.length > 0 && R.push({
1042
+ key: "lifecycle",
1043
+ label: L("manifestEditor.tab.lifecycle", "Lifecycle"),
1044
+ content: /* @__PURE__ */ e("div", { className: "nice-manifest-editor__pane", children: /* @__PURE__ */ e(
1045
+ ke,
1046
+ {
1047
+ triggers: p,
1048
+ bindings: y,
1049
+ handlers: s,
1050
+ onChange: (G) => h == null ? void 0 : h(G),
1051
+ groupByTrigger: !0,
1052
+ allowCondition: !0
1053
+ }
1054
+ ) })
1055
+ }), F && F.length > 0 && R.push({
1056
+ key: "history",
1057
+ label: L("manifestEditor.tab.history", "History"),
1058
+ content: /* @__PURE__ */ e("div", { className: "nice-manifest-editor__pane", children: /* @__PURE__ */ e(
1059
+ Se,
1060
+ {
1061
+ revisions: F,
1062
+ onRollback: O,
1063
+ loadContent: D,
1064
+ language: "json"
1065
+ }
1066
+ ) })
1067
+ }), w && R.push(...w), R;
1068
+ }, [
1069
+ i,
1070
+ S,
1071
+ H,
1072
+ c,
1073
+ f,
1074
+ p,
1075
+ y,
1076
+ s,
1077
+ h,
1078
+ F,
1079
+ O,
1080
+ D,
1081
+ w,
1082
+ L
1083
+ ]), [q, m] = K(((x = N[0]) == null ? void 0 : x.key) ?? "");
1084
+ oe(() => {
1085
+ N.length > 0 && !N.some((R) => R.key === q) && m(N[0].key);
1086
+ }, [N, q]);
1087
+ const _ = P(() => $ ? $(S) : [], [$, S]), E = P(() => {
1088
+ const R = [
1089
+ {
1090
+ key: "sections",
1091
+ label: `${i.length} ${L("manifestEditor.sections", "sections")}`,
1092
+ position: "left"
1093
+ }
1094
+ ];
1095
+ return $ && R.push({
1096
+ key: "validation",
1097
+ label: /* @__PURE__ */ u("span", { className: "nice-manifest-editor__status", children: [
1098
+ /* @__PURE__ */ e(z, { name: _.length === 0 ? "check" : "warning", size: 12 }),
1099
+ _.length === 0 ? L("manifestEditor.status.valid", "Valid") : `${_.length} ${L("manifestEditor.status.issues", "issues")}`
1100
+ ] }),
1101
+ position: "left"
1102
+ }), R;
1103
+ }, [i.length, $, _.length, L]), g = "nice-manifest-editor" + (v ? ` ${v}` : "");
1104
+ return /* @__PURE__ */ e(
1105
+ Te,
1106
+ {
1107
+ ref: a,
1108
+ id: j,
1109
+ className: g,
1110
+ style: { height: M, ...k },
1111
+ "data-testid": U,
1112
+ theme: J,
1113
+ tabs: N,
1114
+ activeTabKey: q,
1115
+ onTabChange: m,
1116
+ statusItems: E,
1117
+ toolbar: I ? /* @__PURE__ */ e(se, { steps: ce(I, wt) }) : void 0,
1118
+ bottomPanel: A !== void 0 ? /* @__PURE__ */ e(
1119
+ Fe,
1120
+ {
1121
+ title: L("manifestEditor.output", "Output"),
1122
+ entries: A,
1123
+ onClear: C,
1124
+ maxHeight: "100%"
1125
+ }
1126
+ ) : void 0
1127
+ }
1128
+ );
1129
+ }
1130
+ ), me = "__eeRid", pe = "__eeFid", kt = [
1131
+ {
1132
+ target: ".nice-entity-editor",
1133
+ titleKey: "tutorial.entityEditor.intro.title",
1134
+ title: "Entity editor",
1135
+ contentKey: "tutorial.entityEditor.intro.content",
1136
+ content: "Browse your entities in the list, then click one (or “New entity”) to edit its metadata, fields and validation on a dedicated screen.",
1137
+ placement: "auto"
1138
+ }
1139
+ ], St = {
1140
+ type: "object",
1141
+ properties: {
1142
+ name: {
1143
+ type: "string",
1144
+ title: "Name",
1145
+ minLength: 1,
1146
+ description: "Unique technical name of the entity (PascalCase)."
1147
+ },
1148
+ displayName: {
1149
+ type: "string",
1150
+ title: "Display name",
1151
+ description: "Human-friendly name shown in the UI."
1152
+ },
1153
+ tableName: {
1154
+ type: "string",
1155
+ title: "Table name",
1156
+ description: "Database table that backs this entity."
1157
+ },
1158
+ description: {
1159
+ type: "string",
1160
+ title: "Description",
1161
+ description: "Optional notes about the entity's purpose."
1162
+ },
1163
+ entityIcon: {
1164
+ type: "string",
1165
+ title: "Icon",
1166
+ description: "Icon key shown next to the entity."
1167
+ },
1168
+ isAudited: {
1169
+ type: "boolean",
1170
+ title: "Audited",
1171
+ description: "Track who created/changed each record and when."
1172
+ },
1173
+ isSoftDeleteEnabled: {
1174
+ type: "boolean",
1175
+ title: "Soft delete",
1176
+ description: "Flag rows as deleted instead of physically removing them."
1177
+ }
1178
+ },
1179
+ required: ["name"]
1180
+ }, Tt = {
1181
+ type: "object",
1182
+ properties: {
1183
+ name: {
1184
+ type: "string",
1185
+ title: "Name",
1186
+ minLength: 1,
1187
+ description: "Field's technical name (the database column)."
1188
+ },
1189
+ displayName: {
1190
+ type: "string",
1191
+ title: "Display name",
1192
+ description: "Human-friendly label shown in the UI."
1193
+ },
1194
+ dataType: {
1195
+ type: "string",
1196
+ title: "Type",
1197
+ description: "Storage / data type of the field.",
1198
+ enum: [
1199
+ "Guid",
1200
+ "string",
1201
+ "text",
1202
+ "int",
1203
+ "long",
1204
+ "decimal",
1205
+ "double",
1206
+ "bool",
1207
+ "DateTime",
1208
+ "DateOnly",
1209
+ "json"
1210
+ ]
1211
+ },
1212
+ isPrimaryKey: {
1213
+ type: "boolean",
1214
+ title: "Primary key",
1215
+ description: "Primary key — uniquely identifies each record."
1216
+ },
1217
+ isForeignKey: {
1218
+ type: "boolean",
1219
+ title: "Foreign key",
1220
+ description: "Foreign key — references another entity's primary key."
1221
+ },
1222
+ isRequired: {
1223
+ type: "boolean",
1224
+ title: "Required",
1225
+ description: "Value must be provided (NOT NULL)."
1226
+ },
1227
+ isUnique: {
1228
+ type: "boolean",
1229
+ title: "Unique",
1230
+ description: "Each value must be unique across all records."
1231
+ },
1232
+ isIndexed: {
1233
+ type: "boolean",
1234
+ title: "Indexed",
1235
+ description: "Add a database index for faster lookups and filtering."
1236
+ },
1237
+ isNullable: {
1238
+ type: "boolean",
1239
+ title: "Nullable",
1240
+ description: "Allow empty (NULL) values."
1241
+ },
1242
+ maxLength: {
1243
+ type: "integer",
1244
+ title: "Max length",
1245
+ description: "Maximum number of characters (for string types)."
1246
+ },
1247
+ defaultValue: {
1248
+ type: "string",
1249
+ title: "Default",
1250
+ description: "Value used when none is provided."
1251
+ },
1252
+ description: {
1253
+ type: "string",
1254
+ title: "Description",
1255
+ description: "Optional notes about the field."
1256
+ },
1257
+ isComputed: {
1258
+ type: "boolean",
1259
+ title: "Computed",
1260
+ description: "Value is derived from an expression instead of stored input."
1261
+ },
1262
+ computedExpression: {
1263
+ type: "string",
1264
+ title: "Computed expression",
1265
+ description: "Expression used to compute the value (when Computed is on)."
1266
+ }
1267
+ },
1268
+ required: ["name", "dataType"]
1269
+ };
1270
+ function he({ title: t, help: r }) {
1271
+ return /* @__PURE__ */ u("span", { className: "nice-entity-editor__field-label", children: [
1272
+ t,
1273
+ r ? /* @__PURE__ */ e(X, { content: r, children: /* @__PURE__ */ e("span", { className: "nice-entity-editor__help", role: "img", "aria-label": r, children: /* @__PURE__ */ e(z, { name: "info", size: 14 }) }) }) : null
1274
+ ] });
1275
+ }
1276
+ function Ft({
1277
+ schema: t,
1278
+ value: r,
1279
+ onChange: a,
1280
+ readOnly: l
1281
+ }) {
1282
+ const o = t.properties ?? {};
1283
+ return /* @__PURE__ */ e("div", { className: "nice-entity-editor__field-form", children: Object.entries(o).map(([i, n]) => {
1284
+ const c = r[i], f = n.description, p = n.title ?? i;
1285
+ if (n.type === "boolean")
1286
+ return /* @__PURE__ */ e(
1287
+ "div",
1288
+ {
1289
+ className: "nice-entity-editor__field-row nice-entity-editor__field-row--check",
1290
+ children: /* @__PURE__ */ e(
1291
+ Ye,
1292
+ {
1293
+ label: /* @__PURE__ */ e(he, { title: p, help: f }),
1294
+ checked: !!c,
1295
+ onChange: (s) => a(i, s),
1296
+ disabled: l
1297
+ }
1298
+ )
1299
+ },
1300
+ i
1301
+ );
1302
+ if (Array.isArray(n.enum) && n.enum.length > 0)
1303
+ return /* @__PURE__ */ u("div", { className: "nice-entity-editor__field-row", children: [
1304
+ /* @__PURE__ */ e(he, { title: p, help: f }),
1305
+ /* @__PURE__ */ e(
1306
+ Qe,
1307
+ {
1308
+ options: n.enum.map((s) => ({ label: String(s), value: String(s) })),
1309
+ value: c == null ? "" : String(c),
1310
+ onChange: (s) => a(i, s),
1311
+ clearable: !0,
1312
+ disabled: l
1313
+ }
1314
+ )
1315
+ ] }, i);
1316
+ const y = n.type === "integer" || n.type === "number";
1317
+ return /* @__PURE__ */ u("div", { className: "nice-entity-editor__field-row", children: [
1318
+ /* @__PURE__ */ e(he, { title: p, help: f }),
1319
+ /* @__PURE__ */ e(
1320
+ Xe,
1321
+ {
1322
+ value: c == null ? "" : String(c),
1323
+ onChange: (s) => a(i, y ? s === "" ? void 0 : Number(s) : s),
1324
+ disabled: l
1325
+ }
1326
+ )
1327
+ ] }, i);
1328
+ }) });
1329
+ }
1330
+ function xt({
1331
+ fields: t,
1332
+ onChange: r,
1333
+ fieldSchema: a,
1334
+ readOnly: l
1335
+ }) {
1336
+ const { t: o } = Z(), [i, n] = K(null), c = P(() => t.map((s, h) => ({ ...s, [pe]: String(h) })), [t]), f = P(
1337
+ () => [
1338
+ {
1339
+ field: "name",
1340
+ header: o("entityEditor.field.name", "Name"),
1341
+ sortable: !0,
1342
+ render: (s) => /* @__PURE__ */ e("span", { className: "nice-entity-editor__name", children: String(s ?? "") })
1343
+ },
1344
+ {
1345
+ field: "dataType",
1346
+ header: o("entityEditor.field.type", "Type"),
1347
+ sortable: !0,
1348
+ render: (s) => /* @__PURE__ */ e(ae, { variant: "secondary", size: "sm", outline: !0, children: String(s ?? "—") })
1349
+ },
1350
+ {
1351
+ field: "__flags",
1352
+ header: o("entityEditor.field.flags", "Constraints"),
1353
+ headerTooltip: o(
1354
+ "entityEditor.field.flags.help",
1355
+ "Key / required / unique / indexed constraints on this field"
1356
+ ),
1357
+ render: (s, h) => {
1358
+ const F = [
1359
+ [!!(h != null && h.isPrimaryKey), "PK", o("entityEditor.flag.pk", "Primary key"), "info"],
1360
+ [!!(h != null && h.isForeignKey), "FK", o("entityEditor.flag.fk", "Foreign key"), "info"],
1361
+ [
1362
+ !!(h != null && h.isRequired),
1363
+ "Req",
1364
+ o("entityEditor.flag.required", "Required (NOT NULL)"),
1365
+ "warning"
1366
+ ],
1367
+ [!!(h != null && h.isUnique), "Uniq", o("entityEditor.flag.unique", "Unique"), "secondary"],
1368
+ [
1369
+ !!(h != null && h.isIndexed),
1370
+ "Idx",
1371
+ o("entityEditor.flag.indexed", "Indexed"),
1372
+ "secondary"
1373
+ ]
1374
+ ];
1375
+ return /* @__PURE__ */ e("span", { className: "nice-entity-editor__flags", children: F.filter(([O]) => O).map(([, O, D, A]) => /* @__PURE__ */ e(X, { content: D, children: /* @__PURE__ */ e(ae, { variant: A, size: "sm", children: O }) }, O)) });
1376
+ }
1377
+ }
1378
+ ],
1379
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1380
+ []
1381
+ ), p = (s, h, F) => {
1382
+ r(t.map((O, D) => D === s ? { ...O, [h]: F } : O));
1383
+ }, y = () => {
1384
+ const s = [...t, { name: `field${t.length + 1}`, dataType: "string" }];
1385
+ r(s), n(s.length - 1);
1386
+ };
1387
+ if (i != null && t[i]) {
1388
+ const s = t[i];
1389
+ return /* @__PURE__ */ u("div", { className: "nice-entity-editor__field-detail", children: [
1390
+ /* @__PURE__ */ u("header", { className: "nice-entity-editor__edit-header", children: [
1391
+ /* @__PURE__ */ e(X, { content: o("entityEditor.field.backHint", "Back to the field list"), children: /* @__PURE__ */ e(
1392
+ te,
1393
+ {
1394
+ variant: "ghost",
1395
+ size: "sm",
1396
+ leftIcon: /* @__PURE__ */ e(z, { name: "arrow-left", size: 14 }),
1397
+ onClick: () => n(null),
1398
+ children: o("entityEditor.field.back", "Fields")
1399
+ }
1400
+ ) }),
1401
+ /* @__PURE__ */ e("span", { className: "nice-entity-editor__breadcrumb-sep", children: "/" }),
1402
+ /* @__PURE__ */ e("span", { className: "nice-entity-editor__edit-title", children: String(s.name ?? o("entityEditor.field.untitled", "New field")) })
1403
+ ] }),
1404
+ /* @__PURE__ */ e(
1405
+ Ft,
1406
+ {
1407
+ schema: a,
1408
+ value: s,
1409
+ onChange: (h, F) => p(i, h, F),
1410
+ readOnly: l
1411
+ }
1412
+ ),
1413
+ /* @__PURE__ */ e("div", { className: "nice-entity-editor__field-detail-actions", children: /* @__PURE__ */ e(te, { variant: "primary", size: "sm", onClick: () => n(null), children: o("entityEditor.field.done", "Done") }) })
1414
+ ] });
1415
+ }
1416
+ return /* @__PURE__ */ e(
1417
+ fe,
1418
+ {
1419
+ data: c,
1420
+ keyField: pe,
1421
+ columns: f,
1422
+ searchable: !0,
1423
+ searchPlaceholder: o("entityEditor.field.search", "Search fields…"),
1424
+ emptyText: o("entityEditor.field.empty", "No fields yet. Add one to define this entity."),
1425
+ onRowClick: (s) => n(Number(s[pe])),
1426
+ onRowDelete: l ? void 0 : (s) => r(t.filter((h, F) => F !== Number(s))),
1427
+ toolbar: l ? void 0 : /* @__PURE__ */ e(
1428
+ te,
1429
+ {
1430
+ variant: "primary",
1431
+ size: "sm",
1432
+ leftIcon: /* @__PURE__ */ e(z, { name: "plus", size: 14 }),
1433
+ onClick: y,
1434
+ children: o("entityEditor.field.add", "Add field")
1435
+ }
1436
+ ),
1437
+ compact: !0,
1438
+ striped: !0
1439
+ }
1440
+ );
1441
+ }
1442
+ const Ct = ee(
1443
+ function(r, a) {
1444
+ const {
1445
+ value: l,
1446
+ defaultValue: o,
1447
+ onChange: i,
1448
+ entityMetaSchema: n = St,
1449
+ fieldSchema: c = Tt,
1450
+ fieldsKey: f = "fields",
1451
+ validationsKey: p = "validations",
1452
+ nameKey: y = "name",
1453
+ renderErPreview: s,
1454
+ readOnly: h = !1,
1455
+ tutorial: F,
1456
+ className: O,
1457
+ style: D,
1458
+ id: A,
1459
+ "data-testid": C
1460
+ } = r, { t: w } = Z(), [$, J] = le({
1461
+ value: l,
1462
+ defaultValue: o,
1463
+ fallbackValue: [],
1464
+ onChange: i,
1465
+ componentName: "NiceEntityEditor"
1466
+ }), [M, I] = K("list"), [v, k] = K(0), [j, U] = K("general"), L = Math.min(v, Math.max(0, $.length - 1)), S = $[L], H = M === "edit" && S != null, N = P(() => {
1467
+ const T = S == null ? void 0 : S[f];
1468
+ return Array.isArray(T) ? T : [];
1469
+ }, [S, f]), q = P(() => {
1470
+ const T = (B) => {
1471
+ const Y = B.toLowerCase();
1472
+ return /(int|long|decimal|double|float|number|money)/.test(Y) ? "number" : /bool/.test(Y) ? "boolean" : /date|time/.test(Y) ? "date" : "string";
1473
+ }, V = [];
1474
+ for (const B of N) {
1475
+ const Y = String(B.name ?? "");
1476
+ Y && V.push({
1477
+ field: Y,
1478
+ label: String(B.displayName ?? Y),
1479
+ type: T(String(B.dataType ?? "string"))
1480
+ });
1481
+ }
1482
+ return V;
1483
+ }, [N]), m = P(() => {
1484
+ const T = S == null ? void 0 : S[p];
1485
+ return Array.isArray(T) ? T : [];
1486
+ }, [S, p]), _ = P(() => $.map((T, V) => ({ ...T, [me]: String(V) })), [$]), E = (T) => {
1487
+ J($.map((V, B) => B === L ? { ...V, ...T } : V));
1488
+ }, g = (T) => {
1489
+ E({ [f]: T });
1490
+ }, x = (T) => {
1491
+ k(T), U("general"), I("edit");
1492
+ }, R = () => {
1493
+ const T = [...$, { [y]: `Entity${$.length + 1}`, [f]: [] }];
1494
+ J(T), k(T.length - 1), U("general"), I("edit");
1495
+ }, G = (T) => {
1496
+ J($.filter((V, B) => B !== T)), k((V) => V >= T ? Math.max(0, V - 1) : V);
1497
+ }, re = P(
1498
+ () => [
1499
+ {
1500
+ field: y,
1501
+ header: w("entityEditor.col.name", "Name"),
1502
+ sortable: !0,
1503
+ render: (T) => /* @__PURE__ */ e("span", { className: "nice-entity-editor__name", children: String(T ?? "") })
1504
+ },
1505
+ {
1506
+ field: "displayName",
1507
+ header: w("entityEditor.col.displayName", "Display name"),
1508
+ sortable: !0,
1509
+ render: (T) => /* @__PURE__ */ e("span", { className: "nice-entity-editor__muted", children: String(T ?? "—") })
1510
+ },
1511
+ {
1512
+ field: "tableName",
1513
+ header: w("entityEditor.col.table", "Table"),
1514
+ sortable: !0,
1515
+ render: (T) => /* @__PURE__ */ e("span", { className: "nice-entity-editor__muted", children: String(T ?? "—") })
1516
+ },
1517
+ {
1518
+ field: f,
1519
+ header: w("entityEditor.col.fields", "Fields"),
1520
+ align: "center",
1521
+ headerTooltip: w(
1522
+ "entityEditor.col.fields.help",
1523
+ "Number of fields defined on this entity"
1524
+ ),
1525
+ render: (T) => /* @__PURE__ */ e(ae, { variant: "secondary", size: "sm", children: Array.isArray(T) ? T.length : 0 })
1526
+ },
1527
+ {
1528
+ field: "__flags",
1529
+ header: w("entityEditor.col.flags", "Flags"),
1530
+ render: (T, V) => /* @__PURE__ */ u("span", { className: "nice-entity-editor__flags", children: [
1531
+ V != null && V.isAudited ? /* @__PURE__ */ e(
1532
+ X,
1533
+ {
1534
+ content: w(
1535
+ "entityEditor.flag.audited",
1536
+ "Audited — tracks who changed each record and when"
1537
+ ),
1538
+ children: /* @__PURE__ */ e(ae, { variant: "info", size: "sm", outline: !0, children: w("entityEditor.flag.audited.abbr", "Audit") })
1539
+ }
1540
+ ) : null,
1541
+ V != null && V.isSoftDeleteEnabled ? /* @__PURE__ */ e(
1542
+ X,
1543
+ {
1544
+ content: w(
1545
+ "entityEditor.flag.softDelete",
1546
+ "Soft delete — rows are flagged deleted, never physically removed"
1547
+ ),
1548
+ children: /* @__PURE__ */ e(ae, { variant: "secondary", size: "sm", outline: !0, children: w("entityEditor.flag.softDelete.abbr", "Soft-del") })
1549
+ }
1550
+ ) : null
1551
+ ] })
1552
+ }
1553
+ ],
1554
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1555
+ [y, f]
1556
+ ), W = P(() => {
1557
+ const T = [
1558
+ {
1559
+ id: "general",
1560
+ label: w("entityEditor.tab.general", "General"),
1561
+ content: S ? /* @__PURE__ */ e(
1562
+ de,
1563
+ {
1564
+ schema: n,
1565
+ value: S,
1566
+ onChange: (V) => E(V),
1567
+ columns: 2,
1568
+ readOnly: h,
1569
+ liveValidation: !0
1570
+ }
1571
+ ) : null
1572
+ },
1573
+ {
1574
+ id: "fields",
1575
+ label: w("entityEditor.tab.fields", "Fields"),
1576
+ badge: N.length || void 0,
1577
+ content: /* @__PURE__ */ e(
1578
+ xt,
1579
+ {
1580
+ fields: N,
1581
+ onChange: g,
1582
+ fieldSchema: c,
1583
+ readOnly: h
1584
+ }
1585
+ )
1586
+ },
1587
+ {
1588
+ id: "validation",
1589
+ label: w("entityEditor.tab.validation", "Validation"),
1590
+ badge: m.length || void 0,
1591
+ content: /* @__PURE__ */ e(
1592
+ Ge,
1593
+ {
1594
+ fields: q,
1595
+ value: m,
1596
+ onChange: (V) => E({ [p]: V })
1597
+ }
1598
+ )
1599
+ }
1600
+ ];
1601
+ return s && T.push({
1602
+ id: "er",
1603
+ label: w("entityEditor.tab.er", "ER diagram"),
1604
+ content: /* @__PURE__ */ e("div", { className: "nice-entity-editor__er", children: s($) })
1605
+ }), T;
1606
+ }, [
1607
+ S,
1608
+ N,
1609
+ m,
1610
+ q,
1611
+ n,
1612
+ c,
1613
+ h,
1614
+ s,
1615
+ $
1616
+ ]), ie = "nice-entity-editor" + (O ? ` ${O}` : "");
1617
+ return /* @__PURE__ */ u("div", { ref: a, id: A, className: ie, style: D, "data-testid": C, children: [
1618
+ F && /* @__PURE__ */ e("div", { className: "nice-entity-editor__tutorial", children: /* @__PURE__ */ e(se, { steps: ce(F, kt) }) }),
1619
+ H ? /* @__PURE__ */ u("div", { className: "nice-entity-editor__edit", children: [
1620
+ /* @__PURE__ */ u("header", { className: "nice-entity-editor__edit-header", children: [
1621
+ /* @__PURE__ */ e(X, { content: w("entityEditor.backHint", "Back to the entity list"), children: /* @__PURE__ */ e(
1622
+ te,
1623
+ {
1624
+ variant: "ghost",
1625
+ size: "sm",
1626
+ leftIcon: /* @__PURE__ */ e(z, { name: "arrow-left", size: 14 }),
1627
+ onClick: () => I("list"),
1628
+ children: w("entityEditor.back", "Entities")
1629
+ }
1630
+ ) }),
1631
+ /* @__PURE__ */ e("span", { className: "nice-entity-editor__breadcrumb-sep", children: "/" }),
1632
+ /* @__PURE__ */ e("span", { className: "nice-entity-editor__edit-title", children: String((S == null ? void 0 : S[y]) ?? w("entityEditor.untitled", "Untitled entity")) }),
1633
+ !h && /* @__PURE__ */ e(X, { content: w("entityEditor.deleteHint", "Delete this entity"), children: /* @__PURE__ */ e(
1634
+ te,
1635
+ {
1636
+ variant: "ghost",
1637
+ size: "sm",
1638
+ leftIcon: /* @__PURE__ */ e(z, { name: "trash", size: 14 }),
1639
+ onClick: () => {
1640
+ G(L), I("list");
1641
+ },
1642
+ children: w("entityEditor.delete", "Delete")
1643
+ }
1644
+ ) })
1645
+ ] }),
1646
+ /* @__PURE__ */ e(
1647
+ We,
1648
+ {
1649
+ tabs: W,
1650
+ activeTab: j,
1651
+ onChange: U,
1652
+ variant: "enclosed"
1653
+ }
1654
+ )
1655
+ ] }) : /* @__PURE__ */ e("div", { className: "nice-entity-editor__list-view", children: /* @__PURE__ */ e(
1656
+ fe,
1657
+ {
1658
+ data: _,
1659
+ keyField: me,
1660
+ columns: re,
1661
+ searchable: !0,
1662
+ searchPlaceholder: w("entityEditor.search", "Search entities…"),
1663
+ emptyText: w("entityEditor.empty", "No entities yet. Create one to get started."),
1664
+ onRowClick: (T) => x(Number(T[me])),
1665
+ onRowDelete: h ? void 0 : (T) => G(Number(T)),
1666
+ toolbar: h ? void 0 : /* @__PURE__ */ e(
1667
+ te,
1668
+ {
1669
+ variant: "primary",
1670
+ size: "sm",
1671
+ leftIcon: /* @__PURE__ */ e(z, { name: "plus", size: 14 }),
1672
+ onClick: R,
1673
+ children: w("entityEditor.new", "New entity")
1674
+ }
1675
+ ),
1676
+ compact: !0,
1677
+ striped: !0
1678
+ }
1679
+ ) })
1680
+ ] });
1681
+ }
1682
+ ), It = [
1683
+ {
1684
+ target: ".nice-i18n-editor",
1685
+ titleKey: "tutorial.i18nEditor.intro.title",
1686
+ title: "Translations",
1687
+ contentKey: "tutorial.i18nEditor.intro.content",
1688
+ content: "Edit translations as a keys × locales grid. Add keys and locales; amber cells mark missing translations.",
1689
+ placement: "auto"
1690
+ },
1691
+ {
1692
+ target: '[data-tour="i18n-grid"]',
1693
+ titleKey: "tutorial.i18nEditor.grid.title",
1694
+ title: "Keys × locales",
1695
+ contentKey: "tutorial.i18nEditor.grid.content",
1696
+ content: "Each row is a translation key and each column a locale. Edit a cell to set a translation; amber cells are still missing.",
1697
+ placement: "top"
1698
+ },
1699
+ {
1700
+ target: '[data-tour="i18n-add"]',
1701
+ titleKey: "tutorial.i18nEditor.add.title",
1702
+ title: "Add keys & locales",
1703
+ contentKey: "tutorial.i18nEditor.add.content",
1704
+ content: "Add a new translation key or a new locale column here; new cells start empty and are flagged as missing.",
1705
+ placement: "top"
1706
+ }
1707
+ ], At = ee(
1708
+ function(r, a) {
1709
+ const {
1710
+ value: l,
1711
+ defaultValue: o,
1712
+ onChange: i,
1713
+ locales: n,
1714
+ allowEditLocales: c = !0,
1715
+ allowEditKeys: f = !0,
1716
+ highlightMissing: p = !0,
1717
+ readOnly: y = !1,
1718
+ tutorial: s,
1719
+ className: h,
1720
+ style: F,
1721
+ id: O,
1722
+ "data-testid": D
1723
+ } = r, { t: A } = ot(), [C, w] = rt({
1724
+ value: l,
1725
+ defaultValue: o,
1726
+ fallbackValue: {},
1727
+ onChange: i,
1728
+ componentName: "NiceI18nEditor"
1729
+ }), [$, J] = K(""), [M, I] = K(""), v = P(() => n ?? Object.keys(C), [n, C]), k = P(() => {
1730
+ const m = /* @__PURE__ */ new Set();
1731
+ for (const _ of Object.keys(C))
1732
+ for (const E of Object.keys(C[_] ?? {}))
1733
+ m.add(E);
1734
+ return [...m].sort();
1735
+ }, [C]), j = (m, _, E) => {
1736
+ w({ ...C, [m]: { ...C[m] ?? {}, [_]: E } });
1737
+ }, U = (m, _) => {
1738
+ if (!_ || _ === m)
1739
+ return;
1740
+ const E = {};
1741
+ for (const g of Object.keys(C)) {
1742
+ const x = { ...C[g] ?? {} };
1743
+ m in x && (x[_] = x[m], delete x[m]), E[g] = x;
1744
+ }
1745
+ w(E);
1746
+ }, L = (m) => {
1747
+ const _ = {};
1748
+ for (const E of Object.keys(C)) {
1749
+ const g = { ...C[E] ?? {} };
1750
+ delete g[m], _[E] = g;
1751
+ }
1752
+ w(_);
1753
+ }, S = () => {
1754
+ const m = $.trim();
1755
+ if (!m || k.includes(m))
1756
+ return;
1757
+ const _ = {};
1758
+ for (const E of v)
1759
+ _[E] = { ...C[E] ?? {}, [m]: "" };
1760
+ for (const E of Object.keys(C))
1761
+ _[E] || (_[E] = C[E]);
1762
+ w(_), J("");
1763
+ }, H = () => {
1764
+ const m = M.trim();
1765
+ if (!m || C[m])
1766
+ return;
1767
+ const _ = {};
1768
+ for (const E of k)
1769
+ _[E] = "";
1770
+ w({ ...C, [m]: _ }), I("");
1771
+ }, N = (m) => {
1772
+ const _ = { ...C };
1773
+ delete _[m], w(_);
1774
+ }, q = "nice-i18n-editor" + (h ? ` ${h}` : "");
1775
+ return /* @__PURE__ */ u("div", { ref: a, id: O, className: q, style: F, "data-testid": D, children: [
1776
+ s && /* @__PURE__ */ e("div", { className: "nice-i18n-editor__tutorial", children: /* @__PURE__ */ e(lt, { steps: st(s, It) }) }),
1777
+ /* @__PURE__ */ e("div", { className: "nice-i18n-editor__scroll", "data-tour": "i18n-grid", children: /* @__PURE__ */ u("table", { className: "nice-i18n-editor__table", children: [
1778
+ /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ u("tr", { children: [
1779
+ /* @__PURE__ */ e("th", { className: "nice-i18n-editor__key-head", children: A("i18nEditor.keyHead", "Key") }),
1780
+ v.map((m) => /* @__PURE__ */ u("th", { className: "nice-i18n-editor__locale-head", children: [
1781
+ /* @__PURE__ */ e("span", { children: m }),
1782
+ c && !y && /* @__PURE__ */ e(
1783
+ "button",
1784
+ {
1785
+ type: "button",
1786
+ className: "nice-i18n-editor__locale-remove",
1787
+ "aria-label": `${A("i18nEditor.removeLocale", "Remove locale")} ${m}`,
1788
+ onClick: () => N(m),
1789
+ children: /* @__PURE__ */ e(be, { name: "close", size: 12 })
1790
+ }
1791
+ )
1792
+ ] }, m))
1793
+ ] }) }),
1794
+ /* @__PURE__ */ u("tbody", { children: [
1795
+ k.map((m) => /* @__PURE__ */ u("tr", { children: [
1796
+ /* @__PURE__ */ u("td", { className: "nice-i18n-editor__key-cell", children: [
1797
+ f && !y ? /* @__PURE__ */ e(
1798
+ "input",
1799
+ {
1800
+ className: "nice-i18n-editor__key-input",
1801
+ defaultValue: m,
1802
+ onBlur: (_) => U(m, _.target.value.trim()),
1803
+ "aria-label": A("i18nEditor.keyAria", "Translation key")
1804
+ }
1805
+ ) : /* @__PURE__ */ e("span", { className: "nice-i18n-editor__key-text", children: m }),
1806
+ f && !y && /* @__PURE__ */ e(
1807
+ "button",
1808
+ {
1809
+ type: "button",
1810
+ className: "nice-i18n-editor__key-remove",
1811
+ "aria-label": `${A("i18nEditor.removeKey", "Remove key")} ${m}`,
1812
+ onClick: () => L(m),
1813
+ children: /* @__PURE__ */ e(be, { name: "close", size: 12 })
1814
+ }
1815
+ )
1816
+ ] }),
1817
+ v.map((_) => {
1818
+ var x;
1819
+ const E = ((x = C[_]) == null ? void 0 : x[m]) ?? "";
1820
+ return /* @__PURE__ */ e("td", { className: "nice-i18n-editor__cell", children: /* @__PURE__ */ e(
1821
+ "input",
1822
+ {
1823
+ className: "nice-i18n-editor__cell-input" + (p && E === "" ? " nice-i18n-editor__cell-input--missing" : ""),
1824
+ value: E,
1825
+ readOnly: y,
1826
+ onChange: (R) => j(_, m, R.target.value),
1827
+ "aria-label": `${m} (${_})`
1828
+ }
1829
+ ) }, _);
1830
+ })
1831
+ ] }, m)),
1832
+ k.length === 0 && /* @__PURE__ */ e("tr", { children: /* @__PURE__ */ e("td", { className: "nice-i18n-editor__empty", colSpan: v.length + 1, children: A("i18nEditor.empty", "No translation keys yet.") }) })
1833
+ ] })
1834
+ ] }) }),
1835
+ !y && (f || c) && /* @__PURE__ */ u("div", { className: "nice-i18n-editor__toolbar", "data-tour": "i18n-add", children: [
1836
+ f && /* @__PURE__ */ u("div", { className: "nice-i18n-editor__add", children: [
1837
+ /* @__PURE__ */ e(
1838
+ "input",
1839
+ {
1840
+ className: "nice-i18n-editor__add-input",
1841
+ placeholder: A("i18nEditor.newKeyPlaceholder", "new.key"),
1842
+ value: $,
1843
+ onChange: (m) => J(m.target.value),
1844
+ onKeyDown: (m) => {
1845
+ m.key === "Enter" && S();
1846
+ },
1847
+ "aria-label": A("i18nEditor.newKeyAria", "New key")
1848
+ }
1849
+ ),
1850
+ /* @__PURE__ */ u("button", { type: "button", onClick: S, children: [
1851
+ "+ ",
1852
+ A("i18nEditor.addKey", "Key")
1853
+ ] })
1854
+ ] }),
1855
+ c && /* @__PURE__ */ u("div", { className: "nice-i18n-editor__add", children: [
1856
+ /* @__PURE__ */ e(
1857
+ "input",
1858
+ {
1859
+ className: "nice-i18n-editor__add-input",
1860
+ placeholder: A("i18nEditor.newLocalePlaceholder", "locale (e.g. de)"),
1861
+ value: M,
1862
+ onChange: (m) => I(m.target.value),
1863
+ onKeyDown: (m) => {
1864
+ m.key === "Enter" && H();
1865
+ },
1866
+ "aria-label": A("i18nEditor.newLocaleAria", "New locale")
1867
+ }
1868
+ ),
1869
+ /* @__PURE__ */ u("button", { type: "button", onClick: H, children: [
1870
+ "+ ",
1871
+ A("i18nEditor.addLocale", "Locale")
1872
+ ] })
1873
+ ] })
1874
+ ] })
1875
+ ] });
1876
+ }
1877
+ ), $t = [
1878
+ {
1879
+ target: ".nice-module-editor",
1880
+ titleKey: "tutorial.moduleEditor.intro.title",
1881
+ title: "Module editor",
1882
+ contentKey: "tutorial.moduleEditor.intro.content",
1883
+ content: "Design a whole module end-to-end — manifest, entities, translations, views, workflows, data sources and permissions — then validate and save.",
1884
+ placement: "auto"
1885
+ },
1886
+ {
1887
+ target: '[data-tour="nme-browser"]',
1888
+ titleKey: "tutorial.moduleEditor.browser.title",
1889
+ title: "Module browser",
1890
+ contentKey: "tutorial.moduleEditor.browser.content",
1891
+ content: "Search and pick a module here to open its manifest, entities and translations.",
1892
+ placement: "right"
1893
+ },
1894
+ {
1895
+ target: '[data-tour="nme-tabs"]',
1896
+ titleKey: "tutorial.moduleEditor.tabs.title",
1897
+ title: "Module parts",
1898
+ contentKey: "tutorial.moduleEditor.tabs.content",
1899
+ content: "Each tab edits one part of the module: Manifest sections, Entities, i18n, Views, Workflows, Data sources, Permissions and more.",
1900
+ placement: "bottom"
1901
+ },
1902
+ {
1903
+ target: '[data-tour="nme-validate"]',
1904
+ titleKey: "tutorial.moduleEditor.validate.title",
1905
+ title: "Validate",
1906
+ contentKey: "tutorial.moduleEditor.validate.content",
1907
+ content: "Check the module against the manifest schema. Issues appear in the status bar and the output panel.",
1908
+ placement: "bottom"
1909
+ },
1910
+ {
1911
+ target: '[data-tour="nme-save"]',
1912
+ titleKey: "tutorial.moduleEditor.save.title",
1913
+ title: "Save",
1914
+ contentKey: "tutorial.moduleEditor.save.content",
1915
+ content: "Persist your changes through the configured data provider (e.g. write the files back to disk).",
1916
+ placement: "bottom"
1917
+ },
1918
+ {
1919
+ target: '[data-tour="nme-output"]',
1920
+ titleKey: "tutorial.moduleEditor.output.title",
1921
+ title: "Output",
1922
+ contentKey: "tutorial.moduleEditor.output.content",
1923
+ content: "Validation results and load/save activity are logged here.",
1924
+ placement: "top"
1925
+ }
1926
+ ], Yt = ee(
1927
+ function(r, a) {
1928
+ var ge;
1929
+ const {
1930
+ dataProvider: l,
1931
+ manifestSections: o,
1932
+ entityConfig: i,
1933
+ locales: n,
1934
+ validate: c,
1935
+ scriptRunner: f,
1936
+ triggers: p,
1937
+ bindings: y = [],
1938
+ handlers: s,
1939
+ onBindingsChange: h,
1940
+ revisions: F,
1941
+ onRollback: O,
1942
+ loadContent: D,
1943
+ theme: A = "light",
1944
+ height: C = 640,
1945
+ tutorial: w,
1946
+ className: $,
1947
+ style: J,
1948
+ id: M,
1949
+ "data-testid": I
1950
+ } = r, { t: v } = Z(), [k, j] = K([]), [U, L] = K(""), [S, H] = K(null), [N, q] = K(null), [m, _] = K(!1), [E, g] = K(!1), [x, R] = K([]), [G, re] = K(""), W = Q((d, b, je) => {
1951
+ R((Be) => [...Be, { level: d, message: b, data: je, timestamp: Date.now() }].slice(-200));
1952
+ }, []), ie = Q(async () => {
1953
+ g(!0);
1954
+ try {
1955
+ j(await l.listModules());
1956
+ } catch (d) {
1957
+ W("error", `List modules failed: ${d instanceof Error ? d.message : String(d)}`);
1958
+ } finally {
1959
+ g(!1);
1960
+ }
1961
+ }, [l, W]);
1962
+ oe(() => {
1963
+ ie();
1964
+ }, [ie]);
1965
+ const T = Q(
1966
+ async (d) => {
1967
+ g(!0);
1968
+ try {
1969
+ const b = await l.loadModule(d);
1970
+ q(b), H(d), _(!1), W("info", `Loaded module ${d}`);
1971
+ } catch (b) {
1972
+ W("error", `Load failed: ${b instanceof Error ? b.message : String(b)}`);
1973
+ } finally {
1974
+ g(!1);
1975
+ }
1976
+ },
1977
+ [l, W]
1978
+ ), V = Q(async () => {
1979
+ if (!(!S || !N)) {
1980
+ g(!0);
1981
+ try {
1982
+ await l.saveModule(S, N), _(!1), W("info", `Saved module ${S}`);
1983
+ } catch (d) {
1984
+ W("error", `Save failed: ${d instanceof Error ? d.message : String(d)}`);
1985
+ } finally {
1986
+ g(!1);
1987
+ }
1988
+ }
1989
+ }, [S, N, l, W]), B = P(() => {
1990
+ if (!N)
1991
+ return [];
1992
+ const d = [];
1993
+ for (const b of o)
1994
+ b.schema && d.push(...Ie(N.manifest ?? {}, b.schema));
1995
+ return c && d.push(...c(N)), d;
1996
+ }, [N, o, c]), Y = Q(() => {
1997
+ if (B.length === 0)
1998
+ W("info", "Validation passed");
1999
+ else {
2000
+ W("warn", `${B.length} validation issue(s)`);
2001
+ for (const d of B)
2002
+ W("error", `${d.field}: ${d.message}`);
2003
+ }
2004
+ }, [B, W]), Ae = (d) => {
2005
+ q((b) => b && { ...b, manifest: d }), _(!0);
2006
+ }, $e = (d) => {
2007
+ q((b) => b && { ...b, entities: d }), _(!0);
2008
+ }, Ke = (d) => {
2009
+ q((b) => b && { ...b, i18n: d }), _(!0);
2010
+ }, Oe = (d) => {
2011
+ q((b) => b && { ...b, views: d }), _(!0);
2012
+ }, De = (d) => {
2013
+ q((b) => b && { ...b, workflows: d }), _(!0);
2014
+ }, Me = (d) => {
2015
+ q((b) => b && { ...b, dataSources: d }), _(!0);
2016
+ }, Le = (d) => {
2017
+ q((b) => b && { ...b, rbac: d }), _(!0);
2018
+ }, ne = P(() => {
2019
+ if (!N)
2020
+ return [];
2021
+ const d = o.map((b) => ({
2022
+ key: `section:${b.id}`,
2023
+ label: b.title,
2024
+ icon: b.icon,
2025
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2026
+ de,
2027
+ {
2028
+ schema: b.schema,
2029
+ fields: b.fields,
2030
+ uiSchema: b.uiSchema,
2031
+ value: N.manifest ?? {},
2032
+ onChange: Ae,
2033
+ showJsonView: !0
2034
+ }
2035
+ ) })
2036
+ }));
2037
+ return d.push({
2038
+ key: "entities",
2039
+ label: v("moduleEditor.tab.entities", "Entities"),
2040
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2041
+ Ct,
2042
+ {
2043
+ value: N.entities ?? [],
2044
+ onChange: $e,
2045
+ entityMetaSchema: i == null ? void 0 : i.entityMetaSchema,
2046
+ fieldSchema: i == null ? void 0 : i.fieldSchema,
2047
+ fieldsKey: i == null ? void 0 : i.fieldsKey,
2048
+ nameKey: i == null ? void 0 : i.nameKey,
2049
+ renderErPreview: i == null ? void 0 : i.renderErPreview
2050
+ }
2051
+ ) })
2052
+ }), d.push({
2053
+ key: "i18n",
2054
+ label: v("moduleEditor.tab.i18n", "i18n"),
2055
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(At, { value: N.i18n ?? {}, onChange: Ke, locales: n }) })
2056
+ }), d.push({
2057
+ key: "views",
2058
+ label: v("moduleEditor.tab.views", "Views"),
2059
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2060
+ Kt,
2061
+ {
2062
+ views: N.views ?? [],
2063
+ entities: N.entities ?? [],
2064
+ onChange: Oe
2065
+ }
2066
+ ) })
2067
+ }), d.push({
2068
+ key: "workflows",
2069
+ label: v("moduleEditor.tab.workflows", "Workflows"),
2070
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(Ot, { workflows: N.workflows ?? [], onChange: De }) })
2071
+ }), d.push({
2072
+ key: "data",
2073
+ label: v("moduleEditor.tab.data", "Data"),
2074
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2075
+ Lt,
2076
+ {
2077
+ dataSources: N.dataSources ?? [],
2078
+ schemas: Dt(N.entities ?? []),
2079
+ onChange: Me
2080
+ }
2081
+ ) })
2082
+ }), d.push({
2083
+ key: "permissions",
2084
+ label: v("moduleEditor.tab.permissions", "Permissions"),
2085
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2086
+ Ze,
2087
+ {
2088
+ value: N.rbac ?? Mt(N),
2089
+ onChange: Le
2090
+ }
2091
+ ) })
2092
+ }), f && d.push({
2093
+ key: "scripts",
2094
+ label: v("moduleEditor.tab.scripts", "Scripts"),
2095
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(we, { ...f }) })
2096
+ }), p && p.length > 0 && d.push({
2097
+ key: "lifecycle",
2098
+ label: v("moduleEditor.tab.lifecycle", "Lifecycle"),
2099
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2100
+ ke,
2101
+ {
2102
+ triggers: p,
2103
+ bindings: y,
2104
+ handlers: s,
2105
+ onChange: (b) => h == null ? void 0 : h(b),
2106
+ groupByTrigger: !0,
2107
+ allowCondition: !0
2108
+ }
2109
+ ) })
2110
+ }), F && F.length > 0 && d.push({
2111
+ key: "history",
2112
+ label: v("moduleEditor.tab.history", "History"),
2113
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e(
2114
+ Se,
2115
+ {
2116
+ revisions: F,
2117
+ onRollback: O,
2118
+ loadContent: D,
2119
+ language: "json"
2120
+ }
2121
+ ) })
2122
+ }), d.push({
2123
+ key: "source",
2124
+ label: v("moduleEditor.tab.source", "Source"),
2125
+ content: /* @__PURE__ */ e("div", { className: "nice-module-editor__pane", children: /* @__PURE__ */ e("pre", { className: "nice-module-editor__source", children: JSON.stringify(N, null, 2) }) })
2126
+ }), d;
2127
+ }, [
2128
+ N,
2129
+ o,
2130
+ i,
2131
+ n,
2132
+ f,
2133
+ p,
2134
+ y,
2135
+ s,
2136
+ F,
2137
+ v
2138
+ ]);
2139
+ oe(() => {
2140
+ ne.length > 0 && !ne.some((d) => d.key === G) && re(ne[0].key);
2141
+ }, [ne, G]);
2142
+ const ye = P(() => {
2143
+ const d = U.trim().toLowerCase();
2144
+ return d ? k.filter(
2145
+ (b) => b.id.toLowerCase().includes(d) || (b.name ?? "").toLowerCase().includes(d) || (b.category ?? "").toLowerCase().includes(d)
2146
+ ) : k;
2147
+ }, [k, U]), Ve = P(() => {
2148
+ const d = [];
2149
+ return S && d.push({ key: "mod", label: S + (m ? " •" : ""), position: "left" }), d.push({
2150
+ key: "val",
2151
+ label: /* @__PURE__ */ u("span", { className: "nice-module-editor__status", children: [
2152
+ /* @__PURE__ */ e(z, { name: B.length === 0 ? "check" : "warning", size: 12 }),
2153
+ B.length === 0 ? v("moduleEditor.status.valid", "Valid") : `${B.length} ${v("moduleEditor.status.issues", "issues")}`
2154
+ ] }),
2155
+ position: "left"
2156
+ }), d;
2157
+ }, [S, m, B.length, v]), qe = /* @__PURE__ */ u("div", { className: "nice-module-editor__browser", "data-tour": "nme-browser", children: [
2158
+ /* @__PURE__ */ e(
2159
+ "input",
2160
+ {
2161
+ className: "nice-module-editor__search",
2162
+ placeholder: v("moduleEditor.searchModules", "Search modules…"),
2163
+ value: U,
2164
+ onChange: (d) => L(d.target.value),
2165
+ "aria-label": v("moduleEditor.searchModules", "Search modules…")
2166
+ }
2167
+ ),
2168
+ /* @__PURE__ */ u("div", { className: "nice-module-editor__modules", children: [
2169
+ ye.map((d) => /* @__PURE__ */ u(
2170
+ "button",
2171
+ {
2172
+ type: "button",
2173
+ className: "nice-module-editor__module" + (d.id === S ? " nice-module-editor__module--active" : ""),
2174
+ onClick: () => void T(d.id),
2175
+ title: d.description,
2176
+ children: [
2177
+ /* @__PURE__ */ e("span", { className: "nice-module-editor__module-name", children: d.name ?? d.id }),
2178
+ d.category && /* @__PURE__ */ e("span", { className: "nice-module-editor__module-cat", children: d.category })
2179
+ ]
2180
+ },
2181
+ d.id
2182
+ )),
2183
+ ye.length === 0 && /* @__PURE__ */ e("div", { className: "nice-module-editor__browser-empty", children: E ? v("moduleEditor.loading", "Loading…") : v("moduleEditor.noModules", "No modules. Open a source first.") })
2184
+ ] })
2185
+ ] }), Pe = /* @__PURE__ */ u("div", { className: "nice-module-editor__toolbar", children: [
2186
+ /* @__PURE__ */ e("strong", { className: "nice-module-editor__title", "data-tour": "nme-tabs", children: S ? ((ge = N == null ? void 0 : N.manifest) == null ? void 0 : ge.packageName) ?? S : v("moduleEditor.title", "Module Editor") }),
2187
+ w && /* @__PURE__ */ e(se, { steps: ce(w, $t) }),
2188
+ /* @__PURE__ */ e("span", { className: "nice-module-editor__spacer" }),
2189
+ /* @__PURE__ */ u("button", { type: "button", onClick: () => void ie(), disabled: E, children: [
2190
+ /* @__PURE__ */ e(z, { name: "refresh", size: 14 }),
2191
+ " ",
2192
+ v("moduleEditor.refresh", "Refresh")
2193
+ ] }),
2194
+ /* @__PURE__ */ u("button", { type: "button", "data-tour": "nme-validate", onClick: Y, disabled: !N, children: [
2195
+ /* @__PURE__ */ e(z, { name: "check", size: 14 }),
2196
+ " ",
2197
+ v("moduleEditor.validate", "Validate")
2198
+ ] }),
2199
+ /* @__PURE__ */ e(
2200
+ "button",
2201
+ {
2202
+ type: "button",
2203
+ "data-tour": "nme-save",
2204
+ className: "nice-module-editor__save",
2205
+ onClick: () => void V(),
2206
+ disabled: !N || !m || E,
2207
+ children: E ? v("moduleEditor.saving", "Saving…") : v("moduleEditor.save", "Save")
2208
+ }
2209
+ )
2210
+ ] }), Re = "nice-module-editor" + ($ ? ` ${$}` : "");
2211
+ return /* @__PURE__ */ e(
2212
+ Te,
2213
+ {
2214
+ ref: a,
2215
+ id: M,
2216
+ className: Re,
2217
+ style: { height: C, ...J },
2218
+ "data-testid": I,
2219
+ theme: A,
2220
+ tabs: ne,
2221
+ activeTabKey: G,
2222
+ onTabChange: re,
2223
+ toolbar: Pe,
2224
+ sidePanel: qe,
2225
+ sidePanelWidth: 260,
2226
+ statusItems: Ve,
2227
+ bottomPanel: /* @__PURE__ */ e("div", { "data-tour": "nme-output", style: { height: "100%" }, children: /* @__PURE__ */ e(
2228
+ Fe,
2229
+ {
2230
+ title: v("moduleEditor.output", "Output"),
2231
+ entries: x,
2232
+ onClear: () => R([]),
2233
+ maxHeight: "100%"
2234
+ }
2235
+ ) }),
2236
+ children: !N && /* @__PURE__ */ e("div", { className: "nice-module-editor__placeholder", children: v("moduleEditor.placeholder", "Select a module from the left to start editing.") })
2237
+ }
2238
+ );
2239
+ }
2240
+ );
2241
+ function Kt({
2242
+ views: t,
2243
+ entities: r,
2244
+ onChange: a
2245
+ }) {
2246
+ var y;
2247
+ const { t: l } = Z(), [o, i] = K(((y = t[0]) == null ? void 0 : y.id) ?? null), n = t.find((s) => s.id === o) ?? null, c = (s) => {
2248
+ a(t.map((h) => h.id === o ? s : h)), s.id !== o && i(s.id);
2249
+ }, f = () => {
2250
+ const s = {
2251
+ id: `view-${Date.now().toString(36)}`,
2252
+ name: "New View",
2253
+ version: 2,
2254
+ columns: 12,
2255
+ rows: [],
2256
+ dataSources: []
2257
+ };
2258
+ a([...t, s]), i(s.id);
2259
+ }, p = (s) => {
2260
+ a(t.filter((h) => h.id !== s)), o === s && i(null);
2261
+ };
2262
+ return /* @__PURE__ */ u("div", { className: "nice-module-views", children: [
2263
+ /* @__PURE__ */ u("div", { className: "nice-module-views__bar", children: [
2264
+ /* @__PURE__ */ u(
2265
+ "select",
2266
+ {
2267
+ className: "nice-module-views__select",
2268
+ value: o ?? "",
2269
+ onChange: (s) => i(s.target.value || null),
2270
+ "aria-label": l("moduleEditor.views.select", "Select view"),
2271
+ children: [
2272
+ /* @__PURE__ */ e("option", { value: "", children: l("moduleEditor.views.placeholder", "— select view —") }),
2273
+ t.map((s) => /* @__PURE__ */ e("option", { value: s.id, children: s.name }, s.id))
2274
+ ]
2275
+ }
2276
+ ),
2277
+ /* @__PURE__ */ u("button", { type: "button", onClick: f, children: [
2278
+ "+ ",
2279
+ l("moduleEditor.views.new", "New view")
2280
+ ] }),
2281
+ n && /* @__PURE__ */ e("button", { type: "button", onClick: () => p(n.id), children: l("moduleEditor.delete", "Delete") })
2282
+ ] }),
2283
+ n ? /* @__PURE__ */ e(et, { value: n, onChange: c, entities: r, height: 520 }) : /* @__PURE__ */ e("div", { className: "nice-module-views__empty", children: l(
2284
+ "moduleEditor.views.empty",
2285
+ "No view selected. Create one, then use “New from entity” inside the editor."
2286
+ ) })
2287
+ ] });
2288
+ }
2289
+ function Ot({
2290
+ workflows: t,
2291
+ onChange: r
2292
+ }) {
2293
+ var p;
2294
+ const { t: a } = Z(), [l, o] = K(((p = t[0]) == null ? void 0 : p.id) ?? null), i = t.find((y) => y.id === l) ?? null, n = (y) => {
2295
+ r(t.map((s) => s.id === l ? y : s)), y.id !== l && o(y.id);
2296
+ }, c = () => {
2297
+ const y = {
2298
+ id: `workflow-${Date.now().toString(36)}`,
2299
+ name: "New Workflow",
2300
+ entityType: "",
2301
+ version: 1,
2302
+ states: [],
2303
+ transitions: []
2304
+ };
2305
+ r([...t, y]), o(y.id);
2306
+ }, f = (y) => {
2307
+ r(t.filter((s) => s.id !== y)), l === y && o(null);
2308
+ };
2309
+ return /* @__PURE__ */ u("div", { className: "nice-module-views", children: [
2310
+ /* @__PURE__ */ u("div", { className: "nice-module-views__bar", children: [
2311
+ /* @__PURE__ */ u(
2312
+ "select",
2313
+ {
2314
+ className: "nice-module-views__select",
2315
+ value: l ?? "",
2316
+ onChange: (y) => o(y.target.value || null),
2317
+ "aria-label": a("moduleEditor.workflows.select", "Select workflow"),
2318
+ children: [
2319
+ /* @__PURE__ */ e("option", { value: "", children: a("moduleEditor.workflows.placeholder", "— select workflow —") }),
2320
+ t.map((y) => /* @__PURE__ */ e("option", { value: y.id, children: y.name }, y.id))
2321
+ ]
2322
+ }
2323
+ ),
2324
+ /* @__PURE__ */ u("button", { type: "button", onClick: c, children: [
2325
+ "+ ",
2326
+ a("moduleEditor.workflows.new", "New workflow")
2327
+ ] }),
2328
+ i && /* @__PURE__ */ e("button", { type: "button", onClick: () => f(i.id), children: a("moduleEditor.delete", "Delete") })
2329
+ ] }),
2330
+ i ? /* @__PURE__ */ e(tt, { workflow: i, onChange: n }) : /* @__PURE__ */ e("div", { className: "nice-module-views__empty", children: a(
2331
+ "moduleEditor.workflows.empty",
2332
+ "No workflow selected. Create one to start designing states and transitions."
2333
+ ) })
2334
+ ] });
2335
+ }
2336
+ function Dt(t) {
2337
+ return t.map((r) => {
2338
+ const a = r;
2339
+ return {
2340
+ name: String(a.tableName || a.name || "Entity"),
2341
+ columns: (Array.isArray(a.fields) ? a.fields : []).map((l) => ({
2342
+ name: String(l.name ?? ""),
2343
+ dataType: String(l.dataType ?? "string"),
2344
+ isPrimaryKey: !!l.isPrimaryKey,
2345
+ isForeignKey: !!l.isForeignKey
2346
+ }))
2347
+ };
2348
+ });
2349
+ }
2350
+ function Mt(t) {
2351
+ const r = t.manifest ?? {}, a = String(r.displayName || r.packageName || "Module"), l = (t.views ?? []).map((i) => ({
2352
+ id: `view:${i.id}`,
2353
+ label: i.name,
2354
+ type: "view"
2355
+ })), o = (t.entities ?? []).map((i) => {
2356
+ const n = String(i.name ?? "Entity");
2357
+ return { id: `entity:${n}`, label: n, type: "entity" };
2358
+ });
2359
+ return {
2360
+ roles: [
2361
+ { id: "admin", label: "Admin" },
2362
+ { id: "user", label: "User" }
2363
+ ],
2364
+ actions: [
2365
+ { id: "view", label: "View" },
2366
+ { id: "create", label: "Create" },
2367
+ { id: "edit", label: "Edit" },
2368
+ { id: "delete", label: "Delete" }
2369
+ ],
2370
+ resources: [
2371
+ {
2372
+ id: "module",
2373
+ label: a,
2374
+ type: "module",
2375
+ children: [
2376
+ ...l.length ? [{ id: "views", label: "Views", type: "group", children: l }] : [],
2377
+ ...o.length ? [{ id: "entities", label: "Entities", type: "group", children: o }] : []
2378
+ ]
2379
+ }
2380
+ ],
2381
+ grants: {}
2382
+ };
2383
+ }
2384
+ function Lt({
2385
+ dataSources: t,
2386
+ schemas: r,
2387
+ onChange: a
2388
+ }) {
2389
+ var y;
2390
+ const { t: l } = Z(), [o, i] = K(((y = t[0]) == null ? void 0 : y.key) ?? null), n = t.find((s) => s.key === o) ?? null, c = (s) => {
2391
+ a(t.map((h) => h.key === o ? s : h)), s.key !== o && i(s.key);
2392
+ }, f = () => {
2393
+ const s = {
2394
+ key: `ds-${Date.now().toString(36)}`,
2395
+ kind: "query",
2396
+ query: { tables: [], joins: [], conditions: [], sorts: [], groupBy: [], distinct: !1 },
2397
+ sql: ""
2398
+ };
2399
+ a([...t, s]), i(s.key);
2400
+ }, p = (s) => {
2401
+ a(t.filter((h) => h.key !== s)), o === s && i(null);
2402
+ };
2403
+ return /* @__PURE__ */ u("div", { className: "nice-module-views", children: [
2404
+ /* @__PURE__ */ u("div", { className: "nice-module-views__bar", children: [
2405
+ /* @__PURE__ */ u(
2406
+ "select",
2407
+ {
2408
+ className: "nice-module-views__select",
2409
+ value: o ?? "",
2410
+ onChange: (s) => i(s.target.value || null),
2411
+ "aria-label": l("moduleEditor.data.select", "Select data source"),
2412
+ children: [
2413
+ /* @__PURE__ */ e("option", { value: "", children: l("moduleEditor.data.placeholder", "— select data source —") }),
2414
+ t.map((s) => /* @__PURE__ */ e("option", { value: s.key, children: s.label || s.key }, s.key))
2415
+ ]
2416
+ }
2417
+ ),
2418
+ /* @__PURE__ */ u("button", { type: "button", onClick: f, children: [
2419
+ "+ ",
2420
+ l("moduleEditor.data.new", "New data source")
2421
+ ] }),
2422
+ n && /* @__PURE__ */ e("button", { type: "button", onClick: () => p(n.key), children: l("moduleEditor.delete", "Delete") })
2423
+ ] }),
2424
+ n ? /* @__PURE__ */ e(it, { value: n, onChange: c, schemas: r }) : /* @__PURE__ */ e("div", { className: "nice-module-views__empty", children: l(
2425
+ "moduleEditor.data.empty",
2426
+ "No data source selected. Create one to build a query from your module’s schema."
2427
+ ) })
2428
+ ] });
2429
+ }
2
2430
  export {
3
- s as NiceArrayField,
4
- o as NiceEntityEditor,
5
- i as NiceFormBuilderAI,
6
- m as NiceI18nEditor,
7
- r as NiceManifestEditor,
8
- c as NiceModuleEditor,
9
- t as NiceSchemaForm,
10
- d as defineManifestSection,
11
- n as formBuilderSchemaToNiceFormItems,
12
- h as formFieldsToFormItems,
13
- F as formSchemaToJsonSchema,
14
- N as jsonSchemaToFormItems,
15
- f as schemaToFormItems,
16
- l as validateAgainstJsonSchema,
17
- S as validateFormSchema
2431
+ pt as NiceArrayField,
2432
+ Ct as NiceEntityEditor,
2433
+ Ut as NiceFormBuilderAI,
2434
+ At as NiceI18nEditor,
2435
+ Wt as NiceManifestEditor,
2436
+ Yt as NiceModuleEditor,
2437
+ de as NiceSchemaForm,
2438
+ Gt as defineManifestSection,
2439
+ Bt as formBuilderSchemaToNiceFormItems,
2440
+ Ce as formFieldsToFormItems,
2441
+ Ht as formSchemaToJsonSchema,
2442
+ xe as jsonSchemaToFormItems,
2443
+ zt as schemaToFormItems,
2444
+ Ie as validateAgainstJsonSchema,
2445
+ Jt as validateFormSchema
18
2446
  };