@burojs/ui-shadcn 0.6.0 → 0.7.0
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/README.md +9 -0
- package/dist/bulk-summary-BWSAS7k2.js +143 -0
- package/dist/bulk-summary-BWSAS7k2.js.map +1 -0
- package/dist/bulk-summary-CrEij5vq.cjs +143 -0
- package/dist/bulk-summary-CrEij5vq.cjs.map +1 -0
- package/dist/{candidates-relation-picker-B116Bmqi.js → candidates-relation-picker-CS_JZ4Fd.js} +3 -3
- package/dist/{candidates-relation-picker-B116Bmqi.js.map → candidates-relation-picker-CS_JZ4Fd.js.map} +1 -1
- package/dist/{candidates-relation-picker-Cy0rTxvI.cjs → candidates-relation-picker-y5M6_oe4.cjs} +4 -4
- package/dist/{candidates-relation-picker-Cy0rTxvI.cjs.map → candidates-relation-picker-y5M6_oe4.cjs.map} +1 -1
- package/dist/{check-confirm-dialog-bRT8lt0d.js → check-confirm-dialog-2j0gOd7x.js} +384 -108
- package/dist/check-confirm-dialog-2j0gOd7x.js.map +1 -0
- package/dist/{check-confirm-dialog--gPFnEeg.cjs → check-confirm-dialog-C-NHgMST.cjs} +468 -107
- package/dist/check-confirm-dialog-C-NHgMST.cjs.map +1 -0
- package/dist/{dialog-B_rt9S1c.js → dialog-C123sVQ8.js} +4 -4
- package/dist/dialog-C123sVQ8.js.map +1 -0
- package/dist/{dialog-DRNUq9EA.cjs → dialog-vmMdfUWs.cjs} +3 -3
- package/dist/dialog-vmMdfUWs.cjs.map +1 -0
- package/dist/{filter-builder-nXqtM_h4.cjs → filter-builder-DFu0JP-1.cjs} +923 -120
- package/dist/filter-builder-DFu0JP-1.cjs.map +1 -0
- package/dist/{filter-builder-Bhn-dhZV.js → filter-builder-DaWHUZuV.js} +839 -108
- package/dist/filter-builder-DaWHUZuV.js.map +1 -0
- package/dist/{flow-runtime-D3avVH0I.cjs → flow-runtime-BpmrIUb6.cjs} +61 -29
- package/dist/flow-runtime-BpmrIUb6.cjs.map +1 -0
- package/dist/{flow-runtime-s6lkRPKF.js → flow-runtime-DyqTmK3H.js} +62 -30
- package/dist/flow-runtime-DyqTmK3H.js.map +1 -0
- package/dist/{flow-screen-Ci_Sik4Y.cjs → flow-screen-Bcz9NF2V.cjs} +128 -87
- package/dist/flow-screen-Bcz9NF2V.cjs.map +1 -0
- package/dist/{flow-screen-CCvgDI9G.js → flow-screen-DCdli6Ha.js} +128 -87
- package/dist/flow-screen-DCdli6Ha.js.map +1 -0
- package/dist/index.cjs +731 -906
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +455 -247
- package/dist/index.d.ts +455 -247
- package/dist/index.js +647 -828
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-DV1et3c6.cjs → inline-flow-host-3vw7LzzD.cjs} +5 -5
- package/dist/inline-flow-host-3vw7LzzD.cjs.map +1 -0
- package/dist/{inline-flow-host-B6FI0ctQ.js → inline-flow-host-C0rI9B7f.js} +5 -5
- package/dist/inline-flow-host-C0rI9B7f.js.map +1 -0
- package/dist/{candidates-gate-D33jXLHO.cjs → lazy-relation-picker-dialog-Bt8lrEIu.cjs} +10 -10
- package/dist/lazy-relation-picker-dialog-Bt8lrEIu.cjs.map +1 -0
- package/dist/{candidates-gate-Bb70LPAy.js → lazy-relation-picker-dialog-CAScLPb2.js} +11 -11
- package/dist/lazy-relation-picker-dialog-CAScLPb2.js.map +1 -0
- package/dist/{page-flow-route-i3ZfJ1sd.js → page-flow-route-BHUEpn0I.js} +36 -23
- package/dist/page-flow-route-BHUEpn0I.js.map +1 -0
- package/dist/{page-flow-route-hdnULWqd.cjs → page-flow-route-DS8IVTVH.cjs} +41 -28
- package/dist/page-flow-route-DS8IVTVH.cjs.map +1 -0
- package/dist/{place-node-C5SmIAYU.cjs → place-node-CNb3w-c7.cjs} +1869 -947
- package/dist/place-node-CNb3w-c7.cjs.map +1 -0
- package/dist/{place-node-NraNYKPx.js → place-node-CfzQvh4Y.js} +1824 -926
- package/dist/place-node-CfzQvh4Y.js.map +1 -0
- package/dist/{related-list-cards-BWZ9GfOG.js → related-list-cards-BIqqY69Y.js} +9 -4
- package/dist/{related-list-cards-BWZ9GfOG.js.map → related-list-cards-BIqqY69Y.js.map} +1 -1
- package/dist/{related-list-cards-CFq3meUn.cjs → related-list-cards-CelMxl4q.cjs} +9 -4
- package/dist/{related-list-cards-CFq3meUn.cjs.map → related-list-cards-CelMxl4q.cjs.map} +1 -1
- package/dist/{related-list-timeline-yrPsjA3F.js → related-list-timeline-CRh7xwLD.js} +6 -7
- package/dist/related-list-timeline-CRh7xwLD.js.map +1 -0
- package/dist/{related-list-timeline-CCzl71aA.cjs → related-list-timeline-DsLdi8sv.cjs} +5 -6
- package/dist/related-list-timeline-DsLdi8sv.cjs.map +1 -0
- package/dist/{related-rows-o0_t-Yce.js → related-rows--uP2iKQC.js} +25 -14
- package/dist/related-rows--uP2iKQC.js.map +1 -0
- package/dist/{related-rows-ea43qhhy.cjs → related-rows-MPnLCmPF.cjs} +27 -16
- package/dist/related-rows-MPnLCmPF.cjs.map +1 -0
- package/dist/{search-access-CPPmfuvy.js → relation-create-C43cdPQt.js} +595 -13
- package/dist/relation-create-C43cdPQt.js.map +1 -0
- package/dist/{search-access-Dugvttlg.cjs → relation-create-DDEYcKfw.cjs} +633 -14
- package/dist/relation-create-DDEYcKfw.cjs.map +1 -0
- package/dist/{relation-many-picker-bvkjkv-k.js → relation-many-picker-BJhaEqxz.js} +203 -102
- package/dist/relation-many-picker-BJhaEqxz.js.map +1 -0
- package/dist/{relation-many-picker-C8zFEjwd.cjs → relation-many-picker-DzuGJpEl.cjs} +211 -110
- package/dist/relation-many-picker-DzuGJpEl.cjs.map +1 -0
- package/dist/{relation-picker-Z0ZJJ5uS.js → relation-picker-D-tBBZW_.js} +23 -59
- package/dist/relation-picker-D-tBBZW_.js.map +1 -0
- package/dist/{relation-picker-gag0qSR5.cjs → relation-picker-DaIMzf2H.cjs} +29 -71
- package/dist/relation-picker-DaIMzf2H.cjs.map +1 -0
- package/dist/{relation-picker-dialog-0IzkjmiA.cjs → relation-picker-dialog-9Vg5vvR1.cjs} +133 -35
- package/dist/relation-picker-dialog-9Vg5vvR1.cjs.map +1 -0
- package/dist/{relation-picker-dialog-B6nIiJBf.js → relation-picker-dialog-DoEY8EkH.js} +134 -36
- package/dist/relation-picker-dialog-DoEY8EkH.js.map +1 -0
- package/dist/relation-select-B8Fq4o-t.js +48 -0
- package/dist/relation-select-B8Fq4o-t.js.map +1 -0
- package/dist/relation-select-Cr3CfNLy.cjs +55 -0
- package/dist/relation-select-Cr3CfNLy.cjs.map +1 -0
- package/dist/{resource-page-router-PXfMW9nh.cjs → resource-page-router-C_kGW2o_.cjs} +543 -300
- package/dist/resource-page-router-C_kGW2o_.cjs.map +1 -0
- package/dist/{resource-page-router-3RUf9d1j.js → resource-page-router-Diw6S6TK.js} +498 -255
- package/dist/resource-page-router-Diw6S6TK.js.map +1 -0
- package/dist/{rich-text-vTyVjDoa.cjs → rich-text-C_7JCvRo.cjs} +2 -2
- package/dist/{rich-text-vTyVjDoa.cjs.map → rich-text-C_7JCvRo.cjs.map} +1 -1
- package/dist/{rich-text-DFerywgz.js → rich-text-RcPBf6hr.js} +2 -2
- package/dist/{rich-text-DFerywgz.js.map → rich-text-RcPBf6hr.js.map} +1 -1
- package/dist/success-notices-Dl3M1fZP.cjs +46 -0
- package/dist/success-notices-Dl3M1fZP.cjs.map +1 -0
- package/dist/success-notices-LDEgEkc4.js +41 -0
- package/dist/success-notices-LDEgEkc4.js.map +1 -0
- package/dist/{toaster-Cr51X7bz.cjs → toaster-BbByOytP.cjs} +60 -15
- package/dist/toaster-BbByOytP.cjs.map +1 -0
- package/dist/{toaster-C02XbB9r.js → toaster-Ct_YHGs6.js} +43 -16
- package/dist/toaster-Ct_YHGs6.js.map +1 -0
- package/dist/{use-dialog-filter-state-C--oMAZG.js → use-dialog-filter-state-B_MqzHaT.js} +5 -4
- package/dist/use-dialog-filter-state-B_MqzHaT.js.map +1 -0
- package/dist/{use-dialog-filter-state-Dhe8PcB5.cjs → use-dialog-filter-state-tNvqAAjh.cjs} +6 -5
- package/dist/use-dialog-filter-state-tNvqAAjh.cjs.map +1 -0
- package/package.json +11 -11
- package/dist/bulk-summary-CwSd6Yjb.cjs +0 -108
- package/dist/bulk-summary-CwSd6Yjb.cjs.map +0 -1
- package/dist/bulk-summary-GxMDP4bw.js +0 -108
- package/dist/bulk-summary-GxMDP4bw.js.map +0 -1
- package/dist/candidates-gate-Bb70LPAy.js.map +0 -1
- package/dist/candidates-gate-D33jXLHO.cjs.map +0 -1
- package/dist/check-confirm-dialog--gPFnEeg.cjs.map +0 -1
- package/dist/check-confirm-dialog-bRT8lt0d.js.map +0 -1
- package/dist/dialog-B_rt9S1c.js.map +0 -1
- package/dist/dialog-DRNUq9EA.cjs.map +0 -1
- package/dist/filter-builder-Bhn-dhZV.js.map +0 -1
- package/dist/filter-builder-nXqtM_h4.cjs.map +0 -1
- package/dist/flow-runtime-D3avVH0I.cjs.map +0 -1
- package/dist/flow-runtime-s6lkRPKF.js.map +0 -1
- package/dist/flow-screen-CCvgDI9G.js.map +0 -1
- package/dist/flow-screen-Ci_Sik4Y.cjs.map +0 -1
- package/dist/inline-flow-host-B6FI0ctQ.js.map +0 -1
- package/dist/inline-flow-host-DV1et3c6.cjs.map +0 -1
- package/dist/page-flow-route-hdnULWqd.cjs.map +0 -1
- package/dist/page-flow-route-i3ZfJ1sd.js.map +0 -1
- package/dist/place-node-C5SmIAYU.cjs.map +0 -1
- package/dist/place-node-NraNYKPx.js.map +0 -1
- package/dist/related-list-timeline-CCzl71aA.cjs.map +0 -1
- package/dist/related-list-timeline-yrPsjA3F.js.map +0 -1
- package/dist/related-rows-ea43qhhy.cjs.map +0 -1
- package/dist/related-rows-o0_t-Yce.js.map +0 -1
- package/dist/relation-create-IA40t1hi.cjs +0 -364
- package/dist/relation-create-IA40t1hi.cjs.map +0 -1
- package/dist/relation-create-h6F9B4C4.js +0 -339
- package/dist/relation-create-h6F9B4C4.js.map +0 -1
- package/dist/relation-many-picker-C8zFEjwd.cjs.map +0 -1
- package/dist/relation-many-picker-bvkjkv-k.js.map +0 -1
- package/dist/relation-picker-Z0ZJJ5uS.js.map +0 -1
- package/dist/relation-picker-dialog-0IzkjmiA.cjs.map +0 -1
- package/dist/relation-picker-dialog-B6nIiJBf.js.map +0 -1
- package/dist/relation-picker-gag0qSR5.cjs.map +0 -1
- package/dist/resource-page-router-3RUf9d1j.js.map +0 -1
- package/dist/resource-page-router-PXfMW9nh.cjs.map +0 -1
- package/dist/search-access-CPPmfuvy.js.map +0 -1
- package/dist/search-access-Dugvttlg.cjs.map +0 -1
- package/dist/shell-BPlk8hEa.js +0 -205
- package/dist/shell-BPlk8hEa.js.map +0 -1
- package/dist/shell-DxhlsPwm.cjs +0 -271
- package/dist/shell-DxhlsPwm.cjs.map +0 -1
- package/dist/toaster-C02XbB9r.js.map +0 -1
- package/dist/toaster-Cr51X7bz.cjs.map +0 -1
- package/dist/use-dialog-filter-state-C--oMAZG.js.map +0 -1
- package/dist/use-dialog-filter-state-Dhe8PcB5.cjs.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const require_use_theme = require("./use-theme-DFlpXils.cjs");
|
|
2
|
-
const require_toaster = require("./toaster-
|
|
2
|
+
const require_toaster = require("./toaster-BbByOytP.cjs");
|
|
3
3
|
const require_button = require("./button-BxnnE28H.cjs");
|
|
4
4
|
const require_input = require("./input-BI0czGyI.cjs");
|
|
5
|
-
const
|
|
5
|
+
const require_relation_create = require("./relation-create-DDEYcKfw.cjs");
|
|
6
|
+
const require_skeleton = require("./skeleton-_1gP7wan.cjs");
|
|
6
7
|
let _burojs_core = require("@burojs/core");
|
|
7
8
|
let _burojs_react = require("@burojs/react");
|
|
8
9
|
let _tabler_icons_react = require("@tabler/icons-react");
|
|
@@ -28,6 +29,505 @@ function saveLocale(code, storageKey = _burojs_react.DEFAULT_LANGUAGE_STORAGE_KE
|
|
|
28
29
|
} catch {}
|
|
29
30
|
}
|
|
30
31
|
//#endregion
|
|
32
|
+
//#region src/fields/legacy-field.ts
|
|
33
|
+
const STRING_ITEM = Object.freeze({ type: "string" });
|
|
34
|
+
const LEGACY_KIND_DECLARATIONS = Object.freeze({
|
|
35
|
+
string: { type: "string" },
|
|
36
|
+
text: {
|
|
37
|
+
type: "string",
|
|
38
|
+
format: "text"
|
|
39
|
+
},
|
|
40
|
+
textarea: {
|
|
41
|
+
type: "string",
|
|
42
|
+
format: "textarea"
|
|
43
|
+
},
|
|
44
|
+
code: {
|
|
45
|
+
type: "string",
|
|
46
|
+
format: "code"
|
|
47
|
+
},
|
|
48
|
+
email: {
|
|
49
|
+
type: "string",
|
|
50
|
+
format: "email"
|
|
51
|
+
},
|
|
52
|
+
url: {
|
|
53
|
+
type: "string",
|
|
54
|
+
format: "url"
|
|
55
|
+
},
|
|
56
|
+
uuid: {
|
|
57
|
+
type: "string",
|
|
58
|
+
format: "uuid"
|
|
59
|
+
},
|
|
60
|
+
number: { type: "number" },
|
|
61
|
+
boolean: { type: "boolean" },
|
|
62
|
+
date: {
|
|
63
|
+
type: "string",
|
|
64
|
+
format: "date"
|
|
65
|
+
},
|
|
66
|
+
dateTime: {
|
|
67
|
+
type: "string",
|
|
68
|
+
format: "date-time"
|
|
69
|
+
},
|
|
70
|
+
enum: {
|
|
71
|
+
type: "string",
|
|
72
|
+
format: "enum"
|
|
73
|
+
},
|
|
74
|
+
json: {
|
|
75
|
+
type: "object",
|
|
76
|
+
format: "json"
|
|
77
|
+
},
|
|
78
|
+
richText: {
|
|
79
|
+
type: "string",
|
|
80
|
+
format: "rich-text"
|
|
81
|
+
},
|
|
82
|
+
file: {
|
|
83
|
+
type: "array",
|
|
84
|
+
format: "file",
|
|
85
|
+
items: STRING_ITEM
|
|
86
|
+
},
|
|
87
|
+
relation: { type: "relation" },
|
|
88
|
+
relationMany: {
|
|
89
|
+
type: "array",
|
|
90
|
+
format: "relation",
|
|
91
|
+
items: STRING_ITEM
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
const SEMANTIC_KEYS = Object.freeze([
|
|
95
|
+
"type",
|
|
96
|
+
"format",
|
|
97
|
+
"meta",
|
|
98
|
+
"required",
|
|
99
|
+
"nullable",
|
|
100
|
+
"empty",
|
|
101
|
+
"default",
|
|
102
|
+
"constraints",
|
|
103
|
+
"texts",
|
|
104
|
+
"options",
|
|
105
|
+
"items",
|
|
106
|
+
"properties",
|
|
107
|
+
"additionalProperties",
|
|
108
|
+
"variants"
|
|
109
|
+
]);
|
|
110
|
+
function ownData(value, key) {
|
|
111
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") return { present: false };
|
|
112
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
113
|
+
if (descriptor === void 0 || !Object.prototype.propertyIsEnumerable.call(value, key) || !("value" in descriptor)) return { present: false };
|
|
114
|
+
return {
|
|
115
|
+
present: true,
|
|
116
|
+
value: descriptor.value
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function ownString(value, key) {
|
|
120
|
+
const candidate = ownData(value, key).value;
|
|
121
|
+
return typeof candidate === "string" && candidate.length > 0 ? candidate : void 0;
|
|
122
|
+
}
|
|
123
|
+
function ownSelection(value, key) {
|
|
124
|
+
const candidate = ownData(value, key).value;
|
|
125
|
+
if (typeof candidate === "string") return candidate.length > 0 ? candidate : void 0;
|
|
126
|
+
return candidate !== null && typeof candidate === "object" && !Array.isArray(candidate) ? candidate : void 0;
|
|
127
|
+
}
|
|
128
|
+
function projectUiSelection(input) {
|
|
129
|
+
const selection = {};
|
|
130
|
+
const inputId = ownSelection(input, "input");
|
|
131
|
+
const displayId = ownSelection(input, "display");
|
|
132
|
+
if (inputId !== void 0) selection.input = inputId;
|
|
133
|
+
if (displayId !== void 0) selection.display = displayId;
|
|
134
|
+
return inputId === void 0 && displayId === void 0 ? void 0 : Object.freeze(selection);
|
|
135
|
+
}
|
|
136
|
+
function projectFieldDeclaration(input) {
|
|
137
|
+
const type = ownString(input, "type");
|
|
138
|
+
if (type === void 0) return void 0;
|
|
139
|
+
const projected = { type };
|
|
140
|
+
for (const key of SEMANTIC_KEYS) {
|
|
141
|
+
if (key === "type" || key === "items" || key === "properties" || key === "variants") continue;
|
|
142
|
+
const candidate = ownData(input, key);
|
|
143
|
+
if (candidate.present && candidate.value !== void 0) projected[key] = candidate.value;
|
|
144
|
+
}
|
|
145
|
+
const ui = projectUiSelection(ownData(input, "ui").value);
|
|
146
|
+
if (ui !== void 0) projected.ui = ui;
|
|
147
|
+
if (type === "array") {
|
|
148
|
+
const item = projectFieldDeclaration(ownData(input, "items").value);
|
|
149
|
+
if (item !== void 0) projected.items = item;
|
|
150
|
+
}
|
|
151
|
+
if (type === "object") {
|
|
152
|
+
const properties = ownData(input, "properties").value;
|
|
153
|
+
if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
|
|
154
|
+
const output = {};
|
|
155
|
+
for (const key of Object.keys(properties)) {
|
|
156
|
+
const child = projectFieldDeclaration(ownData(properties, key).value);
|
|
157
|
+
if (child !== void 0) output[key] = child;
|
|
158
|
+
}
|
|
159
|
+
projected.properties = Object.freeze(output);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (type === "union") {
|
|
163
|
+
const variants = ownData(input, "variants").value;
|
|
164
|
+
if (Array.isArray(variants)) {
|
|
165
|
+
const output = [];
|
|
166
|
+
for (let index = 0; index < variants.length; index += 1) {
|
|
167
|
+
const child = projectFieldDeclaration(ownData(variants, index).value);
|
|
168
|
+
if (child !== void 0) output.push(child);
|
|
169
|
+
}
|
|
170
|
+
projected.variants = Object.freeze(output);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return Object.freeze(projected);
|
|
174
|
+
}
|
|
175
|
+
function projectUiHints(input) {
|
|
176
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
177
|
+
const projected = {};
|
|
178
|
+
for (const key of Object.keys(input)) {
|
|
179
|
+
const candidate = ownData(input, key);
|
|
180
|
+
if (candidate.present) projected[key] = candidate.value;
|
|
181
|
+
}
|
|
182
|
+
return Object.freeze(projected);
|
|
183
|
+
}
|
|
184
|
+
function enumValueOptions(field) {
|
|
185
|
+
const own = ownData(field, "values").value;
|
|
186
|
+
const values = Array.isArray(own) ? own : ownData(ownData(field, "ui").value, "values").value;
|
|
187
|
+
if (!Array.isArray(values)) return void 0;
|
|
188
|
+
const options = values.filter((value) => typeof value === "string").map((value) => Object.freeze({ value }));
|
|
189
|
+
return options.length === 0 ? void 0 : Object.freeze(options);
|
|
190
|
+
}
|
|
191
|
+
function lowerLegacyField(field) {
|
|
192
|
+
const declaration = projectFieldDeclaration(ownData(field, "declaration").value);
|
|
193
|
+
if (declaration !== void 0) return declaration;
|
|
194
|
+
const direct = projectFieldDeclaration(field);
|
|
195
|
+
const kind = ownString(field, "kind");
|
|
196
|
+
const mapping = kind === void 0 ? void 0 : LEGACY_KIND_DECLARATIONS[kind];
|
|
197
|
+
if (direct !== void 0) {
|
|
198
|
+
const format = direct.format ?? mapping?.format ?? kind;
|
|
199
|
+
return format === void 0 ? direct : Object.freeze({
|
|
200
|
+
...direct,
|
|
201
|
+
format
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
const ui = projectUiHints(ownData(field, "ui").value);
|
|
205
|
+
const type = kind === "file" && ui?.multiple !== true ? "unknown" : mapping?.type ?? "unknown";
|
|
206
|
+
const format = ownString(field, "format") ?? mapping?.format ?? kind;
|
|
207
|
+
const items = type === "array" ? projectFieldDeclaration(ownData(field, "items").value) ?? mapping?.items ?? STRING_ITEM : void 0;
|
|
208
|
+
const meta = ownData(field, "meta");
|
|
209
|
+
const texts = ownData(field, "texts");
|
|
210
|
+
const options = kind === "enum" ? enumValueOptions(field) : void 0;
|
|
211
|
+
const required = ownData(field, "required");
|
|
212
|
+
const nullable = ownData(field, "nullable");
|
|
213
|
+
const opts = ownData(field, "opts").value;
|
|
214
|
+
const optionRequired = ownData(opts, "required");
|
|
215
|
+
const optionNullable = ownData(opts, "nullable");
|
|
216
|
+
const requiredValue = required.present ? required.value : optionRequired.value;
|
|
217
|
+
const nullableValue = nullable.present ? nullable.value : optionNullable.value;
|
|
218
|
+
return Object.freeze({
|
|
219
|
+
type,
|
|
220
|
+
...format === void 0 ? {} : { format },
|
|
221
|
+
...items === void 0 ? {} : { items },
|
|
222
|
+
...meta.present && meta.value !== void 0 ? { meta: meta.value } : {},
|
|
223
|
+
...options === void 0 ? {} : { options },
|
|
224
|
+
...texts.present && texts.value !== void 0 ? { texts: texts.value } : {},
|
|
225
|
+
...requiredValue === true ? { required: true } : {},
|
|
226
|
+
...nullableValue === true ? { nullable: true } : {}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function lowerLegacyFieldSource(field) {
|
|
230
|
+
const declaration = lowerLegacyField(field);
|
|
231
|
+
const ui = projectUiHints(ownData(field, "ui").value);
|
|
232
|
+
if (ui === void 0) return declaration;
|
|
233
|
+
return Object.freeze({
|
|
234
|
+
...declaration,
|
|
235
|
+
ui
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function fieldDescription(field) {
|
|
239
|
+
const declaration = field?.declaration;
|
|
240
|
+
return (0, _burojs_core.declaredText)("field", declaration, "description") ?? (0, _burojs_core.declaredText)("field", field, "description");
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/fields/resolved-field.tsx
|
|
244
|
+
const EMPTY = Object.freeze({});
|
|
245
|
+
const EMPTY_ISSUES = Object.freeze([]);
|
|
246
|
+
const EMPTY_OPTIONS = Object.freeze([]);
|
|
247
|
+
function canonical(field) {
|
|
248
|
+
return lowerLegacyField(field);
|
|
249
|
+
}
|
|
250
|
+
function useLoweredField(source) {
|
|
251
|
+
return (0, react.useMemo)(() => {
|
|
252
|
+
const sourceAtEdge = lowerLegacyFieldSource(source);
|
|
253
|
+
return {
|
|
254
|
+
sourceAtEdge,
|
|
255
|
+
field: canonical(sourceAtEdge),
|
|
256
|
+
ui: sourceAtEdge.ui ?? EMPTY
|
|
257
|
+
};
|
|
258
|
+
}, [source]);
|
|
259
|
+
}
|
|
260
|
+
const warnedObjectLabels = new Set();
|
|
261
|
+
function optionsFor(field, name) {
|
|
262
|
+
if (Array.isArray(field.options)) return field.options;
|
|
263
|
+
const candidate = field.meta?.options;
|
|
264
|
+
if (!Array.isArray(candidate)) return EMPTY_OPTIONS;
|
|
265
|
+
const output = [];
|
|
266
|
+
for (const item of candidate) {
|
|
267
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) continue;
|
|
268
|
+
const raw = item;
|
|
269
|
+
if (typeof raw.value !== "string" && typeof raw.value !== "number" && typeof raw.value !== "boolean" && raw.value !== null) continue;
|
|
270
|
+
const { value, label, description, ...legacyMeta } = raw;
|
|
271
|
+
if (typeof label !== "string" && process.env.NODE_ENV !== "production" && !warnedObjectLabels.has(`${name}:${value}`)) {
|
|
272
|
+
warnedObjectLabels.add(`${name}:${value}`);
|
|
273
|
+
console.warn(`[buro/ui-shadcn] field '${name}': option '${value}' has a non-string label, so it renders its raw value. Declare a plain string label and put the translations under fields.${name}.options.${value} (see docs/i18n-guide.md).`);
|
|
274
|
+
}
|
|
275
|
+
output.push(Object.freeze({
|
|
276
|
+
value,
|
|
277
|
+
label: typeof label === "string" ? label : String(value),
|
|
278
|
+
...typeof description === "string" ? { description } : {},
|
|
279
|
+
...Object.keys(legacyMeta).length === 0 ? {} : { meta: Object.freeze(legacyMeta) }
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
return Object.freeze(output);
|
|
283
|
+
}
|
|
284
|
+
function useContextOptions(field, name, meta, ui, resource) {
|
|
285
|
+
const legacy = field.meta?.options;
|
|
286
|
+
const options = (0, react.useMemo)(() => optionsFor(field, name), [
|
|
287
|
+
field.options,
|
|
288
|
+
legacy,
|
|
289
|
+
name
|
|
290
|
+
]);
|
|
291
|
+
return (0, _burojs_react.useResolvedFieldOptions)({
|
|
292
|
+
name,
|
|
293
|
+
meta,
|
|
294
|
+
ui,
|
|
295
|
+
texts: field.texts
|
|
296
|
+
}, options, resource.id);
|
|
297
|
+
}
|
|
298
|
+
function useContextTexts(field, name, resolved, resource) {
|
|
299
|
+
return (0, _burojs_react.useImplementationTexts)({
|
|
300
|
+
fieldName: name,
|
|
301
|
+
fieldTexts: field.texts,
|
|
302
|
+
id: resolved.id,
|
|
303
|
+
implementation: resolved.implementation
|
|
304
|
+
}, resource.id);
|
|
305
|
+
}
|
|
306
|
+
function useFieldRuntimeContext(resource, record, values, metaSources) {
|
|
307
|
+
const locale = (0, _burojs_react.useLocale)();
|
|
308
|
+
const caps = (0, _burojs_react.useI18nCaps)((0, _burojs_core.canonicalResourceKey)(resource));
|
|
309
|
+
const metaSourcesOut = (0, _burojs_react.useFieldMetaSources)({
|
|
310
|
+
record,
|
|
311
|
+
values,
|
|
312
|
+
extra: metaSources
|
|
313
|
+
});
|
|
314
|
+
const scopeState = metaSourcesOut.scope;
|
|
315
|
+
const scope = scopeState === void 0 ? void 0 : (0, _burojs_react.scopeValueOf)(scopeState);
|
|
316
|
+
return (0, react.useMemo)(() => Object.freeze({
|
|
317
|
+
i18n: Object.freeze({
|
|
318
|
+
locale,
|
|
319
|
+
has: caps.has,
|
|
320
|
+
t: caps.t
|
|
321
|
+
}),
|
|
322
|
+
sources: Object.freeze({
|
|
323
|
+
record: record ?? EMPTY,
|
|
324
|
+
values: values ?? EMPTY,
|
|
325
|
+
scope: scope ?? EMPTY
|
|
326
|
+
}),
|
|
327
|
+
metaSources: metaSourcesOut
|
|
328
|
+
}), [
|
|
329
|
+
caps,
|
|
330
|
+
locale,
|
|
331
|
+
record,
|
|
332
|
+
scope,
|
|
333
|
+
values,
|
|
334
|
+
metaSourcesOut
|
|
335
|
+
]);
|
|
336
|
+
}
|
|
337
|
+
function useFieldMetaDiagnostic(state, resource, name, field, surface, entry) {
|
|
338
|
+
const reported = (0, react.useRef)(void 0);
|
|
339
|
+
const reason = state.status === "failed" ? state.reason : void 0;
|
|
340
|
+
(0, react.useEffect)(() => {
|
|
341
|
+
if (reason === void 0 || reported.current === reason || process.env.NODE_ENV === "production") return;
|
|
342
|
+
reported.current = reason;
|
|
343
|
+
const implementation = (0, _burojs_core.resolveSurfaceUi)(field, surface, entry).use ?? field.format ?? field.type;
|
|
344
|
+
console.error(`[burojs] field.meta-invalid: ${(0, _burojs_core.formatEntityRef)(resource)}.${name} (${implementation}): ${reason}`);
|
|
345
|
+
}, [
|
|
346
|
+
reason,
|
|
347
|
+
resource,
|
|
348
|
+
name,
|
|
349
|
+
field,
|
|
350
|
+
surface,
|
|
351
|
+
entry
|
|
352
|
+
]);
|
|
353
|
+
}
|
|
354
|
+
function MetaPlaceholder({ state }) {
|
|
355
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
356
|
+
if (state.status === "pending") return (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, {
|
|
357
|
+
"data-buro-skeleton": "",
|
|
358
|
+
"data-buro-field-meta": "pending",
|
|
359
|
+
className: "h-9 w-full"
|
|
360
|
+
});
|
|
361
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
362
|
+
role: "alert",
|
|
363
|
+
"data-buro-field-meta": "failed",
|
|
364
|
+
className: "rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground",
|
|
365
|
+
children: t("field.misconfigured", { defaultValue: "This field is misconfigured" })
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
function useFieldImplementationDiagnostic(diagnostic) {
|
|
369
|
+
const reported = (0, react.useRef)(void 0);
|
|
370
|
+
(0, react.useEffect)(() => {
|
|
371
|
+
if (diagnostic === void 0 || reported.current === diagnostic || process.env.NODE_ENV === "production") return;
|
|
372
|
+
reported.current = diagnostic;
|
|
373
|
+
console.warn("[buro/ui-shadcn] missing-field-implementation; rendering fallback.", diagnostic);
|
|
374
|
+
}, [diagnostic]);
|
|
375
|
+
}
|
|
376
|
+
function ResolvedFieldDisplay({ resource, name, field: source, value, record, testId, fallback, presentation, metaSources, uiSurface = "display", columnEntry }) {
|
|
377
|
+
const { sourceAtEdge, field, ui } = useLoweredField(source);
|
|
378
|
+
const surfaceField = (0, react.useMemo)(() => sourceAtEdge.ui === void 0 ? field : Object.freeze({
|
|
379
|
+
...field,
|
|
380
|
+
ui
|
|
381
|
+
}), [
|
|
382
|
+
sourceAtEdge,
|
|
383
|
+
field,
|
|
384
|
+
ui
|
|
385
|
+
]);
|
|
386
|
+
const resolved = (0, _burojs_react.useFieldImplementation)({
|
|
387
|
+
field: surfaceField,
|
|
388
|
+
surface: "display",
|
|
389
|
+
uiSurface,
|
|
390
|
+
...columnEntry === void 0 ? {} : { uiEntry: columnEntry }
|
|
391
|
+
});
|
|
392
|
+
const runtimeContext = useFieldRuntimeContext(resource, record, record, metaSources);
|
|
393
|
+
const metaState = (0, _burojs_react.useFieldMeta)(field, resolved.implementation, runtimeContext.metaSources, resolved.params);
|
|
394
|
+
const textField = (0, react.useMemo)(() => Object.freeze({
|
|
395
|
+
...surfaceField,
|
|
396
|
+
name
|
|
397
|
+
}), [surfaceField, name]);
|
|
398
|
+
const text = (0, _burojs_react.useFieldDisplayText)(textField, value, {
|
|
399
|
+
surface: uiSurface,
|
|
400
|
+
...columnEntry === void 0 ? {} : { entry: columnEntry },
|
|
401
|
+
resource: (0, _burojs_core.canonicalResourceKey)(resource)
|
|
402
|
+
});
|
|
403
|
+
const options = useContextOptions(field, name, metaState.status === "ready" ? metaState.meta : void 0, ui, resource);
|
|
404
|
+
const texts = useContextTexts(field, name, resolved, resource);
|
|
405
|
+
useFieldMetaDiagnostic(metaState, resource, name, surfaceField, uiSurface, columnEntry);
|
|
406
|
+
useFieldImplementationDiagnostic(resolved.diagnostic);
|
|
407
|
+
if (resolved.Component === void 0) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: fallback });
|
|
408
|
+
if (metaState.status !== "ready") return (0, react_jsx_runtime.jsx)(MetaPlaceholder, { state: metaState });
|
|
409
|
+
const Component = resolved.Component;
|
|
410
|
+
const context = {
|
|
411
|
+
owner: resource,
|
|
412
|
+
resource,
|
|
413
|
+
field,
|
|
414
|
+
path: Object.freeze([name]),
|
|
415
|
+
surface: "display",
|
|
416
|
+
presentation: presentation ?? "default",
|
|
417
|
+
record,
|
|
418
|
+
meta: metaState.meta,
|
|
419
|
+
ui,
|
|
420
|
+
options,
|
|
421
|
+
texts,
|
|
422
|
+
...text === void 0 ? {} : { text },
|
|
423
|
+
i18n: runtimeContext.i18n,
|
|
424
|
+
sources: runtimeContext.sources,
|
|
425
|
+
pending: false,
|
|
426
|
+
touched: false,
|
|
427
|
+
issues: EMPTY_ISSUES,
|
|
428
|
+
accessibility: EMPTY,
|
|
429
|
+
testIds: testId === void 0 ? EMPTY : Object.freeze({ display: testId })
|
|
430
|
+
};
|
|
431
|
+
if (resolved.multiple) return (0, react.createElement)(Component, {
|
|
432
|
+
...context,
|
|
433
|
+
multiple: true,
|
|
434
|
+
value: Array.isArray(value) ? value : []
|
|
435
|
+
});
|
|
436
|
+
return (0, react.createElement)(Component, {
|
|
437
|
+
...context,
|
|
438
|
+
multiple: false,
|
|
439
|
+
value
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
function ResolvedFieldInput({ resource, name, field: source, value, record, form, testId, inputId, onChange, onBlur, disabled, required, placeholder, descriptionId, labelId, errorId, errorMessage, pending = false, touched = errorMessage != null, issues: suppliedIssues, relationSeeds, fixedFilters, link, metaSources, fallback }) {
|
|
443
|
+
const { sourceAtEdge, field: base } = useLoweredField(source);
|
|
444
|
+
const field = (0, react.useMemo)(() => required === void 0 || required === base.required ? base : Object.freeze({
|
|
445
|
+
...base,
|
|
446
|
+
required
|
|
447
|
+
}), [base, required]);
|
|
448
|
+
const ui = (0, react.useMemo)(() => Object.freeze({
|
|
449
|
+
...sourceAtEdge.ui ?? EMPTY,
|
|
450
|
+
...placeholder === void 0 ? {} : { placeholder }
|
|
451
|
+
}), [sourceAtEdge, placeholder]);
|
|
452
|
+
const inputField = (0, react.useMemo)(() => ({
|
|
453
|
+
...field,
|
|
454
|
+
ui
|
|
455
|
+
}), [field, ui]);
|
|
456
|
+
const resolved = (0, _burojs_react.useFieldImplementation)({
|
|
457
|
+
field: inputField,
|
|
458
|
+
surface: "input"
|
|
459
|
+
});
|
|
460
|
+
const runtimeContext = useFieldRuntimeContext(resource, record, form, metaSources);
|
|
461
|
+
const metaState = (0, _burojs_react.useFieldMeta)(field, resolved.implementation, runtimeContext.metaSources, resolved.params);
|
|
462
|
+
const options = useContextOptions(field, name, metaState.status === "ready" ? metaState.meta : void 0, ui, resource);
|
|
463
|
+
const texts = useContextTexts(field, name, resolved, resource);
|
|
464
|
+
useFieldMetaDiagnostic(metaState, resource, name, inputField, "input");
|
|
465
|
+
useFieldImplementationDiagnostic(resolved.diagnostic);
|
|
466
|
+
if (resolved.Component === void 0) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: fallback });
|
|
467
|
+
if (metaState.status !== "ready") return (0, react_jsx_runtime.jsx)(MetaPlaceholder, { state: metaState });
|
|
468
|
+
const Component = resolved.Component;
|
|
469
|
+
const issues = suppliedIssues ?? (errorMessage == null ? EMPTY_ISSUES : Object.freeze([Object.freeze({
|
|
470
|
+
code: "ui.field-error",
|
|
471
|
+
message: {
|
|
472
|
+
key: "ui.field-error",
|
|
473
|
+
default: errorMessage
|
|
474
|
+
},
|
|
475
|
+
path: Object.freeze([]),
|
|
476
|
+
source: "field",
|
|
477
|
+
severity: "error"
|
|
478
|
+
})]));
|
|
479
|
+
const context = {
|
|
480
|
+
owner: resource,
|
|
481
|
+
resource,
|
|
482
|
+
field,
|
|
483
|
+
path: Object.freeze([name]),
|
|
484
|
+
surface: "input",
|
|
485
|
+
presentation: "default",
|
|
486
|
+
record,
|
|
487
|
+
form,
|
|
488
|
+
meta: metaState.meta,
|
|
489
|
+
ui,
|
|
490
|
+
options,
|
|
491
|
+
texts,
|
|
492
|
+
i18n: runtimeContext.i18n,
|
|
493
|
+
sources: runtimeContext.sources,
|
|
494
|
+
pending,
|
|
495
|
+
touched,
|
|
496
|
+
issues,
|
|
497
|
+
accessibility: Object.freeze({
|
|
498
|
+
input: inputId ?? name,
|
|
499
|
+
label: labelId,
|
|
500
|
+
description: descriptionId,
|
|
501
|
+
error: errorId
|
|
502
|
+
}),
|
|
503
|
+
testIds: testId === void 0 ? EMPTY : Object.freeze({ input: testId })
|
|
504
|
+
};
|
|
505
|
+
if (resolved.multiple) return (0, react.createElement)(Component, {
|
|
506
|
+
...context,
|
|
507
|
+
multiple: true,
|
|
508
|
+
value: Array.isArray(value) ? value : [],
|
|
509
|
+
onChange,
|
|
510
|
+
onBlur,
|
|
511
|
+
disabled,
|
|
512
|
+
relationSeeds,
|
|
513
|
+
fixedFilters,
|
|
514
|
+
link,
|
|
515
|
+
metaSources: runtimeContext.metaSources
|
|
516
|
+
});
|
|
517
|
+
return (0, react.createElement)(Component, {
|
|
518
|
+
...context,
|
|
519
|
+
multiple: false,
|
|
520
|
+
value,
|
|
521
|
+
onChange,
|
|
522
|
+
onBlur,
|
|
523
|
+
disabled,
|
|
524
|
+
relationSeeds,
|
|
525
|
+
fixedFilters,
|
|
526
|
+
link,
|
|
527
|
+
metaSources: runtimeContext.metaSources
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
//#endregion
|
|
31
531
|
//#region src/primitives/badge.tsx
|
|
32
532
|
const badgeVariants = (0, class_variance_authority.cva)("inline-flex max-w-full items-center truncate rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
33
533
|
variants: { variant: {
|
|
@@ -105,11 +605,11 @@ const SelectGroup = _radix_ui_react_select.Group;
|
|
|
105
605
|
const SelectValue = _radix_ui_react_select.Value;
|
|
106
606
|
const SelectTrigger = react.forwardRef(({ className, children, ...props }, ref) => (0, react_jsx_runtime.jsxs)(_radix_ui_react_select.Trigger, {
|
|
107
607
|
ref,
|
|
108
|
-
className: require_use_theme.cn("flex h-9 w-full items-center justify-between rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-input-disabled [&>span]:
|
|
608
|
+
className: require_use_theme.cn("flex h-9 w-full items-center justify-between rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-input-disabled [&>span]:block [&>span]:truncate [&>span]:min-w-0 [&>span]:max-h-[1lh] [&>span]:overflow-hidden [&>span]:text-left", className),
|
|
109
609
|
...props,
|
|
110
610
|
children: [children, (0, react_jsx_runtime.jsx)(_radix_ui_react_select.Icon, {
|
|
111
611
|
asChild: true,
|
|
112
|
-
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconChevronDown, { className: "h-4 w-4 opacity-50" })
|
|
612
|
+
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconChevronDown, { className: "h-4 w-4 shrink-0 opacity-50" })
|
|
113
613
|
})]
|
|
114
614
|
}));
|
|
115
615
|
SelectTrigger.displayName = _radix_ui_react_select.Trigger.displayName;
|
|
@@ -148,15 +648,24 @@ const SelectLabel = react.forwardRef(({ className, ...props }, ref) => (0, react
|
|
|
148
648
|
...props
|
|
149
649
|
}));
|
|
150
650
|
SelectLabel.displayName = _radix_ui_react_select.Label.displayName;
|
|
151
|
-
const SelectItem = react.forwardRef(({ className, children, ...props }, ref) =>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
158
|
-
|
|
159
|
-
}))
|
|
651
|
+
const SelectItem = react.forwardRef(({ className, children, description, ...props }, ref) => {
|
|
652
|
+
const hasDescription = description !== void 0 && description !== null;
|
|
653
|
+
return (0, react_jsx_runtime.jsxs)(_radix_ui_react_select.Item, {
|
|
654
|
+
ref,
|
|
655
|
+
className: require_use_theme.cn("relative flex w-full cursor-default select-none rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", hasDescription ? "items-start" : "items-center", className),
|
|
656
|
+
...props,
|
|
657
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
658
|
+
className: require_use_theme.cn("absolute left-2 flex h-3.5 w-3.5 items-center justify-center", hasDescription && "top-[9px]"),
|
|
659
|
+
children: (0, react_jsx_runtime.jsx)(_radix_ui_react_select.ItemIndicator, { children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, { className: "h-4 w-4" }) })
|
|
660
|
+
}), !hasDescription ? (0, react_jsx_runtime.jsx)(_radix_ui_react_select.ItemText, { children }) : (0, react_jsx_runtime.jsxs)("span", {
|
|
661
|
+
className: "flex min-w-0 flex-col gap-0.5",
|
|
662
|
+
children: [(0, react_jsx_runtime.jsx)(_radix_ui_react_select.ItemText, { children }), (0, react_jsx_runtime.jsx)("span", {
|
|
663
|
+
className: "text-xs leading-snug text-muted-foreground",
|
|
664
|
+
children: description
|
|
665
|
+
})]
|
|
666
|
+
})]
|
|
667
|
+
});
|
|
668
|
+
});
|
|
160
669
|
SelectItem.displayName = _radix_ui_react_select.Item.displayName;
|
|
161
670
|
const SelectSeparator = react.forwardRef(({ className, ...props }, ref) => (0, react_jsx_runtime.jsx)(_radix_ui_react_select.Separator, {
|
|
162
671
|
ref,
|
|
@@ -209,9 +718,9 @@ function formatNumber(n, locale) {
|
|
|
209
718
|
//#endregion
|
|
210
719
|
//#region src/list-kit/filter-builder/describe-row.ts
|
|
211
720
|
const MAX_DESCRIBE_DEPTH = 2;
|
|
212
|
-
function describeValue(value,
|
|
721
|
+
function describeValue(value, chromeT, spec, formatValue) {
|
|
213
722
|
if (value === void 0) return null;
|
|
214
|
-
if (Array.isArray(value)) return
|
|
723
|
+
if (Array.isArray(value)) return chromeT("filters.selectedCount", { count: value.length }, `${value.length} selected`);
|
|
215
724
|
const optionLabel = spec?.options?.find((o) => o.value === String(value))?.label;
|
|
216
725
|
if (optionLabel !== void 0) return optionLabel;
|
|
217
726
|
if (spec && formatValue) {
|
|
@@ -220,20 +729,20 @@ function describeValue(value, t, spec, formatValue) {
|
|
|
220
729
|
}
|
|
221
730
|
return String(value);
|
|
222
731
|
}
|
|
223
|
-
function describeAt(row, available,
|
|
732
|
+
function describeAt(row, available, chromeT, depth, formatValue) {
|
|
224
733
|
if ((0, _burojs_core.isFilterGroup)(row)) {
|
|
225
734
|
if (depth > MAX_DESCRIBE_DEPTH) return "…";
|
|
226
|
-
const joinLabel =
|
|
227
|
-
return `(${row.rows.map((child) => describeAt(child, available,
|
|
735
|
+
const joinLabel = chromeT(`filters.${row.join}`, void 0, row.join);
|
|
736
|
+
return `(${row.rows.map((child) => describeAt(child, available, chromeT, depth + 1, formatValue)).join(` ${joinLabel} `)})`;
|
|
228
737
|
}
|
|
229
738
|
const spec = available.find((s) => s.field === row.field);
|
|
230
739
|
const label = spec?.label ?? row.field;
|
|
231
|
-
const opLabel =
|
|
232
|
-
const valueText = (0, _burojs_core.opArity)(row.op) === "none" ? null : describeValue(row.value,
|
|
740
|
+
const opLabel = chromeT(`filters.operators.${row.op}`, void 0, row.op);
|
|
741
|
+
const valueText = (0, _burojs_core.opArity)(row.op) === "none" ? null : describeValue(row.value, chromeT, spec, formatValue);
|
|
233
742
|
return valueText === null ? `${label} ${opLabel}` : `${label} ${opLabel} ${valueText}`;
|
|
234
743
|
}
|
|
235
|
-
function describeRow(row, available,
|
|
236
|
-
return describeAt(row, available,
|
|
744
|
+
function describeRow(row, available, chromeT, formatValue) {
|
|
745
|
+
return describeAt(row, available, chromeT, 1, formatValue);
|
|
237
746
|
}
|
|
238
747
|
function relationLabelKey(to, by, value) {
|
|
239
748
|
return `${by === void 0 ? to : `${to}#${by}`}::${value}`;
|
|
@@ -296,7 +805,7 @@ function RelationLabelResolver(props) {
|
|
|
296
805
|
const { to, id, by, onResolve } = props;
|
|
297
806
|
const targetDef = (0, _burojs_react.useApp)().registry.get(to);
|
|
298
807
|
const { record } = (0, _burojs_react.useRelatedRecord)(to, id, by === void 0 ? void 0 : { by });
|
|
299
|
-
const rowTitle =
|
|
808
|
+
const rowTitle = require_relation_create.useRowTitle(to, targetDef?.displayField);
|
|
300
809
|
(0, react.useEffect)(() => {
|
|
301
810
|
if (!record) return;
|
|
302
811
|
onResolve(relationLabelKey(to, by, id), rowTitle(record));
|
|
@@ -366,15 +875,18 @@ function badgeKey(row, index) {
|
|
|
366
875
|
if ((0, _burojs_core.isFilterGroup)(row)) return `${index}:group:${row.join}`;
|
|
367
876
|
return `${index}:${row.field}:${row.op}`;
|
|
368
877
|
}
|
|
878
|
+
const BADGE_ROW = "inline-flex max-w-full items-center gap-1 align-middle";
|
|
879
|
+
const REMOVE_BUTTON = "inline-flex size-4 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-foreground/10 hover:text-foreground focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring";
|
|
369
880
|
function FilterBadges(props) {
|
|
370
881
|
const { group, setGroup, available, fixed, testIdBase, onOpenAt, onRemoved, pinnedFields = [], pinnedValue = [], setPinnedValue } = props;
|
|
371
|
-
const
|
|
372
|
-
const
|
|
882
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
883
|
+
const locale = (0, _burojs_react.useOptionalLocale)();
|
|
884
|
+
const tt = (key, params, fallback) => chromeT(key, {
|
|
373
885
|
params,
|
|
374
886
|
...typeof params?.count === "number" ? { count: params.count } : {},
|
|
375
887
|
defaultValue: fallback
|
|
376
888
|
});
|
|
377
|
-
const removeLabel =
|
|
889
|
+
const removeLabel = chromeT("filters.removeRow", { defaultValue: "Remove filter" });
|
|
378
890
|
const { enumLabels, relationLabels, onEnumResolved, onRelationResolved } = useFormatValueMaps();
|
|
379
891
|
const formatValue = (kind, value) => {
|
|
380
892
|
if (kind.kind === "enum") return enumLabels[kind.enumName]?.[String(value)];
|
|
@@ -382,7 +894,7 @@ function FilterBadges(props) {
|
|
|
382
894
|
if (kind.kind === "date") {
|
|
383
895
|
const d = new Date(String(value));
|
|
384
896
|
if (Number.isNaN(d.getTime())) return void 0;
|
|
385
|
-
return kind.time ? formatDateTime(d) : formatDate(d);
|
|
897
|
+
return kind.time ? formatDateTime(d, locale) : formatDate(d, locale);
|
|
386
898
|
}
|
|
387
899
|
};
|
|
388
900
|
const orphanPinned = (0, react.useMemo)(() => {
|
|
@@ -416,49 +928,56 @@ function FilterBadges(props) {
|
|
|
416
928
|
onEnumResolved,
|
|
417
929
|
onRelationResolved
|
|
418
930
|
}),
|
|
419
|
-
group.rows.map((row, index) => (0, react_jsx_runtime.
|
|
931
|
+
group.rows.map((row, index) => (0, react_jsx_runtime.jsx)(Badge, {
|
|
420
932
|
variant: "secondary",
|
|
421
|
-
className: "
|
|
422
|
-
children:
|
|
423
|
-
|
|
424
|
-
"
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
"
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
className:
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
933
|
+
className: "py-1 pr-1",
|
|
934
|
+
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
935
|
+
className: BADGE_ROW,
|
|
936
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
937
|
+
type: "button",
|
|
938
|
+
"data-testid": `${testIdBase}:badge:${index}`,
|
|
939
|
+
onClick: () => onOpenAt([index]),
|
|
940
|
+
className: "min-w-0 cursor-pointer truncate bg-transparent p-0 text-left",
|
|
941
|
+
children: describeRow(row, available, tt, formatValue)
|
|
942
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
943
|
+
type: "button",
|
|
944
|
+
"data-testid": `${testIdBase}:badge:${index}:remove`,
|
|
945
|
+
"aria-label": removeLabel,
|
|
946
|
+
onClick: () => handleRemove(index),
|
|
947
|
+
className: REMOVE_BUTTON,
|
|
948
|
+
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconX, {
|
|
949
|
+
className: "size-3",
|
|
950
|
+
"aria-hidden": "true"
|
|
951
|
+
})
|
|
952
|
+
})]
|
|
953
|
+
})
|
|
439
954
|
}, badgeKey(row, index))),
|
|
440
955
|
labelledFixed.map((entry, index) => (0, react_jsx_runtime.jsx)(Badge, {
|
|
441
956
|
variant: "outline",
|
|
442
957
|
"data-testid": `${testIdBase}:badge:fixed:${index}`,
|
|
443
958
|
children: entry.label
|
|
444
959
|
}, `fixed-${index}`)),
|
|
445
|
-
orphanPinned.map(({ expr, index }) => (0, react_jsx_runtime.
|
|
960
|
+
orphanPinned.map(({ expr, index }) => (0, react_jsx_runtime.jsx)(Badge, {
|
|
446
961
|
variant: "secondary",
|
|
447
|
-
className: "
|
|
448
|
-
children:
|
|
449
|
-
|
|
450
|
-
children:
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
"
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
962
|
+
className: "py-1 pr-1",
|
|
963
|
+
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
964
|
+
className: BADGE_ROW,
|
|
965
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
966
|
+
"data-testid": `${testIdBase}:badge:pinned:${index}`,
|
|
967
|
+
className: "min-w-0 truncate",
|
|
968
|
+
children: describeRow(expr, available, tt, formatValue)
|
|
969
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
970
|
+
type: "button",
|
|
971
|
+
"data-testid": `${testIdBase}:badge:pinned:${index}:remove`,
|
|
972
|
+
"aria-label": removeLabel,
|
|
973
|
+
onClick: () => handleRemovePinned(index),
|
|
974
|
+
className: REMOVE_BUTTON,
|
|
975
|
+
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconX, {
|
|
976
|
+
className: "size-3",
|
|
977
|
+
"aria-hidden": "true"
|
|
978
|
+
})
|
|
979
|
+
})]
|
|
980
|
+
})
|
|
462
981
|
}, `pinned-${index}`))
|
|
463
982
|
]
|
|
464
983
|
});
|
|
@@ -648,14 +1167,15 @@ const OPTIONS = ["true", "false"];
|
|
|
648
1167
|
function BooleanValueControl(props) {
|
|
649
1168
|
const { value, onChange, testId, arity, autoFocus, fieldLabel, fill } = props;
|
|
650
1169
|
const t = (0, _burojs_react.useOptionalT)();
|
|
651
|
-
const
|
|
1170
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1171
|
+
const ariaLabel = fieldLabel ? chromeT("filters.valueFor", {
|
|
652
1172
|
defaultValue: `Value for ${fieldLabel}`,
|
|
653
1173
|
params: { field: fieldLabel }
|
|
654
|
-
}) :
|
|
1174
|
+
}) : chromeT("filters.value", { defaultValue: "Value" });
|
|
655
1175
|
const yesLabel = t("boolean.yes", { defaultValue: "Yes" });
|
|
656
1176
|
const noLabel = t("boolean.no", { defaultValue: "No" });
|
|
657
1177
|
const labelOf = (token) => token === "true" ? yesLabel : noLabel;
|
|
658
|
-
const clearLabel =
|
|
1178
|
+
const clearLabel = chromeT("filters.clear", { defaultValue: "Clear" });
|
|
659
1179
|
const { open, setOpen, selected, select, triggerLabel, clear } = useSelectableValueControl({
|
|
660
1180
|
value,
|
|
661
1181
|
arity,
|
|
@@ -675,12 +1195,12 @@ function BooleanValueControl(props) {
|
|
|
675
1195
|
"data-testid": testId,
|
|
676
1196
|
"aria-label": ariaLabel,
|
|
677
1197
|
className: require_use_theme.cn("h-8 justify-between", fill && "w-full"),
|
|
678
|
-
children: triggerLabel(labelOf, ariaLabel)
|
|
1198
|
+
children: triggerLabel(labelOf, props.placeholder ?? ariaLabel)
|
|
679
1199
|
})
|
|
680
1200
|
}), (0, react_jsx_runtime.jsx)(require_toaster.PopoverContent, {
|
|
681
1201
|
className: "w-[140px] p-0",
|
|
682
1202
|
align: "start",
|
|
683
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
1203
|
+
children: (0, react_jsx_runtime.jsx)(require_relation_create.Command, { children: (0, react_jsx_runtime.jsx)(require_relation_create.CommandList, { children: (0, react_jsx_runtime.jsxs)(require_relation_create.CommandGroup, { children: [arity === "single" && selected.size > 0 && (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
684
1204
|
"data-testid": `${testId}:clear`,
|
|
685
1205
|
value: "__clear__",
|
|
686
1206
|
onSelect: () => clear(),
|
|
@@ -690,7 +1210,7 @@ function BooleanValueControl(props) {
|
|
|
690
1210
|
}), clearLabel]
|
|
691
1211
|
}), OPTIONS.map((token) => {
|
|
692
1212
|
const isSelected = selected.has(token);
|
|
693
|
-
return (0, react_jsx_runtime.jsxs)(
|
|
1213
|
+
return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
694
1214
|
value: labelOf(token),
|
|
695
1215
|
"data-testid": `${testId}:option:${token}`,
|
|
696
1216
|
onSelect: () => select(token),
|
|
@@ -708,12 +1228,13 @@ function BooleanValueControl(props) {
|
|
|
708
1228
|
function SelectListValueControl(props) {
|
|
709
1229
|
const { options, value, onChange, testId, arity, autoFocus, fieldLabel, isLoading = false } = props;
|
|
710
1230
|
const t = (0, _burojs_react.useOptionalT)();
|
|
711
|
-
const
|
|
1231
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1232
|
+
const ariaLabel = fieldLabel ? chromeT("filters.valueFor", {
|
|
712
1233
|
defaultValue: `Value for ${fieldLabel}`,
|
|
713
1234
|
params: { field: fieldLabel }
|
|
714
|
-
}) :
|
|
1235
|
+
}) : chromeT("filters.value", { defaultValue: "Value" });
|
|
715
1236
|
const loadingLabel = t("table.loading", { defaultValue: "Loading…" });
|
|
716
|
-
const clearLabel =
|
|
1237
|
+
const clearLabel = chromeT("filters.clear", { defaultValue: "Clear" });
|
|
717
1238
|
const labelFor = props.labelFor ?? ((raw) => options.find((o) => o.value === raw)?.label ?? raw);
|
|
718
1239
|
const { open, setOpen, selected, select, triggerLabel, clear } = useSelectableValueControl({
|
|
719
1240
|
value,
|
|
@@ -735,16 +1256,16 @@ function SelectListValueControl(props) {
|
|
|
735
1256
|
className: require_use_theme.cn("h-8 justify-between truncate", props.fill ? "w-full" : "max-w-[200px]"),
|
|
736
1257
|
children: (0, react_jsx_runtime.jsx)("span", {
|
|
737
1258
|
className: "truncate",
|
|
738
|
-
children: isLoading ? loadingLabel : triggerLabel(labelFor, ariaLabel)
|
|
1259
|
+
children: isLoading ? loadingLabel : triggerLabel(labelFor, props.placeholder ?? ariaLabel)
|
|
739
1260
|
})
|
|
740
1261
|
})
|
|
741
1262
|
}), (0, react_jsx_runtime.jsx)(require_toaster.PopoverContent, {
|
|
742
1263
|
className: "w-[220px] p-0",
|
|
743
1264
|
align: "start",
|
|
744
|
-
children: (0, react_jsx_runtime.jsxs)(
|
|
1265
|
+
children: (0, react_jsx_runtime.jsxs)(require_relation_create.Command, { children: [(0, react_jsx_runtime.jsx)(require_relation_create.CommandInput, {
|
|
745
1266
|
placeholder: ariaLabel,
|
|
746
1267
|
"data-testid": `${testId}:search`
|
|
747
|
-
}), (0, react_jsx_runtime.jsxs)(
|
|
1268
|
+
}), (0, react_jsx_runtime.jsxs)(require_relation_create.CommandList, { children: [
|
|
748
1269
|
isLoading && (0, react_jsx_runtime.jsxs)("div", {
|
|
749
1270
|
className: "flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground",
|
|
750
1271
|
"data-testid": `${testId}:loading`,
|
|
@@ -753,8 +1274,8 @@ function SelectListValueControl(props) {
|
|
|
753
1274
|
"aria-hidden": "true"
|
|
754
1275
|
}), loadingLabel]
|
|
755
1276
|
}),
|
|
756
|
-
!isLoading && (0, react_jsx_runtime.jsx)(
|
|
757
|
-
!isLoading && (0, react_jsx_runtime.jsxs)(
|
|
1277
|
+
!isLoading && (0, react_jsx_runtime.jsx)(require_relation_create.CommandEmpty, { children: t("relation.noResults", { defaultValue: "No results." }) }),
|
|
1278
|
+
!isLoading && (0, react_jsx_runtime.jsxs)(require_relation_create.CommandGroup, { children: [arity === "single" && selected.size > 0 && (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
758
1279
|
"data-testid": `${testId}:clear`,
|
|
759
1280
|
value: "__clear__",
|
|
760
1281
|
onSelect: () => clear(),
|
|
@@ -765,7 +1286,7 @@ function SelectListValueControl(props) {
|
|
|
765
1286
|
}), options.map((entry) => {
|
|
766
1287
|
const isSelected = selected.has(entry.value);
|
|
767
1288
|
const label = labelFor(entry.value);
|
|
768
|
-
return (0, react_jsx_runtime.jsxs)(
|
|
1289
|
+
return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
769
1290
|
value: label,
|
|
770
1291
|
"data-testid": `${testId}:option:${entry.value}`,
|
|
771
1292
|
onSelect: () => select(entry.value),
|
|
@@ -798,6 +1319,7 @@ function EnumValueControl(props) {
|
|
|
798
1319
|
arity,
|
|
799
1320
|
autoFocus,
|
|
800
1321
|
fieldLabel,
|
|
1322
|
+
placeholder: props.placeholder,
|
|
801
1323
|
options,
|
|
802
1324
|
labelFor,
|
|
803
1325
|
isLoading,
|
|
@@ -809,7 +1331,7 @@ function EnumValueControl(props) {
|
|
|
809
1331
|
function useRelatedLabels(to, ids, by) {
|
|
810
1332
|
const targetDef = (0, _burojs_react.useApp)().registry.get(to);
|
|
811
1333
|
const idField = (targetDef?.data)?.idField;
|
|
812
|
-
const rowTitle =
|
|
1334
|
+
const rowTitle = require_relation_create.useRowTitle(to, targetDef?.displayField);
|
|
813
1335
|
const field = by ?? (typeof idField === "string" && idField.length > 0 ? idField : "id");
|
|
814
1336
|
const query = (0, _burojs_react.useList)(to, {
|
|
815
1337
|
pagination: {
|
|
@@ -844,6 +1366,7 @@ function RelationValueControl(props) {
|
|
|
844
1366
|
const { to, by, value, onChange, testId, arity, autoFocus, fieldLabel } = props;
|
|
845
1367
|
const app = (0, _burojs_react.useApp)();
|
|
846
1368
|
const t = (0, _burojs_react.useOptionalT)();
|
|
1369
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
847
1370
|
const targetDef = app.registry.get(to);
|
|
848
1371
|
const displayField = targetDef?.displayField ?? "name";
|
|
849
1372
|
const [search, setSearch] = (0, react.useState)("");
|
|
@@ -852,9 +1375,9 @@ function RelationValueControl(props) {
|
|
|
852
1375
|
arity,
|
|
853
1376
|
onChange
|
|
854
1377
|
});
|
|
855
|
-
const rowTitle =
|
|
1378
|
+
const rowTitle = require_relation_create.useRowTitle(to, targetDef?.displayField);
|
|
856
1379
|
const access = (0, _burojs_react.useListAccess)(to);
|
|
857
|
-
const searchable = (0, react.useMemo)(() => access.status === "ready" &&
|
|
1380
|
+
const searchable = (0, react.useMemo)(() => access.status === "ready" && require_relation_create.narrowSearchDecl({ fields: [displayField] }, (name) => access.fieldVisible(name)) !== void 0, [access, displayField]);
|
|
858
1381
|
const listQuery = (0, _burojs_react.useList)(to, {
|
|
859
1382
|
pagination: {
|
|
860
1383
|
kind: "offset",
|
|
@@ -882,11 +1405,11 @@ function RelationValueControl(props) {
|
|
|
882
1405
|
if (fromRows) return rowTitle(fromRows);
|
|
883
1406
|
return fallbackLabels[id] ?? id;
|
|
884
1407
|
};
|
|
885
|
-
const ariaLabel = fieldLabel ?
|
|
1408
|
+
const ariaLabel = fieldLabel ? chromeT("filters.valueFor", {
|
|
886
1409
|
defaultValue: `Value for ${fieldLabel}`,
|
|
887
1410
|
params: { field: fieldLabel }
|
|
888
|
-
}) :
|
|
889
|
-
const clearLabel =
|
|
1411
|
+
}) : chromeT("filters.value", { defaultValue: "Value" });
|
|
1412
|
+
const clearLabel = chromeT("filters.clear", { defaultValue: "Clear" });
|
|
890
1413
|
return (0, react_jsx_runtime.jsxs)(require_toaster.Popover, {
|
|
891
1414
|
open,
|
|
892
1415
|
onOpenChange: setOpen,
|
|
@@ -902,20 +1425,20 @@ function RelationValueControl(props) {
|
|
|
902
1425
|
className: require_use_theme.cn("h-8 justify-between truncate", props.fill ? "w-full" : "max-w-[220px]"),
|
|
903
1426
|
children: (0, react_jsx_runtime.jsx)("span", {
|
|
904
1427
|
className: "truncate",
|
|
905
|
-
children: triggerLabel(labelFor, ariaLabel)
|
|
1428
|
+
children: triggerLabel(labelFor, props.placeholder ?? ariaLabel)
|
|
906
1429
|
})
|
|
907
1430
|
})
|
|
908
1431
|
}), (0, react_jsx_runtime.jsx)(require_toaster.PopoverContent, {
|
|
909
1432
|
className: "w-[240px] p-0",
|
|
910
1433
|
align: "start",
|
|
911
|
-
children: (0, react_jsx_runtime.jsxs)(
|
|
1434
|
+
children: (0, react_jsx_runtime.jsxs)(require_relation_create.Command, {
|
|
912
1435
|
shouldFilter: false,
|
|
913
|
-
children: [searchable && (0, react_jsx_runtime.jsx)(
|
|
1436
|
+
children: [searchable && (0, react_jsx_runtime.jsx)(require_relation_create.CommandInput, {
|
|
914
1437
|
value: search,
|
|
915
1438
|
onValueChange: setSearch,
|
|
916
1439
|
placeholder: ariaLabel,
|
|
917
1440
|
"data-testid": `${testId}:search`
|
|
918
|
-
}), (0, react_jsx_runtime.jsxs)(
|
|
1441
|
+
}), (0, react_jsx_runtime.jsxs)(require_relation_create.CommandList, { children: [
|
|
919
1442
|
listQuery.isLoading && (0, react_jsx_runtime.jsxs)("div", {
|
|
920
1443
|
className: "flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground",
|
|
921
1444
|
"data-testid": `${testId}:loading`,
|
|
@@ -924,8 +1447,8 @@ function RelationValueControl(props) {
|
|
|
924
1447
|
"aria-hidden": "true"
|
|
925
1448
|
}), t("table.loading", { defaultValue: "Loading…" })]
|
|
926
1449
|
}),
|
|
927
|
-
!listQuery.isLoading && rows.length === 0 && (0, react_jsx_runtime.jsx)(
|
|
928
|
-
!listQuery.isLoading && arity === "single" && selected.size > 0 && (0, react_jsx_runtime.jsxs)(
|
|
1450
|
+
!listQuery.isLoading && rows.length === 0 && (0, react_jsx_runtime.jsx)(require_relation_create.CommandEmpty, { children: t("relation.noResults", { defaultValue: "No results." }) }),
|
|
1451
|
+
!listQuery.isLoading && arity === "single" && selected.size > 0 && (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
929
1452
|
"data-testid": `${testId}:clear`,
|
|
930
1453
|
value: "__clear__",
|
|
931
1454
|
onSelect: () => clear(),
|
|
@@ -939,7 +1462,7 @@ function RelationValueControl(props) {
|
|
|
939
1462
|
if (id === void 0) return null;
|
|
940
1463
|
const label = rowTitle(row);
|
|
941
1464
|
const isSelected = selected.has(id);
|
|
942
|
-
return (0, react_jsx_runtime.jsxs)(
|
|
1465
|
+
return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
943
1466
|
value: `${label} ${id}`,
|
|
944
1467
|
"data-testid": `${testId}:option:${id}`,
|
|
945
1468
|
onSelect: () => select(id),
|
|
@@ -958,6 +1481,20 @@ function RelationValueControl(props) {
|
|
|
958
1481
|
});
|
|
959
1482
|
}
|
|
960
1483
|
//#endregion
|
|
1484
|
+
//#region src/fields/local-date-time.ts
|
|
1485
|
+
function toLocalDateTimeText(value) {
|
|
1486
|
+
if (value === void 0 || value === null || value === "") return "";
|
|
1487
|
+
const d = value instanceof Date ? value : new Date(String(value));
|
|
1488
|
+
if (Number.isNaN(d.getTime())) return "";
|
|
1489
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
1490
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
1491
|
+
}
|
|
1492
|
+
function fromLocalDateTimeText(text) {
|
|
1493
|
+
if (text === "") return void 0;
|
|
1494
|
+
const d = new Date(text);
|
|
1495
|
+
return Number.isNaN(d.getTime()) ? void 0 : d.toISOString();
|
|
1496
|
+
}
|
|
1497
|
+
//#endregion
|
|
961
1498
|
//#region src/list-kit/filter-builder/values/scalar-value-input.tsx
|
|
962
1499
|
function isDateTime(kind) {
|
|
963
1500
|
return kind.kind === "date" && kind.time === true;
|
|
@@ -970,12 +1507,9 @@ function inputTypeFor(kind) {
|
|
|
970
1507
|
}
|
|
971
1508
|
}
|
|
972
1509
|
function toText(kind, value) {
|
|
1510
|
+
if (isDateTime(kind)) return toLocalDateTimeText(value);
|
|
973
1511
|
if (value === void 0 || value === null || value === "") return "";
|
|
974
|
-
|
|
975
|
-
const d = new Date(String(value));
|
|
976
|
-
if (Number.isNaN(d.getTime())) return "";
|
|
977
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
978
|
-
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
1512
|
+
return String(value);
|
|
979
1513
|
}
|
|
980
1514
|
function parseOne(kind, raw) {
|
|
981
1515
|
if (raw === "") return void 0;
|
|
@@ -983,19 +1517,16 @@ function parseOne(kind, raw) {
|
|
|
983
1517
|
const n = Number(raw);
|
|
984
1518
|
return Number.isFinite(n) ? n : void 0;
|
|
985
1519
|
}
|
|
986
|
-
if (isDateTime(kind))
|
|
987
|
-
const d = new Date(raw);
|
|
988
|
-
return Number.isNaN(d.getTime()) ? void 0 : d.toISOString();
|
|
989
|
-
}
|
|
1520
|
+
if (isDateTime(kind)) return fromLocalDateTimeText(raw);
|
|
990
1521
|
return raw;
|
|
991
1522
|
}
|
|
992
1523
|
function ScalarValueInput(props) {
|
|
993
|
-
const
|
|
1524
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
994
1525
|
const inputType = inputTypeFor(props.kind);
|
|
995
|
-
const ariaLabel = props.fieldLabel ?
|
|
1526
|
+
const ariaLabel = props.fieldLabel ? chromeT("filters.valueFor", {
|
|
996
1527
|
defaultValue: `Value for ${props.fieldLabel}`,
|
|
997
1528
|
params: { field: props.fieldLabel }
|
|
998
|
-
}) :
|
|
1529
|
+
}) : chromeT("filters.value", { defaultValue: "Value" });
|
|
999
1530
|
if (props.arity === "multi") return (0, react_jsx_runtime.jsx)(ScalarMultiInput, {
|
|
1000
1531
|
...props,
|
|
1001
1532
|
inputType,
|
|
@@ -1125,6 +1656,7 @@ function FilterValueControl(props) {
|
|
|
1125
1656
|
arity,
|
|
1126
1657
|
autoFocus: props.autoFocus,
|
|
1127
1658
|
fieldLabel: props.fieldLabel,
|
|
1659
|
+
placeholder: props.placeholder,
|
|
1128
1660
|
options: props.options,
|
|
1129
1661
|
fill: props.fill
|
|
1130
1662
|
});
|
|
@@ -1141,6 +1673,7 @@ function FilterValueControl(props) {
|
|
|
1141
1673
|
arity,
|
|
1142
1674
|
autoFocus: props.autoFocus,
|
|
1143
1675
|
fieldLabel: props.fieldLabel,
|
|
1676
|
+
placeholder: props.placeholder,
|
|
1144
1677
|
options: props.kind.values.map((entry) => ({
|
|
1145
1678
|
value: entry,
|
|
1146
1679
|
label: entry
|
|
@@ -1169,10 +1702,10 @@ const FIELD_CLASS = "h-8 min-w-0 shrink basis-40";
|
|
|
1169
1702
|
const OPERATOR_CLASS = "h-8 min-w-0 shrink basis-[9.5rem]";
|
|
1170
1703
|
function FilterRow(props) {
|
|
1171
1704
|
const { row, path, available, onPatch, onRemove, testIdBase, debounceMs } = props;
|
|
1172
|
-
const
|
|
1705
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1173
1706
|
const base = `${testIdBase}:row:${path.join("-")}`;
|
|
1174
1707
|
const spec = available.find((s) => s.field === row.field);
|
|
1175
|
-
const removeLabel =
|
|
1708
|
+
const removeLabel = chromeT("filters.removeRow", { defaultValue: "Remove filter" });
|
|
1176
1709
|
if (!spec) return (0, react_jsx_runtime.jsxs)("div", {
|
|
1177
1710
|
className: ROW_CLASS,
|
|
1178
1711
|
children: [
|
|
@@ -1212,8 +1745,8 @@ function FilterRow(props) {
|
|
|
1212
1745
|
};
|
|
1213
1746
|
const handleOpChange = (op) => onPatch(path, { op });
|
|
1214
1747
|
const handleValueChange = (value) => onPatch(path, { value });
|
|
1215
|
-
const fieldAriaLabel =
|
|
1216
|
-
const operatorAriaLabel =
|
|
1748
|
+
const fieldAriaLabel = chromeT("filters.field", { defaultValue: "Field" });
|
|
1749
|
+
const operatorAriaLabel = chromeT("filters.operator", { defaultValue: "Operator" });
|
|
1217
1750
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1218
1751
|
className: ROW_CLASS,
|
|
1219
1752
|
children: [
|
|
@@ -1242,7 +1775,7 @@ function FilterRow(props) {
|
|
|
1242
1775
|
}), (0, react_jsx_runtime.jsx)(SelectContent, { children: spec.operators.map((op) => (0, react_jsx_runtime.jsx)(SelectItem, {
|
|
1243
1776
|
value: op,
|
|
1244
1777
|
"data-testid": `${opTestId}:option:${op}`,
|
|
1245
|
-
children:
|
|
1778
|
+
children: chromeT(`filters.operators.${op}`, { defaultValue: op })
|
|
1246
1779
|
}, op)) })]
|
|
1247
1780
|
}),
|
|
1248
1781
|
(0, react_jsx_runtime.jsx)("div", {
|
|
@@ -1290,10 +1823,10 @@ function FilterGroupEditor(props) {
|
|
|
1290
1823
|
}
|
|
1291
1824
|
function GroupEditorInner(props) {
|
|
1292
1825
|
const { group, path, available, onChange, testIdBase, onRemove, addGroupAt, debounceMs } = props;
|
|
1293
|
-
const
|
|
1826
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1294
1827
|
const base = `${testIdBase}:group:${path.join("-")}`;
|
|
1295
1828
|
const canNestGroup = depthOf(path) < 3;
|
|
1296
|
-
const joinLabel = (join) =>
|
|
1829
|
+
const joinLabel = (join) => chromeT(`filters.${join}`, { defaultValue: join });
|
|
1297
1830
|
const handlePatch = (rowPath, patch) => {
|
|
1298
1831
|
const index = rowPath[rowPath.length - 1];
|
|
1299
1832
|
if (index === void 0) return;
|
|
@@ -1326,11 +1859,11 @@ function GroupEditorInner(props) {
|
|
|
1326
1859
|
return (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1327
1860
|
className: CONNECTOR_CLASS,
|
|
1328
1861
|
children: [
|
|
1329
|
-
index === 0 &&
|
|
1862
|
+
index === 0 && chromeT("filters.where", { defaultValue: "Where" }),
|
|
1330
1863
|
index === 1 && (0, react_jsx_runtime.jsx)("button", {
|
|
1331
1864
|
type: "button",
|
|
1332
1865
|
"data-testid": `${base}:join`,
|
|
1333
|
-
"aria-label":
|
|
1866
|
+
"aria-label": chromeT("filters.toggleJoin", {
|
|
1334
1867
|
defaultValue: `Join: ${joinLabel(group.join)} — activate to switch to ${joinLabel(otherJoin)}`,
|
|
1335
1868
|
params: {
|
|
1336
1869
|
current: joinLabel(group.join),
|
|
@@ -1382,7 +1915,7 @@ function GroupEditorInner(props) {
|
|
|
1382
1915
|
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconPlus, {
|
|
1383
1916
|
className: "h-4 w-4",
|
|
1384
1917
|
"aria-hidden": "true"
|
|
1385
|
-
}),
|
|
1918
|
+
}), chromeT("filters.addRow", { defaultValue: "Add filter" })]
|
|
1386
1919
|
}),
|
|
1387
1920
|
canNestGroup && (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
1388
1921
|
type: "button",
|
|
@@ -1393,7 +1926,7 @@ function GroupEditorInner(props) {
|
|
|
1393
1926
|
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconFolderPlus, {
|
|
1394
1927
|
className: "h-4 w-4",
|
|
1395
1928
|
"aria-hidden": "true"
|
|
1396
|
-
}),
|
|
1929
|
+
}), chromeT("filters.addGroup", { defaultValue: "Add group" })]
|
|
1397
1930
|
}),
|
|
1398
1931
|
onRemove && (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
1399
1932
|
type: "button",
|
|
@@ -1404,7 +1937,7 @@ function GroupEditorInner(props) {
|
|
|
1404
1937
|
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconX, {
|
|
1405
1938
|
className: "h-4 w-4",
|
|
1406
1939
|
"aria-hidden": "true"
|
|
1407
|
-
}),
|
|
1940
|
+
}), chromeT("filters.removeGroup", { defaultValue: "Remove group" })]
|
|
1408
1941
|
})
|
|
1409
1942
|
]
|
|
1410
1943
|
})
|
|
@@ -1420,7 +1953,7 @@ function countGroupRows(group) {
|
|
|
1420
1953
|
}
|
|
1421
1954
|
function FilterPanel(props) {
|
|
1422
1955
|
const { group, setGroup, available, setPage, testIdBase, open, onOpenChange, focusPath, externalRemoval } = props;
|
|
1423
|
-
const
|
|
1956
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1424
1957
|
const [draft, setDraft] = (0, react.useState)(() => toDraft(group));
|
|
1425
1958
|
const wasOpenRef = (0, react.useRef)(open);
|
|
1426
1959
|
const topLevelIdsRef = (0, react.useRef)([]);
|
|
@@ -1472,7 +2005,7 @@ function FilterPanel(props) {
|
|
|
1472
2005
|
className: "h-4 w-4",
|
|
1473
2006
|
"aria-hidden": "true"
|
|
1474
2007
|
}),
|
|
1475
|
-
|
|
2008
|
+
chromeT("filters.title", { defaultValue: "Filters" }),
|
|
1476
2009
|
appliedCount > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
1477
2010
|
"data-testid": `${testIdBase}:count`,
|
|
1478
2011
|
className: "ml-1 rounded-full bg-primary px-1.5 text-xs text-primary-foreground",
|
|
@@ -1500,13 +2033,13 @@ function FilterPanel(props) {
|
|
|
1500
2033
|
size: "sm",
|
|
1501
2034
|
"data-testid": `${testIdBase}:reset`,
|
|
1502
2035
|
onClick: handleReset,
|
|
1503
|
-
children:
|
|
2036
|
+
children: chromeT("filters.reset", { defaultValue: "Reset" })
|
|
1504
2037
|
}), (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
1505
2038
|
type: "button",
|
|
1506
2039
|
size: "sm",
|
|
1507
2040
|
"data-testid": `${testIdBase}:apply`,
|
|
1508
2041
|
onClick: handleApply,
|
|
1509
|
-
children:
|
|
2042
|
+
children: chromeT("filters.apply", { defaultValue: "Apply" })
|
|
1510
2043
|
})]
|
|
1511
2044
|
})]
|
|
1512
2045
|
})]
|
|
@@ -1561,11 +2094,204 @@ function PinnedControl(props) {
|
|
|
1561
2094
|
});
|
|
1562
2095
|
}
|
|
1563
2096
|
//#endregion
|
|
2097
|
+
//#region src/data-table/data-table-faceted-filter.tsx
|
|
2098
|
+
function DataTableFacetedFilter({ column, getTestId, ...rest }) {
|
|
2099
|
+
const filterValue = column.getFilterValue();
|
|
2100
|
+
return (0, react_jsx_runtime.jsx)(FacetedFilterPicker, {
|
|
2101
|
+
...rest,
|
|
2102
|
+
...getTestId === void 0 ? {} : { getTestId: (role, value) => role === "hint" ? void 0 : getTestId(role, value) },
|
|
2103
|
+
selected: Array.isArray(filterValue) ? filterValue.map(String) : [],
|
|
2104
|
+
onChange: (next) => column.setFilterValue(next.length === 0 ? void 0 : next)
|
|
2105
|
+
});
|
|
2106
|
+
}
|
|
2107
|
+
function FacetedFilterPicker({ title, options = [], loadOptions, selectedLabelFor, searchPlaceholder, emptyText, getTestId, className, selected: selectedList, onChange, hint, emptyLabel, clearable = true }) {
|
|
2108
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
2109
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
2110
|
+
const selected = (0, react.useMemo)(() => new Set(selectedList), [selectedList]);
|
|
2111
|
+
const [search, setSearch] = (0, react.useState)("");
|
|
2112
|
+
const [asyncOptions, setAsyncOptions] = (0, react.useState)([]);
|
|
2113
|
+
const [loading, setLoading] = (0, react.useState)(false);
|
|
2114
|
+
const debounceRef = (0, react.useRef)(null);
|
|
2115
|
+
const loadOptionsRef = (0, react.useRef)(loadOptions);
|
|
2116
|
+
(0, react.useEffect)(() => {
|
|
2117
|
+
loadOptionsRef.current = loadOptions;
|
|
2118
|
+
});
|
|
2119
|
+
(0, react.useEffect)(() => {
|
|
2120
|
+
if (!loadOptionsRef.current) return;
|
|
2121
|
+
setLoading(true);
|
|
2122
|
+
if (debounceRef.current !== null) clearTimeout(debounceRef.current);
|
|
2123
|
+
let cancelled = false;
|
|
2124
|
+
debounceRef.current = setTimeout(() => {
|
|
2125
|
+
const loader = loadOptionsRef.current;
|
|
2126
|
+
if (!loader) return;
|
|
2127
|
+
loader(search).then((results) => {
|
|
2128
|
+
if (!cancelled) {
|
|
2129
|
+
setAsyncOptions(results);
|
|
2130
|
+
setLoading(false);
|
|
2131
|
+
}
|
|
2132
|
+
}).catch(() => {
|
|
2133
|
+
if (!cancelled) setLoading(false);
|
|
2134
|
+
});
|
|
2135
|
+
}, 250);
|
|
2136
|
+
return () => {
|
|
2137
|
+
cancelled = true;
|
|
2138
|
+
if (debounceRef.current !== null) clearTimeout(debounceRef.current);
|
|
2139
|
+
};
|
|
2140
|
+
}, [search]);
|
|
2141
|
+
const effectiveOptions = loadOptions ? asyncOptions : options;
|
|
2142
|
+
const labelFor = (value) => {
|
|
2143
|
+
const opt = effectiveOptions.find((o) => o.value === value);
|
|
2144
|
+
if (opt) return opt.label;
|
|
2145
|
+
return selectedLabelFor?.(value) ?? value;
|
|
2146
|
+
};
|
|
2147
|
+
const toggle = (value) => {
|
|
2148
|
+
const next = new Set(selected);
|
|
2149
|
+
if (next.has(value)) next.delete(value);
|
|
2150
|
+
else next.add(value);
|
|
2151
|
+
onChange(Array.from(next));
|
|
2152
|
+
};
|
|
2153
|
+
const selectedValues = Array.from(selected);
|
|
2154
|
+
return (0, react_jsx_runtime.jsxs)(require_toaster.Popover, { children: [(0, react_jsx_runtime.jsx)(require_toaster.PopoverTrigger, {
|
|
2155
|
+
asChild: true,
|
|
2156
|
+
children: (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
2157
|
+
type: "button",
|
|
2158
|
+
variant: "outline",
|
|
2159
|
+
size: "sm",
|
|
2160
|
+
"data-testid": getTestId?.("trigger"),
|
|
2161
|
+
title: hint,
|
|
2162
|
+
className: require_use_theme.cn("h-8 border-dashed", className),
|
|
2163
|
+
children: [
|
|
2164
|
+
(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCirclePlus, {
|
|
2165
|
+
className: "mr-2 h-4 w-4",
|
|
2166
|
+
"aria-hidden": "true"
|
|
2167
|
+
}),
|
|
2168
|
+
title,
|
|
2169
|
+
selected.size === 0 && emptyLabel !== void 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
2170
|
+
className: "mx-2 h-4 w-px bg-border",
|
|
2171
|
+
"aria-hidden": "true"
|
|
2172
|
+
}), (0, react_jsx_runtime.jsx)(Badge, {
|
|
2173
|
+
variant: "secondary",
|
|
2174
|
+
className: "rounded-sm px-1 font-normal",
|
|
2175
|
+
children: emptyLabel
|
|
2176
|
+
})] }),
|
|
2177
|
+
selected.size > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2178
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
2179
|
+
className: "mx-2 h-4 w-px bg-border",
|
|
2180
|
+
"aria-hidden": "true"
|
|
2181
|
+
}),
|
|
2182
|
+
(0, react_jsx_runtime.jsx)(Badge, {
|
|
2183
|
+
variant: "secondary",
|
|
2184
|
+
className: "rounded-sm px-1 font-normal lg:hidden",
|
|
2185
|
+
children: selected.size
|
|
2186
|
+
}),
|
|
2187
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
2188
|
+
className: "hidden gap-1 lg:flex",
|
|
2189
|
+
children: selected.size > 2 ? (0, react_jsx_runtime.jsx)(Badge, {
|
|
2190
|
+
variant: "secondary",
|
|
2191
|
+
className: "rounded-sm px-1 font-normal",
|
|
2192
|
+
children: t("table.selectedCount", {
|
|
2193
|
+
count: selected.size,
|
|
2194
|
+
defaultValue: "{{count}} selected"
|
|
2195
|
+
})
|
|
2196
|
+
}) : selectedValues.map((value) => (0, react_jsx_runtime.jsx)(Badge, {
|
|
2197
|
+
variant: "secondary",
|
|
2198
|
+
className: "rounded-sm px-1 font-normal",
|
|
2199
|
+
children: labelFor(value)
|
|
2200
|
+
}, value))
|
|
2201
|
+
})
|
|
2202
|
+
] })
|
|
2203
|
+
]
|
|
2204
|
+
})
|
|
2205
|
+
}), (0, react_jsx_runtime.jsx)(require_toaster.PopoverContent, {
|
|
2206
|
+
className: "w-[220px] p-0",
|
|
2207
|
+
align: "start",
|
|
2208
|
+
children: (0, react_jsx_runtime.jsxs)(require_relation_create.Command, {
|
|
2209
|
+
shouldFilter: !loadOptions,
|
|
2210
|
+
children: [
|
|
2211
|
+
hint !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
2212
|
+
"data-testid": getTestId?.("hint"),
|
|
2213
|
+
className: "border-b px-3 py-2 text-xs text-muted-foreground",
|
|
2214
|
+
children: hint
|
|
2215
|
+
}),
|
|
2216
|
+
(0, react_jsx_runtime.jsx)(require_relation_create.CommandInput, {
|
|
2217
|
+
placeholder: searchPlaceholder ?? title,
|
|
2218
|
+
"data-testid": getTestId?.("search"),
|
|
2219
|
+
...loadOptions ? {
|
|
2220
|
+
value: search,
|
|
2221
|
+
onValueChange: setSearch
|
|
2222
|
+
} : {}
|
|
2223
|
+
}),
|
|
2224
|
+
(0, react_jsx_runtime.jsxs)(require_relation_create.CommandList, { children: [
|
|
2225
|
+
loading && (0, react_jsx_runtime.jsx)("div", {
|
|
2226
|
+
className: "py-6 text-center text-sm text-muted-foreground",
|
|
2227
|
+
children: t("list.loadingShort", { defaultValue: "Loading…" })
|
|
2228
|
+
}),
|
|
2229
|
+
(0, react_jsx_runtime.jsx)(require_relation_create.CommandEmpty, { children: emptyText ?? t("relation.noResults", { defaultValue: "No results." }) }),
|
|
2230
|
+
(0, react_jsx_runtime.jsx)(require_relation_create.CommandGroup, { children: effectiveOptions.map((opt) => {
|
|
2231
|
+
const isSelected = selected.has(opt.value);
|
|
2232
|
+
const Icon = opt.icon;
|
|
2233
|
+
return (0, react_jsx_runtime.jsxs)(require_relation_create.CommandItem, {
|
|
2234
|
+
value: opt.label,
|
|
2235
|
+
"data-testid": getTestId?.("option", opt.value),
|
|
2236
|
+
role: "option",
|
|
2237
|
+
"aria-selected": isSelected,
|
|
2238
|
+
"aria-checked": isSelected,
|
|
2239
|
+
onSelect: () => toggle(opt.value),
|
|
2240
|
+
children: [
|
|
2241
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
2242
|
+
className: require_use_theme.cn("mr-2 flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border", isSelected ? "border-primary bg-primary text-primary-foreground" : "border-input opacity-50"),
|
|
2243
|
+
"aria-hidden": "true",
|
|
2244
|
+
children: isSelected && (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, { className: "h-3.5 w-3.5" })
|
|
2245
|
+
}),
|
|
2246
|
+
Icon && (0, react_jsx_runtime.jsx)(Icon, {
|
|
2247
|
+
className: "mr-2 h-4 w-4 text-muted-foreground",
|
|
2248
|
+
"aria-hidden": "true"
|
|
2249
|
+
}),
|
|
2250
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
2251
|
+
className: "flex min-w-0 flex-1 flex-col text-left",
|
|
2252
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: opt.label }), opt.summary !== void 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
2253
|
+
className: "text-xs text-muted-foreground",
|
|
2254
|
+
children: opt.summary
|
|
2255
|
+
})]
|
|
2256
|
+
})
|
|
2257
|
+
]
|
|
2258
|
+
}, opt.value);
|
|
2259
|
+
}) })
|
|
2260
|
+
] }),
|
|
2261
|
+
clearable && selected.size > 0 && (0, react_jsx_runtime.jsx)("button", {
|
|
2262
|
+
type: "button",
|
|
2263
|
+
"data-testid": getTestId?.("clear"),
|
|
2264
|
+
onClick: () => onChange([]),
|
|
2265
|
+
className: "flex w-full items-center justify-center border-t px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground",
|
|
2266
|
+
children: chromeT("filters.clearAll", { defaultValue: "Clear filters" })
|
|
2267
|
+
})
|
|
2268
|
+
]
|
|
2269
|
+
})
|
|
2270
|
+
})] });
|
|
2271
|
+
}
|
|
2272
|
+
//#endregion
|
|
2273
|
+
//#region src/list-kit/filter-builder/preset-filter-controls.tsx
|
|
2274
|
+
function PresetFilterControls(props) {
|
|
2275
|
+
const { presets, setPreset, testIdBase } = props;
|
|
2276
|
+
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: presets.map((filter) => (0, react_jsx_runtime.jsx)(FacetedFilterPicker, {
|
|
2277
|
+
title: filter.label,
|
|
2278
|
+
...filter.hint === void 0 ? {} : { hint: filter.hint },
|
|
2279
|
+
options: filter.options.map((option) => ({
|
|
2280
|
+
value: option.id,
|
|
2281
|
+
label: option.label,
|
|
2282
|
+
...option.summary === void 0 ? {} : { summary: option.summary }
|
|
2283
|
+
})),
|
|
2284
|
+
selected: filter.selected,
|
|
2285
|
+
onChange: (next) => setPreset(filter.id, filter.options.map((option) => option.id).filter((id) => next.includes(id))),
|
|
2286
|
+
getTestId: (role, value) => `${testIdBase}:preset:${filter.id}:${role}${value === void 0 ? "" : `:${value}`}`
|
|
2287
|
+
}, filter.id)) });
|
|
2288
|
+
}
|
|
2289
|
+
//#endregion
|
|
1564
2290
|
//#region src/list-kit/filter-builder/filter-builder.tsx
|
|
1565
2291
|
const EMPTY_PINNED_FIELDS = Object.freeze([]);
|
|
1566
2292
|
const EMPTY_PINNED_VALUE = Object.freeze([]);
|
|
1567
2293
|
function FilterBuilder(props) {
|
|
1568
|
-
const { group, setGroup, available, fixed, pinnedFields = EMPTY_PINNED_FIELDS, pinnedValue = EMPTY_PINNED_VALUE, setPinnedValue, setPage, testIdBase } = props;
|
|
2294
|
+
const { group, setGroup, available, fixed, pinnedFields = EMPTY_PINNED_FIELDS, pinnedValue = EMPTY_PINNED_VALUE, setPinnedValue, presets, setPreset, setPage, testIdBase } = props;
|
|
1569
2295
|
const [open, setOpen] = (0, react.useState)(false);
|
|
1570
2296
|
const [focusPath, setFocusPath] = (0, react.useState)(void 0);
|
|
1571
2297
|
const [externalRemoval, setExternalRemoval] = (0, react.useState)(void 0);
|
|
@@ -1582,6 +2308,11 @@ function FilterBuilder(props) {
|
|
|
1582
2308
|
setPinnedValue?.(next);
|
|
1583
2309
|
};
|
|
1584
2310
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2311
|
+
presets !== void 0 && presets.length > 0 && setPreset !== void 0 && (0, react_jsx_runtime.jsx)(PresetFilterControls, {
|
|
2312
|
+
presets,
|
|
2313
|
+
setPreset,
|
|
2314
|
+
testIdBase
|
|
2315
|
+
}),
|
|
1585
2316
|
(0, react_jsx_runtime.jsx)(PinnedFilterControls, {
|
|
1586
2317
|
pinnedFields,
|
|
1587
2318
|
value: pinnedValue,
|
|
@@ -1623,6 +2354,18 @@ Object.defineProperty(exports, "Badge", {
|
|
|
1623
2354
|
return Badge;
|
|
1624
2355
|
}
|
|
1625
2356
|
});
|
|
2357
|
+
Object.defineProperty(exports, "DataTableFacetedFilter", {
|
|
2358
|
+
enumerable: true,
|
|
2359
|
+
get: function() {
|
|
2360
|
+
return DataTableFacetedFilter;
|
|
2361
|
+
}
|
|
2362
|
+
});
|
|
2363
|
+
Object.defineProperty(exports, "FacetedFilterPicker", {
|
|
2364
|
+
enumerable: true,
|
|
2365
|
+
get: function() {
|
|
2366
|
+
return FacetedFilterPicker;
|
|
2367
|
+
}
|
|
2368
|
+
});
|
|
1626
2369
|
Object.defineProperty(exports, "FilterBadges", {
|
|
1627
2370
|
enumerable: true,
|
|
1628
2371
|
get: function() {
|
|
@@ -1647,12 +2390,36 @@ Object.defineProperty(exports, "FilterValueControl", {
|
|
|
1647
2390
|
return FilterValueControl;
|
|
1648
2391
|
}
|
|
1649
2392
|
});
|
|
2393
|
+
Object.defineProperty(exports, "MetaPlaceholder", {
|
|
2394
|
+
enumerable: true,
|
|
2395
|
+
get: function() {
|
|
2396
|
+
return MetaPlaceholder;
|
|
2397
|
+
}
|
|
2398
|
+
});
|
|
1650
2399
|
Object.defineProperty(exports, "PinnedFilterControls", {
|
|
1651
2400
|
enumerable: true,
|
|
1652
2401
|
get: function() {
|
|
1653
2402
|
return PinnedFilterControls;
|
|
1654
2403
|
}
|
|
1655
2404
|
});
|
|
2405
|
+
Object.defineProperty(exports, "PresetFilterControls", {
|
|
2406
|
+
enumerable: true,
|
|
2407
|
+
get: function() {
|
|
2408
|
+
return PresetFilterControls;
|
|
2409
|
+
}
|
|
2410
|
+
});
|
|
2411
|
+
Object.defineProperty(exports, "ResolvedFieldDisplay", {
|
|
2412
|
+
enumerable: true,
|
|
2413
|
+
get: function() {
|
|
2414
|
+
return ResolvedFieldDisplay;
|
|
2415
|
+
}
|
|
2416
|
+
});
|
|
2417
|
+
Object.defineProperty(exports, "ResolvedFieldInput", {
|
|
2418
|
+
enumerable: true,
|
|
2419
|
+
get: function() {
|
|
2420
|
+
return ResolvedFieldInput;
|
|
2421
|
+
}
|
|
2422
|
+
});
|
|
1656
2423
|
Object.defineProperty(exports, "Select", {
|
|
1657
2424
|
enumerable: true,
|
|
1658
2425
|
get: function() {
|
|
@@ -1761,29 +2528,65 @@ Object.defineProperty(exports, "badgeVariants", {
|
|
|
1761
2528
|
return badgeVariants;
|
|
1762
2529
|
}
|
|
1763
2530
|
});
|
|
2531
|
+
Object.defineProperty(exports, "fieldDescription", {
|
|
2532
|
+
enumerable: true,
|
|
2533
|
+
get: function() {
|
|
2534
|
+
return fieldDescription;
|
|
2535
|
+
}
|
|
2536
|
+
});
|
|
1764
2537
|
Object.defineProperty(exports, "formatDate", {
|
|
1765
2538
|
enumerable: true,
|
|
1766
2539
|
get: function() {
|
|
1767
2540
|
return formatDate;
|
|
1768
2541
|
}
|
|
1769
2542
|
});
|
|
2543
|
+
Object.defineProperty(exports, "formatDateTime", {
|
|
2544
|
+
enumerable: true,
|
|
2545
|
+
get: function() {
|
|
2546
|
+
return formatDateTime;
|
|
2547
|
+
}
|
|
2548
|
+
});
|
|
1770
2549
|
Object.defineProperty(exports, "formatNumber", {
|
|
1771
2550
|
enumerable: true,
|
|
1772
2551
|
get: function() {
|
|
1773
2552
|
return formatNumber;
|
|
1774
2553
|
}
|
|
1775
2554
|
});
|
|
2555
|
+
Object.defineProperty(exports, "fromLocalDateTimeText", {
|
|
2556
|
+
enumerable: true,
|
|
2557
|
+
get: function() {
|
|
2558
|
+
return fromLocalDateTimeText;
|
|
2559
|
+
}
|
|
2560
|
+
});
|
|
1776
2561
|
Object.defineProperty(exports, "loadLocale", {
|
|
1777
2562
|
enumerable: true,
|
|
1778
2563
|
get: function() {
|
|
1779
2564
|
return loadLocale;
|
|
1780
2565
|
}
|
|
1781
2566
|
});
|
|
2567
|
+
Object.defineProperty(exports, "lowerLegacyField", {
|
|
2568
|
+
enumerable: true,
|
|
2569
|
+
get: function() {
|
|
2570
|
+
return lowerLegacyField;
|
|
2571
|
+
}
|
|
2572
|
+
});
|
|
1782
2573
|
Object.defineProperty(exports, "saveLocale", {
|
|
1783
2574
|
enumerable: true,
|
|
1784
2575
|
get: function() {
|
|
1785
2576
|
return saveLocale;
|
|
1786
2577
|
}
|
|
1787
2578
|
});
|
|
2579
|
+
Object.defineProperty(exports, "toLocalDateTimeText", {
|
|
2580
|
+
enumerable: true,
|
|
2581
|
+
get: function() {
|
|
2582
|
+
return toLocalDateTimeText;
|
|
2583
|
+
}
|
|
2584
|
+
});
|
|
2585
|
+
Object.defineProperty(exports, "useFieldMetaDiagnostic", {
|
|
2586
|
+
enumerable: true,
|
|
2587
|
+
get: function() {
|
|
2588
|
+
return useFieldMetaDiagnostic;
|
|
2589
|
+
}
|
|
2590
|
+
});
|
|
1788
2591
|
|
|
1789
|
-
//# sourceMappingURL=filter-builder-
|
|
2592
|
+
//# sourceMappingURL=filter-builder-DFu0JP-1.cjs.map
|