@burdenoff/microfe-bigconsole 2026.707.3 → 2026.707.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,42 +1,135 @@
|
|
|
1
1
|
import { memo as e, useCallback as t, useEffect as n, useMemo as r, useState as i } from "react";
|
|
2
2
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
3
3
|
//#region src/bigconsole/components/widgets/table/TableConfig.tsx
|
|
4
|
-
var s =
|
|
5
|
-
|
|
4
|
+
var s = [
|
|
5
|
+
{
|
|
6
|
+
value: "gt",
|
|
7
|
+
label: "> greater than"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
value: "gte",
|
|
11
|
+
label: "≥ at least"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
value: "lt",
|
|
15
|
+
label: "< less than"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
value: "lte",
|
|
19
|
+
label: "≤ at most"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
value: "eq",
|
|
23
|
+
label: "= equals"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
value: "neq",
|
|
27
|
+
label: "≠ not equal"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
value: "between",
|
|
31
|
+
label: "between"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
value: "outside",
|
|
35
|
+
label: "outside"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
value: "contains",
|
|
39
|
+
label: "contains"
|
|
40
|
+
}
|
|
41
|
+
], c = [
|
|
42
|
+
{
|
|
43
|
+
value: "danger",
|
|
44
|
+
label: "Red — danger"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
value: "warning",
|
|
48
|
+
label: "Amber — warning"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
value: "success",
|
|
52
|
+
label: "Green — good"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
value: "info",
|
|
56
|
+
label: "Blue — info"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
value: "neutral",
|
|
60
|
+
label: "Neutral"
|
|
61
|
+
}
|
|
62
|
+
], l = "px-2 py-1 text-xs text-text-primary bg-bg-surface border border-border-default rounded-md focus:outline-none focus:ring-2 focus:ring-action-primary-bg", u = e(function({ config: e, onChange: u }) {
|
|
63
|
+
let [d, f] = i(r(() => (e.columns || []).map((e) => typeof e == "string" ? {
|
|
6
64
|
field: e,
|
|
7
65
|
header: e.charAt(0).toUpperCase() + e.slice(1).replace(/_/g, " ")
|
|
8
66
|
} : e), []));
|
|
9
67
|
n(() => {
|
|
10
|
-
JSON.stringify(e.columns) !== JSON.stringify(
|
|
68
|
+
JSON.stringify(e.columns) !== JSON.stringify(d) && d.length > 0 && u({
|
|
11
69
|
...e,
|
|
12
|
-
columns:
|
|
70
|
+
columns: d
|
|
13
71
|
});
|
|
14
|
-
}, [
|
|
15
|
-
|
|
72
|
+
}, [d]), n(() => {
|
|
73
|
+
f((e.columns || []).map((e) => typeof e == "string" ? {
|
|
16
74
|
field: e,
|
|
17
75
|
header: e.charAt(0).toUpperCase() + e.slice(1).replace(/_/g, " ")
|
|
18
76
|
} : e));
|
|
19
77
|
}, [e.columns]);
|
|
20
|
-
let
|
|
21
|
-
|
|
78
|
+
let p = t((t, n) => {
|
|
79
|
+
u({
|
|
22
80
|
...e,
|
|
23
81
|
[t]: n
|
|
24
82
|
});
|
|
25
|
-
}, [e,
|
|
26
|
-
|
|
83
|
+
}, [e, u]), m = t((e, t, n) => {
|
|
84
|
+
f((r) => {
|
|
27
85
|
let i = [...r];
|
|
28
86
|
return i[e] = {
|
|
29
87
|
...i[e],
|
|
30
88
|
[t]: n
|
|
31
89
|
}, i;
|
|
32
90
|
});
|
|
33
|
-
}, []),
|
|
34
|
-
|
|
91
|
+
}, []), h = t((e, t) => {
|
|
92
|
+
f((n) => {
|
|
93
|
+
let r = [...n];
|
|
94
|
+
return r[e] = {
|
|
95
|
+
...r[e],
|
|
96
|
+
conditionalRules: t
|
|
97
|
+
}, r;
|
|
98
|
+
});
|
|
99
|
+
}, []), g = t((e) => {
|
|
100
|
+
let t = d[e]?.conditionalRules ?? [], n = {
|
|
101
|
+
operator: "gt",
|
|
102
|
+
value: 0,
|
|
103
|
+
style: {
|
|
104
|
+
bgColor: "danger",
|
|
105
|
+
textColor: "danger",
|
|
106
|
+
bold: !0
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
h(e, [...t, n]);
|
|
110
|
+
}, [d, h]), _ = t((e, t, n) => {
|
|
111
|
+
h(e, (d[e]?.conditionalRules ?? []).map((e, r) => r === t ? {
|
|
112
|
+
...e,
|
|
113
|
+
...n
|
|
114
|
+
} : e));
|
|
115
|
+
}, [d, h]), v = t((e, t, n) => {
|
|
116
|
+
h(e, (d[e]?.conditionalRules ?? []).map((e, r) => r === t ? {
|
|
117
|
+
...e,
|
|
118
|
+
style: {
|
|
119
|
+
...e.style,
|
|
120
|
+
bgColor: n,
|
|
121
|
+
textColor: n
|
|
122
|
+
}
|
|
123
|
+
} : e));
|
|
124
|
+
}, [d, h]), y = t((e, t) => {
|
|
125
|
+
h(e, (d[e]?.conditionalRules ?? []).filter((e, n) => n !== t));
|
|
126
|
+
}, [d, h]), b = t(() => {
|
|
127
|
+
f((e) => [...e, {
|
|
35
128
|
field: "",
|
|
36
129
|
header: ""
|
|
37
130
|
}]);
|
|
38
|
-
}, []),
|
|
39
|
-
|
|
131
|
+
}, []), x = t((e) => {
|
|
132
|
+
f((t) => t.filter((t, n) => n !== e));
|
|
40
133
|
}, []);
|
|
41
134
|
return /* @__PURE__ */ o("div", {
|
|
42
135
|
className: "space-y-4",
|
|
@@ -46,7 +139,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
46
139
|
children: "Page Size"
|
|
47
140
|
}), /* @__PURE__ */ o("select", {
|
|
48
141
|
value: e.pageSize || 10,
|
|
49
|
-
onChange: (e) =>
|
|
142
|
+
onChange: (e) => p("pageSize", Number(e.target.value)),
|
|
50
143
|
className: "\n w-full px-3 py-2\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 ",
|
|
51
144
|
children: [
|
|
52
145
|
/* @__PURE__ */ a("option", {
|
|
@@ -74,13 +167,13 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
74
167
|
children: "Columns"
|
|
75
168
|
}), /* @__PURE__ */ a("button", {
|
|
76
169
|
type: "button",
|
|
77
|
-
onClick:
|
|
170
|
+
onClick: b,
|
|
78
171
|
className: "\n text-sm text-action-primary-bg\n hover:text-action-primary-bgHover\n ",
|
|
79
172
|
children: "+ Add Column"
|
|
80
173
|
})]
|
|
81
174
|
}), /* @__PURE__ */ o("div", {
|
|
82
175
|
className: "space-y-3",
|
|
83
|
-
children: [
|
|
176
|
+
children: [d.map((e, t) => /* @__PURE__ */ o("div", {
|
|
84
177
|
className: "\n p-3\n bg-bg-sunken\n rounded-md\n space-y-2\n ",
|
|
85
178
|
children: [
|
|
86
179
|
/* @__PURE__ */ o("div", {
|
|
@@ -90,7 +183,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
90
183
|
children: ["Column ", t + 1]
|
|
91
184
|
}), /* @__PURE__ */ a("button", {
|
|
92
185
|
type: "button",
|
|
93
|
-
onClick: () =>
|
|
186
|
+
onClick: () => x(t),
|
|
94
187
|
className: "text-state-error hover:text-state-error/80",
|
|
95
188
|
children: /* @__PURE__ */ a("svg", {
|
|
96
189
|
className: "w-4 h-4",
|
|
@@ -111,13 +204,13 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
111
204
|
children: [/* @__PURE__ */ a("input", {
|
|
112
205
|
type: "text",
|
|
113
206
|
value: e.field || "",
|
|
114
|
-
onChange: (e) =>
|
|
207
|
+
onChange: (e) => m(t, "field", e.target.value),
|
|
115
208
|
placeholder: "Field name",
|
|
116
209
|
className: "\n px-2 py-1\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 "
|
|
117
210
|
}), /* @__PURE__ */ a("input", {
|
|
118
211
|
type: "text",
|
|
119
212
|
value: e.header || "",
|
|
120
|
-
onChange: (e) =>
|
|
213
|
+
onChange: (e) => m(t, "header", e.target.value),
|
|
121
214
|
placeholder: "Header label",
|
|
122
215
|
className: "\n px-2 py-1\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 "
|
|
123
216
|
})]
|
|
@@ -126,7 +219,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
126
219
|
className: "grid grid-cols-2 gap-2",
|
|
127
220
|
children: [/* @__PURE__ */ o("select", {
|
|
128
221
|
value: e.format || "text",
|
|
129
|
-
onChange: (e) =>
|
|
222
|
+
onChange: (e) => m(t, "format", e.target.value),
|
|
130
223
|
className: "\n px-2 py-1\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 ",
|
|
131
224
|
children: [
|
|
132
225
|
/* @__PURE__ */ a("option", {
|
|
@@ -156,7 +249,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
156
249
|
]
|
|
157
250
|
}), /* @__PURE__ */ o("select", {
|
|
158
251
|
value: e.align || "left",
|
|
159
|
-
onChange: (e) =>
|
|
252
|
+
onChange: (e) => m(t, "align", e.target.value),
|
|
160
253
|
className: "\n px-2 py-1\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 ",
|
|
161
254
|
children: [
|
|
162
255
|
/* @__PURE__ */ a("option", {
|
|
@@ -173,9 +266,107 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
173
266
|
})
|
|
174
267
|
]
|
|
175
268
|
})]
|
|
269
|
+
}),
|
|
270
|
+
/* @__PURE__ */ o("div", {
|
|
271
|
+
className: "pt-2 border-t border-border-default/60",
|
|
272
|
+
children: [
|
|
273
|
+
/* @__PURE__ */ o("div", {
|
|
274
|
+
className: "flex items-center justify-between mb-1",
|
|
275
|
+
children: [/* @__PURE__ */ a("span", {
|
|
276
|
+
className: "text-xs font-medium text-text-secondary",
|
|
277
|
+
children: "Conditional formatting"
|
|
278
|
+
}), /* @__PURE__ */ a("button", {
|
|
279
|
+
type: "button",
|
|
280
|
+
onClick: () => g(t),
|
|
281
|
+
className: "text-xs text-action-primary-bg hover:text-action-primary-bgHover",
|
|
282
|
+
children: "+ Add rule"
|
|
283
|
+
})]
|
|
284
|
+
}),
|
|
285
|
+
(e.conditionalRules?.length ?? 0) === 0 && /* @__PURE__ */ a("p", {
|
|
286
|
+
className: "text-xs text-text-secondary",
|
|
287
|
+
children: "No rules — cell shows its plain value."
|
|
288
|
+
}),
|
|
289
|
+
/* @__PURE__ */ a("div", {
|
|
290
|
+
className: "space-y-2",
|
|
291
|
+
children: (e.conditionalRules ?? []).map((e, n) => {
|
|
292
|
+
let r = e.operator === "between" || e.operator === "outside", i = e.style?.bgColor ?? e.style?.textColor ?? "danger";
|
|
293
|
+
return /* @__PURE__ */ o("div", {
|
|
294
|
+
className: "p-2 bg-bg-surface rounded-md border border-border-default space-y-2",
|
|
295
|
+
children: [/* @__PURE__ */ o("div", {
|
|
296
|
+
className: "flex items-center gap-2",
|
|
297
|
+
children: [
|
|
298
|
+
/* @__PURE__ */ a("select", {
|
|
299
|
+
value: e.operator,
|
|
300
|
+
onChange: (e) => _(t, n, { operator: e.target.value }),
|
|
301
|
+
className: `${l} flex-1`,
|
|
302
|
+
children: s.map((e) => /* @__PURE__ */ a("option", {
|
|
303
|
+
value: e.value,
|
|
304
|
+
children: e.label
|
|
305
|
+
}, e.value))
|
|
306
|
+
}),
|
|
307
|
+
/* @__PURE__ */ a("input", {
|
|
308
|
+
type: "text",
|
|
309
|
+
value: e.value ?? "",
|
|
310
|
+
onChange: (e) => _(t, n, { value: e.target.value }),
|
|
311
|
+
placeholder: "value",
|
|
312
|
+
className: `${l} w-20`
|
|
313
|
+
}),
|
|
314
|
+
r && /* @__PURE__ */ a("input", {
|
|
315
|
+
type: "text",
|
|
316
|
+
value: e.value2 ?? "",
|
|
317
|
+
onChange: (e) => _(t, n, { value2: e.target.value }),
|
|
318
|
+
placeholder: "and",
|
|
319
|
+
className: `${l} w-20`
|
|
320
|
+
}),
|
|
321
|
+
/* @__PURE__ */ a("button", {
|
|
322
|
+
type: "button",
|
|
323
|
+
onClick: () => y(t, n),
|
|
324
|
+
className: "text-state-error hover:text-state-error/80",
|
|
325
|
+
"aria-label": "Remove rule",
|
|
326
|
+
children: /* @__PURE__ */ a("svg", {
|
|
327
|
+
className: "w-3.5 h-3.5",
|
|
328
|
+
fill: "none",
|
|
329
|
+
stroke: "currentColor",
|
|
330
|
+
viewBox: "0 0 24 24",
|
|
331
|
+
children: /* @__PURE__ */ a("path", {
|
|
332
|
+
strokeLinecap: "round",
|
|
333
|
+
strokeLinejoin: "round",
|
|
334
|
+
strokeWidth: 2,
|
|
335
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
336
|
+
})
|
|
337
|
+
})
|
|
338
|
+
})
|
|
339
|
+
]
|
|
340
|
+
}), /* @__PURE__ */ o("div", {
|
|
341
|
+
className: "flex items-center gap-2",
|
|
342
|
+
children: [/* @__PURE__ */ a("select", {
|
|
343
|
+
value: i,
|
|
344
|
+
onChange: (e) => v(t, n, e.target.value),
|
|
345
|
+
className: `${l} flex-1`,
|
|
346
|
+
children: c.map((e) => /* @__PURE__ */ a("option", {
|
|
347
|
+
value: e.value,
|
|
348
|
+
children: e.label
|
|
349
|
+
}, e.value))
|
|
350
|
+
}), /* @__PURE__ */ o("label", {
|
|
351
|
+
className: "flex items-center gap-1 text-xs text-text-primary",
|
|
352
|
+
children: [/* @__PURE__ */ a("input", {
|
|
353
|
+
type: "checkbox",
|
|
354
|
+
checked: e.style?.bold === !0,
|
|
355
|
+
onChange: (r) => _(t, n, { style: {
|
|
356
|
+
...e.style,
|
|
357
|
+
bold: r.target.checked
|
|
358
|
+
} }),
|
|
359
|
+
className: "w-3.5 h-3.5 text-action-primary-bg bg-bg-surface border-border-default rounded focus:ring-action-primary-bg"
|
|
360
|
+
}), "Bold"]
|
|
361
|
+
})]
|
|
362
|
+
})]
|
|
363
|
+
}, n);
|
|
364
|
+
})
|
|
365
|
+
})
|
|
366
|
+
]
|
|
176
367
|
})
|
|
177
368
|
]
|
|
178
|
-
}, t)),
|
|
369
|
+
}, t)), d.length === 0 && /* @__PURE__ */ a("p", {
|
|
179
370
|
className: "text-sm text-text-secondary text-center py-4",
|
|
180
371
|
children: "No columns configured. Columns will be auto-generated from data."
|
|
181
372
|
})]
|
|
@@ -188,7 +379,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
188
379
|
children: [/* @__PURE__ */ a("input", {
|
|
189
380
|
type: "checkbox",
|
|
190
381
|
checked: e.showSearch !== !1,
|
|
191
|
-
onChange: (e) =>
|
|
382
|
+
onChange: (e) => p("showSearch", e.target.checked),
|
|
192
383
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
193
384
|
}), /* @__PURE__ */ a("span", {
|
|
194
385
|
className: "text-sm text-text-primary",
|
|
@@ -200,7 +391,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
200
391
|
children: [/* @__PURE__ */ a("input", {
|
|
201
392
|
type: "checkbox",
|
|
202
393
|
checked: e.showPagination !== !1,
|
|
203
|
-
onChange: (e) =>
|
|
394
|
+
onChange: (e) => p("showPagination", e.target.checked),
|
|
204
395
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
205
396
|
}), /* @__PURE__ */ a("span", {
|
|
206
397
|
className: "text-sm text-text-primary",
|
|
@@ -212,7 +403,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
212
403
|
children: [/* @__PURE__ */ a("input", {
|
|
213
404
|
type: "checkbox",
|
|
214
405
|
checked: e.showExport !== !1,
|
|
215
|
-
onChange: (e) =>
|
|
406
|
+
onChange: (e) => p("showExport", e.target.checked),
|
|
216
407
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
217
408
|
}), /* @__PURE__ */ a("span", {
|
|
218
409
|
className: "text-sm text-text-primary",
|
|
@@ -224,7 +415,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
224
415
|
children: [/* @__PURE__ */ a("input", {
|
|
225
416
|
type: "checkbox",
|
|
226
417
|
checked: e.stickyHeader === !0,
|
|
227
|
-
onChange: (e) =>
|
|
418
|
+
onChange: (e) => p("stickyHeader", e.target.checked),
|
|
228
419
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
229
420
|
}), /* @__PURE__ */ a("span", {
|
|
230
421
|
className: "text-sm text-text-primary",
|
|
@@ -236,7 +427,7 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
236
427
|
children: [/* @__PURE__ */ a("input", {
|
|
237
428
|
type: "checkbox",
|
|
238
429
|
checked: e.stripedRows === !0,
|
|
239
|
-
onChange: (e) =>
|
|
430
|
+
onChange: (e) => p("stripedRows", e.target.checked),
|
|
240
431
|
className: "\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n "
|
|
241
432
|
}), /* @__PURE__ */ a("span", {
|
|
242
433
|
className: "text-sm text-text-primary",
|
|
@@ -249,6 +440,6 @@ var s = e(function({ config: e, onChange: s }) {
|
|
|
249
440
|
});
|
|
250
441
|
});
|
|
251
442
|
//#endregion
|
|
252
|
-
export {
|
|
443
|
+
export { u as default };
|
|
253
444
|
|
|
254
445
|
//# sourceMappingURL=TableConfig.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableConfig.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/table/TableConfig.tsx"],"sourcesContent":["/**\n * TableConfig Component\n *\n * Configuration panel for Table widgets.\n */\n\nimport { type FC, memo, useCallback, useMemo, useEffect, useState } from 'react';\nimport type { TableConfig as ConfigType, TableColumnConfig } from '../../../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TableConfigProps {\n /** Current configuration */\n config: ConfigType;\n /** Callback when config changes */\n onChange: (config: ConfigType) => void;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const TableConfig: FC<TableConfigProps> = memo(function TableConfig({ config, onChange }) {\n // Normalize columns - convert string[] to TableColumnConfig[]\n const initialColumns = useMemo(() => {\n return ((config.columns || []) as (string | TableColumnConfig)[]).map((col) => {\n if (typeof col === 'string') {\n return {\n field: col,\n header: col.charAt(0).toUpperCase() + col.slice(1).replace(/_/g, ' '),\n };\n }\n return col as TableColumnConfig;\n });\n }, []); // Only run once on mount\n\n // Local state for columns to make them editable\n const [columns, setColumns] = useState<TableColumnConfig[]>(initialColumns);\n\n // Sync with parent when columns change\n useEffect(() => {\n // Only update if columns actually changed (deep compare)\n const currentStr = JSON.stringify(config.columns);\n const newStr = JSON.stringify(columns);\n if (currentStr !== newStr && columns.length > 0) {\n onChange({ ...config, columns });\n }\n }, [columns]);\n\n // Reset columns when config changes from outside\n useEffect(() => {\n const normalized = ((config.columns || []) as (string | TableColumnConfig)[]).map((col) => {\n if (typeof col === 'string') {\n return {\n field: col,\n header: col.charAt(0).toUpperCase() + col.slice(1).replace(/_/g, ' '),\n };\n }\n return col as TableColumnConfig;\n });\n setColumns(normalized);\n }, [config.columns]);\n\n const handleChange = useCallback(\n <K extends keyof ConfigType>(key: K, value: ConfigType[K]) => {\n onChange({ ...config, [key]: value });\n },\n [config, onChange]\n );\n\n const handleColumnChange = useCallback((index: number, field: keyof TableColumnConfig, value: string) => {\n setColumns((prev) => {\n const newColumns = [...prev];\n newColumns[index] = { ...newColumns[index], [field]: value };\n return newColumns;\n });\n }, []);\n\n const addColumn = useCallback(() => {\n setColumns((prev) => [...prev, { field: '', header: '' }]);\n }, []);\n\n const removeColumn = useCallback((index: number) => {\n setColumns((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n return (\n <div className=\"space-y-4\">\n {/* Page Size */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Page Size</label>\n <select\n value={config.pageSize || 10}\n onChange={(e) => handleChange('pageSize', Number(e.target.value))}\n className=\"\n w-full px-3 py-2\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 \"\n >\n <option value={10}>10 rows</option>\n <option value={25}>25 rows</option>\n <option value={50}>50 rows</option>\n <option value={100}>100 rows</option>\n </select>\n </div>\n\n {/* Columns Configuration */}\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <label className=\"text-sm font-medium text-text-primary\">Columns</label>\n <button\n type=\"button\"\n onClick={addColumn}\n className=\"\n text-sm text-action-primary-bg\n hover:text-action-primary-bgHover\n \"\n >\n + Add Column\n </button>\n </div>\n\n <div className=\"space-y-3\">\n {columns.map((col, index) => (\n <div\n key={index}\n className=\"\n p-3\n bg-bg-sunken\n rounded-md\n space-y-2\n \"\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary\">Column {index + 1}</span>\n <button\n type=\"button\"\n onClick={() => removeColumn(index)}\n className=\"text-state-error hover:text-state-error/80\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <input\n type=\"text\"\n value={col.field || ''}\n onChange={(e) => handleColumnChange(index, 'field', e.target.value)}\n placeholder=\"Field name\"\n className=\"\n px-2 py-1\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 \"\n />\n <input\n type=\"text\"\n value={col.header || ''}\n onChange={(e) => handleColumnChange(index, 'header', e.target.value)}\n placeholder=\"Header label\"\n className=\"\n px-2 py-1\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 \"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <select\n value={col.format || 'text'}\n onChange={(e) => handleColumnChange(index, 'format', e.target.value)}\n className=\"\n px-2 py-1\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 \"\n >\n <option value=\"text\">Text</option>\n <option value=\"number\">Number</option>\n <option value=\"currency\">Currency</option>\n <option value=\"percentage\">Percentage</option>\n <option value=\"date\">Date</option>\n <option value=\"badge\">Badge</option>\n </select>\n <select\n value={col.align || 'left'}\n onChange={(e) => handleColumnChange(index, 'align', e.target.value)}\n className=\"\n px-2 py-1\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 \"\n >\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n </div>\n ))}\n\n {columns.length === 0 && (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n No columns configured. Columns will be auto-generated from data.\n </p>\n )}\n </div>\n </div>\n\n {/* Toggle Options */}\n <div className=\"space-y-3\">\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showSearch !== false}\n onChange={(e) => handleChange('showSearch', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Show search box</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showPagination !== false}\n onChange={(e) => handleChange('showPagination', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Show pagination</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showExport !== false}\n onChange={(e) => handleChange('showExport', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Show export button</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.stickyHeader === true}\n onChange={(e) => handleChange('stickyHeader', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Sticky header</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.stripedRows === true}\n onChange={(e) => handleChange('stripedRows', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Striped rows</span>\n </label>\n </div>\n </div>\n );\n});\n\nexport default TableConfig;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TableConfig.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/table/TableConfig.tsx"],"sourcesContent":["/**\n * TableConfig Component\n *\n * Configuration panel for Table widgets.\n */\n\nimport { type FC, memo, useCallback, useMemo, useEffect, useState } from 'react';\nimport type { TableConfig as ConfigType, TableColumnConfig } from '../../../types';\nimport type { ConditionalRule, ConditionalOperator, SemanticIntent } from '../utils/conditionalFormat';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TableConfigProps {\n /** Current configuration */\n config: ConfigType;\n /** Callback when config changes */\n onChange: (config: ConfigType) => void;\n}\n\n// Operators offered in the conditional-formatting editor. Kept to the common,\n// self-explanatory set; the engine supports more (see conditionalFormat.ts).\nconst CF_OPERATORS: { value: ConditionalOperator; label: string }[] = [\n { value: 'gt', label: '> greater than' },\n { value: 'gte', label: '≥ at least' },\n { value: 'lt', label: '< less than' },\n { value: 'lte', label: '≤ at most' },\n { value: 'eq', label: '= equals' },\n { value: 'neq', label: '≠ not equal' },\n { value: 'between', label: 'between' },\n { value: 'outside', label: 'outside' },\n { value: 'contains', label: 'contains' },\n];\n\n// Semantic color intents — theme-safe (never raw hex). Resolved to status tokens.\nconst CF_INTENTS: { value: SemanticIntent; label: string }[] = [\n { value: 'danger', label: 'Red — danger' },\n { value: 'warning', label: 'Amber — warning' },\n { value: 'success', label: 'Green — good' },\n { value: 'info', label: 'Blue — info' },\n { value: 'neutral', label: 'Neutral' },\n];\n\nconst CF_FIELD_CLASS =\n 'px-2 py-1 text-xs text-text-primary bg-bg-surface border border-border-default rounded-md focus:outline-none focus:ring-2 focus:ring-action-primary-bg';\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const TableConfig: FC<TableConfigProps> = memo(function TableConfig({ config, onChange }) {\n // Normalize columns - convert string[] to TableColumnConfig[]\n const initialColumns = useMemo(() => {\n return ((config.columns || []) as (string | TableColumnConfig)[]).map((col) => {\n if (typeof col === 'string') {\n return {\n field: col,\n header: col.charAt(0).toUpperCase() + col.slice(1).replace(/_/g, ' '),\n };\n }\n return col as TableColumnConfig;\n });\n }, []); // Only run once on mount\n\n // Local state for columns to make them editable\n const [columns, setColumns] = useState<TableColumnConfig[]>(initialColumns);\n\n // Sync with parent when columns change\n useEffect(() => {\n // Only update if columns actually changed (deep compare)\n const currentStr = JSON.stringify(config.columns);\n const newStr = JSON.stringify(columns);\n if (currentStr !== newStr && columns.length > 0) {\n onChange({ ...config, columns });\n }\n }, [columns]);\n\n // Reset columns when config changes from outside\n useEffect(() => {\n const normalized = ((config.columns || []) as (string | TableColumnConfig)[]).map((col) => {\n if (typeof col === 'string') {\n return {\n field: col,\n header: col.charAt(0).toUpperCase() + col.slice(1).replace(/_/g, ' '),\n };\n }\n return col as TableColumnConfig;\n });\n setColumns(normalized);\n }, [config.columns]);\n\n const handleChange = useCallback(\n <K extends keyof ConfigType>(key: K, value: ConfigType[K]) => {\n onChange({ ...config, [key]: value });\n },\n [config, onChange]\n );\n\n const handleColumnChange = useCallback((index: number, field: keyof TableColumnConfig, value: string) => {\n setColumns((prev) => {\n const newColumns = [...prev];\n newColumns[index] = { ...newColumns[index], [field]: value };\n return newColumns;\n });\n }, []);\n\n // Conditional-formatting rule edits for a column. The rules array is stored on\n // `column.conditionalRules` and consumed at render time by TableCell.\n const handleColumnRules = useCallback((index: number, rules: ConditionalRule[]) => {\n setColumns((prev) => {\n const newColumns = [...prev];\n newColumns[index] = { ...newColumns[index], conditionalRules: rules };\n return newColumns;\n });\n }, []);\n\n const addRule = useCallback(\n (index: number) => {\n const existing = columns[index]?.conditionalRules ?? [];\n const next: ConditionalRule = {\n operator: 'gt',\n value: 0,\n style: { bgColor: 'danger', textColor: 'danger', bold: true },\n };\n handleColumnRules(index, [...existing, next]);\n },\n [columns, handleColumnRules]\n );\n\n const updateRule = useCallback(\n (colIndex: number, ruleIndex: number, patch: Partial<ConditionalRule>) => {\n const existing = columns[colIndex]?.conditionalRules ?? [];\n const next = existing.map((r, i) => (i === ruleIndex ? { ...r, ...patch } : r));\n handleColumnRules(colIndex, next);\n },\n [columns, handleColumnRules]\n );\n\n const updateRuleStyle = useCallback(\n (colIndex: number, ruleIndex: number, intent: SemanticIntent) => {\n const existing = columns[colIndex]?.conditionalRules ?? [];\n const next = existing.map((r, i) =>\n i === ruleIndex ? { ...r, style: { ...r.style, bgColor: intent, textColor: intent } } : r\n );\n handleColumnRules(colIndex, next);\n },\n [columns, handleColumnRules]\n );\n\n const removeRule = useCallback(\n (colIndex: number, ruleIndex: number) => {\n const existing = columns[colIndex]?.conditionalRules ?? [];\n handleColumnRules(\n colIndex,\n existing.filter((_, i) => i !== ruleIndex)\n );\n },\n [columns, handleColumnRules]\n );\n\n const addColumn = useCallback(() => {\n setColumns((prev) => [...prev, { field: '', header: '' }]);\n }, []);\n\n const removeColumn = useCallback((index: number) => {\n setColumns((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n return (\n <div className=\"space-y-4\">\n {/* Page Size */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Page Size</label>\n <select\n value={config.pageSize || 10}\n onChange={(e) => handleChange('pageSize', Number(e.target.value))}\n className=\"\n w-full px-3 py-2\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 \"\n >\n <option value={10}>10 rows</option>\n <option value={25}>25 rows</option>\n <option value={50}>50 rows</option>\n <option value={100}>100 rows</option>\n </select>\n </div>\n\n {/* Columns Configuration */}\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <label className=\"text-sm font-medium text-text-primary\">Columns</label>\n <button\n type=\"button\"\n onClick={addColumn}\n className=\"\n text-sm text-action-primary-bg\n hover:text-action-primary-bgHover\n \"\n >\n + Add Column\n </button>\n </div>\n\n <div className=\"space-y-3\">\n {columns.map((col, index) => (\n <div\n key={index}\n className=\"\n p-3\n bg-bg-sunken\n rounded-md\n space-y-2\n \"\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary\">Column {index + 1}</span>\n <button\n type=\"button\"\n onClick={() => removeColumn(index)}\n className=\"text-state-error hover:text-state-error/80\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <input\n type=\"text\"\n value={col.field || ''}\n onChange={(e) => handleColumnChange(index, 'field', e.target.value)}\n placeholder=\"Field name\"\n className=\"\n px-2 py-1\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 \"\n />\n <input\n type=\"text\"\n value={col.header || ''}\n onChange={(e) => handleColumnChange(index, 'header', e.target.value)}\n placeholder=\"Header label\"\n className=\"\n px-2 py-1\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 \"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <select\n value={col.format || 'text'}\n onChange={(e) => handleColumnChange(index, 'format', e.target.value)}\n className=\"\n px-2 py-1\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 \"\n >\n <option value=\"text\">Text</option>\n <option value=\"number\">Number</option>\n <option value=\"currency\">Currency</option>\n <option value=\"percentage\">Percentage</option>\n <option value=\"date\">Date</option>\n <option value=\"badge\">Badge</option>\n </select>\n <select\n value={col.align || 'left'}\n onChange={(e) => handleColumnChange(index, 'align', e.target.value)}\n className=\"\n px-2 py-1\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 \"\n >\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n\n {/* Conditional formatting rules */}\n <div className=\"pt-2 border-t border-border-default/60\">\n <div className=\"flex items-center justify-between mb-1\">\n <span className=\"text-xs font-medium text-text-secondary\">Conditional formatting</span>\n <button\n type=\"button\"\n onClick={() => addRule(index)}\n className=\"text-xs text-action-primary-bg hover:text-action-primary-bgHover\"\n >\n + Add rule\n </button>\n </div>\n\n {(col.conditionalRules?.length ?? 0) === 0 && (\n <p className=\"text-xs text-text-secondary\">No rules — cell shows its plain value.</p>\n )}\n\n <div className=\"space-y-2\">\n {(col.conditionalRules ?? []).map((rule, ruleIndex) => {\n const needsSecond = rule.operator === 'between' || rule.operator === 'outside';\n const currentIntent: SemanticIntent = rule.style?.bgColor ?? rule.style?.textColor ?? 'danger';\n return (\n <div\n key={ruleIndex}\n className=\"p-2 bg-bg-surface rounded-md border border-border-default space-y-2\"\n >\n <div className=\"flex items-center gap-2\">\n <select\n value={rule.operator}\n onChange={(e) =>\n updateRule(index, ruleIndex, { operator: e.target.value as ConditionalOperator })\n }\n className={`${CF_FIELD_CLASS} flex-1`}\n >\n {CF_OPERATORS.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label}\n </option>\n ))}\n </select>\n <input\n type=\"text\"\n value={rule.value ?? ''}\n onChange={(e) => updateRule(index, ruleIndex, { value: e.target.value })}\n placeholder=\"value\"\n className={`${CF_FIELD_CLASS} w-20`}\n />\n {needsSecond && (\n <input\n type=\"text\"\n value={rule.value2 ?? ''}\n onChange={(e) => updateRule(index, ruleIndex, { value2: e.target.value })}\n placeholder=\"and\"\n className={`${CF_FIELD_CLASS} w-20`}\n />\n )}\n <button\n type=\"button\"\n onClick={() => removeRule(index, ruleIndex)}\n className=\"text-state-error hover:text-state-error/80\"\n aria-label=\"Remove rule\"\n >\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n <div className=\"flex items-center gap-2\">\n <select\n value={currentIntent}\n onChange={(e) => updateRuleStyle(index, ruleIndex, e.target.value as SemanticIntent)}\n className={`${CF_FIELD_CLASS} flex-1`}\n >\n {CF_INTENTS.map((it) => (\n <option key={it.value} value={it.value}>\n {it.label}\n </option>\n ))}\n </select>\n <label className=\"flex items-center gap-1 text-xs text-text-primary\">\n <input\n type=\"checkbox\"\n checked={rule.style?.bold === true}\n onChange={(e) =>\n updateRule(index, ruleIndex, { style: { ...rule.style, bold: e.target.checked } })\n }\n className=\"w-3.5 h-3.5 text-action-primary-bg bg-bg-surface border-border-default rounded focus:ring-action-primary-bg\"\n />\n Bold\n </label>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n ))}\n\n {columns.length === 0 && (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n No columns configured. Columns will be auto-generated from data.\n </p>\n )}\n </div>\n </div>\n\n {/* Toggle Options */}\n <div className=\"space-y-3\">\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showSearch !== false}\n onChange={(e) => handleChange('showSearch', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Show search box</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showPagination !== false}\n onChange={(e) => handleChange('showPagination', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Show pagination</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.showExport !== false}\n onChange={(e) => handleChange('showExport', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Show export button</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.stickyHeader === true}\n onChange={(e) => handleChange('stickyHeader', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Sticky header</span>\n </label>\n\n <label className=\"flex items-center gap-3\">\n <input\n type=\"checkbox\"\n checked={config.stripedRows === true}\n onChange={(e) => handleChange('stripedRows', e.target.checked)}\n className=\"\n w-4 h-4\n text-action-primary-bg\n bg-bg-surface\n border-border-default\n rounded\n focus:ring-action-primary-bg\n \"\n />\n <span className=\"text-sm text-text-primary\">Striped rows</span>\n </label>\n </div>\n </div>\n );\n});\n\nexport default TableConfig;\n"],"mappings":"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"}
|