@burojs/ui-shadcn 0.6.0 → 0.8.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-2HLgz7Il.cjs +169 -0
- package/dist/bulk-summary-2HLgz7Il.cjs.map +1 -0
- package/dist/bulk-summary-D6A0ua21.js +169 -0
- package/dist/bulk-summary-D6A0ua21.js.map +1 -0
- package/dist/{candidates-relation-picker-Cy0rTxvI.cjs → candidates-relation-picker-C47mF260.cjs} +4 -4
- package/dist/{candidates-relation-picker-Cy0rTxvI.cjs.map → candidates-relation-picker-C47mF260.cjs.map} +1 -1
- package/dist/{candidates-relation-picker-B116Bmqi.js → candidates-relation-picker-CGXItMN0.js} +3 -3
- package/dist/{candidates-relation-picker-B116Bmqi.js.map → candidates-relation-picker-CGXItMN0.js.map} +1 -1
- package/dist/{check-confirm-dialog--gPFnEeg.cjs → check-confirm-dialog-BT04Mieo.cjs} +475 -107
- package/dist/check-confirm-dialog-BT04Mieo.cjs.map +1 -0
- package/dist/{check-confirm-dialog-bRT8lt0d.js → check-confirm-dialog-CtiRzOAt.js} +391 -108
- package/dist/check-confirm-dialog-CtiRzOAt.js.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-ByGhxLf_.cjs} +1021 -154
- package/dist/filter-builder-ByGhxLf_.cjs.map +1 -0
- package/dist/{filter-builder-Bhn-dhZV.js → filter-builder-z3Axzf9Y.js} +929 -140
- package/dist/filter-builder-z3Axzf9Y.js.map +1 -0
- package/dist/{flow-runtime-D3avVH0I.cjs → flow-runtime-BVFjMU5-.cjs} +64 -29
- package/dist/flow-runtime-BVFjMU5-.cjs.map +1 -0
- package/dist/{flow-runtime-s6lkRPKF.js → flow-runtime-DrUWyTS0.js} +65 -30
- package/dist/flow-runtime-DrUWyTS0.js.map +1 -0
- package/dist/{flow-screen-CCvgDI9G.js → flow-screen-3fk6J33y.js} +130 -87
- package/dist/flow-screen-3fk6J33y.js.map +1 -0
- package/dist/{flow-screen-Ci_Sik4Y.cjs → flow-screen-6y5E_HT6.cjs} +130 -87
- package/dist/flow-screen-6y5E_HT6.cjs.map +1 -0
- package/dist/index.cjs +1186 -950
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +631 -322
- package/dist/index.d.ts +631 -322
- package/dist/index.js +1100 -870
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-DV1et3c6.cjs → inline-flow-host-C4KmZIYE.cjs} +5 -5
- package/dist/inline-flow-host-C4KmZIYE.cjs.map +1 -0
- package/dist/{inline-flow-host-B6FI0ctQ.js → inline-flow-host-YnnvWjdU.js} +5 -5
- package/dist/inline-flow-host-YnnvWjdU.js.map +1 -0
- package/dist/{candidates-gate-D33jXLHO.cjs → lazy-relation-picker-dialog-BAKBRn3V.cjs} +10 -10
- package/dist/lazy-relation-picker-dialog-BAKBRn3V.cjs.map +1 -0
- package/dist/{candidates-gate-Bb70LPAy.js → lazy-relation-picker-dialog-DN4bvQfg.js} +11 -11
- package/dist/lazy-relation-picker-dialog-DN4bvQfg.js.map +1 -0
- package/dist/{page-flow-route-i3ZfJ1sd.js → page-flow-route-CtEfqAvU.js} +35 -23
- package/dist/page-flow-route-CtEfqAvU.js.map +1 -0
- package/dist/{page-flow-route-hdnULWqd.cjs → page-flow-route-DEjAxHe3.cjs} +42 -30
- package/dist/page-flow-route-DEjAxHe3.cjs.map +1 -0
- package/dist/{place-node-NraNYKPx.js → place-node-BdxT-30h.js} +1980 -1041
- package/dist/place-node-BdxT-30h.js.map +1 -0
- package/dist/{place-node-C5SmIAYU.cjs → place-node-Bhl8B3fF.cjs} +2038 -1087
- package/dist/place-node-Bhl8B3fF.cjs.map +1 -0
- package/dist/{related-list-cards-CFq3meUn.cjs → related-list-cards-Bc_vfCE_.cjs} +9 -4
- package/dist/{related-list-cards-CFq3meUn.cjs.map → related-list-cards-Bc_vfCE_.cjs.map} +1 -1
- package/dist/{related-list-cards-BWZ9GfOG.js → related-list-cards-BvkD5OcC.js} +9 -4
- package/dist/{related-list-cards-BWZ9GfOG.js.map → related-list-cards-BvkD5OcC.js.map} +1 -1
- package/dist/related-list-timeline-DCrwN9oO.js +167 -0
- package/dist/related-list-timeline-DCrwN9oO.js.map +1 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs +167 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs.map +1 -0
- package/dist/{related-rows-ea43qhhy.cjs → related-rows-BW9Jr07T.cjs} +27 -16
- package/dist/related-rows-BW9Jr07T.cjs.map +1 -0
- package/dist/{related-rows-o0_t-Yce.js → related-rows-CPE-9FFr.js} +25 -14
- package/dist/related-rows-CPE-9FFr.js.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-BlrGRwMV.js} +210 -104
- package/dist/relation-many-picker-BlrGRwMV.js.map +1 -0
- package/dist/{relation-many-picker-C8zFEjwd.cjs → relation-many-picker-Br-zBHxT.cjs} +218 -112
- package/dist/relation-many-picker-Br-zBHxT.cjs.map +1 -0
- package/dist/{relation-picker-gag0qSR5.cjs → relation-picker-ADjxI_TI.cjs} +36 -73
- package/dist/relation-picker-ADjxI_TI.cjs.map +1 -0
- package/dist/{relation-picker-dialog-B6nIiJBf.js → relation-picker-dialog-CyKliBkN.js} +134 -36
- package/dist/relation-picker-dialog-CyKliBkN.js.map +1 -0
- package/dist/{relation-picker-dialog-0IzkjmiA.cjs → relation-picker-dialog-DimVQF9Y.cjs} +133 -35
- package/dist/relation-picker-dialog-DimVQF9Y.cjs.map +1 -0
- package/dist/{relation-picker-Z0ZJJ5uS.js → relation-picker-x7P5HKie.js} +30 -61
- package/dist/relation-picker-x7P5HKie.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-3RUf9d1j.js → resource-page-router-BRpUnhay.js} +634 -264
- package/dist/resource-page-router-BRpUnhay.js.map +1 -0
- package/dist/{resource-page-router-PXfMW9nh.cjs → resource-page-router-qEd2xb55.cjs} +694 -312
- package/dist/resource-page-router-qEd2xb55.cjs.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/dist/use-record-subtitle-bfwIoUme.cjs +70 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs.map +1 -0
- package/dist/use-record-subtitle-gIaCGgbI.js +53 -0
- package/dist/use-record-subtitle-gIaCGgbI.js.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 +0 -142
- package/dist/related-list-timeline-CCzl71aA.cjs.map +0 -1
- package/dist/related-list-timeline-yrPsjA3F.js +0 -142
- 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,13 +1,15 @@
|
|
|
1
1
|
const require_use_theme = require("./use-theme-DFlpXils.cjs");
|
|
2
|
-
const require_toaster = require("./toaster-
|
|
3
|
-
const require_check_confirm_dialog = require("./check-confirm-dialog
|
|
2
|
+
const require_toaster = require("./toaster-BbByOytP.cjs");
|
|
3
|
+
const require_check_confirm_dialog = require("./check-confirm-dialog-BT04Mieo.cjs");
|
|
4
4
|
const require_button = require("./button-BxnnE28H.cjs");
|
|
5
5
|
const require_input = require("./input-BI0czGyI.cjs");
|
|
6
|
-
const require_dialog = require("./dialog-
|
|
7
|
-
const
|
|
6
|
+
const require_dialog = require("./dialog-vmMdfUWs.cjs");
|
|
7
|
+
const require_relation_create = require("./relation-create-DDEYcKfw.cjs");
|
|
8
8
|
const require_skeleton = require("./skeleton-_1gP7wan.cjs");
|
|
9
|
-
const require_filter_builder = require("./filter-builder-
|
|
9
|
+
const require_filter_builder = require("./filter-builder-ByGhxLf_.cjs");
|
|
10
10
|
const require_label = require("./label-w6JYf2cF.cjs");
|
|
11
|
+
const require_lazy_relation_picker_dialog = require("./lazy-relation-picker-dialog-BAKBRn3V.cjs");
|
|
12
|
+
const require_relation_select = require("./relation-select-Cr3CfNLy.cjs");
|
|
11
13
|
let _burojs_core = require("@burojs/core");
|
|
12
14
|
let _burojs_react = require("@burojs/react");
|
|
13
15
|
let _tabler_icons_react = require("@tabler/icons-react");
|
|
@@ -120,428 +122,91 @@ function toDisplayText(value) {
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
//#endregion
|
|
123
|
-
//#region src/
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
text
|
|
128
|
-
|
|
129
|
-
format: "text"
|
|
130
|
-
},
|
|
131
|
-
textarea: {
|
|
132
|
-
type: "string",
|
|
133
|
-
format: "textarea"
|
|
134
|
-
},
|
|
135
|
-
code: {
|
|
136
|
-
type: "string",
|
|
137
|
-
format: "code"
|
|
138
|
-
},
|
|
139
|
-
email: {
|
|
140
|
-
type: "string",
|
|
141
|
-
format: "email"
|
|
142
|
-
},
|
|
143
|
-
url: {
|
|
144
|
-
type: "string",
|
|
145
|
-
format: "url"
|
|
146
|
-
},
|
|
147
|
-
uuid: {
|
|
148
|
-
type: "string",
|
|
149
|
-
format: "uuid"
|
|
150
|
-
},
|
|
151
|
-
number: { type: "number" },
|
|
152
|
-
boolean: { type: "boolean" },
|
|
153
|
-
date: {
|
|
154
|
-
type: "string",
|
|
155
|
-
format: "date"
|
|
156
|
-
},
|
|
157
|
-
dateTime: {
|
|
158
|
-
type: "string",
|
|
159
|
-
format: "date-time"
|
|
160
|
-
},
|
|
161
|
-
enum: {
|
|
162
|
-
type: "string",
|
|
163
|
-
format: "enum"
|
|
164
|
-
},
|
|
165
|
-
json: {
|
|
166
|
-
type: "object",
|
|
167
|
-
format: "json"
|
|
168
|
-
},
|
|
169
|
-
richText: {
|
|
170
|
-
type: "string",
|
|
171
|
-
format: "rich-text"
|
|
172
|
-
},
|
|
173
|
-
file: {
|
|
174
|
-
type: "array",
|
|
175
|
-
format: "file",
|
|
176
|
-
items: STRING_ITEM
|
|
177
|
-
},
|
|
178
|
-
relation: { type: "relation" },
|
|
179
|
-
relationMany: {
|
|
180
|
-
type: "array",
|
|
181
|
-
format: "relation",
|
|
182
|
-
items: STRING_ITEM
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
const SEMANTIC_KEYS = Object.freeze([
|
|
186
|
-
"type",
|
|
187
|
-
"format",
|
|
188
|
-
"meta",
|
|
189
|
-
"required",
|
|
190
|
-
"nullable",
|
|
191
|
-
"empty",
|
|
192
|
-
"default",
|
|
193
|
-
"constraints",
|
|
194
|
-
"texts",
|
|
195
|
-
"options",
|
|
196
|
-
"items",
|
|
197
|
-
"properties",
|
|
198
|
-
"additionalProperties",
|
|
199
|
-
"variants"
|
|
200
|
-
]);
|
|
201
|
-
function ownData(value, key) {
|
|
202
|
-
if (value === null || typeof value !== "object" && typeof value !== "function") return { present: false };
|
|
203
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
204
|
-
if (descriptor === void 0 || !Object.prototype.propertyIsEnumerable.call(value, key) || !("value" in descriptor)) return { present: false };
|
|
205
|
-
return {
|
|
206
|
-
present: true,
|
|
207
|
-
value: descriptor.value
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
function ownString(value, key) {
|
|
211
|
-
const candidate = ownData(value, key).value;
|
|
212
|
-
return typeof candidate === "string" && candidate.length > 0 ? candidate : void 0;
|
|
213
|
-
}
|
|
214
|
-
function projectUiSelection(input) {
|
|
215
|
-
const selection = {};
|
|
216
|
-
const inputId = ownString(input, "input");
|
|
217
|
-
const displayId = ownString(input, "display");
|
|
218
|
-
if (inputId !== void 0) selection.input = inputId;
|
|
219
|
-
if (displayId !== void 0) selection.display = displayId;
|
|
220
|
-
return inputId === void 0 && displayId === void 0 ? void 0 : Object.freeze(selection);
|
|
221
|
-
}
|
|
222
|
-
function projectFieldDeclaration(input) {
|
|
223
|
-
const type = ownString(input, "type");
|
|
224
|
-
if (type === void 0) return void 0;
|
|
225
|
-
const projected = { type };
|
|
226
|
-
for (const key of SEMANTIC_KEYS) {
|
|
227
|
-
if (key === "type" || key === "items" || key === "properties" || key === "variants") continue;
|
|
228
|
-
const candidate = ownData(input, key);
|
|
229
|
-
if (candidate.present && candidate.value !== void 0) projected[key] = candidate.value;
|
|
230
|
-
}
|
|
231
|
-
const ui = projectUiSelection(ownData(input, "ui").value);
|
|
232
|
-
if (ui !== void 0) projected.ui = ui;
|
|
233
|
-
if (type === "array") {
|
|
234
|
-
const item = projectFieldDeclaration(ownData(input, "items").value);
|
|
235
|
-
if (item !== void 0) projected.items = item;
|
|
236
|
-
}
|
|
237
|
-
if (type === "object") {
|
|
238
|
-
const properties = ownData(input, "properties").value;
|
|
239
|
-
if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
|
|
240
|
-
const output = {};
|
|
241
|
-
for (const key of Object.keys(properties)) {
|
|
242
|
-
const child = projectFieldDeclaration(ownData(properties, key).value);
|
|
243
|
-
if (child !== void 0) output[key] = child;
|
|
244
|
-
}
|
|
245
|
-
projected.properties = Object.freeze(output);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (type === "union") {
|
|
249
|
-
const variants = ownData(input, "variants").value;
|
|
250
|
-
if (Array.isArray(variants)) {
|
|
251
|
-
const output = [];
|
|
252
|
-
for (let index = 0; index < variants.length; index += 1) {
|
|
253
|
-
const child = projectFieldDeclaration(ownData(variants, index).value);
|
|
254
|
-
if (child !== void 0) output.push(child);
|
|
255
|
-
}
|
|
256
|
-
projected.variants = Object.freeze(output);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return Object.freeze(projected);
|
|
260
|
-
}
|
|
261
|
-
function projectUiHints(input) {
|
|
262
|
-
if (input === null || typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
263
|
-
const projected = {};
|
|
264
|
-
for (const key of Object.keys(input)) {
|
|
265
|
-
const candidate = ownData(input, key);
|
|
266
|
-
if (candidate.present) projected[key] = candidate.value;
|
|
267
|
-
}
|
|
268
|
-
return Object.freeze(projected);
|
|
269
|
-
}
|
|
270
|
-
function lowerLegacyField(field) {
|
|
271
|
-
const declaration = projectFieldDeclaration(ownData(field, "declaration").value);
|
|
272
|
-
if (declaration !== void 0) return declaration;
|
|
273
|
-
const direct = projectFieldDeclaration(field);
|
|
274
|
-
const kind = ownString(field, "kind");
|
|
275
|
-
const mapping = kind === void 0 ? void 0 : LEGACY_KIND_DECLARATIONS[kind];
|
|
276
|
-
if (direct !== void 0) {
|
|
277
|
-
const format = direct.format ?? mapping?.format ?? kind;
|
|
278
|
-
return format === void 0 ? direct : Object.freeze({
|
|
279
|
-
...direct,
|
|
280
|
-
format
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
const ui = projectUiHints(ownData(field, "ui").value);
|
|
284
|
-
const type = kind === "file" && ui?.multiple !== true ? "unknown" : mapping?.type ?? "unknown";
|
|
285
|
-
const format = ownString(field, "format") ?? mapping?.format ?? kind;
|
|
286
|
-
const items = type === "array" ? projectFieldDeclaration(ownData(field, "items").value) ?? mapping?.items ?? STRING_ITEM : void 0;
|
|
287
|
-
const meta = ownData(field, "meta");
|
|
288
|
-
const texts = ownData(field, "texts");
|
|
289
|
-
const required = ownData(field, "required");
|
|
290
|
-
const nullable = ownData(field, "nullable");
|
|
291
|
-
const opts = ownData(field, "opts").value;
|
|
292
|
-
const optionRequired = ownData(opts, "required");
|
|
293
|
-
const optionNullable = ownData(opts, "nullable");
|
|
294
|
-
const requiredValue = required.present ? required.value : optionRequired.value;
|
|
295
|
-
const nullableValue = nullable.present ? nullable.value : optionNullable.value;
|
|
296
|
-
return Object.freeze({
|
|
297
|
-
type,
|
|
298
|
-
...format === void 0 ? {} : { format },
|
|
299
|
-
...items === void 0 ? {} : { items },
|
|
300
|
-
...meta.present && meta.value !== void 0 ? { meta: meta.value } : {},
|
|
301
|
-
...texts.present && texts.value !== void 0 ? { texts: texts.value } : {},
|
|
302
|
-
...requiredValue === true ? { required: true } : {},
|
|
303
|
-
...nullableValue === true ? { nullable: true } : {}
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
function lowerLegacyFieldSource(field) {
|
|
307
|
-
const declaration = lowerLegacyField(field);
|
|
308
|
-
const ui = projectUiHints(ownData(field, "ui").value);
|
|
309
|
-
if (ui === void 0) return declaration;
|
|
310
|
-
return Object.freeze({
|
|
311
|
-
...declaration,
|
|
312
|
-
ui
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
function fieldDescription(field) {
|
|
316
|
-
const declaration = field?.declaration;
|
|
317
|
-
return (0, _burojs_core.declaredText)("field", declaration, "description") ?? (0, _burojs_core.declaredText)("field", field, "description");
|
|
125
|
+
//#region src/data-table/annotate-if-clipped.ts
|
|
126
|
+
function annotateIfClipped(e) {
|
|
127
|
+
const el = e.currentTarget;
|
|
128
|
+
const text = el.scrollWidth > el.clientWidth || Array.from(el.querySelectorAll("*")).some((c) => c.scrollWidth > c.clientWidth) ? (el.textContent ?? "").trim() : "";
|
|
129
|
+
if (text) el.setAttribute("title", text);
|
|
130
|
+
else el.removeAttribute("title");
|
|
318
131
|
}
|
|
319
132
|
//#endregion
|
|
320
|
-
//#region src/fields/
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
if (item === null || typeof item !== "object" || Array.isArray(item)) continue;
|
|
335
|
-
const raw = item;
|
|
336
|
-
if (typeof raw.value !== "string" && typeof raw.value !== "number" && typeof raw.value !== "boolean" && raw.value !== null) continue;
|
|
337
|
-
const { value, label, description, ...legacyMeta } = raw;
|
|
338
|
-
if (typeof label !== "string" && process.env.NODE_ENV !== "production" && !warnedObjectLabels.has(`${name}:${value}`)) {
|
|
339
|
-
warnedObjectLabels.add(`${name}:${value}`);
|
|
340
|
-
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).`);
|
|
341
|
-
}
|
|
342
|
-
output.push(Object.freeze({
|
|
343
|
-
value,
|
|
344
|
-
label: typeof label === "string" ? label : String(value),
|
|
345
|
-
...typeof description === "string" ? { description } : {},
|
|
346
|
-
...Object.keys(legacyMeta).length === 0 ? {} : { meta: Object.freeze(legacyMeta) }
|
|
347
|
-
}));
|
|
348
|
-
}
|
|
349
|
-
return Object.freeze(output);
|
|
350
|
-
}
|
|
351
|
-
const readScope = (ctx) => ctx.scope;
|
|
352
|
-
function useFieldRuntimeContext(resource, record, values, metaSources) {
|
|
353
|
-
const scope = (0, _burojs_react.useCtx)(readScope);
|
|
354
|
-
const locale = (0, _burojs_react.useLocale)();
|
|
355
|
-
const caps = (0, _burojs_react.useI18nCaps)((0, _burojs_core.formatEntityRef)(resource));
|
|
356
|
-
const metaSourcesOut = (0, _burojs_react.useFieldMetaSources)({
|
|
357
|
-
record,
|
|
358
|
-
values,
|
|
359
|
-
extra: metaSources
|
|
360
|
-
});
|
|
361
|
-
return (0, react.useMemo)(() => Object.freeze({
|
|
362
|
-
i18n: Object.freeze({
|
|
363
|
-
locale,
|
|
364
|
-
has: caps.has,
|
|
365
|
-
t: caps.t
|
|
366
|
-
}),
|
|
367
|
-
sources: Object.freeze({
|
|
368
|
-
record: record ?? EMPTY,
|
|
369
|
-
values: values ?? EMPTY,
|
|
370
|
-
scope: scope ?? EMPTY
|
|
371
|
-
}),
|
|
372
|
-
metaSources: metaSourcesOut
|
|
373
|
-
}), [
|
|
374
|
-
caps,
|
|
375
|
-
locale,
|
|
376
|
-
record,
|
|
377
|
-
scope,
|
|
378
|
-
values,
|
|
379
|
-
metaSourcesOut
|
|
380
|
-
]);
|
|
381
|
-
}
|
|
382
|
-
function useFieldMetaDiagnostic(state, resource, name, field, surface) {
|
|
383
|
-
const reported = (0, react.useRef)(void 0);
|
|
384
|
-
const reason = state.status === "failed" ? state.reason : void 0;
|
|
385
|
-
(0, react.useEffect)(() => {
|
|
386
|
-
if (reason === void 0 || reported.current === reason || process.env.NODE_ENV === "production") return;
|
|
387
|
-
reported.current = reason;
|
|
388
|
-
const named = field.ui?.[surface];
|
|
389
|
-
const implementation = typeof named === "string" ? named : field.format ?? field.type;
|
|
390
|
-
console.error(`[burojs] field.meta-invalid: ${(0, _burojs_core.formatEntityRef)(resource)}.${name} (${implementation}): ${reason}`);
|
|
391
|
-
}, [
|
|
392
|
-
reason,
|
|
393
|
-
resource,
|
|
394
|
-
name,
|
|
395
|
-
field,
|
|
396
|
-
surface
|
|
397
|
-
]);
|
|
398
|
-
}
|
|
399
|
-
function MetaPlaceholder({ state }) {
|
|
133
|
+
//#region src/fields/field-value-frame.tsx
|
|
134
|
+
const COPY_CLASSES = [
|
|
135
|
+
"string",
|
|
136
|
+
"number",
|
|
137
|
+
"date"
|
|
138
|
+
];
|
|
139
|
+
const COPIED_MS = 2e3;
|
|
140
|
+
const isRecord$1 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
141
|
+
const isEmpty = (value) => value === null || value === void 0 || value === "";
|
|
142
|
+
function copyText(value) {
|
|
143
|
+
if (value instanceof Date) return value.toISOString();
|
|
144
|
+
return typeof value === "string" ? value : String(value);
|
|
145
|
+
}
|
|
146
|
+
function FieldValueFrame({ field, value, surface, entry, children }) {
|
|
400
147
|
const t = (0, _burojs_react.useOptionalT)();
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
"data-buro-field-meta": "pending",
|
|
404
|
-
className: "h-9 w-full"
|
|
405
|
-
});
|
|
406
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
407
|
-
role: "alert",
|
|
408
|
-
"data-buro-field-meta": "failed",
|
|
409
|
-
className: "rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground",
|
|
410
|
-
children: t("field.misconfigured", { defaultValue: "This field is misconfigured" })
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
function useFieldImplementationDiagnostic(diagnostic) {
|
|
414
|
-
const reported = (0, react.useRef)(void 0);
|
|
148
|
+
const clipboard = (0, _burojs_react.useClipboard)();
|
|
149
|
+
const [copied, setCopied] = (0, react.useState)(null);
|
|
415
150
|
(0, react.useEffect)(() => {
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}, [
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
});
|
|
428
|
-
const runtimeContext = useFieldRuntimeContext(resource, record, record, metaSources);
|
|
429
|
-
const metaState = (0, _burojs_react.useFieldMeta)(field, resolved.implementation, runtimeContext.metaSources);
|
|
430
|
-
useFieldMetaDiagnostic(metaState, resource, name, field, "display");
|
|
431
|
-
useFieldImplementationDiagnostic(resolved.diagnostic);
|
|
432
|
-
if (resolved.Component === void 0) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: fallback });
|
|
433
|
-
if (metaState.status !== "ready") return (0, react_jsx_runtime.jsx)(MetaPlaceholder, { state: metaState });
|
|
434
|
-
const Component = resolved.Component;
|
|
435
|
-
const context = {
|
|
436
|
-
owner: resource,
|
|
437
|
-
resource,
|
|
151
|
+
if (copied === null) return;
|
|
152
|
+
const timer = setTimeout(() => setCopied(null), COPIED_MS);
|
|
153
|
+
return () => clearTimeout(timer);
|
|
154
|
+
}, [copied]);
|
|
155
|
+
const ui = isRecord$1(field.ui) ? field.ui : void 0;
|
|
156
|
+
const asksCopy = ui?.copy === true;
|
|
157
|
+
const valueClass = (0, react.useMemo)(() => asksCopy ? (0, _burojs_core.displayClassOf)({
|
|
158
|
+
...require_filter_builder.lowerLegacyField(field),
|
|
159
|
+
...ui === void 0 ? {} : { ui }
|
|
160
|
+
}) : void 0, [
|
|
161
|
+
asksCopy,
|
|
438
162
|
field,
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
};
|
|
454
|
-
if (resolved.multiple) return (0, react.createElement)(Component, {
|
|
455
|
-
...context,
|
|
456
|
-
multiple: true,
|
|
457
|
-
value: Array.isArray(value) ? value : []
|
|
458
|
-
});
|
|
459
|
-
return (0, react.createElement)(Component, {
|
|
460
|
-
...context,
|
|
461
|
-
multiple: false,
|
|
462
|
-
value
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
function ResolvedFieldInput({ resource, name, field: source, value, record, form, testId, inputId, onChange, onBlur, disabled, required, placeholder, descriptionId, errorId, errorMessage, pending = false, touched = errorMessage != null, issues: suppliedIssues, relationSeeds, fixedFilters, metaSources, fallback }) {
|
|
466
|
-
const sourceAtEdge = lowerLegacyFieldSource(source);
|
|
467
|
-
const base = canonical(sourceAtEdge);
|
|
468
|
-
const field = required === void 0 || required === base.required ? base : Object.freeze({
|
|
469
|
-
...base,
|
|
470
|
-
required
|
|
471
|
-
});
|
|
472
|
-
const ui = Object.freeze({
|
|
473
|
-
...sourceAtEdge.ui ?? EMPTY,
|
|
474
|
-
...placeholder === void 0 ? {} : { placeholder }
|
|
475
|
-
});
|
|
476
|
-
const resolved = (0, _burojs_react.useFieldImplementation)({
|
|
477
|
-
field: {
|
|
478
|
-
...field,
|
|
479
|
-
ui
|
|
480
|
-
},
|
|
481
|
-
surface: "input"
|
|
163
|
+
ui
|
|
164
|
+
]);
|
|
165
|
+
const { overflow: declared } = (0, _burojs_core.resolveSurfaceUi)(field, surface, entry);
|
|
166
|
+
const copyable = asksCopy && clipboard !== void 0 && !isEmpty(value) && valueClass !== void 0 && COPY_CLASSES.includes(valueClass);
|
|
167
|
+
if (!copyable && declared === void 0) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
168
|
+
const body = (declared ?? (surface === "column" ? "truncate" : "wrap")) === "wrap" ? (0, react_jsx_runtime.jsx)("span", {
|
|
169
|
+
className: "min-w-0 whitespace-normal [overflow-wrap:anywhere]",
|
|
170
|
+
"data-buro-overflow": "wrap",
|
|
171
|
+
children
|
|
172
|
+
}) : (0, react_jsx_runtime.jsx)("span", {
|
|
173
|
+
className: "inline-block min-w-0 max-w-full truncate align-bottom",
|
|
174
|
+
"data-buro-overflow": "truncate",
|
|
175
|
+
onPointerEnter: annotateIfClipped,
|
|
176
|
+
children
|
|
482
177
|
});
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const Component = resolved.Component;
|
|
490
|
-
const issues = suppliedIssues ?? (errorMessage == null ? EMPTY_ISSUES$1 : Object.freeze([Object.freeze({
|
|
491
|
-
code: "ui.field-error",
|
|
492
|
-
message: {
|
|
493
|
-
key: "ui.field-error",
|
|
494
|
-
default: errorMessage
|
|
495
|
-
},
|
|
496
|
-
path: Object.freeze([]),
|
|
497
|
-
source: "field",
|
|
498
|
-
severity: "error"
|
|
499
|
-
})]));
|
|
500
|
-
const context = {
|
|
501
|
-
owner: resource,
|
|
502
|
-
resource,
|
|
503
|
-
field,
|
|
504
|
-
path: Object.freeze([name]),
|
|
505
|
-
surface: "input",
|
|
506
|
-
presentation: "default",
|
|
507
|
-
record,
|
|
508
|
-
form,
|
|
509
|
-
meta: metaState.meta,
|
|
510
|
-
ui,
|
|
511
|
-
options: optionsFor(field, name),
|
|
512
|
-
i18n: runtimeContext.i18n,
|
|
513
|
-
sources: runtimeContext.sources,
|
|
514
|
-
pending,
|
|
515
|
-
touched,
|
|
516
|
-
issues,
|
|
517
|
-
accessibility: Object.freeze({
|
|
518
|
-
input: inputId ?? name,
|
|
519
|
-
description: descriptionId,
|
|
520
|
-
error: errorId
|
|
521
|
-
}),
|
|
522
|
-
testIds: testId === void 0 ? EMPTY : Object.freeze({ input: testId })
|
|
178
|
+
if (!copyable) return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: body });
|
|
179
|
+
const label = t("field.copy", { defaultValue: "Copy" });
|
|
180
|
+
const copy = (event) => {
|
|
181
|
+
event.preventDefault();
|
|
182
|
+
event.stopPropagation();
|
|
183
|
+
clipboard(copyText(value)).then(() => setCopied("copied"), () => setCopied("failed"));
|
|
523
184
|
};
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
185
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
186
|
+
className: "inline-flex min-w-0 max-w-full items-center gap-1 align-bottom",
|
|
187
|
+
children: [
|
|
188
|
+
body,
|
|
189
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
190
|
+
type: "button",
|
|
191
|
+
"data-testid": `field-copy:${field.name}`,
|
|
192
|
+
"aria-label": label,
|
|
193
|
+
title: label,
|
|
194
|
+
onClick: copy,
|
|
195
|
+
className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
196
|
+
children: copied === "copied" ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, {
|
|
197
|
+
"aria-hidden": "true",
|
|
198
|
+
className: "size-3.5"
|
|
199
|
+
}) : (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCopy, {
|
|
200
|
+
"aria-hidden": "true",
|
|
201
|
+
className: "size-3.5"
|
|
202
|
+
})
|
|
203
|
+
}),
|
|
204
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
205
|
+
"aria-live": "polite",
|
|
206
|
+
className: "sr-only",
|
|
207
|
+
children: copied === "copied" ? t("field.copied", { defaultValue: "Copied" }) : copied === "failed" ? t("field.copyFailed", { defaultValue: "Could not copy" }) : ""
|
|
208
|
+
})
|
|
209
|
+
]
|
|
545
210
|
});
|
|
546
211
|
}
|
|
547
212
|
//#endregion
|
|
@@ -555,7 +220,7 @@ function resolveRef(resource, i18nPrefix) {
|
|
|
555
220
|
};
|
|
556
221
|
}
|
|
557
222
|
function Field({ resource, i18nPrefix, fallback, fixedFilters, field, doc, ...rest }) {
|
|
558
|
-
const input = (0, react_jsx_runtime.jsx)(ResolvedFieldInput, {
|
|
223
|
+
const input = (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldInput, {
|
|
559
224
|
...rest,
|
|
560
225
|
field,
|
|
561
226
|
...fixedFilters === void 0 ? {} : { fixedFilters },
|
|
@@ -581,20 +246,30 @@ function Field({ resource, i18nPrefix, fallback, fixedFilters, field, doc, ...re
|
|
|
581
246
|
});
|
|
582
247
|
}
|
|
583
248
|
function FieldDisplay({ resource, i18nPrefix, fallback, value, ...rest }) {
|
|
584
|
-
|
|
585
|
-
...rest,
|
|
249
|
+
const frameField = (0, react.useMemo)(() => ({
|
|
250
|
+
...rest.field,
|
|
251
|
+
name: rest.name
|
|
252
|
+
}), [rest.field, rest.name]);
|
|
253
|
+
return (0, react_jsx_runtime.jsx)(FieldValueFrame, {
|
|
254
|
+
field: frameField,
|
|
586
255
|
value,
|
|
587
|
-
|
|
588
|
-
|
|
256
|
+
surface: "display",
|
|
257
|
+
children: (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldDisplay, {
|
|
258
|
+
...rest,
|
|
259
|
+
value,
|
|
260
|
+
resource: resolveRef(resource, i18nPrefix),
|
|
261
|
+
fallback: fallback ?? (0, react_jsx_runtime.jsx)("span", { children: value == null || value === "" ? "—" : String(value) })
|
|
262
|
+
})
|
|
589
263
|
});
|
|
590
264
|
}
|
|
591
265
|
//#endregion
|
|
592
266
|
//#region src/screen/field-leaf.tsx
|
|
593
267
|
const SIZES = new Set(_burojs_core.LAYOUT_SIZES);
|
|
268
|
+
const SHOWN_ISSUES = 3;
|
|
594
269
|
const FOCUSABLE = "input:not([type=\"hidden\"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled]), [contenteditable=\"true\"], [tabindex]:not([tabindex=\"-1\"])";
|
|
595
270
|
function useLeafSize(field) {
|
|
596
271
|
const implementation = (0, _burojs_react.useFieldImplementation)({
|
|
597
|
-
field: lowerLegacyField(field),
|
|
272
|
+
field: require_filter_builder.lowerLegacyField(field),
|
|
598
273
|
surface: "input"
|
|
599
274
|
});
|
|
600
275
|
const declared = field.ui?.size;
|
|
@@ -609,6 +284,10 @@ function leafAttributes(size, weight) {
|
|
|
609
284
|
...weight === void 0 ? {} : { "data-buro-weight": String(weight) }
|
|
610
285
|
};
|
|
611
286
|
}
|
|
287
|
+
function labelHiddenOf(compiled, node) {
|
|
288
|
+
return compiled.nodes[node.index]?.options.label === "hidden";
|
|
289
|
+
}
|
|
290
|
+
const labelRegion = (hidden, visible) => hidden ? "sr-only" : visible;
|
|
612
291
|
function FieldLeaf({ node }) {
|
|
613
292
|
const { leafIds } = useScreenTree();
|
|
614
293
|
if (node.state === "failed" && node.failedOn.length > 0 && node.failedOn.every((name) => name.startsWith("meta:"))) return (0, react_jsx_runtime.jsx)(MisconfiguredLeaf, { node });
|
|
@@ -620,12 +299,13 @@ function FieldLeaf({ node }) {
|
|
|
620
299
|
return (0, react_jsx_runtime.jsx)(RecordLeaf, { node });
|
|
621
300
|
}
|
|
622
301
|
function MisconfiguredLeaf({ node }) {
|
|
623
|
-
const { leafIds, resource, mode, controller } = useScreenTree();
|
|
302
|
+
const { leafIds, resource, mode, compiled, controller } = useScreenTree();
|
|
303
|
+
const hidden = labelHiddenOf(compiled, node);
|
|
624
304
|
const name = node.field;
|
|
625
305
|
const binding = controller.field(name);
|
|
626
306
|
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
627
307
|
const tid = (0, _burojs_react.useTestIds)();
|
|
628
|
-
const field = lowerLegacyField(binding.field);
|
|
308
|
+
const field = require_filter_builder.lowerLegacyField(binding.field);
|
|
629
309
|
const surface = mode === "show" ? "display" : "input";
|
|
630
310
|
const resolved = (0, _burojs_react.useFieldImplementation)({
|
|
631
311
|
field,
|
|
@@ -636,8 +316,8 @@ function MisconfiguredLeaf({ node }) {
|
|
|
636
316
|
values: controller.values,
|
|
637
317
|
extra: controller.sources
|
|
638
318
|
});
|
|
639
|
-
const state = (0, _burojs_react.useFieldMeta)(field, resolved.implementation, sources);
|
|
640
|
-
useFieldMetaDiagnostic(state, binding.resource, name, field, surface);
|
|
319
|
+
const state = (0, _burojs_react.useFieldMeta)(field, resolved.implementation, sources, resolved.params);
|
|
320
|
+
require_filter_builder.useFieldMetaDiagnostic(state, binding.resource, name, field, surface);
|
|
641
321
|
const label = (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", binding.field, "label"));
|
|
642
322
|
const testId = leafIds === "record" ? tid.formField(resource, mode, name) : `${leafIds.prefix}:field:${name}`;
|
|
643
323
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -647,20 +327,30 @@ function MisconfiguredLeaf({ node }) {
|
|
|
647
327
|
"data-buro-field-meta": "failed",
|
|
648
328
|
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
649
329
|
"data-buro-region": "field-label",
|
|
650
|
-
className: "text-sm font-medium leading-none",
|
|
330
|
+
className: labelRegion(hidden, "text-sm font-medium leading-none"),
|
|
651
331
|
children: label
|
|
652
332
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
653
333
|
"data-buro-region": "field-control",
|
|
654
|
-
children: (0, react_jsx_runtime.jsx)(MetaPlaceholder, { state })
|
|
334
|
+
children: (0, react_jsx_runtime.jsx)(require_filter_builder.MetaPlaceholder, { state })
|
|
655
335
|
})]
|
|
656
336
|
});
|
|
657
337
|
}
|
|
338
|
+
function valueAt(record, path) {
|
|
339
|
+
let at = record;
|
|
340
|
+
for (const segment of path.split(".")) {
|
|
341
|
+
if (at === null || typeof at !== "object") return void 0;
|
|
342
|
+
at = at[segment];
|
|
343
|
+
}
|
|
344
|
+
return at;
|
|
345
|
+
}
|
|
658
346
|
function RecordLeaf({ node }) {
|
|
659
347
|
const { resource, mode, compiled, controller } = useScreenTree();
|
|
660
|
-
const
|
|
348
|
+
const head = node.field;
|
|
349
|
+
const name = node.fieldPath ?? head;
|
|
661
350
|
const binding = controller.field(name);
|
|
662
351
|
const size = useLeafSize(binding.field);
|
|
663
352
|
const weight = compiled.nodes[node.index]?.options.weight;
|
|
353
|
+
const hidden = labelHiddenOf(compiled, node);
|
|
664
354
|
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
665
355
|
const tid = (0, _burojs_react.useTestIds)();
|
|
666
356
|
const label = (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", binding.field, "label"));
|
|
@@ -668,10 +358,7 @@ function RecordLeaf({ node }) {
|
|
|
668
358
|
const t = (0, _burojs_react.useOptionalT)();
|
|
669
359
|
if (node.restricted === true) {
|
|
670
360
|
const rawReason = node.restrictedReason;
|
|
671
|
-
const reason = rawReason === void 0 || rawReason === "" ? void 0 :
|
|
672
|
-
resource,
|
|
673
|
-
default: rawReason
|
|
674
|
-
});
|
|
361
|
+
const reason = rawReason === void 0 || rawReason === "" ? void 0 : require_check_confirm_dialog.reasonText(caps, rawReason, resource);
|
|
675
362
|
const restrictedId = tid.formFieldRestricted(resource, mode, name);
|
|
676
363
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
677
364
|
...attributes,
|
|
@@ -680,7 +367,7 @@ function RecordLeaf({ node }) {
|
|
|
680
367
|
"data-buro-restricted": "true",
|
|
681
368
|
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
682
369
|
"data-buro-region": "field-label",
|
|
683
|
-
className: "text-sm font-medium leading-none",
|
|
370
|
+
className: labelRegion(hidden, "text-sm font-medium leading-none"),
|
|
684
371
|
children: label
|
|
685
372
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
686
373
|
"data-buro-region": "field-control",
|
|
@@ -700,7 +387,7 @@ function RecordLeaf({ node }) {
|
|
|
700
387
|
});
|
|
701
388
|
}
|
|
702
389
|
const record = controller.record;
|
|
703
|
-
const value = mode === "show" ? record
|
|
390
|
+
const value = mode === "show" ? valueAt(record, name) ?? binding.value : mode === "edit" && controller.plan?.fields[head] !== "active" ? valueAt(record, name) ?? binding.value : binding.value;
|
|
704
391
|
const display = (0, react_jsx_runtime.jsx)(FieldDisplay, {
|
|
705
392
|
resource: binding.resource,
|
|
706
393
|
name,
|
|
@@ -708,6 +395,8 @@ function RecordLeaf({ node }) {
|
|
|
708
395
|
value,
|
|
709
396
|
metaSources: controller.sources,
|
|
710
397
|
...record === void 0 ? {} : { record },
|
|
398
|
+
...binding.absentPaths === void 0 ? {} : { absentPaths: binding.absentPaths },
|
|
399
|
+
...binding.pathStatus === void 0 ? {} : { pathStatus: binding.pathStatus },
|
|
711
400
|
fallback: value == null || value === "" ? (0, react_jsx_runtime.jsx)("span", {
|
|
712
401
|
className: "text-muted-foreground",
|
|
713
402
|
children: "—"
|
|
@@ -718,11 +407,11 @@ function RecordLeaf({ node }) {
|
|
|
718
407
|
"data-testid": `show-field:${resource}:${name}`,
|
|
719
408
|
children: [(0, react_jsx_runtime.jsxs)("dt", {
|
|
720
409
|
"data-buro-region": "field-label",
|
|
721
|
-
className: require_use_theme.cn("flex items-center gap-0.5", FIELD_LABEL_SHOW),
|
|
410
|
+
className: labelRegion(hidden, require_use_theme.cn("flex items-center gap-0.5", FIELD_LABEL_SHOW)),
|
|
722
411
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
723
412
|
className: "min-w-0",
|
|
724
413
|
children: label
|
|
725
|
-
}), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
414
|
+
}), hidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
726
415
|
address: `${resource}/fields/${name}`,
|
|
727
416
|
name: label
|
|
728
417
|
})]
|
|
@@ -734,10 +423,7 @@ function RecordLeaf({ node }) {
|
|
|
734
423
|
});
|
|
735
424
|
if (node.editable !== true) {
|
|
736
425
|
const rawReason = node.lockReason;
|
|
737
|
-
const reason = rawReason === void 0 ? void 0 :
|
|
738
|
-
resource,
|
|
739
|
-
default: rawReason
|
|
740
|
-
});
|
|
426
|
+
const reason = rawReason === void 0 ? void 0 : require_check_confirm_dialog.reasonText(caps, rawReason, resource);
|
|
741
427
|
const locked = tid.formFieldLocked(resource, mode, name);
|
|
742
428
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
743
429
|
...attributes,
|
|
@@ -745,8 +431,8 @@ function RecordLeaf({ node }) {
|
|
|
745
431
|
"data-testid": tid.formField(resource, mode, name),
|
|
746
432
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
747
433
|
"data-buro-region": "field-label",
|
|
748
|
-
className: "flex items-center gap-2",
|
|
749
|
-
children: [(0, react_jsx_runtime.jsx)(require_label.Label, { children: label }), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
434
|
+
className: labelRegion(hidden, "flex items-center gap-2"),
|
|
435
|
+
children: [(0, react_jsx_runtime.jsx)(require_label.Label, { children: label }), hidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
750
436
|
address: `${resource}/fields/${name}`,
|
|
751
437
|
name: label,
|
|
752
438
|
testId: `${tid.formField(resource, mode, name)}:info`
|
|
@@ -782,14 +468,14 @@ function RecordLeaf({ node }) {
|
|
|
782
468
|
node,
|
|
783
469
|
binding,
|
|
784
470
|
label,
|
|
471
|
+
labelHidden: hidden,
|
|
785
472
|
attributes,
|
|
786
473
|
inputId
|
|
787
474
|
});
|
|
788
475
|
}
|
|
789
|
-
function ActiveLeaf({ node, binding, label, attributes, inputId }) {
|
|
476
|
+
function ActiveLeaf({ node, binding, label, labelHidden, attributes, inputId }) {
|
|
790
477
|
const { resource, mode, controller, disabled: locked } = useScreenTree();
|
|
791
478
|
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
792
|
-
const t = (0, _burojs_react.useOptionalT)();
|
|
793
479
|
const tid = (0, _burojs_react.useTestIds)();
|
|
794
480
|
const name = binding.name;
|
|
795
481
|
const record = controller.record;
|
|
@@ -804,25 +490,22 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
|
|
|
804
490
|
});
|
|
805
491
|
const messageId = `${mode}-${name}-msg`;
|
|
806
492
|
const placeholder = (0, _burojs_core.resolveFieldSlot)(caps, name, "placeholder");
|
|
807
|
-
const hint = (0, _burojs_core.resolveFieldSlot)(caps, name, "description", fieldDescription(binding.field));
|
|
493
|
+
const hint = (0, _burojs_core.resolveFieldSlot)(caps, name, "description", require_filter_builder.fieldDescription(binding.field));
|
|
494
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
808
495
|
const fieldKey = `resources.${resource}.fields.${name}`;
|
|
809
|
-
const
|
|
810
|
-
code:
|
|
811
|
-
message:
|
|
812
|
-
...
|
|
813
|
-
}, {
|
|
814
|
-
t,
|
|
815
|
-
fieldKey
|
|
816
|
-
});
|
|
817
|
-
const warning = errorText === null ? binding.warnings[0] : void 0;
|
|
818
|
-
const warningText = warning === void 0 ? null : (0, _burojs_react.resolveValidationMessage)({
|
|
819
|
-
code: warning.code ?? "",
|
|
820
|
-
message: warning.message,
|
|
821
|
-
...warning.params === void 0 ? {} : { params: warning.params }
|
|
496
|
+
const text = (issue) => (0, _burojs_react.resolveValidationMessage)({
|
|
497
|
+
code: issue.code ?? "",
|
|
498
|
+
message: issue.message,
|
|
499
|
+
...issue.check === void 0 ? {} : { check: issue.check }
|
|
822
500
|
}, {
|
|
823
|
-
|
|
501
|
+
has: caps.has,
|
|
502
|
+
t: caps.t,
|
|
824
503
|
fieldKey
|
|
825
504
|
});
|
|
505
|
+
const shown = binding.issues.slice(0, SHOWN_ISSUES);
|
|
506
|
+
const more = binding.issues.length - shown.length;
|
|
507
|
+
const firstError = shown.find((issue) => issue.severity === "error");
|
|
508
|
+
const errorText = firstError === void 0 ? null : text(firstError);
|
|
826
509
|
const disabled = binding.disabled || controller.isSubmitting || locked === true;
|
|
827
510
|
const describedBy = errorText === null && hint ? messageId : void 0;
|
|
828
511
|
const errorMessageId = errorText === null ? void 0 : messageId;
|
|
@@ -834,12 +517,13 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
|
|
|
834
517
|
onBlur: binding.onBlur,
|
|
835
518
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
836
519
|
"data-buro-region": "field-label",
|
|
837
|
-
className: "flex items-center gap-2",
|
|
520
|
+
className: labelRegion(labelHidden, "flex items-center gap-2"),
|
|
838
521
|
children: [(0, react_jsx_runtime.jsx)(require_label.Label, {
|
|
522
|
+
id: `${inputId}-label`,
|
|
839
523
|
htmlFor: inputId,
|
|
840
524
|
required: binding.required,
|
|
841
525
|
children: label
|
|
842
|
-
}), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
526
|
+
}), labelHidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
843
527
|
address: `${resource}/fields/${name}`,
|
|
844
528
|
name: label,
|
|
845
529
|
testId: `${tid.formField(resource, mode, name)}:info`
|
|
@@ -851,6 +535,7 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
|
|
|
851
535
|
resource: binding.resource,
|
|
852
536
|
name,
|
|
853
537
|
inputId,
|
|
538
|
+
labelId: `${inputId}-label`,
|
|
854
539
|
field: binding.field,
|
|
855
540
|
value: binding.value,
|
|
856
541
|
onChange: binding.onChange,
|
|
@@ -861,11 +546,17 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
|
|
|
861
546
|
...mode === "create" || record === void 0 ? {} : { record },
|
|
862
547
|
form: controller.values,
|
|
863
548
|
metaSources: controller.sources,
|
|
549
|
+
...controller.baseline === void 0 ? {} : { baseline: controller.baseline },
|
|
864
550
|
...describedBy === void 0 ? {} : { descriptionId: describedBy },
|
|
865
551
|
...errorMessageId === void 0 ? {} : { errorId: errorMessageId },
|
|
866
552
|
errorMessage: errorText,
|
|
553
|
+
issues: binding.issues,
|
|
867
554
|
...binding.fixedFilters === void 0 ? {} : { fixedFilters: binding.fixedFilters },
|
|
555
|
+
...binding.optionSubtitle === void 0 ? {} : { optionSubtitle: binding.optionSubtitle },
|
|
868
556
|
...binding.relationSeeds === void 0 ? {} : { relationSeeds: binding.relationSeeds },
|
|
557
|
+
...binding.link === void 0 ? {} : { link: binding.link },
|
|
558
|
+
...binding.absentPaths === void 0 ? {} : { absentPaths: binding.absentPaths },
|
|
559
|
+
...binding.pathStatus === void 0 ? {} : { pathStatus: binding.pathStatus },
|
|
869
560
|
fallback: (0, react_jsx_runtime.jsx)(require_input.Input, {
|
|
870
561
|
id: inputId,
|
|
871
562
|
name: inputId,
|
|
@@ -880,18 +571,23 @@ function ActiveLeaf({ node, binding, label, attributes, inputId }) {
|
|
|
880
571
|
...errorMessageId === void 0 ? {} : { "aria-errormessage": errorMessageId },
|
|
881
572
|
onChange: (event) => binding.onChange(event.target.value)
|
|
882
573
|
})
|
|
883
|
-
}),
|
|
884
|
-
id: messageId,
|
|
885
|
-
"aria-live": "polite",
|
|
886
|
-
className: "text-sm text-destructive",
|
|
887
|
-
"data-testid": tid.formFieldError(resource, mode, name),
|
|
888
|
-
children: errorText
|
|
889
|
-
}) : warningText !== null ? (0, react_jsx_runtime.jsx)("p", {
|
|
574
|
+
}), shown.length > 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
890
575
|
id: messageId,
|
|
891
576
|
"aria-live": "polite",
|
|
892
|
-
className: "text-sm text-warning-emphasis",
|
|
893
|
-
"data-testid": `form-field-warning:${resource}:${mode}:${name}
|
|
894
|
-
children:
|
|
577
|
+
className: require_use_theme.cn("space-y-0.5 text-sm", errorText === null ? "text-warning-emphasis" : "text-destructive"),
|
|
578
|
+
"data-testid": errorText === null ? `form-field-warning:${resource}:${mode}:${name}` : tid.formFieldError(resource, mode, name),
|
|
579
|
+
children: [shown.map((issue, index) => (0, react_jsx_runtime.jsx)("p", {
|
|
580
|
+
"data-buro-severity": issue.severity,
|
|
581
|
+
className: issue.severity === "error" ? "text-destructive" : "text-warning-emphasis",
|
|
582
|
+
children: text(issue)
|
|
583
|
+
}, index)), more > 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
584
|
+
className: "text-muted-foreground",
|
|
585
|
+
"data-testid": `form-field-more:${resource}:${mode}:${name}`,
|
|
586
|
+
children: chromeT("validation.moreIssues", {
|
|
587
|
+
count: more,
|
|
588
|
+
defaultValue: "+{{count}} more"
|
|
589
|
+
})
|
|
590
|
+
}) : null]
|
|
895
591
|
}) : hint ? (0, react_jsx_runtime.jsx)("p", {
|
|
896
592
|
id: messageId,
|
|
897
593
|
"data-testid": tid.formFieldHelp(resource, mode, name),
|
|
@@ -907,11 +603,12 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
|
|
|
907
603
|
const binding = controller.field(name);
|
|
908
604
|
const size = useLeafSize(binding.field);
|
|
909
605
|
const weight = compiled.nodes[node.index]?.options.weight;
|
|
606
|
+
const hidden = labelHiddenOf(compiled, node);
|
|
910
607
|
const attributes = leafAttributes(size, weight);
|
|
911
608
|
const docRef = (0, _burojs_core.i18nPrefixToRef)(prefix);
|
|
912
609
|
const docScope = docRef.namespace === "default" ? docRef.id : (0, _burojs_core.formatEntityRef)(docRef);
|
|
913
610
|
const caps = (0, _burojs_react.useI18nCaps)(docScope);
|
|
914
|
-
const
|
|
611
|
+
const issueCaps = (0, _burojs_react.useI18nCaps)();
|
|
915
612
|
const uid = (0, react.useId)();
|
|
916
613
|
const root = (0, react.useRef)(null);
|
|
917
614
|
const inputId = `${inputIds ?? uid}-${name}`;
|
|
@@ -924,8 +621,8 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
|
|
|
924
621
|
element.querySelector(FOCUSABLE)?.focus();
|
|
925
622
|
});
|
|
926
623
|
const label = (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", binding.field, "label"));
|
|
927
|
-
const hint = (0, _burojs_core.resolveFieldSlot)(caps, name, "description", fieldDescription(binding.field));
|
|
928
|
-
const info = (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
624
|
+
const hint = (0, _burojs_core.resolveFieldSlot)(caps, name, "description", require_filter_builder.fieldDescription(binding.field));
|
|
625
|
+
const info = hidden ? null : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DocInfo, {
|
|
929
626
|
address: `${docScope}/fields/${name}`,
|
|
930
627
|
name: label,
|
|
931
628
|
testId: `${prefix}:field:${name}:info`
|
|
@@ -942,7 +639,7 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
|
|
|
942
639
|
children: [
|
|
943
640
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
944
641
|
"data-buro-region": "field-label",
|
|
945
|
-
className: "flex items-center gap-2",
|
|
642
|
+
className: labelRegion(hidden, "flex items-center gap-2"),
|
|
946
643
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
947
644
|
className: FIELD_LABEL_SHOW,
|
|
948
645
|
children: label
|
|
@@ -965,16 +662,19 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
|
|
|
965
662
|
const text = (issue) => (0, _burojs_react.resolveValidationMessage)({
|
|
966
663
|
code: issue.code ?? "",
|
|
967
664
|
message: issue.message,
|
|
968
|
-
...issue.
|
|
665
|
+
...issue.check === void 0 ? {} : { check: issue.check }
|
|
969
666
|
}, {
|
|
970
|
-
|
|
667
|
+
has: issueCaps.has,
|
|
668
|
+
t: issueCaps.t,
|
|
971
669
|
fieldKey
|
|
972
670
|
});
|
|
973
671
|
const defaultNode = (0, react_jsx_runtime.jsx)(Field, {
|
|
974
672
|
...binding,
|
|
975
673
|
field: binding.field,
|
|
976
674
|
metaSources: controller.sources,
|
|
675
|
+
...controller.baseline === void 0 ? {} : { baseline: controller.baseline },
|
|
977
676
|
inputId,
|
|
677
|
+
labelId: `${inputId}-label`,
|
|
978
678
|
i18nPrefix: prefix,
|
|
979
679
|
disabled: disabled === true || binding.disabled
|
|
980
680
|
});
|
|
@@ -988,8 +688,9 @@ function DeclarativeLeaf({ node, prefix, inputIds }) {
|
|
|
988
688
|
children: [
|
|
989
689
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
990
690
|
"data-buro-region": "field-label",
|
|
991
|
-
className: "flex items-center gap-2",
|
|
691
|
+
className: labelRegion(hidden, "flex items-center gap-2"),
|
|
992
692
|
children: [(0, react_jsx_runtime.jsx)(require_label.Label, {
|
|
693
|
+
id: `${inputId}-label`,
|
|
993
694
|
htmlFor: inputId,
|
|
994
695
|
required: binding.required,
|
|
995
696
|
children: label
|
|
@@ -1030,9 +731,10 @@ function Notice({ children }) {
|
|
|
1030
731
|
children
|
|
1031
732
|
});
|
|
1032
733
|
}
|
|
1033
|
-
function FactsView({ props }) {
|
|
734
|
+
function FactsView({ props, empty }) {
|
|
1034
735
|
const own = props;
|
|
1035
736
|
const t = (0, _burojs_react.useOptionalT)();
|
|
737
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1036
738
|
const snapshot = (0, _burojs_react.useApplicationSnapshot)();
|
|
1037
739
|
const queryId = (0, _burojs_core.formatEntityRef)(own.query);
|
|
1038
740
|
const caps = (0, _burojs_react.useI18nCaps)();
|
|
@@ -1049,7 +751,10 @@ function FactsView({ props }) {
|
|
|
1049
751
|
kind: "custom-query",
|
|
1050
752
|
ref: own.query
|
|
1051
753
|
}), [own.query]);
|
|
1052
|
-
const result = (0, _burojs_react.useCustomQuery)(handle, blocked ? {} : input, {
|
|
754
|
+
const result = (0, _burojs_react.useCustomQuery)(handle, blocked ? {} : input, {
|
|
755
|
+
enabled: !blocked,
|
|
756
|
+
...own.refetchInterval === void 0 ? {} : { refetchInterval: own.refetchInterval }
|
|
757
|
+
});
|
|
1053
758
|
const shown = (0, react.useMemo)(() => {
|
|
1054
759
|
const byName = new Map(fields.map((field) => [field.name, field]));
|
|
1055
760
|
return (own.rows ?? fields.map((field) => field.name)).flatMap((name) => {
|
|
@@ -1057,7 +762,7 @@ function FactsView({ props }) {
|
|
|
1057
762
|
return field === void 0 ? [] : [field];
|
|
1058
763
|
});
|
|
1059
764
|
}, [fields, own.rows]);
|
|
1060
|
-
if (blocked) return (0, react_jsx_runtime.jsx)(Notice, { children: own.missing ?? t("facts.empty", { defaultValue: "No data" }) });
|
|
765
|
+
if (blocked) return (0, react_jsx_runtime.jsx)(Notice, { children: own.missing ?? empty ?? t("facts.empty", { defaultValue: "No data" }) });
|
|
1061
766
|
if (result.isError) return (0, react_jsx_runtime.jsxs)("div", {
|
|
1062
767
|
role: "alert",
|
|
1063
768
|
className: "flex flex-wrap items-center gap-2 rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground",
|
|
@@ -1066,7 +771,7 @@ function FactsView({ props }) {
|
|
|
1066
771
|
variant: "outline",
|
|
1067
772
|
size: "sm",
|
|
1068
773
|
onClick: () => void result.refetch(),
|
|
1069
|
-
children:
|
|
774
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
1070
775
|
})]
|
|
1071
776
|
});
|
|
1072
777
|
if (result.data === void 0) return own.view === "list" ? (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, {
|
|
@@ -1080,7 +785,7 @@ function FactsView({ props }) {
|
|
|
1080
785
|
}, field.name))
|
|
1081
786
|
});
|
|
1082
787
|
const data = result.data;
|
|
1083
|
-
if (data === null || typeof data !== "object" || shown.length === 0) return (0, react_jsx_runtime.jsx)(Notice, { children: own.missing ?? t("facts.empty", { defaultValue: "No data" }) });
|
|
788
|
+
if (data === null || typeof data !== "object" || shown.length === 0) return (0, react_jsx_runtime.jsx)(Notice, { children: own.missing ?? empty ?? t("facts.empty", { defaultValue: "No data" }) });
|
|
1084
789
|
const pairs = shown.map((field) => {
|
|
1085
790
|
const value = data[field.name];
|
|
1086
791
|
const label = (0, _burojs_core.resolveContentSlot)(caps, [`queries.${queryId}.fields.${field.name}.label`, `queries.${queryId}.fields.${field.name}`], {
|
|
@@ -1090,13 +795,18 @@ function FactsView({ props }) {
|
|
|
1090
795
|
const body = value === null || value === void 0 ? (0, react_jsx_runtime.jsx)("span", {
|
|
1091
796
|
className: "text-muted-foreground",
|
|
1092
797
|
children: "—"
|
|
1093
|
-
}) : (0, react_jsx_runtime.jsx)(
|
|
1094
|
-
resource: own.query,
|
|
1095
|
-
name: field.name,
|
|
798
|
+
}) : (0, react_jsx_runtime.jsx)(FieldValueFrame, {
|
|
1096
799
|
field,
|
|
1097
800
|
value,
|
|
1098
|
-
|
|
1099
|
-
|
|
801
|
+
surface: "display",
|
|
802
|
+
children: (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldDisplay, {
|
|
803
|
+
resource: own.query,
|
|
804
|
+
name: field.name,
|
|
805
|
+
field,
|
|
806
|
+
value,
|
|
807
|
+
record: data,
|
|
808
|
+
fallback: toDisplayText(value).text
|
|
809
|
+
})
|
|
1100
810
|
});
|
|
1101
811
|
return {
|
|
1102
812
|
name: field.name,
|
|
@@ -1150,6 +860,9 @@ const PlacementFrameContext = (0, react.createContext)(null);
|
|
|
1150
860
|
function usePlacementFrame() {
|
|
1151
861
|
return (0, react.useContext)(PlacementFrameContext);
|
|
1152
862
|
}
|
|
863
|
+
function placementLayoutId(frame) {
|
|
864
|
+
return frame?.owner === void 0 ? void 0 : `${frame.owner}/${frame.key.split(".").join("/")}`;
|
|
865
|
+
}
|
|
1153
866
|
//#endregion
|
|
1154
867
|
//#region src/flows/app-flow-button.tsx
|
|
1155
868
|
function AppFlowButton({ action, variant = "ghost", size = "sm", className }) {
|
|
@@ -1237,10 +950,7 @@ function RecordInlineFlow({ name }) {
|
|
|
1237
950
|
const id = frame?.recordId;
|
|
1238
951
|
const asRead = frame === null ? void 0 : (0, _burojs_react.policyRecordOf)(frame.controller, frame.record);
|
|
1239
952
|
const key = placement?.key ?? flowName;
|
|
1240
|
-
const state = frame === null || id === void 0 || asRead === void 0 ? null : resolve(flowName, {
|
|
1241
|
-
...asRead,
|
|
1242
|
-
id
|
|
1243
|
-
});
|
|
953
|
+
const state = frame === null || id === void 0 || asRead === void 0 ? null : resolve(flowName, (0, _burojs_react.withRecordKeys)(asRead, { id }));
|
|
1244
954
|
const kept = holder?.get(key);
|
|
1245
955
|
const stale = state?.state === "absent" && state.cause === "when" && kept !== void 0 && kept.dirty;
|
|
1246
956
|
const gone = state?.state === "absent" && !stale;
|
|
@@ -1252,10 +962,7 @@ function RecordInlineFlow({ name }) {
|
|
|
1252
962
|
key
|
|
1253
963
|
]);
|
|
1254
964
|
if (frame === null || asRead === void 0 || id === void 0 || compiled === null) return null;
|
|
1255
|
-
const row = {
|
|
1256
|
-
...asRead,
|
|
1257
|
-
id
|
|
1258
|
-
};
|
|
965
|
+
const row = (0, _burojs_react.withRecordKeys)(asRead, { id });
|
|
1259
966
|
const control = resolve(flowName, row);
|
|
1260
967
|
switch (control.state) {
|
|
1261
968
|
case "undecided":
|
|
@@ -1269,7 +976,7 @@ function RecordInlineFlow({ name }) {
|
|
|
1269
976
|
return (0, react_jsx_runtime.jsx)(InlineHostLoader, {
|
|
1270
977
|
resource,
|
|
1271
978
|
name: flowName,
|
|
1272
|
-
|
|
979
|
+
...hostRecord((0, _burojs_core.flowRecordOf)(compiled, row)),
|
|
1273
980
|
placementKey: key,
|
|
1274
981
|
lease: kept,
|
|
1275
982
|
stale: true,
|
|
@@ -1285,7 +992,7 @@ function RecordInlineFlow({ name }) {
|
|
|
1285
992
|
if (control.state === "disabled" && kept !== void 0 && kept.dirty) return (0, react_jsx_runtime.jsx)(InlineHostLoader, {
|
|
1286
993
|
resource,
|
|
1287
994
|
name: flowName,
|
|
1288
|
-
|
|
995
|
+
...hostRecord((0, _burojs_core.flowRecordOf)(compiled, row)),
|
|
1289
996
|
placementKey: key,
|
|
1290
997
|
lease: kept,
|
|
1291
998
|
stale: true,
|
|
@@ -1297,11 +1004,12 @@ function RecordInlineFlow({ name }) {
|
|
|
1297
1004
|
return (0, react_jsx_runtime.jsx)(InlineHostLoader, {
|
|
1298
1005
|
resource,
|
|
1299
1006
|
name: flowName,
|
|
1300
|
-
|
|
1007
|
+
...hostRecord((0, _burojs_core.flowRecordOf)(compiled, control.record ?? row)),
|
|
1301
1008
|
placementKey: key,
|
|
1302
1009
|
...lease === void 0 ? {} : { lease }
|
|
1303
1010
|
});
|
|
1304
1011
|
}
|
|
1012
|
+
const hostRecord = (record) => record === void 0 ? {} : { record };
|
|
1305
1013
|
function InlineHostLoader(props) {
|
|
1306
1014
|
const loaded = require_check_confirm_dialog.useLoaded(require_check_confirm_dialog.loadInlineFlowHost);
|
|
1307
1015
|
if (loaded.error !== void 0) return (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -1517,6 +1225,7 @@ function placementSeeds(where, resolved, closure) {
|
|
|
1517
1225
|
where.forEach((entry, index) => {
|
|
1518
1226
|
const value = resolved[index]?.value;
|
|
1519
1227
|
if (entry.op !== "eq" || value === null || value === void 0) return;
|
|
1228
|
+
if (typeof entry.field !== "string" || entry.field.includes(".")) return;
|
|
1520
1229
|
if (resolved[index]?.field !== entry.field) return;
|
|
1521
1230
|
const source = refSource(entry.value);
|
|
1522
1231
|
if (source === null ? isLiteral(entry.value) : source === "record" || source === "user" || !UNTRUSTED.includes(source) && Object.hasOwn(closure, source) && !(closure[source] ?? []).some((input) => UNTRUSTED.includes(input))) seeds[entry.field] = value;
|
|
@@ -1524,6 +1233,28 @@ function placementSeeds(where, resolved, closure) {
|
|
|
1524
1233
|
return Object.freeze(seeds);
|
|
1525
1234
|
}
|
|
1526
1235
|
//#endregion
|
|
1236
|
+
//#region src/enum/enum-settling.tsx
|
|
1237
|
+
function unknownEnumValueLabel(caps, def, ns, value) {
|
|
1238
|
+
const declared = (0, _burojs_core.enumFallbackText)(def);
|
|
1239
|
+
if (def.fallback === void 0 && declared === void 0) return {
|
|
1240
|
+
label: value,
|
|
1241
|
+
fallback: false
|
|
1242
|
+
};
|
|
1243
|
+
return {
|
|
1244
|
+
label: (0, _burojs_core.resolveContentSlot)(caps, [(0, _burojs_core.enumFallbackKey)(ns)], { default: declared }) ?? value,
|
|
1245
|
+
fallback: true
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
function EnumSettlingRow({ status, testid }) {
|
|
1249
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
1250
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
1251
|
+
role: "status",
|
|
1252
|
+
"data-testid": testid === void 0 ? void 0 : `${testid}:${status}`,
|
|
1253
|
+
className: "px-2 py-1.5 text-sm text-muted-foreground",
|
|
1254
|
+
children: status === "pending" ? t("field.loading", { defaultValue: "Loading…" }) : t("relation.failed", { defaultValue: "Failed to load options." })
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
//#endregion
|
|
1527
1258
|
//#region src/enum/enum-badge.tsx
|
|
1528
1259
|
function BadgeBody({ icon, label }) {
|
|
1529
1260
|
return (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -1534,7 +1265,8 @@ function BadgeBody({ icon, label }) {
|
|
|
1534
1265
|
}) : null, label]
|
|
1535
1266
|
});
|
|
1536
1267
|
}
|
|
1537
|
-
function EnumBadge({ enumName, value, testid, className, presentation }) {
|
|
1268
|
+
function EnumBadge({ enumName: enumInput, value, testid, className, presentation }) {
|
|
1269
|
+
const enumName = (0, _burojs_core_internal.enumBindingKey)(enumInput) ?? "";
|
|
1538
1270
|
const app = (0, _burojs_react.useApp)();
|
|
1539
1271
|
const caps = (0, _burojs_react.useI18nCaps)();
|
|
1540
1272
|
const def = app.registry.enums.get(enumName);
|
|
@@ -1593,9 +1325,9 @@ function EnumBadge({ enumName, value, testid, className, presentation }) {
|
|
|
1593
1325
|
children: body
|
|
1594
1326
|
});
|
|
1595
1327
|
}
|
|
1596
|
-
const
|
|
1597
|
-
if (
|
|
1598
|
-
const fallbackLabel =
|
|
1328
|
+
const unknown = unknownEnumValueLabel(caps, def, ns, value);
|
|
1329
|
+
if (unknown.fallback) {
|
|
1330
|
+
const fallbackLabel = unknown.label;
|
|
1599
1331
|
if (presentation === "plain") return (0, react_jsx_runtime.jsx)("span", {
|
|
1600
1332
|
"data-testid": `${id}:fallback`,
|
|
1601
1333
|
className,
|
|
@@ -1680,6 +1412,7 @@ function useExportRunWatcher() {
|
|
|
1680
1412
|
const runtime = (0, _burojs_react.useDataRuntime)();
|
|
1681
1413
|
const runs = (0, _burojs_react.useExportRuns)();
|
|
1682
1414
|
const t = (0, _burojs_react.useOptionalT)();
|
|
1415
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
1683
1416
|
react.useEffect(() => {
|
|
1684
1417
|
const announced = announcedRunsFor(runtime);
|
|
1685
1418
|
const unsubscribes = runs.map((run) => {
|
|
@@ -1698,7 +1431,7 @@ function useExportRunWatcher() {
|
|
|
1698
1431
|
label: t("export.toast.download"),
|
|
1699
1432
|
onClick: () => downloadArtifact(artifact)
|
|
1700
1433
|
} });
|
|
1701
|
-
} else if (state.status === "failed") sonner.toast.error(t("export.toast.failed", { params: { message: state.error
|
|
1434
|
+
} else if (state.status === "failed") sonner.toast.error(t("export.toast.failed", { params: { message: (0, _burojs_react.resolveErrorText)(state.error, caps) } }));
|
|
1702
1435
|
};
|
|
1703
1436
|
check();
|
|
1704
1437
|
return run.handle.subscribe(check);
|
|
@@ -1709,24 +1442,27 @@ function useExportRunWatcher() {
|
|
|
1709
1442
|
}, [
|
|
1710
1443
|
runs,
|
|
1711
1444
|
runtime,
|
|
1712
|
-
t
|
|
1445
|
+
t,
|
|
1446
|
+
caps
|
|
1713
1447
|
]);
|
|
1714
1448
|
}
|
|
1715
1449
|
//#endregion
|
|
1716
1450
|
//#region src/actions/action-overflow.tsx
|
|
1717
1451
|
const RowActionsCollapseContext = (0, react.createContext)(false);
|
|
1718
|
-
function ActionOverflow({ resource, record, surface, className, hideFlows, collapse }) {
|
|
1719
|
-
const
|
|
1452
|
+
function ActionOverflow({ resource: resourceInput, record, surface, className, hideFlows, collapse, sources }) {
|
|
1453
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
1454
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
1720
1455
|
const tid = (0, _burojs_react.useTestIds)();
|
|
1456
|
+
const recordKey = String((0, _burojs_react.recordKeyOf)((0, _burojs_react.useApp)().registry.get(resource), record) ?? "");
|
|
1721
1457
|
const collapsedRows = (0, react.useContext)(RowActionsCollapseContext);
|
|
1722
1458
|
const [flowFor, setFlowFor] = (0, react.useState)(null);
|
|
1723
|
-
const actions = useShownItemActions(resource, record, surface, hideFlows);
|
|
1459
|
+
const actions = useShownItemActions(resource, record, surface, hideFlows, sources);
|
|
1724
1460
|
if (actions.length === 0) return null;
|
|
1725
1461
|
const isRow = surface === "row";
|
|
1726
1462
|
const folded = isRow && (collapse ?? collapsedRows);
|
|
1727
1463
|
const standalone = folded ? [] : actions.filter((a) => a.placement === "standalone");
|
|
1728
1464
|
const menu = folded ? actions : actions.filter((a) => a.placement === "menu");
|
|
1729
|
-
const menuTestId = isRow ? tid.listRowActionsMenu(resource,
|
|
1465
|
+
const menuTestId = isRow ? tid.listRowActionsMenu(resource, recordKey) : tid.formActionsMenu(resource, surface);
|
|
1730
1466
|
const firstDestructive = menu.findIndex((a) => a.variant === "destructive");
|
|
1731
1467
|
const overlays = (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: flowFor != null ? (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.RuntimeFlowRunner, {
|
|
1732
1468
|
resource,
|
|
@@ -1740,6 +1476,7 @@ function ActionOverflow({ resource, record, surface, className, hideFlows, colla
|
|
|
1740
1476
|
actionName: a.name,
|
|
1741
1477
|
record,
|
|
1742
1478
|
scope: surface,
|
|
1479
|
+
...sources === void 0 ? {} : { sources },
|
|
1743
1480
|
density: a.density
|
|
1744
1481
|
}, a.name));
|
|
1745
1482
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1763,7 +1500,7 @@ function ActionOverflow({ resource, record, surface, className, hideFlows, colla
|
|
|
1763
1500
|
size: "icon",
|
|
1764
1501
|
className: "size-7",
|
|
1765
1502
|
"data-testid": menuTestId,
|
|
1766
|
-
"aria-label":
|
|
1503
|
+
"aria-label": chromeT("actions.more", { defaultValue: "More" }),
|
|
1767
1504
|
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconDots, {
|
|
1768
1505
|
className: "h-4 w-4",
|
|
1769
1506
|
"aria-hidden": "true"
|
|
@@ -1777,15 +1514,16 @@ function ActionOverflow({ resource, record, surface, className, hideFlows, colla
|
|
|
1777
1514
|
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconDots, {
|
|
1778
1515
|
className: "h-4 w-4",
|
|
1779
1516
|
"aria-hidden": "true"
|
|
1780
|
-
}),
|
|
1517
|
+
}), chromeT("actions.more", { defaultValue: "More" })]
|
|
1781
1518
|
})
|
|
1782
1519
|
}), (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DropdownMenuContent, {
|
|
1783
1520
|
align: "end",
|
|
1784
|
-
children: menu.map((a, index) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [index === firstDestructive && index > 0 && (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DropdownMenuSeparator, { "data-testid": isRow ? `list-row-actions-separator:${resource}:${
|
|
1521
|
+
children: menu.map((a, index) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [index === firstDestructive && index > 0 && (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DropdownMenuSeparator, { "data-testid": isRow ? `list-row-actions-separator:${resource}:${recordKey}` : `form-actions-separator:${resource}:${surface}` }), a.flow === void 0 ? (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.ActionButton, {
|
|
1785
1522
|
resource,
|
|
1786
1523
|
actionName: a.name,
|
|
1787
1524
|
record,
|
|
1788
1525
|
scope: surface,
|
|
1526
|
+
...sources === void 0 ? {} : { sources },
|
|
1789
1527
|
asMenuItem: true
|
|
1790
1528
|
}) : (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.FlowMenuItem, {
|
|
1791
1529
|
resource,
|
|
@@ -1805,46 +1543,18 @@ function ActionOverflow({ resource, record, surface, className, hideFlows, colla
|
|
|
1805
1543
|
]
|
|
1806
1544
|
});
|
|
1807
1545
|
}
|
|
1808
|
-
function useShownItemActions(resource, record, surface, hideFlows) {
|
|
1546
|
+
function useShownItemActions(resource, record, surface, hideFlows, sources) {
|
|
1809
1547
|
const resolved = (0, _burojs_react.useItemActions)({
|
|
1810
1548
|
resource,
|
|
1811
1549
|
record,
|
|
1812
|
-
surface
|
|
1550
|
+
surface,
|
|
1551
|
+
...sources === void 0 ? {} : { sources }
|
|
1813
1552
|
});
|
|
1814
1553
|
const def = (0, _burojs_react.useApp)().registry.get(resource);
|
|
1815
1554
|
const shown = def !== void 0 && (0, _burojs_core.isBuiltinItemAction)((def.actions?.item)?.find((action) => action.name === "edit"), "edit") && !(0, _burojs_core.recordEntries)(def).page.edit && (0, _burojs_core.recordEntries)(def).quick.edit === null ? resolved.filter((a) => a.name !== "edit") : resolved;
|
|
1816
1555
|
return hideFlows === void 0 ? shown : shown.filter((a) => a.flow === void 0 || !hideFlows(a.name));
|
|
1817
1556
|
}
|
|
1818
1557
|
//#endregion
|
|
1819
|
-
//#region src/layout/record-targets.ts
|
|
1820
|
-
function recordRouteAvailable(registry, resource, action) {
|
|
1821
|
-
if ((0, _burojs_core.resolveStaticAvailability)(registry, resource, action).state !== "available") return false;
|
|
1822
|
-
const def = registry.get(resource);
|
|
1823
|
-
return def !== void 0 && (0, _burojs_core.hasRecordPage)(def, action);
|
|
1824
|
-
}
|
|
1825
|
-
function isShowAvailable(registry, resource) {
|
|
1826
|
-
return recordRouteAvailable(registry, resource, "show");
|
|
1827
|
-
}
|
|
1828
|
-
function showTarget(resource, id) {
|
|
1829
|
-
return {
|
|
1830
|
-
resource,
|
|
1831
|
-
action: "show",
|
|
1832
|
-
params: { id }
|
|
1833
|
-
};
|
|
1834
|
-
}
|
|
1835
|
-
function listTarget(resource) {
|
|
1836
|
-
return {
|
|
1837
|
-
resource,
|
|
1838
|
-
action: "list"
|
|
1839
|
-
};
|
|
1840
|
-
}
|
|
1841
|
-
function recordReturnTarget(registry, resource, id) {
|
|
1842
|
-
return isShowAvailable(registry, resource) ? showTarget(resource, id) : listTarget(resource);
|
|
1843
|
-
}
|
|
1844
|
-
function editBackHref(registry, resource, id, backHref) {
|
|
1845
|
-
return backHref ?? (0, _burojs_react.resolveRoute)(recordReturnTarget(registry, resource, id), registry);
|
|
1846
|
-
}
|
|
1847
|
-
//#endregion
|
|
1848
1558
|
//#region src/lib/typography.ts
|
|
1849
1559
|
const typography = {
|
|
1850
1560
|
h1: "text-2xl font-semibold tracking-tight",
|
|
@@ -1902,8 +1612,14 @@ function DocumentTitleProvider({ routeKey, children }) {
|
|
|
1902
1612
|
});
|
|
1903
1613
|
}
|
|
1904
1614
|
//#endregion
|
|
1615
|
+
//#region src/resource/resource-title.ts
|
|
1616
|
+
function resolveResourceTitle(caps, t, resource, slot, params) {
|
|
1617
|
+
return (0, _burojs_core.resolveContentSlot)(caps, [`resources.${resource}.${slot}`], { params: { ...params } }) ?? t(`pageHeader.${slot}`, { params: { ...params } });
|
|
1618
|
+
}
|
|
1619
|
+
//#endregion
|
|
1905
1620
|
//#region src/resource/page-header.tsx
|
|
1906
|
-
function PageHeader({ resource, mode, recordName, backHref, backLabel, actions, title, breadcrumbs, backLink = false, visibleTitle = false, labelOverride, className }) {
|
|
1621
|
+
function PageHeader({ resource: resourceInput, mode, recordName, backHref, backLabel, actions, title, breadcrumbs, backLink = false, visibleTitle = false, labelOverride, className }) {
|
|
1622
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
1907
1623
|
const app = (0, _burojs_react.useApp)();
|
|
1908
1624
|
const t = (0, _burojs_react.useT)();
|
|
1909
1625
|
const def = app.registry.get(resource);
|
|
@@ -1912,10 +1628,10 @@ function PageHeader({ resource, mode, recordName, backHref, backLabel, actions,
|
|
|
1912
1628
|
const resourceSingle = (0, _burojs_core.resolveResourceLabel)(caps, resource, "single", def);
|
|
1913
1629
|
const labelSingle = labelOverride ?? resourceSingle;
|
|
1914
1630
|
const labelPlural = (0, _burojs_core.resolveResourceLabel)(caps, resource, "plural", def);
|
|
1915
|
-
const computedTitle = title ?? (mode === "list" ? labelPlural : mode === "show" ? recordName ?? labelSingle : mode === "edit" ? recordName ? t
|
|
1631
|
+
const computedTitle = title ?? (mode === "list" ? labelPlural : mode === "show" ? recordName ?? labelSingle : mode === "edit" ? recordName ? resolveResourceTitle(caps, t, resource, "editTitleNamed", {
|
|
1916
1632
|
label: labelSingle,
|
|
1917
1633
|
name: recordName
|
|
1918
|
-
}
|
|
1634
|
+
}) : resolveResourceTitle(caps, t, resource, "editTitle", { label: labelSingle }) : resolveResourceTitle(caps, t, resource, "createTitle", { label: labelSingle }));
|
|
1919
1635
|
useDocumentTitle(app?.name ? `${computedTitle} · ${app.name}` : computedTitle);
|
|
1920
1636
|
const showBack = backLink && mode !== "list" && !breadcrumbs;
|
|
1921
1637
|
const computedBackHref = backHref ?? def?.basePath ?? `/${resource}`;
|
|
@@ -1946,9 +1662,10 @@ function PageHeader({ resource, mode, recordName, backHref, backLabel, actions,
|
|
|
1946
1662
|
]
|
|
1947
1663
|
});
|
|
1948
1664
|
}
|
|
1949
|
-
function ShowPageHeader({ resource, record, extraActions, breadcrumbs }) {
|
|
1665
|
+
function ShowPageHeader({ resource: resourceInput, record, extraActions, breadcrumbs }) {
|
|
1666
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
1950
1667
|
const def = (0, _burojs_react.useApp)().registry.get(resource);
|
|
1951
|
-
const recordName = (0, _burojs_react.useProjectedTitle)(resource, record
|
|
1668
|
+
const recordName = (0, _burojs_react.useProjectedTitle)(resource, (0, _burojs_react.recordKeyOf)(def, record), record);
|
|
1952
1669
|
(0, _burojs_react.usePublishDocVariant)(resource, record);
|
|
1953
1670
|
if (!def) return null;
|
|
1954
1671
|
return (0, react_jsx_runtime.jsx)(PageHeader, {
|
|
@@ -1963,16 +1680,18 @@ function ShowPageHeader({ resource, record, extraActions, breadcrumbs }) {
|
|
|
1963
1680
|
}), extraActions] })
|
|
1964
1681
|
});
|
|
1965
1682
|
}
|
|
1966
|
-
function EditPageHeader({ resource, record, backHref, breadcrumbs }) {
|
|
1967
|
-
const
|
|
1968
|
-
const def =
|
|
1683
|
+
function EditPageHeader({ resource: resourceInput, record, backHref, breadcrumbs }) {
|
|
1684
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
1685
|
+
const def = (0, _burojs_react.useApp)().registry.get(resource);
|
|
1969
1686
|
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
1970
|
-
const
|
|
1687
|
+
const recordKey = (0, _burojs_react.recordKeyOf)(def, record);
|
|
1688
|
+
const recordName = (0, _burojs_react.useProjectedTitle)(resource, recordKey, record);
|
|
1689
|
+
const back = (0, _burojs_react.useReturnTarget)(resource, "edit", String(recordKey ?? ""));
|
|
1971
1690
|
return (0, react_jsx_runtime.jsx)(PageHeader, {
|
|
1972
1691
|
resource,
|
|
1973
1692
|
mode: "edit",
|
|
1974
1693
|
recordName,
|
|
1975
|
-
backHref:
|
|
1694
|
+
backHref: backHref ?? back,
|
|
1976
1695
|
breadcrumbs,
|
|
1977
1696
|
backLabel: recordName ? `${(0, _burojs_core.resolveResourceLabel)(caps, resource, "single", def)}: ${recordName}` : void 0,
|
|
1978
1697
|
actions: (0, react_jsx_runtime.jsx)(ActionOverflow, {
|
|
@@ -2172,7 +1891,8 @@ function ItemNode({ node, row, fallback }) {
|
|
|
2172
1891
|
const viewProps = {
|
|
2173
1892
|
props,
|
|
2174
1893
|
data: {},
|
|
2175
|
-
t: placement.viewProps?.t ?? ((name) => name)
|
|
1894
|
+
t: placement.viewProps?.t ?? ((name) => name),
|
|
1895
|
+
...placement.viewProps?.empty === void 0 ? {} : { empty: placement.viewProps.empty }
|
|
2176
1896
|
};
|
|
2177
1897
|
return (0, react_jsx_runtime.jsx)(View, { ...viewProps });
|
|
2178
1898
|
}
|
|
@@ -2254,24 +1974,32 @@ function BuroPanelFrame({ body, title, description, collapsible, open, onToggle,
|
|
|
2254
1974
|
const t = (0, _burojs_react.useOptionalT)();
|
|
2255
1975
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
2256
1976
|
...nodeAttributes,
|
|
1977
|
+
...title === void 0 ? {} : { "aria-labelledby": titleId },
|
|
2257
1978
|
children: [
|
|
2258
1979
|
title === void 0 && info === null && !collapsible ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
2259
1980
|
"data-buro-region": "panel-title",
|
|
2260
1981
|
className: "flex items-center gap-1",
|
|
2261
1982
|
children: [
|
|
2262
|
-
collapsible ? (0, react_jsx_runtime.jsx)("
|
|
1983
|
+
collapsible && title !== void 0 ? (0, react_jsx_runtime.jsx)("h3", {
|
|
1984
|
+
id: titleId,
|
|
1985
|
+
className: "min-w-0 flex-1 text-sm font-semibold",
|
|
1986
|
+
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
1987
|
+
type: "button",
|
|
1988
|
+
"aria-expanded": open,
|
|
1989
|
+
"aria-controls": bodyId,
|
|
1990
|
+
onClick: () => onToggle(!open),
|
|
1991
|
+
className: "-mx-1 flex w-full items-center gap-1 rounded px-1 text-left hover:bg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
1992
|
+
children: [(0, react_jsx_runtime.jsx)(Chevron, { open }), title]
|
|
1993
|
+
})
|
|
1994
|
+
}) : collapsible ? (0, react_jsx_runtime.jsx)("button", {
|
|
2263
1995
|
type: "button",
|
|
2264
1996
|
"aria-expanded": open,
|
|
2265
1997
|
"aria-controls": bodyId,
|
|
2266
1998
|
"aria-label": open ? t("screen.collapse", { defaultValue: "Collapse" }) : t("screen.expand", { defaultValue: "Expand" }),
|
|
2267
1999
|
onClick: () => onToggle(!open),
|
|
2268
2000
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:bg-muted",
|
|
2269
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
2270
|
-
|
|
2271
|
-
"aria-hidden": "true"
|
|
2272
|
-
})
|
|
2273
|
-
}) : null,
|
|
2274
|
-
title === void 0 ? null : (0, react_jsx_runtime.jsx)("h3", {
|
|
2001
|
+
children: (0, react_jsx_runtime.jsx)(Chevron, { open })
|
|
2002
|
+
}) : title === void 0 ? null : (0, react_jsx_runtime.jsx)("h3", {
|
|
2275
2003
|
id: titleId,
|
|
2276
2004
|
className: "text-sm font-semibold",
|
|
2277
2005
|
children: title
|
|
@@ -2289,6 +2017,12 @@ function BuroPanelFrame({ body, title, description, collapsible, open, onToggle,
|
|
|
2289
2017
|
]
|
|
2290
2018
|
});
|
|
2291
2019
|
}
|
|
2020
|
+
function Chevron({ open }) {
|
|
2021
|
+
return (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconChevronRight, {
|
|
2022
|
+
className: open ? "h-4 w-4 shrink-0 rotate-90 text-muted-foreground transition-transform" : "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
|
|
2023
|
+
"aria-hidden": "true"
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2292
2026
|
function BuroTabsFrame({ tabs, active, onSelect, info, nodeAttributes }) {
|
|
2293
2027
|
if (tabs.length === 1) return (0, react_jsx_runtime.jsx)("div", {
|
|
2294
2028
|
...nodeAttributes,
|
|
@@ -2313,7 +2047,6 @@ function BuroTabsFrame({ tabs, active, onSelect, info, nodeAttributes }) {
|
|
|
2313
2047
|
}), info]
|
|
2314
2048
|
}), tabs.map((tab) => (0, react_jsx_runtime.jsx)(TabsContent, {
|
|
2315
2049
|
value: tab.key,
|
|
2316
|
-
forceMount: true,
|
|
2317
2050
|
"data-buro-region": "tab-panel",
|
|
2318
2051
|
"data-buro-key": tab.key,
|
|
2319
2052
|
children: tab.panel
|
|
@@ -2401,17 +2134,17 @@ function BuroStepsFrame({ wizard, steps, goTo, back, next, headingRef, info, nod
|
|
|
2401
2134
|
//#region src/primitives/checkbox.tsx
|
|
2402
2135
|
const Checkbox = react.forwardRef(({ className, checked, ...props }, ref) => (0, react_jsx_runtime.jsx)(_radix_ui_react_checkbox.Root, {
|
|
2403
2136
|
ref,
|
|
2404
|
-
className: require_use_theme.cn("peer h-4 w-4 shrink-0 rounded-
|
|
2137
|
+
className: require_use_theme.cn("peer inline-flex h-4 w-4 shrink-0 items-center justify-center align-middle rounded-[4px] border border-primary ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground", className),
|
|
2405
2138
|
checked,
|
|
2406
2139
|
...props,
|
|
2407
2140
|
children: (0, react_jsx_runtime.jsx)(_radix_ui_react_checkbox.Indicator, {
|
|
2408
2141
|
className: require_use_theme.cn("flex items-center justify-center text-current"),
|
|
2409
2142
|
children: checked === "indeterminate" ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconMinus, {
|
|
2410
2143
|
"data-icon": "minus",
|
|
2411
|
-
className: "
|
|
2144
|
+
className: "size-3.5"
|
|
2412
2145
|
}) : (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconCheck, {
|
|
2413
2146
|
"data-icon": "check",
|
|
2414
|
-
className: "
|
|
2147
|
+
className: "size-3.5"
|
|
2415
2148
|
})
|
|
2416
2149
|
})
|
|
2417
2150
|
}));
|
|
@@ -2436,6 +2169,17 @@ function useContainerNarrow(maxRem = 40) {
|
|
|
2436
2169
|
return [setElement, narrow];
|
|
2437
2170
|
}
|
|
2438
2171
|
//#endregion
|
|
2172
|
+
//#region src/data-table/fill-column.ts
|
|
2173
|
+
function fillColumnId(columns) {
|
|
2174
|
+
const eligible = columns.filter((c) => !c.pinned && !c.service);
|
|
2175
|
+
const declared = eligible.find((c) => c.fill);
|
|
2176
|
+
if (declared !== void 0) return declared.id;
|
|
2177
|
+
for (let i = eligible.length - 1; i >= 0; i--) {
|
|
2178
|
+
const c = eligible[i];
|
|
2179
|
+
if (c.resize && c.max === void 0) return c.id;
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
//#endregion
|
|
2439
2183
|
//#region src/data-table/data-table.tsx
|
|
2440
2184
|
function pinEdgeClass(isLastLeft, isFirstRight) {
|
|
2441
2185
|
if (isLastLeft) return "after:pointer-events-none after:absolute after:inset-y-0 after:left-full after:z-10 after:w-1.5 after:bg-gradient-to-r after:from-overlay/[0.07] after:to-transparent dark:after:from-overlay/30";
|
|
@@ -2447,7 +2191,8 @@ function pinEdgeClassFor(column, overflowing) {
|
|
|
2447
2191
|
if (!pinned || !overflowing) return "";
|
|
2448
2192
|
return pinEdgeClass(pinned === "left" && column.getIsLastColumn("left"), pinned === "right" && column.getIsFirstColumn("right"));
|
|
2449
2193
|
}
|
|
2450
|
-
function getPinStyles(column, overflowing) {
|
|
2194
|
+
function getPinStyles(column, overflowing, fill = false) {
|
|
2195
|
+
if (fill) return {};
|
|
2451
2196
|
const explicitWidth = { width: `calc(var(--col-${column.id}-size) * 1px)` };
|
|
2452
2197
|
const pinned = column.getIsPinned();
|
|
2453
2198
|
if (!pinned || !overflowing) return explicitWidth;
|
|
@@ -2472,21 +2217,35 @@ function columnMetaNoRowNav(meta) {
|
|
|
2472
2217
|
function columnMetaNoClip(meta) {
|
|
2473
2218
|
return meta?.noClip === true;
|
|
2474
2219
|
}
|
|
2475
|
-
function
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2220
|
+
function columnMetaWrap(meta) {
|
|
2221
|
+
return meta?.wrap === true;
|
|
2222
|
+
}
|
|
2223
|
+
function columnMetaFill(meta) {
|
|
2224
|
+
return meta?.fill === true;
|
|
2480
2225
|
}
|
|
2481
|
-
function
|
|
2226
|
+
function tableFillColumnId(table) {
|
|
2227
|
+
if (table.options.enableColumnResizing !== true) return void 0;
|
|
2228
|
+
return fillColumnId(table.getVisibleLeafColumns().map((c) => {
|
|
2229
|
+
const max = c.columnDef.maxSize;
|
|
2230
|
+
return {
|
|
2231
|
+
id: c.id,
|
|
2232
|
+
fill: columnMetaFill(c.columnDef.meta),
|
|
2233
|
+
resize: c.getCanResize(),
|
|
2234
|
+
...max !== void 0 && max < Number.MAX_SAFE_INTEGER ? { max } : {},
|
|
2235
|
+
pinned: c.getIsPinned() !== false,
|
|
2236
|
+
service: c.id.startsWith("__")
|
|
2237
|
+
};
|
|
2238
|
+
}));
|
|
2239
|
+
}
|
|
2240
|
+
function renderCellMarkup({ cell, resizable, overflowing, fill, testId, onCellClick, noRowNav }) {
|
|
2482
2241
|
const liveColumn = cell.getContext().table.getColumn(cell.column.id) ?? cell.column;
|
|
2483
2242
|
const pinEdge = pinEdgeClassFor(liveColumn, overflowing);
|
|
2484
|
-
const noClip = columnMetaNoClip(cell.column.columnDef.meta);
|
|
2243
|
+
const noClip = columnMetaNoClip(cell.column.columnDef.meta) || columnMetaWrap(cell.column.columnDef.meta);
|
|
2485
2244
|
return (0, react_jsx_runtime.jsx)(require_filter_builder.TableCell, {
|
|
2486
2245
|
"data-testid": testId,
|
|
2487
2246
|
"data-no-row-nav": columnMetaNoRowNav(cell.column.columnDef.meta) || noRowNav ? "" : void 0,
|
|
2488
2247
|
onClick: onCellClick,
|
|
2489
|
-
style: getPinStyles(liveColumn, overflowing),
|
|
2248
|
+
style: getPinStyles(liveColumn, overflowing, fill),
|
|
2490
2249
|
className: require_use_theme.cn(resizable && !pinEdge && !noClip && "overflow-hidden", pinEdge && "relative", pinEdge, columnMetaClassName(cell.column.columnDef.meta), onCellClick && "cursor-pointer"),
|
|
2491
2250
|
children: resizable && !noClip ? (0, react_jsx_runtime.jsx)("div", {
|
|
2492
2251
|
className: "truncate",
|
|
@@ -2498,7 +2257,7 @@ function renderCellMarkup({ cell, resizable, overflowing, testId, onCellClick, n
|
|
|
2498
2257
|
function MemoCellInner(props) {
|
|
2499
2258
|
return renderCellMarkup(props);
|
|
2500
2259
|
}
|
|
2501
|
-
const MemoCell = (0, react.memo)(MemoCellInner, (prev, next) => prev.rowOriginal === next.rowOriginal && prev.cell.column.id === next.cell.column.id && prev.resizable === next.resizable && (!prev.pinned && !next.pinned || prev.overflowing === next.overflowing) && prev.pinned === next.pinned && prev.testId === next.testId);
|
|
2260
|
+
const MemoCell = (0, react.memo)(MemoCellInner, (prev, next) => prev.rowOriginal === next.rowOriginal && prev.cell.column.id === next.cell.column.id && prev.resizable === next.resizable && (!prev.pinned && !next.pinned || prev.overflowing === next.overflowing) && prev.pinned === next.pinned && prev.fill === next.fill && prev.testId === next.testId);
|
|
2502
2261
|
function SelectionCellInner(props) {
|
|
2503
2262
|
const row = props.cell.row;
|
|
2504
2263
|
const toggle = (e) => {
|
|
@@ -2512,7 +2271,7 @@ function SelectionCellInner(props) {
|
|
|
2512
2271
|
});
|
|
2513
2272
|
}
|
|
2514
2273
|
const SelectionCell = (0, react.memo)(SelectionCellInner);
|
|
2515
|
-
function DataRowInner({ row, isSelected, resizable, overflowing, selectionColumnId, getCellTestId, getRowTestId, rowHref, onRowOpen, activateRow, rowClassName }) {
|
|
2274
|
+
function DataRowInner({ row, isSelected, resizable, overflowing, fillColumnId, selectionColumnId, getCellTestId, getRowTestId, rowHref, onRowOpen, activateRow, rowClassName }) {
|
|
2516
2275
|
const clickable = rowHref !== void 0 || onRowOpen !== void 0;
|
|
2517
2276
|
return (0, react_jsx_runtime.jsx)(require_filter_builder.TableRow, {
|
|
2518
2277
|
"data-state": isSelected ? "selected" : void 0,
|
|
@@ -2525,6 +2284,7 @@ function DataRowInner({ row, isSelected, resizable, overflowing, selectionColumn
|
|
|
2525
2284
|
isSelected,
|
|
2526
2285
|
resizable,
|
|
2527
2286
|
overflowing,
|
|
2287
|
+
fill: cell.column.id === fillColumnId,
|
|
2528
2288
|
pinned: cell.getContext().table.getColumn(cell.column.id)?.getIsPinned() ?? false,
|
|
2529
2289
|
testId: getCellTestId?.(row.original, cell.column.id)
|
|
2530
2290
|
}, cell.id) : (0, react_jsx_runtime.jsx)(MemoCell, {
|
|
@@ -2532,13 +2292,14 @@ function DataRowInner({ row, isSelected, resizable, overflowing, selectionColumn
|
|
|
2532
2292
|
rowOriginal: row.original,
|
|
2533
2293
|
resizable,
|
|
2534
2294
|
overflowing,
|
|
2295
|
+
fill: cell.column.id === fillColumnId,
|
|
2535
2296
|
pinned: cell.getContext().table.getColumn(cell.column.id)?.getIsPinned() ?? false,
|
|
2536
2297
|
testId: getCellTestId?.(row.original, cell.column.id)
|
|
2537
2298
|
}, cell.id))
|
|
2538
2299
|
});
|
|
2539
2300
|
}
|
|
2540
|
-
const MemoRow = (0, react.memo)(DataRowInner, (prev, next) => prev.row.original === next.row.original && prev.row.id === next.row.id && prev.isSelected === next.isSelected && prev.resizable === next.resizable && prev.overflowing === next.overflowing && prev.columnLayoutKey === next.columnLayoutKey && prev.selectionColumnId === next.selectionColumnId && prev.getCellTestId === next.getCellTestId && prev.getRowTestId === next.getRowTestId && prev.rowHref === next.rowHref && prev.onRowOpen === next.onRowOpen && prev.activateRow === next.activateRow && prev.rowClassName === next.rowClassName);
|
|
2541
|
-
function DataTableBodyInner({ rows, isLoading, loadingRowCount, visibleColumnCount, emptyState, emptyText, resizable, overflowing, columnLayoutKey, selectionColumnId, getCellTestId, getRowTestId, rowHref, onRowOpen, activateRow, rowClassName }) {
|
|
2301
|
+
const MemoRow = (0, react.memo)(DataRowInner, (prev, next) => prev.row.original === next.row.original && prev.row.id === next.row.id && prev.isSelected === next.isSelected && prev.resizable === next.resizable && prev.overflowing === next.overflowing && prev.columnLayoutKey === next.columnLayoutKey && prev.fillColumnId === next.fillColumnId && prev.selectionColumnId === next.selectionColumnId && prev.getCellTestId === next.getCellTestId && prev.getRowTestId === next.getRowTestId && prev.rowHref === next.rowHref && prev.onRowOpen === next.onRowOpen && prev.activateRow === next.activateRow && prev.rowClassName === next.rowClassName);
|
|
2302
|
+
function DataTableBodyInner({ rows, isLoading, loadingRowCount, visibleColumnCount, emptyState, emptyText, resizable, overflowing, columnLayoutKey, fillColumnId, selectionColumnId, getCellTestId, getRowTestId, rowHref, onRowOpen, activateRow, rowClassName }) {
|
|
2542
2303
|
return (0, react_jsx_runtime.jsx)(require_filter_builder.TableBody, { children: isLoading ? Array.from({ length: loadingRowCount }).map((_, i) => (0, react_jsx_runtime.jsx)(require_filter_builder.TableRow, {
|
|
2543
2304
|
"aria-busy": "true",
|
|
2544
2305
|
children: Array.from({ length: Math.max(1, visibleColumnCount) }).map((__, j) => (0, react_jsx_runtime.jsx)(require_filter_builder.TableCell, { children: (0, react_jsx_runtime.jsx)("div", { className: "h-4 w-3/4 animate-pulse rounded bg-muted" }) }, `skeleton-${i}-${j}`))
|
|
@@ -2555,6 +2316,7 @@ function DataTableBodyInner({ rows, isLoading, loadingRowCount, visibleColumnCou
|
|
|
2555
2316
|
resizable,
|
|
2556
2317
|
overflowing,
|
|
2557
2318
|
columnLayoutKey,
|
|
2319
|
+
fillColumnId,
|
|
2558
2320
|
selectionColumnId,
|
|
2559
2321
|
getCellTestId,
|
|
2560
2322
|
getRowTestId,
|
|
@@ -2566,7 +2328,7 @@ function DataTableBodyInner({ rows, isLoading, loadingRowCount, visibleColumnCou
|
|
|
2566
2328
|
}
|
|
2567
2329
|
const DataTableBody = (0, react.memo)(DataTableBodyInner, (prev, next) => {
|
|
2568
2330
|
if (!next.isResizing) return false;
|
|
2569
|
-
return prev.rows === next.rows && prev.overflowing === next.overflowing && prev.isLoading === next.isLoading && prev.columnLayoutKey === next.columnLayoutKey && prev.selectionColumnId === next.selectionColumnId;
|
|
2331
|
+
return prev.rows === next.rows && prev.overflowing === next.overflowing && prev.isLoading === next.isLoading && prev.columnLayoutKey === next.columnLayoutKey && prev.fillColumnId === next.fillColumnId && prev.selectionColumnId === next.selectionColumnId;
|
|
2570
2332
|
});
|
|
2571
2333
|
function DataTable({ table, tableTestId, getRowTestId, getCellTestId, isLoading = false, loadingRowCount = 5, emptyState, errorState, rowClassName, ariaLabel, onColumnReorder, rowHref, onRowOpen, selectionColumnId, className }) {
|
|
2572
2334
|
const t = (0, _burojs_react.useOptionalT)();
|
|
@@ -2596,8 +2358,10 @@ function DataTable({ table, tableTestId, getRowTestId, getCellTestId, isLoading
|
|
|
2596
2358
|
const rows = table.getRowModel().rows;
|
|
2597
2359
|
const headerGroups = table.getHeaderGroups();
|
|
2598
2360
|
const visibleColumnCount = table.getVisibleLeafColumns().length;
|
|
2361
|
+
const fillId = tableFillColumnId(table);
|
|
2599
2362
|
const columnLayoutKey = table.getVisibleLeafColumns().map((c) => `${c.id}:${c.getIsPinned() || ""}`).join("|");
|
|
2600
2363
|
const resizable = table.options.enableColumnResizing === true;
|
|
2364
|
+
const widthSum = resizable ? table.getVisibleLeafColumns().reduce((sum, c) => sum + c.getSize(), 0) : 0;
|
|
2601
2365
|
const hasPinned = table.getState().columnPinning != null && (table.getState().columnPinning.left?.length || table.getState().columnPinning.right?.length);
|
|
2602
2366
|
const sizingState = table.getState().columnSizing;
|
|
2603
2367
|
const sizingInfo = table.getState().columnSizingInfo;
|
|
@@ -2689,7 +2453,7 @@ function DataTable({ table, tableTestId, getRowTestId, getCellTestId, isLoading
|
|
|
2689
2453
|
className,
|
|
2690
2454
|
style: resizable ? {
|
|
2691
2455
|
...columnSizeVars,
|
|
2692
|
-
|
|
2456
|
+
width: fillId !== void 0 ? `max(100%, ${widthSum}px)` : `${widthSum}px`,
|
|
2693
2457
|
tableLayout: "fixed"
|
|
2694
2458
|
} : void 0,
|
|
2695
2459
|
children: [(0, react_jsx_runtime.jsx)(require_filter_builder.TableHeader, { children: headerGroups.map((hg) => (0, react_jsx_runtime.jsx)(require_filter_builder.TableRow, { children: hg.headers.map((header) => {
|
|
@@ -2700,7 +2464,7 @@ function DataTable({ table, tableTestId, getRowTestId, getCellTestId, isLoading
|
|
|
2700
2464
|
return (0, react_jsx_runtime.jsxs)(require_filter_builder.TableHead, {
|
|
2701
2465
|
colSpan: header.colSpan,
|
|
2702
2466
|
"aria-sort": ariaSort,
|
|
2703
|
-
style: getPinStyles(header.column, overflowing),
|
|
2467
|
+
style: getPinStyles(header.column, overflowing, header.column.id === fillId),
|
|
2704
2468
|
className: require_use_theme.cn("relative", resizable && !columnMetaNoClip(header.column.columnDef.meta) && (pinEdgeClassFor(header.column, overflowing) ? "[&>*:not([data-testid^=col-resize])]:truncate" : "overflow-hidden [&>*:not([data-testid^=col-resize])]:truncate"), canReorder && "cursor-grab", pinEdgeClassFor(header.column, overflowing), columnMetaClassName(header.column.columnDef.meta)),
|
|
2705
2469
|
draggable: canReorder || void 0,
|
|
2706
2470
|
onDragStart: canReorder ? (e) => {
|
|
@@ -2759,6 +2523,7 @@ function DataTable({ table, tableTestId, getRowTestId, getCellTestId, isLoading
|
|
|
2759
2523
|
resizable,
|
|
2760
2524
|
overflowing,
|
|
2761
2525
|
columnLayoutKey,
|
|
2526
|
+
fillColumnId: fillId,
|
|
2762
2527
|
selectionColumnId,
|
|
2763
2528
|
isResizing: Boolean(sizingInfo.isResizingColumn),
|
|
2764
2529
|
getCellTestId,
|
|
@@ -2875,7 +2640,8 @@ function ColumnHeaderMenu({ label, sortDirection, sortable, onSort, pinned, onPi
|
|
|
2875
2640
|
}
|
|
2876
2641
|
//#endregion
|
|
2877
2642
|
//#region src/resource/column-accessor.ts
|
|
2878
|
-
function columnAccessor(column) {
|
|
2643
|
+
function columnAccessor(column, objectPath = false) {
|
|
2644
|
+
if (objectPath) return { accessorFn: (row) => (0, _burojs_react.readColumnValue)(row, column, true) };
|
|
2879
2645
|
return column.includes(".") ? { accessorFn: (row) => row[column] } : { accessorKey: column };
|
|
2880
2646
|
}
|
|
2881
2647
|
//#endregion
|
|
@@ -2982,104 +2748,292 @@ function resolveUpdater(updater, prev) {
|
|
|
2982
2748
|
}
|
|
2983
2749
|
//#endregion
|
|
2984
2750
|
//#region src/resource/list-error-state.tsx
|
|
2985
|
-
function ListErrorState(
|
|
2986
|
-
const
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
children: [
|
|
2995
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
2996
|
-
className: "rounded-full bg-destructive/10 p-3 text-destructive",
|
|
2997
|
-
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconAlertCircle, {
|
|
2998
|
-
className: "size-6",
|
|
2999
|
-
"aria-hidden": "true"
|
|
3000
|
-
})
|
|
3001
|
-
}),
|
|
3002
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
3003
|
-
className: "space-y-1",
|
|
3004
|
-
children: [(0, react_jsx_runtime.jsx)("h3", {
|
|
3005
|
-
className: "text-base font-semibold tracking-tight text-destructive",
|
|
3006
|
-
children: title ?? t("list.errorTitle")
|
|
3007
|
-
}), (0, react_jsx_runtime.jsx)("p", {
|
|
3008
|
-
className: "max-w-md text-sm text-muted-foreground",
|
|
3009
|
-
children: friendlyError || t("list.errorBody")
|
|
3010
|
-
})]
|
|
3011
|
-
}),
|
|
3012
|
-
raw && raw !== friendlyError ? (0, react_jsx_runtime.jsxs)("details", {
|
|
3013
|
-
className: "max-w-md text-left",
|
|
3014
|
-
children: [(0, react_jsx_runtime.jsx)("summary", {
|
|
3015
|
-
className: "cursor-pointer text-xs text-muted-foreground hover:text-foreground",
|
|
3016
|
-
children: t("list.errorDetails")
|
|
3017
|
-
}), (0, react_jsx_runtime.jsx)("p", {
|
|
3018
|
-
className: "mt-1.5 break-all font-mono text-xs text-muted-foreground",
|
|
3019
|
-
"data-testid": "list-error-detail",
|
|
3020
|
-
children: raw
|
|
3021
|
-
})]
|
|
3022
|
-
}) : null,
|
|
3023
|
-
onRetry && (0, react_jsx_runtime.jsx)("div", {
|
|
3024
|
-
className: "flex justify-center pt-2",
|
|
3025
|
-
children: (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
3026
|
-
type: "button",
|
|
3027
|
-
variant: "outline",
|
|
3028
|
-
size: "sm",
|
|
3029
|
-
"data-testid": resource ? `list-error-retry:${resource}` : "list-error-retry",
|
|
3030
|
-
onClick: onRetry,
|
|
3031
|
-
className: "gap-1.5",
|
|
3032
|
-
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconRefresh, {
|
|
3033
|
-
className: "size-3.5",
|
|
3034
|
-
"aria-hidden": "true"
|
|
3035
|
-
}), t("actions.retry")]
|
|
3036
|
-
})
|
|
3037
|
-
})
|
|
3038
|
-
]
|
|
2751
|
+
function ListErrorState(props) {
|
|
2752
|
+
const { error, onRetry, resource, title, className } = props;
|
|
2753
|
+
return (0, react_jsx_runtime.jsx)(require_relation_create.LoadError, {
|
|
2754
|
+
surface: "list",
|
|
2755
|
+
error,
|
|
2756
|
+
...onRetry === void 0 ? {} : { retry: onRetry },
|
|
2757
|
+
...resource === void 0 ? {} : { resource },
|
|
2758
|
+
...title === void 0 ? {} : { title },
|
|
2759
|
+
...className === void 0 ? {} : { className }
|
|
3039
2760
|
});
|
|
3040
2761
|
}
|
|
3041
2762
|
//#endregion
|
|
3042
|
-
//#region src/
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
variant: "outline",
|
|
3051
|
-
size: "sm",
|
|
3052
|
-
disabled: loading,
|
|
3053
|
-
onClick: onMore,
|
|
3054
|
-
"data-testid": "cursor-load-more",
|
|
3055
|
-
children: loading ? t("pagination.loadingMore") : t("pagination.loadMore")
|
|
3056
|
-
})
|
|
3057
|
-
});
|
|
2763
|
+
//#region src/resource/use-table-layout.ts
|
|
2764
|
+
const WRITE_DEBOUNCE_MS = 200;
|
|
2765
|
+
function mutate(run, ok, then) {
|
|
2766
|
+
try {
|
|
2767
|
+
run().then((result) => {
|
|
2768
|
+
if (ok(result.status)) then();
|
|
2769
|
+
}, () => void 0);
|
|
2770
|
+
} catch {}
|
|
3058
2771
|
}
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
2772
|
+
function resolve(updater, current) {
|
|
2773
|
+
return typeof updater === "function" ? updater(current) : updater;
|
|
2774
|
+
}
|
|
2775
|
+
function sameNames(a, b) {
|
|
2776
|
+
return a.length === b.length && a.every((name, index) => name === b[index]);
|
|
2777
|
+
}
|
|
2778
|
+
function readSizes(sizes, rule) {
|
|
2779
|
+
const out = {};
|
|
2780
|
+
for (const [column, size] of Object.entries(sizes)) {
|
|
2781
|
+
const of = rule(column);
|
|
2782
|
+
if (of === void 0 || !of.resize) continue;
|
|
2783
|
+
out[column] = Math.min(Math.max(size, of.min), of.max ?? Number.POSITIVE_INFINITY);
|
|
2784
|
+
}
|
|
2785
|
+
return out;
|
|
2786
|
+
}
|
|
2787
|
+
function useTableLayout({ resource, layoutId, rule, defaultPinning, resetLayout }) {
|
|
2788
|
+
const params = (0, react.useMemo)(() => layoutId === void 0 ? null : {
|
|
2789
|
+
resource,
|
|
2790
|
+
list: layoutId
|
|
2791
|
+
}, [resource, layoutId]);
|
|
2792
|
+
const settings = (0, _burojs_react.useOptionalUiSettings)(_burojs_react.tableLayoutSetting, params);
|
|
2793
|
+
const settingsRef = (0, react.useRef)(settings);
|
|
2794
|
+
settingsRef.current = settings;
|
|
2795
|
+
const key = layoutId === void 0 ? void 0 : `${resource}\u0000${layoutId}`;
|
|
2796
|
+
const fallback = (0, react.useMemo)(() => ({
|
|
2797
|
+
sizes: {},
|
|
2798
|
+
order: [],
|
|
2799
|
+
pinning: defaultPinning
|
|
2800
|
+
}), [defaultPinning]);
|
|
2801
|
+
const [local, setLocal] = (0, react.useState)();
|
|
2802
|
+
const stored = settings?.snapshot.entries[0]?.value;
|
|
2803
|
+
const settled = settings === void 0 || !settings.snapshot.pending;
|
|
2804
|
+
const held = (0, react.useRef)(null);
|
|
2805
|
+
const layout = (local !== void 0 && local.key === key ? local.value : void 0) ?? stored ?? fallback;
|
|
2806
|
+
const latest = (0, react.useRef)(layout);
|
|
2807
|
+
latest.current = layout;
|
|
2808
|
+
const sizing = (0, react.useMemo)(() => readSizes(layout.sizes, rule), [layout.sizes, rule]);
|
|
2809
|
+
const sizingRef = (0, react.useRef)(sizing);
|
|
2810
|
+
sizingRef.current = sizing;
|
|
2811
|
+
const generation = (0, react.useRef)(0);
|
|
2812
|
+
const timer = (0, react.useRef)(null);
|
|
2813
|
+
const pending = (0, react.useRef)(null);
|
|
2814
|
+
const confirm = (0, react.useCallback)((sent) => {
|
|
2815
|
+
if (generation.current === sent && pending.current === null) setLocal(void 0);
|
|
2816
|
+
}, []);
|
|
2817
|
+
const write = (0, react.useCallback)((target, value) => {
|
|
2818
|
+
const scopeId = target.snapshot.entries[0]?.scope.id ?? target.snapshot.writeScopes[0]?.id;
|
|
2819
|
+
if (scopeId === void 0) return;
|
|
2820
|
+
const sent = generation.current;
|
|
2821
|
+
mutate(() => target.set({
|
|
2822
|
+
scopeId,
|
|
2823
|
+
value
|
|
2824
|
+
}), (status) => status === "created" || status === "updated", () => confirm(sent));
|
|
2825
|
+
}, [confirm]);
|
|
2826
|
+
const store = (0, react.useCallback)((target, next) => {
|
|
2827
|
+
if (!(Object.keys(next.sizes).length === 0 && next.order.length === 0 && sameNames(next.pinning.left, defaultPinning.left) && sameNames(next.pinning.right, defaultPinning.right))) {
|
|
2828
|
+
write(target, next);
|
|
2829
|
+
return;
|
|
2830
|
+
}
|
|
2831
|
+
const entry = target.snapshot.entries[0];
|
|
2832
|
+
if (entry === void 0) {
|
|
2833
|
+
setLocal(void 0);
|
|
2834
|
+
return;
|
|
2835
|
+
}
|
|
2836
|
+
const sent = generation.current;
|
|
2837
|
+
mutate(() => target.remove({ id: entry.id }), (status) => status === "removed", () => confirm(sent));
|
|
2838
|
+
}, [
|
|
2839
|
+
defaultPinning,
|
|
2840
|
+
write,
|
|
2841
|
+
confirm
|
|
2842
|
+
]);
|
|
2843
|
+
const flush = (0, react.useCallback)(() => {
|
|
2844
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
2845
|
+
timer.current = null;
|
|
2846
|
+
const due = pending.current;
|
|
2847
|
+
pending.current = null;
|
|
2848
|
+
if (due !== null) write(due.target, due.value);
|
|
2849
|
+
}, [write]);
|
|
2850
|
+
const change = (0, react.useCallback)((next, debounced, touch) => {
|
|
2851
|
+
latest.current = next;
|
|
2852
|
+
generation.current += 1;
|
|
2853
|
+
setLocal({
|
|
2854
|
+
key,
|
|
2855
|
+
value: next
|
|
2856
|
+
});
|
|
2857
|
+
const target = settingsRef.current;
|
|
2858
|
+
if (target === void 0) return;
|
|
2859
|
+
if (target.snapshot.pending || held.current !== null && held.current.key === key) {
|
|
2860
|
+
const edits = held.current !== null && held.current.key === key ? held.current : {
|
|
2861
|
+
key,
|
|
2862
|
+
resetAll: false,
|
|
2863
|
+
resetSizes: false,
|
|
2864
|
+
sizes: new Map()
|
|
2865
|
+
};
|
|
2866
|
+
held.current = edits;
|
|
2867
|
+
touch(edits);
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
pending.current = {
|
|
2871
|
+
target,
|
|
2872
|
+
value: next
|
|
2873
|
+
};
|
|
2874
|
+
if (!debounced) {
|
|
2875
|
+
flush();
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
2879
|
+
timer.current = setTimeout(flush, WRITE_DEBOUNCE_MS);
|
|
2880
|
+
}, [key, flush]);
|
|
2881
|
+
(0, react.useEffect)(() => flush, [key]);
|
|
2882
|
+
(0, react.useEffect)(() => {
|
|
2883
|
+
const edits = held.current;
|
|
2884
|
+
if (edits === null) return;
|
|
2885
|
+
if (edits.key !== key) {
|
|
2886
|
+
held.current = null;
|
|
2887
|
+
return;
|
|
2888
|
+
}
|
|
2889
|
+
const target = settingsRef.current;
|
|
2890
|
+
if (!settled || target === void 0) return;
|
|
2891
|
+
held.current = null;
|
|
2892
|
+
const base = edits.resetAll ? fallback : stored ?? fallback;
|
|
2893
|
+
const sizes = edits.resetAll || edits.resetSizes ? {} : { ...readSizes(base.sizes, rule) };
|
|
2894
|
+
for (const [column, size] of edits.sizes) if (size === void 0) delete sizes[column];
|
|
2895
|
+
else sizes[column] = size;
|
|
2896
|
+
const next = {
|
|
2897
|
+
sizes,
|
|
2898
|
+
order: edits.order ?? base.order,
|
|
2899
|
+
pinning: edits.pinning ?? base.pinning
|
|
2900
|
+
};
|
|
2901
|
+
latest.current = next;
|
|
2902
|
+
generation.current += 1;
|
|
2903
|
+
setLocal({
|
|
2904
|
+
key,
|
|
2905
|
+
value: next
|
|
2906
|
+
});
|
|
2907
|
+
store(target, next);
|
|
2908
|
+
}, [settled, key]);
|
|
2909
|
+
const resetToken = resetLayout?.token ?? 0;
|
|
2910
|
+
const seenToken = (0, react.useRef)(resetToken);
|
|
2911
|
+
(0, react.useEffect)(() => {
|
|
2912
|
+
if (resetToken === seenToken.current) return;
|
|
2913
|
+
seenToken.current = resetToken;
|
|
2914
|
+
const all = resetLayout?.mode === "all";
|
|
2915
|
+
const next = all ? fallback : {
|
|
2916
|
+
...latest.current,
|
|
2917
|
+
sizes: {}
|
|
2918
|
+
};
|
|
2919
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
2920
|
+
timer.current = null;
|
|
2921
|
+
pending.current = null;
|
|
2922
|
+
latest.current = next;
|
|
2923
|
+
generation.current += 1;
|
|
2924
|
+
setLocal({
|
|
2925
|
+
key,
|
|
2926
|
+
value: next
|
|
2927
|
+
});
|
|
2928
|
+
const target = settingsRef.current;
|
|
2929
|
+
if (target === void 0) return;
|
|
2930
|
+
if (target.snapshot.pending || held.current !== null && held.current.key === key) {
|
|
2931
|
+
const prior = held.current !== null && held.current.key === key ? held.current : void 0;
|
|
2932
|
+
held.current = all ? {
|
|
2933
|
+
key,
|
|
2934
|
+
resetAll: true,
|
|
2935
|
+
resetSizes: false,
|
|
2936
|
+
sizes: new Map()
|
|
2937
|
+
} : {
|
|
2938
|
+
key,
|
|
2939
|
+
resetAll: prior?.resetAll ?? false,
|
|
2940
|
+
resetSizes: true,
|
|
2941
|
+
sizes: new Map(),
|
|
2942
|
+
...prior?.order === void 0 ? {} : { order: prior.order },
|
|
2943
|
+
...prior?.pinning === void 0 ? {} : { pinning: prior.pinning }
|
|
2944
|
+
};
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
store(target, next);
|
|
2948
|
+
}, [resetToken]);
|
|
2949
|
+
const setColumnSizing = (0, react.useCallback)((updater) => {
|
|
2950
|
+
const before = sizingRef.current;
|
|
2951
|
+
const sizes = resolve(updater, before);
|
|
2952
|
+
sizingRef.current = sizes;
|
|
2953
|
+
change({
|
|
2954
|
+
...latest.current,
|
|
2955
|
+
sizes
|
|
2956
|
+
}, true, (edits) => {
|
|
2957
|
+
for (const column of new Set([...Object.keys(before), ...Object.keys(sizes)])) if (before[column] !== sizes[column]) edits.sizes.set(column, sizes[column]);
|
|
2958
|
+
});
|
|
2959
|
+
}, [change]);
|
|
2960
|
+
const setColumnOrder = (0, react.useCallback)((updater) => {
|
|
2961
|
+
const order = resolve(updater, latest.current.order);
|
|
2962
|
+
change({
|
|
2963
|
+
...latest.current,
|
|
2964
|
+
order
|
|
2965
|
+
}, false, (edits) => {
|
|
2966
|
+
edits.order = order;
|
|
2967
|
+
});
|
|
2968
|
+
}, [change]);
|
|
2969
|
+
const setColumnPinning = (0, react.useCallback)((updater) => {
|
|
2970
|
+
const resolved = resolve(updater, latest.current.pinning);
|
|
2971
|
+
const pinning = {
|
|
2972
|
+
left: resolved.left ?? [],
|
|
2973
|
+
right: resolved.right ?? []
|
|
2974
|
+
};
|
|
2975
|
+
change({
|
|
2976
|
+
...latest.current,
|
|
2977
|
+
pinning
|
|
2978
|
+
}, false, (edits) => {
|
|
2979
|
+
edits.pinning = pinning;
|
|
2980
|
+
});
|
|
2981
|
+
}, [change]);
|
|
2982
|
+
return {
|
|
2983
|
+
columnSizing: sizing,
|
|
2984
|
+
setColumnSizing,
|
|
2985
|
+
columnOrder: layout.order,
|
|
2986
|
+
setColumnOrder,
|
|
2987
|
+
columnPinning: layout.pinning,
|
|
2988
|
+
setColumnPinning
|
|
2989
|
+
};
|
|
2990
|
+
}
|
|
2991
|
+
//#endregion
|
|
2992
|
+
//#region src/list-kit/cursor-load-more.tsx
|
|
2993
|
+
function CursorLoadMore({ hasMore, loading, onMore }) {
|
|
2994
|
+
const t = (0, _burojs_react.useT)();
|
|
2995
|
+
if (!hasMore) return null;
|
|
2996
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
2997
|
+
className: "flex justify-center py-4",
|
|
2998
|
+
children: (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
2999
|
+
type: "button",
|
|
3000
|
+
variant: "outline",
|
|
3001
|
+
size: "sm",
|
|
3002
|
+
disabled: loading,
|
|
3003
|
+
onClick: onMore,
|
|
3004
|
+
"data-testid": "cursor-load-more",
|
|
3005
|
+
children: loading ? t("pagination.loadingMore") : t("pagination.loadMore")
|
|
3006
|
+
})
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
//#endregion
|
|
3010
|
+
//#region src/resource/resource-list.tsx
|
|
3011
|
+
function CountRowsTrigger({ label, loading, onClick, testid, variant, className }) {
|
|
3012
|
+
return (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
3013
|
+
type: "button",
|
|
3014
|
+
variant,
|
|
3015
|
+
size: "sm",
|
|
3016
|
+
"data-testid": testid,
|
|
3017
|
+
onClick,
|
|
3018
|
+
disabled: loading,
|
|
3019
|
+
"aria-label": label,
|
|
3020
|
+
"aria-busy": loading || void 0,
|
|
3021
|
+
className: require_use_theme.cn("relative", className),
|
|
3022
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
3023
|
+
className: loading ? "invisible" : void 0,
|
|
3024
|
+
children: label
|
|
3025
|
+
}), loading && (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
|
|
3026
|
+
className: "absolute inset-0 m-auto size-3.5 animate-spin",
|
|
3027
|
+
"aria-hidden": "true"
|
|
3078
3028
|
})]
|
|
3079
3029
|
});
|
|
3080
3030
|
}
|
|
3081
3031
|
const SELECT_COL_ID = "__select__";
|
|
3082
3032
|
const ACTIONS_COL_ID = "__actions__";
|
|
3033
|
+
const DEFAULT_PINNING = Object.freeze({
|
|
3034
|
+
left: Object.freeze([SELECT_COL_ID, "id"]),
|
|
3035
|
+
right: Object.freeze([ACTIONS_COL_ID])
|
|
3036
|
+
});
|
|
3083
3037
|
const ROW_ACTION_CONTROL_PX = 28;
|
|
3084
3038
|
const ROW_ACTION_GAP_PX = 4;
|
|
3085
3039
|
const ACTIONS_CELL_PADDING_PX = 16;
|
|
@@ -3091,29 +3045,30 @@ function actionsColumnSize(items) {
|
|
|
3091
3045
|
const strip = controls * ROW_ACTION_CONTROL_PX + (controls - 1) * ROW_ACTION_GAP_PX + ACTIONS_CELL_PADDING_PX;
|
|
3092
3046
|
return Math.max(ACTIONS_COL_MIN_PX, strip);
|
|
3093
3047
|
}
|
|
3094
|
-
const
|
|
3095
|
-
|
|
3096
|
-
|
|
3048
|
+
const ALIGN_CLASS = {
|
|
3049
|
+
start: "text-start",
|
|
3050
|
+
center: "text-center",
|
|
3051
|
+
end: "text-end"
|
|
3097
3052
|
};
|
|
3098
|
-
const
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
}
|
|
3108
|
-
function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSize, onRequestCount, isCountingRows = false, pageSizeOptions = [
|
|
3053
|
+
const STANDALONE_COLUMN_UI = Object.freeze({
|
|
3054
|
+
default: 160,
|
|
3055
|
+
min: 90,
|
|
3056
|
+
align: "start",
|
|
3057
|
+
resize: true,
|
|
3058
|
+
fill: false,
|
|
3059
|
+
display: Object.freeze({ params: Object.freeze({}) })
|
|
3060
|
+
});
|
|
3061
|
+
function ResourceList({ resource: resourceInput, data, total, page = 1, pageSize = 10, onPageSize, onRequestCount, isCountingRows = false, pageSizeOptions = [
|
|
3109
3062
|
10,
|
|
3110
3063
|
25,
|
|
3111
3064
|
50,
|
|
3112
3065
|
100
|
|
3113
|
-
], onPage, loadMore, selectable = false, rowActions = true, selectedIds, onSelectionChange, className, isLoading = false, error = null, onRetry, createHref, isFiltered = false, onClearFilter, emptyState, rowsView, rowHref, rowQuick, rowLinkKey, renderCell, sort, onSort, onHideColumn, requiredColumns, resetLayout, columns: columnsOverride, tableRef }) {
|
|
3066
|
+
], onPage, loadMore, selectable = false, rowActions = true, selectedIds, onSelectionChange, className, isLoading = false, error = null, onRetry, createHref, isFiltered = false, onClearFilter, emptyState, rowsView, rowHref, rowQuick, rowLinkKey, renderCell, sort, onSort, sortable, onHideColumn, requiredColumns, resetLayout, columns: columnsOverride, columnUi, layoutId, tableRef }) {
|
|
3067
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
3114
3068
|
const app = (0, _burojs_react.useApp)();
|
|
3115
3069
|
const tid = (0, _burojs_react.useTestIds)();
|
|
3116
3070
|
const t = (0, _burojs_react.useOptionalT)();
|
|
3071
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
3117
3072
|
const locale = (0, _burojs_react.useLocale)();
|
|
3118
3073
|
const nf = (0, react.useMemo)(() => new Intl.NumberFormat(locale), [locale]);
|
|
3119
3074
|
const i18nCaps = (0, _burojs_react.useI18nCaps)(resource);
|
|
@@ -3135,23 +3090,6 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3135
3090
|
(0, react.useEffect)(() => {
|
|
3136
3091
|
emittedRef.current = null;
|
|
3137
3092
|
}, [controlledSelection]);
|
|
3138
|
-
const layoutKey = `buro:table-layout:${resource}`;
|
|
3139
|
-
const [columnSizing, setColumnSizing] = usePersistedState(`${layoutKey}:sizing`, {}, 200);
|
|
3140
|
-
const [columnOrder, setColumnOrder] = usePersistedState(`${layoutKey}:order`, []);
|
|
3141
|
-
const DEFAULT_PINNING = {
|
|
3142
|
-
left: [SELECT_COL_ID, "id"],
|
|
3143
|
-
right: [ACTIONS_COL_ID]
|
|
3144
|
-
};
|
|
3145
|
-
const [columnPinning, setColumnPinning] = usePersistedState(`${layoutKey}:pinning`, DEFAULT_PINNING);
|
|
3146
|
-
const resetToken = resetLayout?.token ?? 0;
|
|
3147
|
-
(0, react.useEffect)(() => {
|
|
3148
|
-
if (!resetToken) return;
|
|
3149
|
-
setColumnSizing({});
|
|
3150
|
-
if (resetLayout?.mode === "all") {
|
|
3151
|
-
setColumnOrder([]);
|
|
3152
|
-
setColumnPinning(DEFAULT_PINNING);
|
|
3153
|
-
}
|
|
3154
|
-
}, [resetToken]);
|
|
3155
3093
|
(0, react.useEffect)(() => {
|
|
3156
3094
|
if (controlled) return;
|
|
3157
3095
|
setOwnSelection({});
|
|
@@ -3161,7 +3099,7 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3161
3099
|
const accessPending = listAccess.status === "pending" || pathAccess.pending;
|
|
3162
3100
|
const declaredColumnKeys = (0, react.useMemo)(() => {
|
|
3163
3101
|
if (!def) return [];
|
|
3164
|
-
return [...columnsOverride ?? def.views?.list?.columns ?? Object.keys(def.fields)];
|
|
3102
|
+
return [...columnsOverride ?? def.views?.list?.columns?.map(_burojs_core.columnName) ?? Object.keys(def.fields)];
|
|
3165
3103
|
}, [def, columnsOverride]);
|
|
3166
3104
|
const visibleColumnKeys = (0, react.useMemo)(() => accessPending ? [] : declaredColumnKeys.filter((col) => listAccess.columnVisible(col) && (columnTarget(app.registry, resource, col) === void 0 || listAccess.columnVisible(col.split(".")[0]) && pathAccess.visible(col))), [
|
|
3167
3105
|
accessPending,
|
|
@@ -3211,10 +3149,11 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3211
3149
|
const resourceLabel = (0, _burojs_core.resolveResourceLabel)(i18nCaps, resource, "plural", def);
|
|
3212
3150
|
const recordSingular = (0, _burojs_core.resolveResourceLabel)(i18nCaps, resource, "single", def);
|
|
3213
3151
|
const ariaLabel = resourceLabel;
|
|
3214
|
-
const actionsHeader =
|
|
3152
|
+
const actionsHeader = chromeT("actions.column", { defaultValue: "Actions" });
|
|
3215
3153
|
const viewRow = (0, _burojs_react.useViewRow)(resource);
|
|
3216
3154
|
const volatileRef = (0, react.useRef)({
|
|
3217
3155
|
onSort,
|
|
3156
|
+
sortable,
|
|
3218
3157
|
onHideColumn,
|
|
3219
3158
|
requiredColumns,
|
|
3220
3159
|
renderCell,
|
|
@@ -3226,6 +3165,7 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3226
3165
|
});
|
|
3227
3166
|
volatileRef.current = {
|
|
3228
3167
|
onSort,
|
|
3168
|
+
sortable,
|
|
3229
3169
|
onHideColumn,
|
|
3230
3170
|
requiredColumns,
|
|
3231
3171
|
renderCell,
|
|
@@ -3249,6 +3189,45 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3249
3189
|
}, [rowLinkKey]);
|
|
3250
3190
|
const stableRowClassName = (0, react.useCallback)((row) => volatileRef.current.rowHref?.(volatileRef.current.viewRow(row.original)) || (volatileRef.current.rowQuick?.(row.original) ?? null) !== null ? "cursor-pointer" : void 0, [rowLinkKey]);
|
|
3251
3191
|
const [listRoot, narrow] = useContainerNarrow();
|
|
3192
|
+
const columnUiOf = (0, react.useMemo)(() => {
|
|
3193
|
+
const entries = new Map();
|
|
3194
|
+
for (const entry of [...def?.views?.list?.columns ?? [], ...def?.views?.list?.optionalColumns ?? []]) {
|
|
3195
|
+
const name = (0, _burojs_core.columnName)(entry);
|
|
3196
|
+
if (!entries.has(name)) entries.set(name, entry);
|
|
3197
|
+
}
|
|
3198
|
+
return (col) => columnUi?.[col] ?? (def === void 0 ? STANDALONE_COLUMN_UI : (0, _burojs_core.resolveColumnUi)(def, entries.get(col) ?? col, app.registry, _burojs_react.columnTypeWidth));
|
|
3199
|
+
}, [
|
|
3200
|
+
app,
|
|
3201
|
+
def,
|
|
3202
|
+
columnUi
|
|
3203
|
+
]);
|
|
3204
|
+
const { columnSizing, setColumnSizing, columnOrder, setColumnOrder, columnPinning, setColumnPinning } = useTableLayout({
|
|
3205
|
+
resource,
|
|
3206
|
+
layoutId,
|
|
3207
|
+
rule: (0, react.useMemo)(() => {
|
|
3208
|
+
const known = new Set([
|
|
3209
|
+
...declaredColumnKeys,
|
|
3210
|
+
...(def?.views?.list?.columns ?? []).map(_burojs_core.columnName),
|
|
3211
|
+
...(def?.views?.list?.optionalColumns ?? []).map(_burojs_core.columnName),
|
|
3212
|
+
...Object.keys(def?.fields ?? {})
|
|
3213
|
+
]);
|
|
3214
|
+
return (col) => {
|
|
3215
|
+
if (!known.has(col)) return void 0;
|
|
3216
|
+
const ui = columnUiOf(col);
|
|
3217
|
+
return {
|
|
3218
|
+
min: ui.min,
|
|
3219
|
+
max: ui.max,
|
|
3220
|
+
resize: ui.resize
|
|
3221
|
+
};
|
|
3222
|
+
};
|
|
3223
|
+
}, [
|
|
3224
|
+
declaredColumnKeys,
|
|
3225
|
+
def,
|
|
3226
|
+
columnUiOf
|
|
3227
|
+
]),
|
|
3228
|
+
defaultPinning: DEFAULT_PINNING,
|
|
3229
|
+
resetLayout
|
|
3230
|
+
});
|
|
3252
3231
|
const tableColumns = (0, react.useMemo)(() => {
|
|
3253
3232
|
const cols = [];
|
|
3254
3233
|
if (selectable) cols.push({
|
|
@@ -3271,19 +3250,36 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3271
3250
|
});
|
|
3272
3251
|
for (const col of visibleColumnKeys) {
|
|
3273
3252
|
const target = columnTarget(app.registry, resource, col);
|
|
3274
|
-
const
|
|
3253
|
+
const objectPath = (0, _burojs_react.isObjectColumn)(app.registry, resource, col);
|
|
3254
|
+
const field = target !== void 0 ? target.field : objectPath ? (0, _burojs_react.resolveObjectColumn)(app.registry, resource, col)?.field : def === void 0 ? void 0 : (0, _burojs_core.declaredField)(def, col);
|
|
3275
3255
|
const declaredLabel = (0, _burojs_core.declaredText)("field", field, "label");
|
|
3276
3256
|
const headerLabel = target === void 0 ? (0, _burojs_core.resolveFieldLabel)(volatileRef.current.i18nCaps, col, declaredLabel) : (0, _burojs_core.resolveFieldLabel)(capsOf(volatileRef.current.i18nCaps, target.resource), target.name, declaredLabel);
|
|
3277
|
-
const
|
|
3278
|
-
const
|
|
3279
|
-
|
|
3257
|
+
const ui = columnUiOf(col);
|
|
3258
|
+
const frameField = {
|
|
3259
|
+
...field ?? { type: "unknown" },
|
|
3260
|
+
name: target === void 0 ? col : target.name
|
|
3261
|
+
};
|
|
3262
|
+
const cellEntry = { display: {
|
|
3263
|
+
...ui.display,
|
|
3264
|
+
...ui.display.dateDisplay
|
|
3265
|
+
} };
|
|
3266
|
+
const wraps = ui.display.overflow === "wrap";
|
|
3267
|
+
const columnSortable = volatileRef.current.sortable?.(col) ?? (def !== void 0 && (0, _burojs_core.isColumnSortable)(def, col, app, app.registry));
|
|
3280
3268
|
cols.push({
|
|
3281
3269
|
id: col,
|
|
3282
|
-
...columnAccessor(col),
|
|
3283
|
-
|
|
3284
|
-
|
|
3270
|
+
...columnAccessor(col, objectPath),
|
|
3271
|
+
size: ui.default,
|
|
3272
|
+
minSize: ui.min,
|
|
3273
|
+
maxSize: ui.max ?? Number.MAX_SAFE_INTEGER,
|
|
3274
|
+
enableResizing: ui.resize,
|
|
3275
|
+
enableSorting: columnSortable && Boolean(volatileRef.current.onSort),
|
|
3285
3276
|
enableHiding: true,
|
|
3286
|
-
meta: {
|
|
3277
|
+
meta: {
|
|
3278
|
+
testid: col,
|
|
3279
|
+
className: ALIGN_CLASS[ui.align],
|
|
3280
|
+
...wraps ? { wrap: true } : {},
|
|
3281
|
+
...ui.fill ? { fill: true } : {}
|
|
3282
|
+
},
|
|
3287
3283
|
header: ({ column, table }) => {
|
|
3288
3284
|
const v = volatileRef.current;
|
|
3289
3285
|
const pinSide = column.getIsPinned();
|
|
@@ -3314,9 +3310,9 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3314
3310
|
};
|
|
3315
3311
|
return (0, react_jsx_runtime.jsx)(ColumnHeaderMenu, {
|
|
3316
3312
|
label: headerLabel,
|
|
3317
|
-
sortable:
|
|
3313
|
+
sortable: columnSortable && Boolean(v.onSort),
|
|
3318
3314
|
sortDirection: v.sort?.[0]?.field === col ? v.sort[0].direction : null,
|
|
3319
|
-
onSort:
|
|
3315
|
+
onSort: columnSortable && v.onSort ? (dir) => v.onSort?.(col, dir) : void 0,
|
|
3320
3316
|
pinned: column.getIsPinned(),
|
|
3321
3317
|
onPin: (side) => column.pin(side),
|
|
3322
3318
|
canHide: Boolean(v.onHideColumn) && !v.requiredColumns?.includes(col),
|
|
@@ -3330,40 +3326,49 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3330
3326
|
cell: ({ row }) => {
|
|
3331
3327
|
const raw = row.original;
|
|
3332
3328
|
const record = volatileRef.current.viewRow(raw);
|
|
3333
|
-
const value = record
|
|
3329
|
+
const value = (0, _burojs_react.readColumnValue)(record, col, objectPath);
|
|
3334
3330
|
const customCell = volatileRef.current.renderCell?.(col, value, record);
|
|
3335
|
-
const cellInner = customCell !== void 0 ? customCell : (0, react_jsx_runtime.jsx)(ResolvedFieldDisplay, {
|
|
3331
|
+
const cellInner = customCell !== void 0 ? customCell : (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldDisplay, {
|
|
3336
3332
|
resource: target === void 0 ? resourceRef : target.ref,
|
|
3337
3333
|
name: target === void 0 ? col : target.name,
|
|
3338
3334
|
field: field ?? { type: "unknown" },
|
|
3339
3335
|
value,
|
|
3340
3336
|
record,
|
|
3337
|
+
uiSurface: "column",
|
|
3338
|
+
columnEntry: cellEntry,
|
|
3341
3339
|
fallback: (0, react_jsx_runtime.jsx)("span", { children: String(value ?? "") })
|
|
3342
3340
|
});
|
|
3341
|
+
const framed = (node) => customCell !== void 0 ? node : (0, react_jsx_runtime.jsx)(FieldValueFrame, {
|
|
3342
|
+
field: frameField,
|
|
3343
|
+
value,
|
|
3344
|
+
surface: "column",
|
|
3345
|
+
entry: cellEntry,
|
|
3346
|
+
children: node
|
|
3347
|
+
});
|
|
3343
3348
|
const href = volatileRef.current.rowHref?.(record);
|
|
3344
3349
|
const isFirstContentCell = visibleColumnKeys.indexOf(col) === 0;
|
|
3345
3350
|
const quick = isFirstContentCell ? volatileRef.current.rowQuick?.(raw) ?? null : null;
|
|
3346
|
-
if (quick !== null) return href ? (0, react_jsx_runtime.jsx)(
|
|
3351
|
+
if (quick !== null) return framed(href ? (0, react_jsx_runtime.jsx)(require_relation_create.ClaimedQuickLink, {
|
|
3347
3352
|
href,
|
|
3348
|
-
className:
|
|
3353
|
+
className: require_relation_create.relationLinkClassName,
|
|
3349
3354
|
onOpen: quick,
|
|
3350
3355
|
children: cellInner
|
|
3351
3356
|
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
3352
3357
|
type: "button",
|
|
3353
3358
|
[_burojs_react.QUICK_ANCHOR_ATTRIBUTE]: "",
|
|
3354
|
-
className: `${
|
|
3359
|
+
className: `${require_relation_create.relationLinkClassName} text-left`,
|
|
3355
3360
|
onClick: (e) => {
|
|
3356
3361
|
e.stopPropagation();
|
|
3357
3362
|
quick();
|
|
3358
3363
|
},
|
|
3359
3364
|
children: cellInner
|
|
3360
|
-
});
|
|
3361
|
-
return isFirstContentCell && href ? (0, react_jsx_runtime.jsx)(RouterLink, {
|
|
3365
|
+
}));
|
|
3366
|
+
return framed(isFirstContentCell && href ? (0, react_jsx_runtime.jsx)(RouterLink, {
|
|
3362
3367
|
href,
|
|
3363
|
-
className:
|
|
3368
|
+
className: require_relation_create.relationLinkClassName,
|
|
3364
3369
|
onClick: (e) => e.stopPropagation(),
|
|
3365
3370
|
children: cellInner
|
|
3366
|
-
}) : cellInner;
|
|
3371
|
+
}) : cellInner);
|
|
3367
3372
|
}
|
|
3368
3373
|
});
|
|
3369
3374
|
}
|
|
@@ -3372,7 +3377,7 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3372
3377
|
id: ACTIONS_COL_ID,
|
|
3373
3378
|
enableSorting: false,
|
|
3374
3379
|
enableResizing: false,
|
|
3375
|
-
size: narrow ? 44 : actionsColumnSize(def?.actions?.item),
|
|
3380
|
+
size: narrow || typeof rowActions === "function" ? 44 : actionsColumnSize(def?.actions?.item),
|
|
3376
3381
|
enableHiding: false,
|
|
3377
3382
|
header: () => (0, react_jsx_runtime.jsx)("span", {
|
|
3378
3383
|
className: "sr-only",
|
|
@@ -3383,7 +3388,7 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3383
3388
|
noRowNav: true,
|
|
3384
3389
|
noClip: true
|
|
3385
3390
|
},
|
|
3386
|
-
cell: ({ row }) => (0, react_jsx_runtime.jsx)(ActionOverflow, {
|
|
3391
|
+
cell: ({ row }) => typeof rowActions === "function" ? rowActions(row.original) : (0, react_jsx_runtime.jsx)(ActionOverflow, {
|
|
3387
3392
|
resource,
|
|
3388
3393
|
record: row.original,
|
|
3389
3394
|
surface: "row"
|
|
@@ -3403,7 +3408,8 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3403
3408
|
actionsHeader,
|
|
3404
3409
|
i18nCaps,
|
|
3405
3410
|
rowLinkKey,
|
|
3406
|
-
narrow
|
|
3411
|
+
narrow,
|
|
3412
|
+
columnUiOf
|
|
3407
3413
|
]);
|
|
3408
3414
|
const handleSelectionChange = (updater) => {
|
|
3409
3415
|
if (controlled) {
|
|
@@ -3506,8 +3512,23 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3506
3512
|
const isWrongPage = page > 1;
|
|
3507
3513
|
const EmptyIcon = isFiltered ? _tabler_icons_react.IconFilterX : _tabler_icons_react.IconInbox;
|
|
3508
3514
|
const items = resourceLabel.toLowerCase();
|
|
3509
|
-
const heading = isWrongPage ? t("pagination.emptyPage") : isFiltered ? t("list.emptyFilteredTitle", {
|
|
3510
|
-
|
|
3515
|
+
const heading = isWrongPage ? t("pagination.emptyPage") : isFiltered ? t("list.emptyFilteredTitle", {
|
|
3516
|
+
resource,
|
|
3517
|
+
params: { items }
|
|
3518
|
+
}) : t("list.emptyTitle", {
|
|
3519
|
+
resource,
|
|
3520
|
+
params: { items }
|
|
3521
|
+
});
|
|
3522
|
+
const body = isWrongPage ? null : isFiltered ? t("list.emptyFilteredBody", {
|
|
3523
|
+
resource,
|
|
3524
|
+
params: { items }
|
|
3525
|
+
}) : createHref ? t("list.emptyBody", {
|
|
3526
|
+
resource,
|
|
3527
|
+
params: { item: recordSingular.toLowerCase() }
|
|
3528
|
+
}) : t("list.emptyBodyReadOnly", {
|
|
3529
|
+
resource,
|
|
3530
|
+
params: { items }
|
|
3531
|
+
});
|
|
3511
3532
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
3512
3533
|
className: require_use_theme.cn("flex flex-col items-center justify-center gap-3 px-6 py-16 rounded-lg border border-dashed text-center", className),
|
|
3513
3534
|
"data-testid": tid.listEmpty(resource),
|
|
@@ -3532,7 +3553,7 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3532
3553
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
3533
3554
|
className: "flex justify-center gap-2 pt-2",
|
|
3534
3555
|
children: [
|
|
3535
|
-
|
|
3556
|
+
onClearFilter && (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
3536
3557
|
type: "button",
|
|
3537
3558
|
variant: "outline",
|
|
3538
3559
|
size: "sm",
|
|
@@ -3720,43 +3741,46 @@ function ResourceList({ resource, data, total, page = 1, pageSize = 10, onPageSi
|
|
|
3720
3741
|
})
|
|
3721
3742
|
});
|
|
3722
3743
|
}
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3744
|
+
//#endregion
|
|
3745
|
+
//#region src/blocks/related-list-unbound.tsx
|
|
3746
|
+
function UnboundRelatedList(props) {
|
|
3747
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
3748
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
3749
|
+
className: "flex flex-col gap-2",
|
|
3750
|
+
"data-testid": `list-unbound:${props.resource}`,
|
|
3751
|
+
children: [props.title === void 0 ? null : (0, react_jsx_runtime.jsx)("h3", {
|
|
3752
|
+
className: "text-sm font-semibold",
|
|
3753
|
+
children: props.title
|
|
3754
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
3755
|
+
className: "text-sm text-muted-foreground",
|
|
3756
|
+
children: props.empty ?? t("table.empty", { defaultValue: "No records" })
|
|
3757
|
+
})]
|
|
3732
3758
|
});
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
};
|
|
3759
|
-
return [state, set];
|
|
3759
|
+
}
|
|
3760
|
+
function placementScope(scope, owner) {
|
|
3761
|
+
return scope ?? (owner === void 0 ? "session" : "none");
|
|
3762
|
+
}
|
|
3763
|
+
//#endregion
|
|
3764
|
+
//#region src/list-kit/pieces/bulk-reach.tsx
|
|
3765
|
+
function useBulkFlowReachable(resource) {
|
|
3766
|
+
const app = (0, _burojs_react.useApp)();
|
|
3767
|
+
const control = (0, _burojs_react.useFlowRowResolver)(resource);
|
|
3768
|
+
return (app.registry.get(resource)?.actions.bulk ?? []).some((action) => (0, _burojs_core_internal.isFlowAction)(action) && control(action.name, void 0).state !== "absent");
|
|
3769
|
+
}
|
|
3770
|
+
function ExportReach(props) {
|
|
3771
|
+
const { available } = (0, _burojs_react.useResourceExport)(props.resource);
|
|
3772
|
+
const capability = (0, _burojs_react.useCapability)("run", {
|
|
3773
|
+
resource: props.resource,
|
|
3774
|
+
target: {
|
|
3775
|
+
kind: "action",
|
|
3776
|
+
name: "export"
|
|
3777
|
+
},
|
|
3778
|
+
mode: "list"
|
|
3779
|
+
});
|
|
3780
|
+
return props.children(available && capability.allowed);
|
|
3781
|
+
}
|
|
3782
|
+
function BulkExportReach(props) {
|
|
3783
|
+
return (0, _burojs_react.useOptionalDataRuntime)() !== null ? (0, react_jsx_runtime.jsx)(ExportReach, { ...props }) : props.children(false);
|
|
3760
3784
|
}
|
|
3761
3785
|
//#endregion
|
|
3762
3786
|
//#region src/list-kit/pieces/piece.tsx
|
|
@@ -3824,15 +3848,47 @@ function ForceTableView(props) {
|
|
|
3824
3848
|
}
|
|
3825
3849
|
//#endregion
|
|
3826
3850
|
//#region src/list-kit/pieces/list-body.tsx
|
|
3851
|
+
function LinkDetachRowButton(props) {
|
|
3852
|
+
const { resource, linkEditing } = useListSurface();
|
|
3853
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
3854
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
3855
|
+
const detach = linkEditing?.detach;
|
|
3856
|
+
if (detach === void 0) return null;
|
|
3857
|
+
const label = t("field.link.detach", { defaultValue: "Detach" });
|
|
3858
|
+
return (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
3859
|
+
type: "button",
|
|
3860
|
+
size: "icon",
|
|
3861
|
+
variant: "ghost",
|
|
3862
|
+
className: "size-7",
|
|
3863
|
+
"aria-label": label,
|
|
3864
|
+
title: label,
|
|
3865
|
+
disabled: busy,
|
|
3866
|
+
"data-testid": `list-link-detach:${resource}:${props.row.id}`,
|
|
3867
|
+
onClick: (event) => {
|
|
3868
|
+
event.stopPropagation();
|
|
3869
|
+
setBusy(true);
|
|
3870
|
+
detach.onDetach([props.row]).finally(() => setBusy(false));
|
|
3871
|
+
},
|
|
3872
|
+
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconUnlink, {
|
|
3873
|
+
className: "size-4",
|
|
3874
|
+
"aria-hidden": "true"
|
|
3875
|
+
})
|
|
3876
|
+
});
|
|
3877
|
+
}
|
|
3878
|
+
const linkDetachRow = (row) => (0, react_jsx_runtime.jsx)(LinkDetachRowButton, { row });
|
|
3827
3879
|
function ListBodyView() {
|
|
3828
3880
|
usePieceMount("body");
|
|
3829
3881
|
const list = (0, _burojs_react.useResourceListContext)();
|
|
3830
|
-
const { resource, route, tableView, createAvailable, createPage, rowProps, rowsViewFor, emptyState, renderCell, readOnly } = useListSurface();
|
|
3882
|
+
const { resource, route, tableView, createAvailable, createPage, rowProps, rowsViewFor, emptyState, renderCell, readOnly, linkEditing, layoutId } = useListSurface();
|
|
3883
|
+
const detachable = readOnly && linkEditing?.detach !== void 0;
|
|
3884
|
+
const flowReachable = useBulkFlowReachable(resource);
|
|
3885
|
+
const selectable = (exportReachable) => tableView && (detachable || !readOnly && (flowReachable || exportReachable));
|
|
3831
3886
|
const item = (0, react.useContext)(ListItemContext);
|
|
3832
3887
|
const rowsView = (0, react.useMemo)(() => rowsViewFor?.(item), [rowsViewFor, item]);
|
|
3833
3888
|
const { query, pagination, cursor, count, columns, selection, filters, sorting, routing } = list;
|
|
3834
3889
|
const rows = (0, _burojs_react.policyRowsOf)(list, list.rows);
|
|
3835
|
-
return (0, react_jsx_runtime.jsx)(
|
|
3890
|
+
if (query.unbound) return (0, react_jsx_runtime.jsx)(UnboundRelatedList, { resource });
|
|
3891
|
+
const view = (exportReachable) => (0, react_jsx_runtime.jsx)(ResourceList, {
|
|
3836
3892
|
resource,
|
|
3837
3893
|
data: rows,
|
|
3838
3894
|
total: pagination.total,
|
|
@@ -3849,29 +3905,50 @@ function ListBodyView() {
|
|
|
3849
3905
|
onRequestCount: count.available ? count.request : void 0,
|
|
3850
3906
|
isCountingRows: count.isLoading,
|
|
3851
3907
|
columns: columns.visible,
|
|
3908
|
+
columnUi: columns.ui,
|
|
3852
3909
|
isLoading: query.isLoading,
|
|
3853
3910
|
error: query.error,
|
|
3854
3911
|
onRetry: query.refetch,
|
|
3855
3912
|
createHref: route && createAvailable && createPage ? routing.createHref : void 0,
|
|
3856
3913
|
...rowProps,
|
|
3857
3914
|
...rowsView === void 0 ? {} : { rowsView },
|
|
3858
|
-
selectable:
|
|
3859
|
-
rowActions: !readOnly,
|
|
3915
|
+
selectable: selectable(exportReachable),
|
|
3916
|
+
rowActions: detachable ? linkDetachRow : !readOnly,
|
|
3860
3917
|
selectedIds: selection.ids,
|
|
3861
3918
|
onSelectionChange: selection.set,
|
|
3862
3919
|
isFiltered: filters.isFiltered,
|
|
3863
|
-
onClearFilter: filters.
|
|
3920
|
+
onClearFilter: filters.canReset ? filters.reset : void 0,
|
|
3864
3921
|
emptyState,
|
|
3865
3922
|
sort: sorting.value ?? [],
|
|
3866
3923
|
requiredColumns: columns.required,
|
|
3867
3924
|
resetLayout: columns.resetLayout,
|
|
3925
|
+
layoutId,
|
|
3868
3926
|
onHideColumn: columns.hide,
|
|
3869
3927
|
onSort: sorting.toggle,
|
|
3928
|
+
sortable: sorting.sortable,
|
|
3870
3929
|
renderCell
|
|
3871
3930
|
});
|
|
3931
|
+
return (0, react_jsx_runtime.jsx)(BulkExportReach, {
|
|
3932
|
+
resource,
|
|
3933
|
+
children: view
|
|
3934
|
+
});
|
|
3872
3935
|
}
|
|
3873
3936
|
const ListBody = listPiece("ListBody", ListBodyView);
|
|
3874
3937
|
//#endregion
|
|
3938
|
+
//#region src/resource/form-context.tsx
|
|
3939
|
+
const FormControlContext = (0, react.createContext)(null);
|
|
3940
|
+
const FormControlProvider = FormControlContext.Provider;
|
|
3941
|
+
function useFormControlOf(controller) {
|
|
3942
|
+
const latest = (0, react.useRef)(controller);
|
|
3943
|
+
latest.current = controller;
|
|
3944
|
+
return (0, react.useMemo)(() => ({ setValues: (patch) => {
|
|
3945
|
+
for (const [name, value] of Object.entries(patch)) latest.current.setValue(name, value);
|
|
3946
|
+
} }), []);
|
|
3947
|
+
}
|
|
3948
|
+
function useFormControl() {
|
|
3949
|
+
return (0, react.useContext)(FormControlContext);
|
|
3950
|
+
}
|
|
3951
|
+
//#endregion
|
|
3875
3952
|
//#region src/record/route-screen-context.ts
|
|
3876
3953
|
const RouteScreenClaimContext = (0, react.createContext)(false);
|
|
3877
3954
|
const RouteScreenContext = (0, react.createContext)(false);
|
|
@@ -3995,7 +4072,7 @@ function PanelHost({ node, region = "panel-body", renderChildren }) {
|
|
|
3995
4072
|
region,
|
|
3996
4073
|
form,
|
|
3997
4074
|
labelledBy: title === void 0 ? void 0 : titleId,
|
|
3998
|
-
children: renderChildren(node.children)
|
|
4075
|
+
children: renderChildren(node.children, node)
|
|
3999
4076
|
}) : null,
|
|
4000
4077
|
...title === void 0 ? {} : { title },
|
|
4001
4078
|
...description === void 0 ? {} : { description },
|
|
@@ -4030,10 +4107,12 @@ function TabsHost({ node, renderChildren }) {
|
|
|
4030
4107
|
const state = (0, _burojs_react.useScreenState)();
|
|
4031
4108
|
const text = useNodeText();
|
|
4032
4109
|
const panels = node.children.filter((child) => child.state !== "absent");
|
|
4033
|
-
const
|
|
4110
|
+
const declared = compiled.nodes[node.index].options.default;
|
|
4111
|
+
const effectiveDefault = (declared === void 0 ? void 0 : panels.find((child) => child.key === declared)) ?? panels[0];
|
|
4112
|
+
const open = panels.find((child) => child.open === true) ?? effectiveDefault;
|
|
4034
4113
|
const urlSelect = useTabsUrlSelect();
|
|
4035
4114
|
const select = (panel, reveal) => {
|
|
4036
|
-
if (urlSelect !== null && node.key !== void 0 && panel.key !== void 0) urlSelect(node.key, panel.key, panel ===
|
|
4115
|
+
if (urlSelect !== null && node.key !== void 0 && panel.key !== void 0) urlSelect(node.key, panel.key, panel === effectiveDefault, reveal);
|
|
4037
4116
|
else state?.openPanel(node.id, panelValue(panel));
|
|
4038
4117
|
};
|
|
4039
4118
|
const onSelect = (key) => {
|
|
@@ -4045,7 +4124,7 @@ function TabsHost({ node, renderChildren }) {
|
|
|
4045
4124
|
key: panelValue(panel),
|
|
4046
4125
|
title: titleOf(panel),
|
|
4047
4126
|
errorCount: panel.key === void 0 ? 0 : controller.errorsIn(panel.key),
|
|
4048
|
-
panel: panels.length === 1 || panel.open === true ? (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderChildren(panel.children) }) : null
|
|
4127
|
+
panel: panels.length === 1 || panel.open === true ? (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderChildren(panel.children, panel) }) : null
|
|
4049
4128
|
}));
|
|
4050
4129
|
const { view: View, id } = useNodeView(node, "tabs");
|
|
4051
4130
|
const t = (0, _burojs_react.useFrameT)(id);
|
|
@@ -4156,7 +4235,7 @@ function WizardHost({ node, renderChildren }) {
|
|
|
4156
4235
|
region: "step-panel",
|
|
4157
4236
|
form,
|
|
4158
4237
|
labelledBy: titleId,
|
|
4159
|
-
children: renderChildren(panel.children)
|
|
4238
|
+
children: renderChildren(panel.children, panel)
|
|
4160
4239
|
}),
|
|
4161
4240
|
...description === void 0 ? {} : { description },
|
|
4162
4241
|
titleId,
|
|
@@ -4202,18 +4281,23 @@ function WizardHost({ node, renderChildren }) {
|
|
|
4202
4281
|
//#region src/screen/nodes.tsx
|
|
4203
4282
|
function FailedNode({ node }) {
|
|
4204
4283
|
const { controller } = useScreenTree();
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4284
|
+
let error;
|
|
4285
|
+
for (const name of node.failedOn) {
|
|
4286
|
+
const source = controller.sources[name];
|
|
4287
|
+
if (source?.status === "failed") {
|
|
4288
|
+
error = source.error;
|
|
4289
|
+
break;
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4292
|
+
return (0, react_jsx_runtime.jsx)(require_relation_create.LoadError, {
|
|
4293
|
+
surface: "tab",
|
|
4294
|
+
error,
|
|
4295
|
+
retry: () => controller.retry(node.failedOn),
|
|
4296
|
+
fallback: {
|
|
4297
|
+
key: "screen.failed",
|
|
4298
|
+
default: "This section could not be loaded."
|
|
4299
|
+
},
|
|
4300
|
+
attributes: nodeAttributes(node)
|
|
4217
4301
|
});
|
|
4218
4302
|
}
|
|
4219
4303
|
function failedOnlyOnMeta(node) {
|
|
@@ -4226,8 +4310,17 @@ function drawn(node, hiddenFields) {
|
|
|
4226
4310
|
if (node.state === "absent") return false;
|
|
4227
4311
|
return !(node.kind === "field" && node.field !== void 0 && hiddenFields?.has(node.field));
|
|
4228
4312
|
}
|
|
4229
|
-
function SectionChildren({ nodes }) {
|
|
4230
|
-
const { hiddenFields } = useScreenTree();
|
|
4313
|
+
function SectionChildren({ nodes, owner }) {
|
|
4314
|
+
const { compiled, hiddenFields } = useScreenTree();
|
|
4315
|
+
const text = useNodeText();
|
|
4316
|
+
if (owner !== void 0 && !nodes.some((node) => drawn(node, hiddenFields))) {
|
|
4317
|
+
const empty = text(compiled.nodes[owner.index]?.options.empty);
|
|
4318
|
+
return empty === void 0 || empty === "" ? null : (0, react_jsx_runtime.jsx)("p", {
|
|
4319
|
+
"data-buro-region": "empty",
|
|
4320
|
+
className: "text-sm text-muted-foreground",
|
|
4321
|
+
children: empty
|
|
4322
|
+
});
|
|
4323
|
+
}
|
|
4231
4324
|
const out = [];
|
|
4232
4325
|
let run = [];
|
|
4233
4326
|
const flush = () => {
|
|
@@ -4249,8 +4342,11 @@ function SectionChildren({ nodes }) {
|
|
|
4249
4342
|
flush();
|
|
4250
4343
|
return out;
|
|
4251
4344
|
}
|
|
4252
|
-
function renderSection(nodes) {
|
|
4253
|
-
return (0, react_jsx_runtime.jsx)(SectionChildren, {
|
|
4345
|
+
function renderSection(nodes, owner) {
|
|
4346
|
+
return (0, react_jsx_runtime.jsx)(SectionChildren, {
|
|
4347
|
+
nodes,
|
|
4348
|
+
owner
|
|
4349
|
+
});
|
|
4254
4350
|
}
|
|
4255
4351
|
function Layout({ node }) {
|
|
4256
4352
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -4372,17 +4468,14 @@ function pageHost(page) {
|
|
|
4372
4468
|
}
|
|
4373
4469
|
//#endregion
|
|
4374
4470
|
//#region src/forms/declarative-form.tsx
|
|
4375
|
-
function
|
|
4376
|
-
const translated = t(key);
|
|
4377
|
-
return translated === key ? fallback : translated;
|
|
4378
|
-
}
|
|
4379
|
-
function issueText(issue, t, i18nPrefix) {
|
|
4471
|
+
function issueText(issue, caps, i18nPrefix) {
|
|
4380
4472
|
return (0, _burojs_react.resolveValidationMessage)({
|
|
4381
4473
|
code: issue.code ?? "",
|
|
4382
4474
|
message: issue.message,
|
|
4383
|
-
...issue.
|
|
4475
|
+
...issue.check === void 0 ? {} : { check: issue.check }
|
|
4384
4476
|
}, {
|
|
4385
|
-
|
|
4477
|
+
has: caps.has,
|
|
4478
|
+
t: caps.t,
|
|
4386
4479
|
...issue.field === "_form" ? {} : { fieldKey: `resources.${i18nPrefix}.fields.${issue.field}` }
|
|
4387
4480
|
});
|
|
4388
4481
|
}
|
|
@@ -4449,7 +4542,9 @@ function DeclarativeFormBody(props) {
|
|
|
4449
4542
|
...props.surface === void 0 ? {} : { surface: props.surface },
|
|
4450
4543
|
...props.onSubmit === void 0 ? {} : { onSubmit: props.onSubmit }
|
|
4451
4544
|
});
|
|
4452
|
-
const
|
|
4545
|
+
const formControl = useFormControlOf(form);
|
|
4546
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
4547
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
4453
4548
|
const disabled = props.disabled === true;
|
|
4454
4549
|
const uid = (0, react.useId)();
|
|
4455
4550
|
const leafIds = (0, react.useMemo)(() => ({
|
|
@@ -4459,8 +4554,8 @@ function DeclarativeFormBody(props) {
|
|
|
4459
4554
|
const formErrors = form.errors.filter((issue) => issue.field === "_form");
|
|
4460
4555
|
const retryableChecks = [];
|
|
4461
4556
|
for (const issue of form.checkOutcome?.blockers ?? []) {
|
|
4462
|
-
const checkId = issue.
|
|
4463
|
-
if (issue.
|
|
4557
|
+
const checkId = issue.check?.id;
|
|
4558
|
+
if (issue.check?.cause === void 0 || typeof checkId !== "string") continue;
|
|
4464
4559
|
if (!retryableChecks.includes(checkId)) retryableChecks.push(checkId);
|
|
4465
4560
|
}
|
|
4466
4561
|
const formWarnings = form.warnings.filter((issue) => issue.field === "_form");
|
|
@@ -4473,7 +4568,7 @@ function DeclarativeFormBody(props) {
|
|
|
4473
4568
|
formErrors.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
4474
4569
|
role: "alert",
|
|
4475
4570
|
className: "mb-4 flex flex-col gap-1 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
4476
|
-
children: formErrors.map((issue, index) => (0, react_jsx_runtime.jsx)("p", { children: issueText(issue,
|
|
4571
|
+
children: formErrors.map((issue, index) => (0, react_jsx_runtime.jsx)("p", { children: issueText(issue, caps, prefix) }, index))
|
|
4477
4572
|
}),
|
|
4478
4573
|
retryableChecks.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
4479
4574
|
className: "mb-4 flex flex-wrap gap-2",
|
|
@@ -4483,25 +4578,28 @@ function DeclarativeFormBody(props) {
|
|
|
4483
4578
|
size: "sm",
|
|
4484
4579
|
"data-testid": `form-check-retry:${checkId}`,
|
|
4485
4580
|
onClick: () => void form.revalidate(),
|
|
4486
|
-
children:
|
|
4581
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
4487
4582
|
}, checkId))
|
|
4488
4583
|
}),
|
|
4489
4584
|
formWarnings.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
4490
4585
|
role: "status",
|
|
4491
4586
|
"aria-live": "polite",
|
|
4492
4587
|
className: "mb-4 flex flex-col gap-1 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm text-warning-emphasis",
|
|
4493
|
-
children: formWarnings.map((issue, index) => (0, react_jsx_runtime.jsx)("p", { children: issueText(issue,
|
|
4588
|
+
children: formWarnings.map((issue, index) => (0, react_jsx_runtime.jsx)("p", { children: issueText(issue, caps, prefix) }, index))
|
|
4494
4589
|
}),
|
|
4495
|
-
(0, react_jsx_runtime.jsx)(
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4590
|
+
(0, react_jsx_runtime.jsx)(FormControlProvider, {
|
|
4591
|
+
value: formControl,
|
|
4592
|
+
children: (0, react_jsx_runtime.jsx)(ScreenTree, {
|
|
4593
|
+
region: "form-body",
|
|
4594
|
+
resource: prefix,
|
|
4595
|
+
mode: "create",
|
|
4596
|
+
compiled: form.screen,
|
|
4597
|
+
controller: form,
|
|
4598
|
+
leafIds,
|
|
4599
|
+
...props.renderField === void 0 ? {} : { renderField: props.renderField },
|
|
4600
|
+
disabled,
|
|
4601
|
+
...props.bodyClassName === void 0 ? {} : { className: props.bodyClassName }
|
|
4602
|
+
})
|
|
4505
4603
|
}),
|
|
4506
4604
|
props.slots?.footer === void 0 ? (0, react_jsx_runtime.jsx)("div", {
|
|
4507
4605
|
className: "mt-4 flex justify-end",
|
|
@@ -4509,7 +4607,7 @@ function DeclarativeFormBody(props) {
|
|
|
4509
4607
|
type: "submit",
|
|
4510
4608
|
disabled: !form.canSubmit || disabled,
|
|
4511
4609
|
onMouseDown: (event) => event.preventDefault(),
|
|
4512
|
-
children: props.submitLabel ??
|
|
4610
|
+
children: props.submitLabel ?? chromeT("actions.save", { defaultValue: "Save" })
|
|
4513
4611
|
})
|
|
4514
4612
|
}) : typeof props.slots.footer === "function" ? props.slots.footer({ canSubmit: form.canSubmit && !disabled }) : props.slots.footer
|
|
4515
4613
|
]
|
|
@@ -4594,7 +4692,8 @@ function ExportOptionsDirty({ dirty }) {
|
|
|
4594
4692
|
return null;
|
|
4595
4693
|
}
|
|
4596
4694
|
function getNoRunState() {}
|
|
4597
|
-
function ExportDialog({ open, onOpenChange, resource, target, visibleColumns, estimatedCount, scope }) {
|
|
4695
|
+
function ExportDialog({ open, onOpenChange, resource: resourceInput, target, visibleColumns, estimatedCount, scope }) {
|
|
4696
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
4598
4697
|
const t = (0, _burojs_react.useOptionalT)();
|
|
4599
4698
|
const dialogTestId = (0, _burojs_react.useTestIds)().exportDialog(resource);
|
|
4600
4699
|
const { formats, start, exporter, available, error, loading } = (0, _burojs_react.useResourceExport)(resource, {
|
|
@@ -4716,14 +4815,15 @@ function ExportDialog({ open, onOpenChange, resource, target, visibleColumns, es
|
|
|
4716
4815
|
})] }), (0, react_jsx_runtime.jsx)(ExportProgressView, {
|
|
4717
4816
|
state: runState,
|
|
4718
4817
|
dialogTestId,
|
|
4719
|
-
t
|
|
4818
|
+
t,
|
|
4819
|
+
caps
|
|
4720
4820
|
})] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)(require_dialog.DialogHeader, { children: [(0, react_jsx_runtime.jsx)(require_dialog.DialogTitle, { children: titleText }), (0, react_jsx_runtime.jsx)(require_dialog.DialogDescription, {
|
|
4721
4821
|
className: "sr-only",
|
|
4722
4822
|
children: titleText
|
|
4723
4823
|
})] }), !available ? (0, react_jsx_runtime.jsx)("p", {
|
|
4724
4824
|
role: "alert",
|
|
4725
4825
|
"data-testid": `${dialogTestId}:unavailable`,
|
|
4726
|
-
children: error
|
|
4826
|
+
children: error === void 0 || error === null ? t("export.dialog.unavailable") : (0, _burojs_react.resolveErrorText)(error, caps)
|
|
4727
4827
|
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4728
4828
|
loading ? (0, react_jsx_runtime.jsx)("p", {
|
|
4729
4829
|
role: "status",
|
|
@@ -4802,7 +4902,7 @@ function ExportDialog({ open, onOpenChange, resource, target, visibleColumns, es
|
|
|
4802
4902
|
})
|
|
4803
4903
|
});
|
|
4804
4904
|
}
|
|
4805
|
-
function ExportProgressView({ state, dialogTestId, t }) {
|
|
4905
|
+
function ExportProgressView({ state, dialogTestId, t, caps }) {
|
|
4806
4906
|
if (state === void 0) return null;
|
|
4807
4907
|
if (state.status === "running") {
|
|
4808
4908
|
const total = state.progress?.total;
|
|
@@ -4823,7 +4923,7 @@ function ExportProgressView({ state, dialogTestId, t }) {
|
|
|
4823
4923
|
if (state.status === "failed") return (0, react_jsx_runtime.jsx)("p", {
|
|
4824
4924
|
role: "alert",
|
|
4825
4925
|
"data-testid": `${dialogTestId}:error`,
|
|
4826
|
-
children: `${t("export.dialog.failed")}: ${state.error
|
|
4926
|
+
children: `${t("export.dialog.failed")}: ${(0, _burojs_react.resolveErrorText)(state.error, caps)}`
|
|
4827
4927
|
});
|
|
4828
4928
|
if (state.status === "canceled") return (0, react_jsx_runtime.jsx)("p", {
|
|
4829
4929
|
"data-testid": `${dialogTestId}:canceled`,
|
|
@@ -4836,6 +4936,7 @@ function ExportProgressView({ state, dialogTestId, t }) {
|
|
|
4836
4936
|
function BulkSummary(props) {
|
|
4837
4937
|
const loaded = require_check_confirm_dialog.useLoaded(require_check_confirm_dialog.loadBulkSummary);
|
|
4838
4938
|
const t = (0, _burojs_react.useOptionalT)();
|
|
4939
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
4839
4940
|
const failed = (retry) => (0, react_jsx_runtime.jsxs)("div", {
|
|
4840
4941
|
role: "alert",
|
|
4841
4942
|
className: "flex items-center gap-2 text-sm",
|
|
@@ -4844,7 +4945,7 @@ function BulkSummary(props) {
|
|
|
4844
4945
|
size: "sm",
|
|
4845
4946
|
variant: "outline",
|
|
4846
4947
|
onClick: retry,
|
|
4847
|
-
children:
|
|
4948
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
4848
4949
|
})]
|
|
4849
4950
|
});
|
|
4850
4951
|
if (loaded.error !== void 0) return failed(loaded.retry);
|
|
@@ -4862,21 +4963,26 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
|
|
|
4862
4963
|
const control = (0, _burojs_react.useFlowRowResolver)(resource)(actionName, void 0);
|
|
4863
4964
|
const chrome = require_check_confirm_dialog.useFlowChrome(resource, actionName);
|
|
4864
4965
|
const def = app.registry.get(resource);
|
|
4865
|
-
const
|
|
4966
|
+
const compiled = (0, react.useMemo)(() => {
|
|
4866
4967
|
try {
|
|
4867
|
-
return def === void 0 ?
|
|
4968
|
+
return def === void 0 ? void 0 : (0, _burojs_core.compileFlow)(def, actionName);
|
|
4868
4969
|
} catch {
|
|
4869
|
-
return
|
|
4970
|
+
return;
|
|
4870
4971
|
}
|
|
4871
4972
|
}, [def, actionName]);
|
|
4973
|
+
const each = compiled?.each ?? false;
|
|
4872
4974
|
const [running, setRunning] = (0, react.useState)(false);
|
|
4873
4975
|
const [summary, setSummary] = (0, react.useState)(null);
|
|
4976
|
+
const afterSummary = (0, react.useRef)(null);
|
|
4874
4977
|
const testid = tid.bulkAction(resource, actionName);
|
|
4875
4978
|
if (control.state === "absent") return null;
|
|
4876
4979
|
const variant = chrome.destructive ? "destructive" : "outline";
|
|
4877
4980
|
const overLimit = each && ids.length > _burojs_core.BULK_EACH_LIMIT;
|
|
4878
4981
|
if (overLimit || control.state === "disabled") return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DisabledAction, {
|
|
4879
|
-
reason: overLimit ?
|
|
4982
|
+
reason: overLimit ? t("flow.bulkLimit", {
|
|
4983
|
+
defaultValue: `Select at most ${_burojs_core.BULK_EACH_LIMIT}.`,
|
|
4984
|
+
count: _burojs_core.BULK_EACH_LIMIT
|
|
4985
|
+
}) : control.reason,
|
|
4880
4986
|
label: chrome.label,
|
|
4881
4987
|
icon: chrome.icon,
|
|
4882
4988
|
testid,
|
|
@@ -4890,11 +4996,20 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
|
|
|
4890
4996
|
const finish = (result, progress) => {
|
|
4891
4997
|
setRunning(false);
|
|
4892
4998
|
if (progress === void 0) return;
|
|
4893
|
-
|
|
4999
|
+
const summarize = result.outcome !== "success" || progress.rereadSkipped.some((entry) => entry.policy === "warn");
|
|
5000
|
+
if (summarize) setSummary({
|
|
4894
5001
|
progress,
|
|
4895
5002
|
total: ids.length
|
|
4896
5003
|
});
|
|
4897
|
-
|
|
5004
|
+
const remaining = ids.filter((id) => !progress.success.includes(id));
|
|
5005
|
+
if (summarize && remaining.length === 0) afterSummary.current = () => onSelectionChange?.([]);
|
|
5006
|
+
else onSelectionChange?.(remaining);
|
|
5007
|
+
};
|
|
5008
|
+
const closeSummary = () => {
|
|
5009
|
+
setSummary(null);
|
|
5010
|
+
const pending = afterSummary.current;
|
|
5011
|
+
afterSummary.current = null;
|
|
5012
|
+
pending?.();
|
|
4898
5013
|
};
|
|
4899
5014
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4900
5015
|
(0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
@@ -4924,7 +5039,7 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
|
|
|
4924
5039
|
(0, react_jsx_runtime.jsx)(require_dialog.Dialog, {
|
|
4925
5040
|
open: summary !== null,
|
|
4926
5041
|
onOpenChange: (open) => {
|
|
4927
|
-
if (!open)
|
|
5042
|
+
if (!open) closeSummary();
|
|
4928
5043
|
},
|
|
4929
5044
|
children: (0, react_jsx_runtime.jsxs)(require_dialog.DialogContent, {
|
|
4930
5045
|
"data-testid": `${tid.bulkSummary(resource, actionName)}:dialog`,
|
|
@@ -4938,14 +5053,15 @@ function BulkFlowButton({ resource, actionName, ids, onSelectionChange }) {
|
|
|
4938
5053
|
actionName,
|
|
4939
5054
|
label: chrome.labelText,
|
|
4940
5055
|
total: summary.total,
|
|
4941
|
-
progress: summary.progress
|
|
5056
|
+
progress: summary.progress,
|
|
5057
|
+
texts: compiled?.flow.texts
|
|
4942
5058
|
}),
|
|
4943
5059
|
(0, react_jsx_runtime.jsx)(require_dialog.DialogFooter, { children: (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
4944
5060
|
type: "button",
|
|
4945
5061
|
variant: "outline",
|
|
4946
5062
|
"data-testid": `${tid.bulkSummary(resource, actionName)}:close`,
|
|
4947
|
-
onClick:
|
|
4948
|
-
children:
|
|
5063
|
+
onClick: closeSummary,
|
|
5064
|
+
children: t("flow.close", { defaultValue: "Close" })
|
|
4949
5065
|
}) })
|
|
4950
5066
|
]
|
|
4951
5067
|
})
|
|
@@ -4961,10 +5077,12 @@ function orderBulkActions(actions) {
|
|
|
4961
5077
|
seq: index
|
|
4962
5078
|
})).sort((a, b) => a.weight - b.weight || a.seq - b.seq).map(({ action }) => action);
|
|
4963
5079
|
}
|
|
4964
|
-
function BulkActionToolbar({ resource, table, selectedRecords, selectedIds, onClearSelection, onSelectionChange, className, visibleColumns, scope }) {
|
|
5080
|
+
function BulkActionToolbar({ resource: resourceInput, table, selectedRecords, selectedIds, onClearSelection, onSelectionChange, className, visibleColumns, scope, actions }) {
|
|
5081
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
4965
5082
|
const app = (0, _burojs_react.useApp)();
|
|
4966
5083
|
const tid = (0, _burojs_react.useTestIds)();
|
|
4967
5084
|
const t = (0, _burojs_react.useOptionalT)();
|
|
5085
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
4968
5086
|
const def = app.registry.get(resource);
|
|
4969
5087
|
const records = selectedRecords ?? (table ? table.getFilteredSelectedRowModel().rows.map((r) => r.original) : []);
|
|
4970
5088
|
const ids = selectedIds ?? records.map((record) => record.id);
|
|
@@ -4997,7 +5115,8 @@ function BulkActionToolbar({ resource, table, selectedRecords, selectedIds, onCl
|
|
|
4997
5115
|
className: "mx-0.5 h-6 w-px bg-border",
|
|
4998
5116
|
"aria-hidden": "true"
|
|
4999
5117
|
}),
|
|
5000
|
-
|
|
5118
|
+
actions !== void 0 ? actions : null,
|
|
5119
|
+
actions === void 0 && bulkActions.map((action) => (0, react_jsx_runtime.jsx)(BulkFlowButton, {
|
|
5001
5120
|
resource,
|
|
5002
5121
|
actionName: action.name,
|
|
5003
5122
|
ids,
|
|
@@ -5006,7 +5125,7 @@ function BulkActionToolbar({ resource, table, selectedRecords, selectedIds, onCl
|
|
|
5006
5125
|
else if (next.length === 0) handleClear();
|
|
5007
5126
|
}
|
|
5008
5127
|
}, action.name)),
|
|
5009
|
-
(0, react_jsx_runtime.jsx)(BulkExportButton, {
|
|
5128
|
+
actions === void 0 && (0, react_jsx_runtime.jsx)(BulkExportButton, {
|
|
5010
5129
|
resource,
|
|
5011
5130
|
ids,
|
|
5012
5131
|
visibleColumns: visibleColumns ?? [],
|
|
@@ -5023,7 +5142,7 @@ function BulkActionToolbar({ resource, table, selectedRecords, selectedIds, onCl
|
|
|
5023
5142
|
"aria-hidden": "true"
|
|
5024
5143
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
5025
5144
|
className: "hidden sm:inline",
|
|
5026
|
-
children:
|
|
5145
|
+
children: chromeT("actions.clearSelection", { defaultValue: "Clear" })
|
|
5027
5146
|
})]
|
|
5028
5147
|
})
|
|
5029
5148
|
]
|
|
@@ -5083,12 +5202,36 @@ function BulkExportButtonActive({ resource, ids, visibleColumns, scope }) {
|
|
|
5083
5202
|
}
|
|
5084
5203
|
//#endregion
|
|
5085
5204
|
//#region src/list-kit/pieces/list-bulk-bar.tsx
|
|
5205
|
+
function LinkDetachBulkButton(props) {
|
|
5206
|
+
const { selection } = (0, _burojs_react.useResourceListContext)();
|
|
5207
|
+
const { resource } = useListSurface();
|
|
5208
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
5209
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
5210
|
+
return (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
5211
|
+
type: "button",
|
|
5212
|
+
size: "sm",
|
|
5213
|
+
variant: "ghost",
|
|
5214
|
+
className: "h-8 gap-1.5 rounded-full px-2.5 text-destructive",
|
|
5215
|
+
disabled: busy,
|
|
5216
|
+
"data-testid": `list-link-detach-bulk:${resource}`,
|
|
5217
|
+
onClick: () => {
|
|
5218
|
+
setBusy(true);
|
|
5219
|
+
props.onDetach(selection.records).finally(() => setBusy(false));
|
|
5220
|
+
},
|
|
5221
|
+
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconUnlink, {
|
|
5222
|
+
className: "size-4",
|
|
5223
|
+
"aria-hidden": "true"
|
|
5224
|
+
}), t("field.link.detach", { defaultValue: "Detach" })]
|
|
5225
|
+
});
|
|
5226
|
+
}
|
|
5086
5227
|
function ListBulkBarView() {
|
|
5087
5228
|
usePieceMount("bulk-bar");
|
|
5088
5229
|
const { selection, columns, scope } = (0, _burojs_react.useResourceListContext)();
|
|
5089
|
-
const { resource, tableView, readOnly } = useListSurface();
|
|
5090
|
-
|
|
5230
|
+
const { resource, tableView, readOnly, linkEditing } = useListSurface();
|
|
5231
|
+
const detach = readOnly ? linkEditing?.detach : void 0;
|
|
5232
|
+
if (!tableView || readOnly && detach === void 0 || selection.ids.length === 0) return null;
|
|
5091
5233
|
return (0, react_jsx_runtime.jsx)(BulkActionToolbar, {
|
|
5234
|
+
...detach === void 0 ? {} : { actions: (0, react_jsx_runtime.jsx)(LinkDetachBulkButton, { onDetach: detach.onDetach }) },
|
|
5092
5235
|
resource,
|
|
5093
5236
|
selectedRecords: selection.records,
|
|
5094
5237
|
selectedIds: selection.ids,
|
|
@@ -5177,7 +5320,8 @@ function DataTableViewOptions({ table, getColumnLabel, isColumnRequired, getTest
|
|
|
5177
5320
|
}
|
|
5178
5321
|
//#endregion
|
|
5179
5322
|
//#region src/list-kit/columns-toggle.tsx
|
|
5180
|
-
function ColumnsToggle({ resource, def, allAvailable, required, visibleColumns, defaultVisible, onChange, onResetSizes, onRestoreDefaults }) {
|
|
5323
|
+
function ColumnsToggle({ resource: resourceInput, def, allAvailable, required, visibleColumns, defaultVisible, onChange, onResetSizes, onRestoreDefaults }) {
|
|
5324
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
5181
5325
|
const t = (0, _burojs_react.useT)();
|
|
5182
5326
|
const columnsCaps = (0, _burojs_react.useI18nCaps)(resource);
|
|
5183
5327
|
const app = (0, _burojs_react.useApp)();
|
|
@@ -5284,12 +5428,16 @@ function ListColumnsView() {
|
|
|
5284
5428
|
const ListColumns = listPiece("ListColumns", ListColumnsView);
|
|
5285
5429
|
//#endregion
|
|
5286
5430
|
//#region src/resource/create-button.tsx
|
|
5287
|
-
function CreateButton({ resource, href, testid, size = "sm", variant, label, className, onOpen }) {
|
|
5431
|
+
function CreateButton({ resource: resourceInput, href, testid, size = "sm", variant, label, className, onOpen }) {
|
|
5432
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
5288
5433
|
const t = (0, _burojs_react.useOptionalT)();
|
|
5289
5434
|
const Link = require_toaster.useLinkComponent();
|
|
5290
5435
|
const availability = (0, _burojs_react.useAvailability)(resource, "create");
|
|
5291
5436
|
const gate = (0, _burojs_react.useEntryGate)();
|
|
5292
|
-
const text = label ?? t("actions.create", {
|
|
5437
|
+
const text = label ?? t("actions.create", {
|
|
5438
|
+
resource,
|
|
5439
|
+
defaultValue: "Create"
|
|
5440
|
+
});
|
|
5293
5441
|
if (onOpen !== void 0) {
|
|
5294
5442
|
const answer = gate(resource, "create");
|
|
5295
5443
|
if (answer.state === "disabled") return (0, react_jsx_runtime.jsx)(require_check_confirm_dialog.DisabledAction, {
|
|
@@ -5360,7 +5508,8 @@ const ListCreate = listPiece("ListCreate", ListCreateView);
|
|
|
5360
5508
|
//#endregion
|
|
5361
5509
|
//#region src/export/export-button.tsx
|
|
5362
5510
|
const warnedProviderQueryResources = new Set();
|
|
5363
|
-
function ExportButton({ resource, className }) {
|
|
5511
|
+
function ExportButton({ resource: resourceInput, className }) {
|
|
5512
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
5364
5513
|
if (!((0, _burojs_react.useOptionalDataRuntime)() !== null)) return null;
|
|
5365
5514
|
return (0, react_jsx_runtime.jsx)(ExportButtonActive, {
|
|
5366
5515
|
resource,
|
|
@@ -5381,36 +5530,19 @@ function ExportButtonActive({ resource, className }) {
|
|
|
5381
5530
|
const tid = (0, _burojs_react.useTestIds)();
|
|
5382
5531
|
const t = (0, _burojs_react.useOptionalT)();
|
|
5383
5532
|
const [open, setOpen] = react.useState(false);
|
|
5384
|
-
const
|
|
5385
|
-
resource,
|
|
5386
|
-
def: list.def
|
|
5387
|
-
}), [resource, list.def]);
|
|
5533
|
+
const sent = list.query.sent;
|
|
5388
5534
|
const target = react.useMemo(() => {
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
pinned: list.filters.value,
|
|
5392
|
-
group: list.filters.group,
|
|
5393
|
-
search: list.filters.search,
|
|
5394
|
-
searchDecl: list.filters.searchEnabled ? list.filters.searchDecl ?? list.def?.views?.list?.search : void 0,
|
|
5395
|
-
searchContext
|
|
5396
|
-
});
|
|
5397
|
-
const sort = list.sorting.value;
|
|
5535
|
+
if (sent === null) return null;
|
|
5536
|
+
const { filter, sort } = sent;
|
|
5398
5537
|
return {
|
|
5399
5538
|
kind: "filter",
|
|
5400
5539
|
...filter === void 0 ? {} : { filter },
|
|
5401
5540
|
...sort.length > 0 ? { sort } : {}
|
|
5402
5541
|
};
|
|
5403
|
-
}, [
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
list.filters.search,
|
|
5408
|
-
list.filters.searchDecl,
|
|
5409
|
-
list.filters.searchEnabled,
|
|
5410
|
-
list.def,
|
|
5411
|
-
searchContext,
|
|
5412
|
-
list.sorting.value
|
|
5413
|
-
]);
|
|
5542
|
+
}, [sent]);
|
|
5543
|
+
const lastTarget = react.useRef(target);
|
|
5544
|
+
if (target !== null) lastTarget.current = target;
|
|
5545
|
+
const dialogTarget = target ?? lastTarget.current;
|
|
5414
5546
|
react.useEffect(() => {
|
|
5415
5547
|
if (!available || !capability.allowed) return;
|
|
5416
5548
|
if (list.providerQuery.value === void 0) return;
|
|
@@ -5424,7 +5556,9 @@ function ExportButtonActive({ resource, className }) {
|
|
|
5424
5556
|
resource
|
|
5425
5557
|
]);
|
|
5426
5558
|
if (!available || !capability.allowed || list.isForbidden) return null;
|
|
5427
|
-
|
|
5559
|
+
if (target === null && !open) return null;
|
|
5560
|
+
if (dialogTarget === null) return null;
|
|
5561
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [target === null ? null : (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
5428
5562
|
type: "button",
|
|
5429
5563
|
variant: "outline",
|
|
5430
5564
|
size: "icon",
|
|
@@ -5443,7 +5577,7 @@ function ExportButtonActive({ resource, className }) {
|
|
|
5443
5577
|
open,
|
|
5444
5578
|
onOpenChange: setOpen,
|
|
5445
5579
|
resource,
|
|
5446
|
-
target,
|
|
5580
|
+
target: dialogTarget,
|
|
5447
5581
|
visibleColumns: list.columns.visible,
|
|
5448
5582
|
estimatedCount: list.pagination.total,
|
|
5449
5583
|
scope: list.scope
|
|
@@ -5461,8 +5595,9 @@ function ListExportView() {
|
|
|
5461
5595
|
const ListExport = listPiece("ListExport", ListExportView);
|
|
5462
5596
|
//#endregion
|
|
5463
5597
|
//#region src/list-kit/list-search-input.tsx
|
|
5464
|
-
function ListSearchInput({ resource
|
|
5465
|
-
const
|
|
5598
|
+
function ListSearchInput({ resource: resourceInput, value, onCommit, placeholder }) {
|
|
5599
|
+
const resource = (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
5600
|
+
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
5466
5601
|
const [text, setText] = (0, react.useState)(value);
|
|
5467
5602
|
const lastPushedRef = (0, react.useRef)(value);
|
|
5468
5603
|
const timerRef = (0, react.useRef)(null);
|
|
@@ -5477,7 +5612,7 @@ function ListSearchInput({ resource, label, value, onCommit, placeholder }) {
|
|
|
5477
5612
|
}, []);
|
|
5478
5613
|
return (0, react_jsx_runtime.jsx)(require_input.Input, {
|
|
5479
5614
|
type: "search",
|
|
5480
|
-
placeholder: placeholder ??
|
|
5615
|
+
placeholder: placeholder ?? (0, _burojs_core.resolveContentSlot)(caps, ["list.search"]) ?? "Search",
|
|
5481
5616
|
value: text,
|
|
5482
5617
|
"data-testid": `list-search:${resource}`,
|
|
5483
5618
|
className: "h-8 w-full min-[420px]:w-72",
|
|
@@ -5495,24 +5630,18 @@ function ListSearchInput({ resource, label, value, onCommit, placeholder }) {
|
|
|
5495
5630
|
//#endregion
|
|
5496
5631
|
//#region src/list-kit/filter-builder/filter-region.tsx
|
|
5497
5632
|
function FilterRegion({ search } = {}) {
|
|
5498
|
-
const { resource, def, filters, pagination
|
|
5499
|
-
const
|
|
5500
|
-
const listCaps = (0, _burojs_react.useI18nCaps)(resource);
|
|
5633
|
+
const { resource, def, filters, pagination } = (0, _burojs_react.useResourceListContext)();
|
|
5634
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
5501
5635
|
const testIdBase = `list-filter:${resource}`;
|
|
5636
|
+
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
5637
|
+
const placeholder = search === void 0 ? (0, _burojs_core.resolveContentSlot)(caps, ["list.searchPlaceholder", "list.search"]) ?? "Search" : void 0;
|
|
5502
5638
|
const searchDecl = search === void 0 ? def?.views?.list?.search : search ?? void 0;
|
|
5503
|
-
const searchField = searchDecl !== void 0 && typeof searchDecl !== "function" ? (() => {
|
|
5504
|
-
return searchDecl.fields.map((entry) => typeof entry === "string" ? entry : entry.field).find((name) => access.fieldVisible(name));
|
|
5505
|
-
})() : void 0;
|
|
5506
|
-
const searchGenericLabel = (0, _burojs_core.resolveContentSlot)(listCaps, ["list.search"]) ?? "Search";
|
|
5507
|
-
const searchLabel = searchField ? (0, _burojs_core.resolveFieldLabel)(listCaps, searchField, (0, _burojs_core.declaredText)("field", def?.fields[searchField], "label")) : searchGenericLabel;
|
|
5508
|
-
const searchPlaceholder = searchField ? t("toolbar.searchBy", { params: { name: searchLabel } }) : searchGenericLabel;
|
|
5509
5639
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
5510
5640
|
className: "flex flex-wrap items-center gap-2",
|
|
5511
5641
|
children: [
|
|
5512
5642
|
searchDecl !== void 0 && filters.searchEnabled && (0, react_jsx_runtime.jsx)(ListSearchInput, {
|
|
5513
5643
|
resource,
|
|
5514
|
-
|
|
5515
|
-
placeholder: searchPlaceholder,
|
|
5644
|
+
...placeholder === void 0 ? {} : { placeholder },
|
|
5516
5645
|
value: filters.search,
|
|
5517
5646
|
onCommit: (v) => {
|
|
5518
5647
|
pagination.setPage(1);
|
|
@@ -5524,19 +5653,21 @@ function FilterRegion({ search } = {}) {
|
|
|
5524
5653
|
setGroup: filters.setGroup,
|
|
5525
5654
|
available: filters.available,
|
|
5526
5655
|
fixed: filters.fixed,
|
|
5656
|
+
presets: filters.presets,
|
|
5657
|
+
setPreset: filters.setPreset,
|
|
5527
5658
|
pinnedFields: filters.pinnedFields,
|
|
5528
5659
|
pinnedValue: filters.value,
|
|
5529
5660
|
setPinnedValue: filters.set,
|
|
5530
5661
|
setPage: pagination.setPage,
|
|
5531
5662
|
testIdBase
|
|
5532
5663
|
}),
|
|
5533
|
-
filters.
|
|
5664
|
+
filters.canReset && (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
5534
5665
|
type: "button",
|
|
5535
5666
|
variant: "ghost",
|
|
5536
5667
|
size: "sm",
|
|
5537
5668
|
"data-testid": `${testIdBase}:clear-all`,
|
|
5538
|
-
onClick: filters.
|
|
5539
|
-
children:
|
|
5669
|
+
onClick: filters.reset,
|
|
5670
|
+
children: chromeT("filters.clearAll")
|
|
5540
5671
|
})
|
|
5541
5672
|
]
|
|
5542
5673
|
});
|
|
@@ -5666,6 +5797,7 @@ function ViewItem({ view, caps, resource, onClick, testid }) {
|
|
|
5666
5797
|
});
|
|
5667
5798
|
}
|
|
5668
5799
|
function EntryRow({ entry, onApply, onRename, onFork, onDelete, forkAvailable, applyTestId, renameTestId, forkTestId, deleteTestId, tr }) {
|
|
5800
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
5669
5801
|
const canRename = entry.permissions.update && onRename !== void 0;
|
|
5670
5802
|
const canFork = forkAvailable && entry.permissions.fork && onFork !== void 0;
|
|
5671
5803
|
const canDelete = entry.permissions.remove && onDelete !== void 0;
|
|
@@ -5711,8 +5843,8 @@ function EntryRow({ entry, onApply, onRename, onFork, onDelete, forkAvailable, a
|
|
|
5711
5843
|
canDelete && (0, react_jsx_runtime.jsx)("button", {
|
|
5712
5844
|
type: "button",
|
|
5713
5845
|
onClick: onDelete,
|
|
5714
|
-
"aria-label":
|
|
5715
|
-
title:
|
|
5846
|
+
"aria-label": chromeT("actions.delete", { defaultValue: "Delete" }),
|
|
5847
|
+
title: chromeT("actions.delete", { defaultValue: "Delete" }),
|
|
5716
5848
|
"data-testid": deleteTestId,
|
|
5717
5849
|
className: "shrink-0 rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
5718
5850
|
children: (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconTrash, {
|
|
@@ -5752,7 +5884,8 @@ function groupByScope(entries) {
|
|
|
5752
5884
|
}
|
|
5753
5885
|
return order.map((id) => byId.get(id));
|
|
5754
5886
|
}
|
|
5755
|
-
function SavedViewsDropdown({ resource, adopterViews, entries, issues = [], onApply, onSaveCurrent, canSaveCurrent = true, onManage, onRenameEntry, onDeleteEntry, onForkEntry, canFork = true, getTestId, triggerLabel = "Views", iconOnly = false, triggerClassName = "h-9", popoverContentClassName = "w-64 p-1", popoverAlign = "start" }) {
|
|
5887
|
+
function SavedViewsDropdown({ resource: resourceInput, adopterViews, entries, issues = [], onApply, onSaveCurrent, canSaveCurrent = true, onManage, onRenameEntry, onDeleteEntry, onForkEntry, canFork = true, getTestId, triggerLabel = "Views", iconOnly = false, triggerClassName = "h-9", popoverContentClassName = "w-64 p-1", popoverAlign = "start" }) {
|
|
5888
|
+
const resource = resourceInput === void 0 ? void 0 : (0, _burojs_core.routeResourceKey)(resourceInput);
|
|
5756
5889
|
const t = (0, _burojs_react.useOptionalT)();
|
|
5757
5890
|
const caps = (0, _burojs_react.useI18nCaps)(resource);
|
|
5758
5891
|
const tr = (key, fallback) => t?.(key, { defaultValue: fallback }) ?? fallback;
|
|
@@ -5966,9 +6099,10 @@ function useOptionalFrameChrome() {
|
|
|
5966
6099
|
//#endregion
|
|
5967
6100
|
//#region src/record/frame-pieces.tsx
|
|
5968
6101
|
function useFrameId() {
|
|
5969
|
-
const { recordId, record } = (0, _burojs_react.useRecordFrame)();
|
|
6102
|
+
const { resource, recordId, record } = (0, _burojs_react.useRecordFrame)();
|
|
6103
|
+
const def = (0, _burojs_react.useApp)().registry.get(resource);
|
|
5970
6104
|
if (recordId !== void 0) return recordId;
|
|
5971
|
-
const id = record
|
|
6105
|
+
const id = (0, _burojs_react.recordKeyOf)(def, record);
|
|
5972
6106
|
return typeof id === "string" || typeof id === "number" ? String(id) : void 0;
|
|
5973
6107
|
}
|
|
5974
6108
|
function RecordTitleView() {
|
|
@@ -5979,7 +6113,7 @@ function RecordTitleView() {
|
|
|
5979
6113
|
const t = (0, _burojs_react.useOptionalT)();
|
|
5980
6114
|
const title = (0, _burojs_react.useRecordTitle)(resource, mode === "create" ? void 0 : id, record);
|
|
5981
6115
|
if (useFrameChrome().hostTitle === true) return null;
|
|
5982
|
-
const text = mode === "create" ? t
|
|
6116
|
+
const text = mode === "create" ? resolveResourceTitle(caps, t, resource, "createTitle", { label: (0, _burojs_core.resolveResourceLabel)(caps, resource, "single", app.registry.get(resource)) }) : title;
|
|
5983
6117
|
if (text === "") return null;
|
|
5984
6118
|
return (0, react_jsx_runtime.jsx)("h2", {
|
|
5985
6119
|
className: "min-w-0 break-words text-xl font-semibold tracking-tight",
|
|
@@ -5992,10 +6126,7 @@ function RecordActionsView() {
|
|
|
5992
6126
|
const id = useFrameId();
|
|
5993
6127
|
const holder = (0, _burojs_react.useScreenState)()?.inline;
|
|
5994
6128
|
if (mode === "create" || record === void 0 || id === void 0) return null;
|
|
5995
|
-
const row = {
|
|
5996
|
-
...(0, _burojs_react.policyRecordOf)(controller, record),
|
|
5997
|
-
id
|
|
5998
|
-
};
|
|
6129
|
+
const row = (0, _burojs_react.withRecordKeys)((0, _burojs_react.policyRecordOf)(controller) ?? record, { id });
|
|
5999
6130
|
holder?.declare(inlineFlowNames(controller.screen, controller.plan));
|
|
6000
6131
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
6001
6132
|
className: "flex flex-wrap items-center gap-2",
|
|
@@ -6003,6 +6134,7 @@ function RecordActionsView() {
|
|
|
6003
6134
|
resource,
|
|
6004
6135
|
record: row,
|
|
6005
6136
|
surface: mode,
|
|
6137
|
+
sources: controller.sources,
|
|
6006
6138
|
...holder === void 0 ? {} : { hideFlows: (name) => holder.suppressed(name) }
|
|
6007
6139
|
}), mode === "show" ? extraActions : null]
|
|
6008
6140
|
});
|
|
@@ -6032,24 +6164,38 @@ function FormActionsView() {
|
|
|
6032
6164
|
const app = (0, _burojs_react.useApp)();
|
|
6033
6165
|
const navigate = (0, _burojs_react.useRouteNavigate)();
|
|
6034
6166
|
const t = (0, _burojs_react.useOptionalT)();
|
|
6167
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
6168
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
6169
|
+
const labelCaps = (0, _burojs_react.useI18nCaps)(resource);
|
|
6035
6170
|
const tid = (0, _burojs_react.useTestIds)();
|
|
6036
6171
|
const id = useFrameId();
|
|
6172
|
+
const back = (0, _burojs_react.useReturnTarget)(resource, mode === "create" ? "create" : "edit", mode === "edit" ? id : void 0);
|
|
6173
|
+
const failedIssues = chrome.serverIssues;
|
|
6174
|
+
const livePlan = controller.plan;
|
|
6175
|
+
const placed = (0, react.useMemo)(() => new Set(livePlan?.placedPaths ?? []), [livePlan]);
|
|
6176
|
+
const alertIssues = (0, react.useMemo)(() => failedIssues === void 0 || failedIssues.length === 0 ? NO_ALERT_ISSUES : (0, _burojs_core.routeServerIssues)({ issues: failedIssues }, (segment) => segment, (field, path) => field !== "_form" && (livePlan === null || livePlan.fields[field] === "active" && (0, _burojs_core_internal.deepestPlacedPath)(path, placed) !== void 0)).form, [
|
|
6177
|
+
failedIssues,
|
|
6178
|
+
livePlan,
|
|
6179
|
+
placed
|
|
6180
|
+
]);
|
|
6181
|
+
const fieldDefs = app.registry.get(resource)?.fields;
|
|
6037
6182
|
if (mode === "show") return null;
|
|
6038
|
-
const busy = controller.isSubmitting;
|
|
6183
|
+
const busy = controller.isSubmitting || chrome.created === true;
|
|
6039
6184
|
const cancel = () => {
|
|
6040
6185
|
if (chrome.onCancel !== void 0) chrome.onCancel();
|
|
6041
|
-
else navigate(
|
|
6186
|
+
else navigate(back, { origin: "inherit" });
|
|
6042
6187
|
};
|
|
6043
6188
|
const plan = controller.plan;
|
|
6044
6189
|
const undrawn = (field) => plan === null || plan.fields[field] === void 0 || plan.fields[field] === "inactive";
|
|
6045
|
-
const recordLevel = (issue) => issue.field === "_form" || undrawn(issue.field);
|
|
6190
|
+
const recordLevel = (issue) => issue.field === "_form" || undrawn((0, _burojs_core_internal.pathHead)(issue.field)) || !placed.has(issue.field);
|
|
6046
6191
|
const undrawnBlockers = (controller.checkOutcome?.blockers ?? []).flatMap((issue) => {
|
|
6047
6192
|
const field = typeof issue.path?.[0] === "string" ? issue.path[0] : "_form";
|
|
6048
|
-
if (field !== "_form" && !undrawn(field)) return [];
|
|
6193
|
+
if (field !== "_form" && !undrawn(field) && (0, _burojs_core_internal.deepestPlacedPath)(issue.path, placed) !== void 0) return [];
|
|
6049
6194
|
if (controller.errors.some((own) => own.code === issue.code && own.field === field)) return [];
|
|
6050
6195
|
return [{
|
|
6051
6196
|
...issue,
|
|
6052
|
-
field
|
|
6197
|
+
field,
|
|
6198
|
+
path: field === "_form" ? [] : issue.path.slice(1)
|
|
6053
6199
|
}];
|
|
6054
6200
|
});
|
|
6055
6201
|
const formErrors = firstPreferred([...controller.errors.filter(recordLevel), ...undrawnBlockers]);
|
|
@@ -6057,21 +6203,44 @@ function FormActionsView() {
|
|
|
6057
6203
|
const text = (issue) => (0, _burojs_react.resolveValidationMessage)({
|
|
6058
6204
|
code: issue.code ?? "",
|
|
6059
6205
|
message: issue.message,
|
|
6060
|
-
...issue.
|
|
6061
|
-
}, {
|
|
6206
|
+
...issue.check === void 0 ? {} : { check: issue.check }
|
|
6207
|
+
}, {
|
|
6208
|
+
has: caps.has,
|
|
6209
|
+
t: caps.t
|
|
6210
|
+
});
|
|
6062
6211
|
const retryable = [];
|
|
6063
6212
|
for (const issue of controller.checkOutcome?.blockers ?? []) {
|
|
6064
|
-
const checkId = issue.
|
|
6065
|
-
if (issue.
|
|
6213
|
+
const checkId = issue.check?.id;
|
|
6214
|
+
if (issue.check?.cause === void 0 || typeof checkId !== "string") continue;
|
|
6066
6215
|
if (!retryable.includes(checkId)) retryable.push(checkId);
|
|
6067
6216
|
}
|
|
6068
|
-
const failure = chrome.submitError === void 0 ? void 0 : failureText(chrome.submitError, t);
|
|
6217
|
+
const failure = chrome.submitError === void 0 ? void 0 : failureText(chrome.submitError, chrome.submitApplied, t, caps);
|
|
6218
|
+
const serverIssues = bySeverity(alertIssues).flatMap((issue) => {
|
|
6219
|
+
const head = issue.path[0];
|
|
6220
|
+
const name = typeof head === "string" ? head : void 0;
|
|
6221
|
+
const declared = name === void 0 ? void 0 : fieldDefs?.[name];
|
|
6222
|
+
const message = (0, _burojs_react.resolveValidationMessage)({
|
|
6223
|
+
code: issue.code,
|
|
6224
|
+
message: issue.message,
|
|
6225
|
+
...issue.check === void 0 ? {} : { check: issue.check }
|
|
6226
|
+
}, {
|
|
6227
|
+
has: caps.has,
|
|
6228
|
+
t: caps.t,
|
|
6229
|
+
...declared === void 0 ? {} : { fieldKey: `resources.${resource}.fields.${name}` }
|
|
6230
|
+
});
|
|
6231
|
+
if (issue.path.length === 0 && message === failure) return [];
|
|
6232
|
+
return [{
|
|
6233
|
+
label: declared === void 0 || name === void 0 ? void 0 : (0, _burojs_core.resolveFieldLabel)(labelCaps, name, (0, _burojs_core.declaredText)("field", declared, "label")),
|
|
6234
|
+
message,
|
|
6235
|
+
severity: issue.severity
|
|
6236
|
+
}];
|
|
6237
|
+
});
|
|
6069
6238
|
const steps = controller.steps;
|
|
6070
6239
|
const midSteps = steps !== null && steps.ids.length > 1 && steps.current !== void 0 && steps.current !== steps.ids[steps.ids.length - 1];
|
|
6071
6240
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
6072
6241
|
className: "flex flex-col gap-3",
|
|
6073
6242
|
children: [
|
|
6074
|
-
failure === void 0 && formErrors.length === 0 ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
6243
|
+
failure === void 0 && formErrors.length === 0 && serverIssues.length === 0 ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
6075
6244
|
role: "alert",
|
|
6076
6245
|
className: "flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
6077
6246
|
children: [
|
|
@@ -6081,10 +6250,22 @@ function FormActionsView() {
|
|
|
6081
6250
|
}),
|
|
6082
6251
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
6083
6252
|
className: "leading-snug",
|
|
6084
|
-
children: [
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6253
|
+
children: [
|
|
6254
|
+
failure === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
|
|
6255
|
+
className: "font-medium",
|
|
6256
|
+
children: failure
|
|
6257
|
+
}),
|
|
6258
|
+
serverIssues.map((issue, index) => (0, react_jsx_runtime.jsxs)("p", {
|
|
6259
|
+
"data-testid": `form-server-issue:${resource}:${mode}:${index}`,
|
|
6260
|
+
"data-buro-severity": issue.severity,
|
|
6261
|
+
className: issue.severity === "error" ? void 0 : "text-warning-emphasis",
|
|
6262
|
+
children: [issue.label === void 0 ? null : (0, react_jsx_runtime.jsxs)("span", {
|
|
6263
|
+
className: "font-medium",
|
|
6264
|
+
children: [issue.label, ": "]
|
|
6265
|
+
}), issue.message]
|
|
6266
|
+
}, index)),
|
|
6267
|
+
formErrors.map((issue) => (0, react_jsx_runtime.jsx)("p", { children: text(issue) }, issueKey(issue)))
|
|
6268
|
+
]
|
|
6088
6269
|
}),
|
|
6089
6270
|
failure !== void 0 && steps !== null ? (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
6090
6271
|
type: "button",
|
|
@@ -6093,7 +6274,7 @@ function FormActionsView() {
|
|
|
6093
6274
|
className: "ml-auto",
|
|
6094
6275
|
onMouseDown: (event) => event.preventDefault(),
|
|
6095
6276
|
onClick: () => void chrome.submit(),
|
|
6096
|
-
children:
|
|
6277
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
6097
6278
|
}) : null
|
|
6098
6279
|
]
|
|
6099
6280
|
}),
|
|
@@ -6105,7 +6286,7 @@ function FormActionsView() {
|
|
|
6105
6286
|
size: "sm",
|
|
6106
6287
|
"data-testid": `form-check-retry:${checkId}`,
|
|
6107
6288
|
onClick: () => void controller.revalidate(),
|
|
6108
|
-
children:
|
|
6289
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
6109
6290
|
}, checkId))
|
|
6110
6291
|
}),
|
|
6111
6292
|
formWarnings.length === 0 ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -6131,7 +6312,7 @@ function FormActionsView() {
|
|
|
6131
6312
|
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
|
|
6132
6313
|
className: "h-3.5 w-3.5 animate-spin",
|
|
6133
6314
|
"aria-hidden": "true"
|
|
6134
|
-
}), (0, react_jsx_runtime.jsx)("span", { children:
|
|
6315
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: chromeT("actions.validating", { defaultValue: "Validating…" }) })]
|
|
6135
6316
|
}) : null,
|
|
6136
6317
|
(0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
6137
6318
|
type: "button",
|
|
@@ -6139,7 +6320,7 @@ function FormActionsView() {
|
|
|
6139
6320
|
onClick: cancel,
|
|
6140
6321
|
onMouseDown: (event) => event.preventDefault(),
|
|
6141
6322
|
"data-testid": tid.formCancel(resource, mode),
|
|
6142
|
-
children:
|
|
6323
|
+
children: chromeT("actions.cancel", { defaultValue: "Cancel" })
|
|
6143
6324
|
}),
|
|
6144
6325
|
midSteps ? null : (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
6145
6326
|
type: "submit",
|
|
@@ -6156,37 +6337,71 @@ function FormActionsView() {
|
|
|
6156
6337
|
children: [busy ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
|
|
6157
6338
|
className: "mr-2 h-4 w-4 animate-spin",
|
|
6158
6339
|
"aria-hidden": "true"
|
|
6159
|
-
}) : null, busy ? mode === "edit" ?
|
|
6340
|
+
}) : null, busy ? mode === "edit" ? chromeT("actions.saving", { defaultValue: "Saving…" }) : chromeT("actions.creating", { defaultValue: "Creating…" }) : chrome.submitLabel ?? (mode === "edit" ? chromeT("actions.save", { defaultValue: "Save" }) : chromeT("actions.create", { defaultValue: "Create" }))]
|
|
6160
6341
|
})
|
|
6161
6342
|
]
|
|
6162
6343
|
})
|
|
6163
6344
|
]
|
|
6164
6345
|
});
|
|
6165
6346
|
}
|
|
6347
|
+
const NO_ALERT_ISSUES = Object.freeze([]);
|
|
6348
|
+
const SEVERITY_RANK = {
|
|
6349
|
+
error: 0,
|
|
6350
|
+
warning: 1,
|
|
6351
|
+
info: 2
|
|
6352
|
+
};
|
|
6353
|
+
function bySeverity(issues) {
|
|
6354
|
+
return [...issues].sort((a, b) => (SEVERITY_RANK[a.severity] ?? 3) - (SEVERITY_RANK[b.severity] ?? 3));
|
|
6355
|
+
}
|
|
6166
6356
|
function firstPreferred(issues) {
|
|
6167
|
-
const first = issues.find((issue) => issue.
|
|
6357
|
+
const first = issues.find((issue) => issue.check?.id === void 0) ?? issues[0];
|
|
6168
6358
|
return first === void 0 ? [] : [first];
|
|
6169
6359
|
}
|
|
6170
6360
|
function issueKey(issue) {
|
|
6171
6361
|
return JSON.stringify([
|
|
6172
6362
|
issue.code ?? "",
|
|
6173
6363
|
issue.message.key,
|
|
6174
|
-
issue.
|
|
6364
|
+
issue.check?.id ?? null
|
|
6175
6365
|
]);
|
|
6176
6366
|
}
|
|
6177
|
-
function failureText(error, t) {
|
|
6178
|
-
const
|
|
6179
|
-
|
|
6367
|
+
function failureText(error, settled, t, caps) {
|
|
6368
|
+
const texts = require_toaster.technicalTexts(error).filter((text) => text.length <= 1024);
|
|
6369
|
+
const strings = require_toaster.friendlyStringsFrom(t);
|
|
6370
|
+
const friendly = texts.map((text) => require_toaster.toFriendlyError(text, void 0, strings)).find((f) => f.replaced) ?? require_toaster.toFriendlyError(texts[0], void 0, strings);
|
|
6371
|
+
const applied = settled ?? ownDataProperty(error, "applied");
|
|
6372
|
+
if (applied === "partial" || applied === "unknown") {
|
|
6373
|
+
const key = applied === "partial" ? "errors.partlyApplied" : "errors.mayHaveBeenApplied";
|
|
6374
|
+
const sentence = caps.has(key) ? caps.t(key) : applied === "partial" ? "Part of this may have been saved. Check the record before trying again." : "It may have been saved. Check the record before trying again.";
|
|
6375
|
+
const lead = texts.some(require_toaster.isNetworkFailure) ? strings.offline : "";
|
|
6376
|
+
return lead === "" ? sentence : `${lead} ${sentence}`;
|
|
6377
|
+
}
|
|
6378
|
+
const code = ownDataProperty(error, "code");
|
|
6379
|
+
const kind = ownDataProperty(error, "kind");
|
|
6380
|
+
const hasOwnSentence = typeof code === "string" && typeof kind === "string" && kind !== "transport" && Object.hasOwn(_burojs_react.RECORD_KIND_KEYS, kind);
|
|
6381
|
+
const message = ownDataProperty(error, "message");
|
|
6382
|
+
if (friendly.replaced && !hasOwnSentence) return (typeof code === "string" ? (0, _burojs_react.specificErrorText)({
|
|
6383
|
+
code,
|
|
6384
|
+
...isMessageReference(message) ? { message } : {}
|
|
6385
|
+
}, caps, { record: true }) : void 0) ?? friendly.title;
|
|
6386
|
+
if (typeof code !== "string") return strings.title;
|
|
6387
|
+
const reference = {
|
|
6388
|
+
code,
|
|
6389
|
+
...isMessageReference(message) ? { message } : {}
|
|
6390
|
+
};
|
|
6391
|
+
return (0, _burojs_react.specificErrorText)(reference, caps, { record: true }) ?? (typeof kind === "string" ? (0, _burojs_react.kindErrorText)(kind, caps, { record: true }) : void 0) ?? strings.title;
|
|
6180
6392
|
}
|
|
6181
|
-
function
|
|
6393
|
+
function ownDataProperty(error, name) {
|
|
6182
6394
|
if (error === null || typeof error !== "object") return void 0;
|
|
6183
6395
|
try {
|
|
6184
|
-
const descriptor = Object.getOwnPropertyDescriptor(error,
|
|
6185
|
-
return descriptor !== void 0 && "value" in descriptor
|
|
6396
|
+
const descriptor = Object.getOwnPropertyDescriptor(error, name);
|
|
6397
|
+
return descriptor !== void 0 && "value" in descriptor ? descriptor.value : void 0;
|
|
6186
6398
|
} catch {
|
|
6187
6399
|
return;
|
|
6188
6400
|
}
|
|
6189
6401
|
}
|
|
6402
|
+
function isMessageReference(value) {
|
|
6403
|
+
return value !== null && typeof value === "object" && typeof value.key === "string";
|
|
6404
|
+
}
|
|
6190
6405
|
function inlineFlowNames(screen, plan) {
|
|
6191
6406
|
if (screen === null) return [];
|
|
6192
6407
|
const names = [];
|
|
@@ -6459,31 +6674,35 @@ function PlannedFrame(props) {
|
|
|
6459
6674
|
})
|
|
6460
6675
|
}, name);
|
|
6461
6676
|
const { PlacementScope } = page;
|
|
6677
|
+
const claimedRoute = (0, react.useContext)(_burojs_react.RouteSourceContext);
|
|
6462
6678
|
const itemNode = page.plan.slots.item?.[0];
|
|
6463
6679
|
const item = (0, react.useMemo)(() => itemNode === void 0 ? void 0 : itemHandle(itemNode), [itemNode]);
|
|
6464
6680
|
return (0, react_jsx_runtime.jsx)(_burojs_react.RouteSourceContext.Provider, {
|
|
6465
6681
|
value: null,
|
|
6466
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6682
|
+
children: (0, react_jsx_runtime.jsx)(_burojs_react.ActionRouteContext.Provider, {
|
|
6683
|
+
value: claimedRoute,
|
|
6684
|
+
children: (0, react_jsx_runtime.jsx)(PlacementScope, { children: (0, react_jsx_runtime.jsx)(ScreenTreeScope, {
|
|
6685
|
+
resource,
|
|
6686
|
+
mode: "show",
|
|
6687
|
+
compiled,
|
|
6688
|
+
page,
|
|
6689
|
+
children: (0, react_jsx_runtime.jsx)(ListItemContext.Provider, {
|
|
6690
|
+
value: item,
|
|
6691
|
+
children: (0, react_jsx_runtime.jsx)(FrameView, {
|
|
6692
|
+
resource,
|
|
6693
|
+
compiled,
|
|
6694
|
+
slots
|
|
6695
|
+
})
|
|
6696
|
+
})
|
|
6697
|
+
}) })
|
|
6698
|
+
})
|
|
6480
6699
|
});
|
|
6481
6700
|
}
|
|
6482
6701
|
function ListFrameHost({ resource }) {
|
|
6483
6702
|
const compiled = useCompiledListScreen(resource);
|
|
6484
6703
|
const hasDataRuntime = (0, _burojs_react.useOptionalDataRuntime)() !== null;
|
|
6485
6704
|
const { def } = (0, _burojs_react.useResourceListContext)();
|
|
6486
|
-
const rowsView =
|
|
6705
|
+
const rowsView = def?.views?.list?.initial?.view ?? "table";
|
|
6487
6706
|
if (compiled === null) return (0, react_jsx_runtime.jsx)(Arrangement, {});
|
|
6488
6707
|
if (compiled.nodes.length === 0 && rowsView === "table") {
|
|
6489
6708
|
const empty = {};
|
|
@@ -6502,8 +6721,12 @@ function ListFrameHost({ resource }) {
|
|
|
6502
6721
|
}
|
|
6503
6722
|
//#endregion
|
|
6504
6723
|
//#region src/list-kit/resource-list-surface.tsx
|
|
6505
|
-
|
|
6506
|
-
|
|
6724
|
+
function declaresDisplay(field) {
|
|
6725
|
+
return field !== void 0 && (0, _burojs_core.resolveSurfaceUi)(field, "column").use !== void 0;
|
|
6726
|
+
}
|
|
6727
|
+
const NO_INITIAL_FILTERS = Object.freeze({});
|
|
6728
|
+
const RelatedCards = (0, react.lazy)(async () => ({ default: (await Promise.resolve().then(() => require("./related-list-cards-Bc_vfCE_.cjs"))).RelatedCards }));
|
|
6729
|
+
const RelatedTimeline = (0, react.lazy)(async () => ({ default: (await Promise.resolve().then(() => require("./related-list-timeline-k0DtnxTs.cjs"))).RelatedTimeline }));
|
|
6507
6730
|
function discriminatorOptionLabel(field, value) {
|
|
6508
6731
|
const text = (0, _burojs_core.fieldOptionText)(field, value);
|
|
6509
6732
|
if (text !== void 0) return text;
|
|
@@ -6511,10 +6734,17 @@ function discriminatorOptionLabel(field, value) {
|
|
|
6511
6734
|
const label = (Array.isArray(declared?.options) ? declared.options : Array.isArray(declared?.meta?.options) ? declared.meta.options : []).find((option) => option?.value === value)?.label;
|
|
6512
6735
|
return typeof label === "string" ? label : value;
|
|
6513
6736
|
}
|
|
6514
|
-
function
|
|
6737
|
+
function declaredInitialSort(def) {
|
|
6738
|
+
return def?.views?.list?.initial?.sort;
|
|
6739
|
+
}
|
|
6740
|
+
function declaredRouteView(def) {
|
|
6741
|
+
return def?.views?.list?.initial?.view;
|
|
6742
|
+
}
|
|
6743
|
+
function ResourceListSurface({ resource, variant, state, fixedFilters, initial, search: searchField, columns: columnEntries, open, title, empty, scope, view, item, placementKey, onCreate, count: countPolicy, rowTarget, readOnly, linkEditing, exportable, layoutId, meta, renderCell, emptyState }) {
|
|
6515
6744
|
const route = variant === "route";
|
|
6516
6745
|
const t = (0, _burojs_react.useT)();
|
|
6517
6746
|
const optionalT = (0, _burojs_react.useOptionalT)();
|
|
6747
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
6518
6748
|
const tid = (0, _burojs_react.useTestIds)();
|
|
6519
6749
|
const listCaps = (0, _burojs_react.useI18nCaps)(resource);
|
|
6520
6750
|
const RouteFiltersSlot = require_check_confirm_dialog.useListSlot("filters", resource);
|
|
@@ -6529,17 +6759,45 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6529
6759
|
console.error(`[burojs] list.body-removed: list.body.${require_check_confirm_dialog.canonicalResourceName(resource)} is no longer rendered; a whole-body override is a list frame (views.list.frame).`);
|
|
6530
6760
|
}, [removedBody, resource]);
|
|
6531
6761
|
const searchDecl = (0, react.useMemo)(() => searchField === void 0 ? void 0 : { fields: [searchField] }, [searchField]);
|
|
6532
|
-
const
|
|
6762
|
+
const appRegistry = (0, _burojs_react.useApp)().registry;
|
|
6763
|
+
const effectiveView = route ? declaredRouteView(appRegistry.get(resource)) ?? "table" : view ?? "table";
|
|
6764
|
+
const timeline = effectiveView === "timeline";
|
|
6765
|
+
const initialKey = JSON.stringify(initial ?? null);
|
|
6766
|
+
const placementInitial = (0, react.useMemo)(() => route ? void 0 : {
|
|
6767
|
+
...initial,
|
|
6768
|
+
filters: initial?.filters ?? NO_INITIAL_FILTERS
|
|
6769
|
+
}, [route, initialKey]);
|
|
6770
|
+
const timelineAxis = (placementInitial?.sort ?? declaredInitialSort(appRegistry.get(resource)))?.[0]?.field;
|
|
6771
|
+
const columnNames = (0, react.useMemo)(() => columnEntries?.map(_burojs_core.columnName), [columnEntries]);
|
|
6772
|
+
const list = (0, _burojs_react.useResourceList)(resource, route ? {
|
|
6773
|
+
meta,
|
|
6774
|
+
...timeline ? { timeline } : {}
|
|
6775
|
+
} : {
|
|
6776
|
+
...timeline ? { timeline } : {},
|
|
6533
6777
|
...state === void 0 ? {} : { state },
|
|
6534
6778
|
...fixedFilters === void 0 ? {} : { fixedFilters },
|
|
6535
|
-
...
|
|
6779
|
+
...placementInitial === void 0 ? {} : { initial: placementInitial },
|
|
6536
6780
|
...searchDecl === void 0 ? {} : { search: searchDecl },
|
|
6537
|
-
...
|
|
6781
|
+
...columnEntries === void 0 ? {} : { columns: columnEntries },
|
|
6538
6782
|
...scope === void 0 ? {} : { scope },
|
|
6539
6783
|
...countPolicy === void 0 ? {} : { countPolicy }
|
|
6540
6784
|
});
|
|
6541
6785
|
const { def, query, pagination, cursor, count, filters, sorting, columns, selection, savedViews, routing, live, droppedPredicates } = list;
|
|
6542
6786
|
(0, _burojs_react.policyRowsOf)(list, list.rows);
|
|
6787
|
+
const selectionRef = (0, react.useRef)(selection);
|
|
6788
|
+
selectionRef.current = selection;
|
|
6789
|
+
const onDetach = linkEditing?.detach?.onDetach;
|
|
6790
|
+
const surfaceLinkEditing = (0, react.useMemo)(() => onDetach === void 0 ? void 0 : { detach: { onDetach: async (detached) => {
|
|
6791
|
+
const left = await onDetach(detached);
|
|
6792
|
+
if (left.length > 0) {
|
|
6793
|
+
const gone = new Set(left);
|
|
6794
|
+
const current = selectionRef.current;
|
|
6795
|
+
if (current.ids.some((id) => gone.has(id))) current.set(current.ids.filter((id) => !gone.has(id)));
|
|
6796
|
+
}
|
|
6797
|
+
return left;
|
|
6798
|
+
} } }, [onDetach]);
|
|
6799
|
+
const onAttach = linkEditing?.attach?.onAttach;
|
|
6800
|
+
const attachBusy = linkEditing?.attach?.busy === true;
|
|
6543
6801
|
const hasDataRuntime = (0, _burojs_react.useOptionalDataRuntime)() !== null;
|
|
6544
6802
|
const scopeLabel = (scope) => scope.id === _burojs_react.LOCAL_USER_SCOPE_ID ? t("toolbar.viewsMyScope") : scope.label;
|
|
6545
6803
|
const createAvailable = (0, _burojs_react.useAvailability)(resource, "create").state === "available";
|
|
@@ -6587,7 +6845,6 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6587
6845
|
resource,
|
|
6588
6846
|
routing.rowHref
|
|
6589
6847
|
]);
|
|
6590
|
-
const effectiveView = route ? (def?.views?.list)?.view ?? "table" : view ?? "table";
|
|
6591
6848
|
const tableView = effectiveView === "table";
|
|
6592
6849
|
const rowsViewFor = (0, react.useMemo)(() => tableView ? void 0 : (planned) => ({
|
|
6593
6850
|
skeleton: effectiveView === "cards" ? (0, react_jsx_runtime.jsx)(RelatedCardsSkeleton, {}) : (0, react_jsx_runtime.jsx)(RelatedTimelineSkeleton, {}),
|
|
@@ -6599,11 +6856,15 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6599
6856
|
item: route ? planned : item,
|
|
6600
6857
|
columns: route ? columns.visible : columnNames,
|
|
6601
6858
|
rowQuick,
|
|
6602
|
-
rowHref
|
|
6859
|
+
rowHref,
|
|
6860
|
+
...empty === void 0 ? {} : { empty }
|
|
6603
6861
|
};
|
|
6604
6862
|
return (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
6605
6863
|
fallback: effectiveView === "cards" ? (0, react_jsx_runtime.jsx)(RelatedCardsSkeleton, {}) : (0, react_jsx_runtime.jsx)(RelatedTimelineSkeleton, {}),
|
|
6606
|
-
children: effectiveView === "cards" ? (0, react_jsx_runtime.jsx)(RelatedCards, { ...common }) : (0, react_jsx_runtime.jsx)(RelatedTimeline, {
|
|
6864
|
+
children: effectiveView === "cards" ? (0, react_jsx_runtime.jsx)(RelatedCards, { ...common }) : (0, react_jsx_runtime.jsx)(RelatedTimeline, {
|
|
6865
|
+
...common,
|
|
6866
|
+
axis: timelineAxis
|
|
6867
|
+
})
|
|
6607
6868
|
});
|
|
6608
6869
|
}
|
|
6609
6870
|
}), [
|
|
@@ -6616,7 +6877,9 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6616
6877
|
columns.visible,
|
|
6617
6878
|
columnNames,
|
|
6618
6879
|
rowQuick,
|
|
6619
|
-
rowHref
|
|
6880
|
+
rowHref,
|
|
6881
|
+
empty,
|
|
6882
|
+
timelineAxis
|
|
6620
6883
|
]);
|
|
6621
6884
|
const pageTitle = (0, _burojs_core.resolveResourceLabel)(listCaps, resource, "plural", def);
|
|
6622
6885
|
const [saveOpen, setSaveOpen] = (0, react.useState)(false);
|
|
@@ -6698,6 +6961,10 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6698
6961
|
sonner.toast.error(t("toolbar.viewsForkFailed"));
|
|
6699
6962
|
}
|
|
6700
6963
|
};
|
|
6964
|
+
const columnNamesDisplay = (col, field) => {
|
|
6965
|
+
const resolved = list.columns.ui[col];
|
|
6966
|
+
return resolved === void 0 ? declaresDisplay(field) : resolved.display.use !== void 0;
|
|
6967
|
+
};
|
|
6701
6968
|
const renderCellLadder = (col, value, row) => {
|
|
6702
6969
|
if (def?.types && col === def.types.by) {
|
|
6703
6970
|
const raw = typeof value === "string" ? value : "";
|
|
@@ -6716,13 +6983,14 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6716
6983
|
children: label
|
|
6717
6984
|
});
|
|
6718
6985
|
}
|
|
6986
|
+
const custom = (renderCell ?? CellSlot)?.(col, value, row);
|
|
6987
|
+
if (custom !== void 0) return custom;
|
|
6719
6988
|
const fieldDef = def?.fields[col];
|
|
6720
|
-
const enumName = fieldDef?.opts?.enum ?? fieldDef?.ui?.enum;
|
|
6721
|
-
if (enumName && typeof value === "string") return (0, react_jsx_runtime.jsx)(EnumBadge, {
|
|
6989
|
+
const enumName = (0, _burojs_core_internal.enumBindingKey)(fieldDef?.opts?.enum ?? fieldDef?.ui?.enum);
|
|
6990
|
+
if (enumName && typeof value === "string" && !columnNamesDisplay(col, fieldDef)) return (0, react_jsx_runtime.jsx)(EnumBadge, {
|
|
6722
6991
|
enumName,
|
|
6723
6992
|
value
|
|
6724
6993
|
});
|
|
6725
|
-
return (renderCell ?? CellSlot)?.(col, value, row);
|
|
6726
6994
|
};
|
|
6727
6995
|
const surface = {
|
|
6728
6996
|
resource,
|
|
@@ -6750,10 +7018,16 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6750
7018
|
}
|
|
6751
7019
|
},
|
|
6752
7020
|
rowsViewFor,
|
|
6753
|
-
emptyState,
|
|
7021
|
+
emptyState: empty !== void 0 && !list.filters.isFiltered && list.pagination.page <= 1 && (list.cursor === null || list.cursor.next === null) ? (0, react_jsx_runtime.jsx)("p", {
|
|
7022
|
+
"data-buro-region": "empty",
|
|
7023
|
+
className: "text-sm text-muted-foreground",
|
|
7024
|
+
children: empty
|
|
7025
|
+
}) : emptyState,
|
|
6754
7026
|
renderCell: renderCellLadder,
|
|
6755
7027
|
readOnly: readOnly === true,
|
|
6756
|
-
exportable: exportable !== false
|
|
7028
|
+
exportable: exportable !== false,
|
|
7029
|
+
...layoutId === void 0 ? {} : { layoutId },
|
|
7030
|
+
...surfaceLinkEditing === void 0 ? {} : { linkEditing: surfaceLinkEditing }
|
|
6757
7031
|
};
|
|
6758
7032
|
return (0, react_jsx_runtime.jsx)(_burojs_react.ResourceListProvider, {
|
|
6759
7033
|
value: list,
|
|
@@ -6766,22 +7040,44 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6766
7040
|
resource,
|
|
6767
7041
|
mode: "list",
|
|
6768
7042
|
title: pageTitle
|
|
6769
|
-
}) : title === void 0 && onCreate === void 0 ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
7043
|
+
}) : title === void 0 && onCreate === void 0 && onAttach === void 0 ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
6770
7044
|
className: "flex items-center justify-between gap-2",
|
|
6771
|
-
children: [
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
7045
|
+
children: [
|
|
7046
|
+
title === void 0 ? (0, react_jsx_runtime.jsx)("span", {}) : (0, react_jsx_runtime.jsx)("h3", {
|
|
7047
|
+
className: "text-sm font-semibold",
|
|
7048
|
+
children: title
|
|
7049
|
+
}),
|
|
7050
|
+
onAttach === void 0 ? null : (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
7051
|
+
type: "button",
|
|
7052
|
+
size: "sm",
|
|
7053
|
+
variant: "outline",
|
|
7054
|
+
"data-testid": `list-link-attach:${resource}`,
|
|
7055
|
+
onClick: onAttach,
|
|
7056
|
+
disabled: attachBusy,
|
|
7057
|
+
"aria-busy": attachBusy,
|
|
7058
|
+
children: [attachBusy ? (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLoader2, {
|
|
7059
|
+
className: "mr-1 h-4 w-4 animate-spin",
|
|
7060
|
+
"aria-hidden": "true"
|
|
7061
|
+
}) : (0, react_jsx_runtime.jsx)(_tabler_icons_react.IconLink, {
|
|
7062
|
+
className: "mr-1 h-4 w-4",
|
|
7063
|
+
"aria-hidden": "true"
|
|
7064
|
+
}), optionalT("field.link.attach", { defaultValue: "Attach" })]
|
|
7065
|
+
}),
|
|
7066
|
+
onCreate === void 0 ? null : (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
7067
|
+
type: "button",
|
|
7068
|
+
size: "sm",
|
|
7069
|
+
variant: "outline",
|
|
7070
|
+
"data-testid": `list-create:${resource}`,
|
|
7071
|
+
onClick: onCreate,
|
|
7072
|
+
children: [(0, react_jsx_runtime.jsx)(_tabler_icons_react.IconPlus, {
|
|
7073
|
+
className: "mr-1 h-4 w-4",
|
|
7074
|
+
"aria-hidden": "true"
|
|
7075
|
+
}), optionalT("actions.create", {
|
|
7076
|
+
resource,
|
|
7077
|
+
defaultValue: "Create"
|
|
7078
|
+
})]
|
|
7079
|
+
})
|
|
7080
|
+
]
|
|
6785
7081
|
}),
|
|
6786
7082
|
hasDataRuntime && (0, react_jsx_runtime.jsx)(ExportRunWatcherMount, {}),
|
|
6787
7083
|
droppedPredicates > 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -6830,13 +7126,13 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6830
7126
|
variant: "outline",
|
|
6831
7127
|
onClick: () => setSaveOpen(false),
|
|
6832
7128
|
"data-testid": `list-saved-view-save-cancel:${resource}`,
|
|
6833
|
-
children:
|
|
7129
|
+
children: chromeT("actions.cancel")
|
|
6834
7130
|
}), (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
6835
7131
|
type: "button",
|
|
6836
7132
|
onClick: handleSaveConfirm,
|
|
6837
7133
|
disabled: saveLabel.trim().length === 0,
|
|
6838
7134
|
"data-testid": `list-saved-view-save-confirm:${resource}`,
|
|
6839
|
-
children:
|
|
7135
|
+
children: chromeT("actions.save")
|
|
6840
7136
|
})] })
|
|
6841
7137
|
]
|
|
6842
7138
|
})
|
|
@@ -6873,7 +7169,7 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6873
7169
|
variant: "outline",
|
|
6874
7170
|
onClick: () => handleDeleteUserView(entry.id),
|
|
6875
7171
|
"data-testid": `list-saved-view-manage-delete:${resource}:${entry.id}`,
|
|
6876
|
-
children:
|
|
7172
|
+
children: chromeT("actions.delete")
|
|
6877
7173
|
}) : (0, react_jsx_runtime.jsx)("span", {
|
|
6878
7174
|
className: "shrink-0 text-xs text-muted-foreground",
|
|
6879
7175
|
children: t("toolbar.viewsReadOnly")
|
|
@@ -6885,7 +7181,7 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6885
7181
|
variant: "outline",
|
|
6886
7182
|
onClick: () => setManageOpen(false),
|
|
6887
7183
|
"data-testid": `list-saved-view-manage-close:${resource}`,
|
|
6888
|
-
children:
|
|
7184
|
+
children: chromeT("actions.close")
|
|
6889
7185
|
}) })
|
|
6890
7186
|
]
|
|
6891
7187
|
})
|
|
@@ -6918,13 +7214,13 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6918
7214
|
setRenameTarget(null);
|
|
6919
7215
|
},
|
|
6920
7216
|
"data-testid": `list-saved-view-rename-cancel:${resource}`,
|
|
6921
|
-
children:
|
|
7217
|
+
children: chromeT("actions.cancel")
|
|
6922
7218
|
}), (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
6923
7219
|
type: "button",
|
|
6924
7220
|
onClick: handleRenameConfirm,
|
|
6925
7221
|
disabled: renameLabel.trim().length === 0,
|
|
6926
7222
|
"data-testid": `list-saved-view-rename-confirm:${resource}`,
|
|
6927
|
-
children:
|
|
7223
|
+
children: chromeT("actions.save")
|
|
6928
7224
|
})] })
|
|
6929
7225
|
]
|
|
6930
7226
|
})
|
|
@@ -6959,7 +7255,7 @@ function ResourceListSurface({ resource, variant, state, fixedFilters, pageSize,
|
|
|
6959
7255
|
setForkTarget(null);
|
|
6960
7256
|
},
|
|
6961
7257
|
"data-testid": `list-saved-view-fork-cancel:${resource}`,
|
|
6962
|
-
children:
|
|
7258
|
+
children: chromeT("actions.cancel")
|
|
6963
7259
|
}), (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
6964
7260
|
type: "button",
|
|
6965
7261
|
onClick: handleForkConfirm,
|
|
@@ -6982,6 +7278,582 @@ function ExportRunWatcherMount() {
|
|
|
6982
7278
|
return null;
|
|
6983
7279
|
}
|
|
6984
7280
|
//#endregion
|
|
7281
|
+
//#region src/fields/use-relation-picker.tsx
|
|
7282
|
+
const noop = () => void 0;
|
|
7283
|
+
function safeKey(input) {
|
|
7284
|
+
if (input === void 0 || input === null) return void 0;
|
|
7285
|
+
try {
|
|
7286
|
+
return (0, _burojs_core.resourceKey)(input);
|
|
7287
|
+
} catch {
|
|
7288
|
+
return;
|
|
7289
|
+
}
|
|
7290
|
+
}
|
|
7291
|
+
function sessionIdentity(runtime) {
|
|
7292
|
+
const state = runtime.dataSession.getState();
|
|
7293
|
+
const snapshot = state.status === "ready" ? state.snapshot : state.target;
|
|
7294
|
+
const selection = snapshot.scope?.selection;
|
|
7295
|
+
const partition = selection === void 0 ? snapshot.scopeKey : [snapshot.scopeKey, selection];
|
|
7296
|
+
let scopeKey;
|
|
7297
|
+
try {
|
|
7298
|
+
scopeKey = JSON.stringify(partition) ?? "";
|
|
7299
|
+
} catch {
|
|
7300
|
+
scopeKey = String(snapshot.scopeKey);
|
|
7301
|
+
}
|
|
7302
|
+
return {
|
|
7303
|
+
sessionKey: snapshot.sessionKey,
|
|
7304
|
+
scopeKey
|
|
7305
|
+
};
|
|
7306
|
+
}
|
|
7307
|
+
function PickerHost(props) {
|
|
7308
|
+
const { register } = props;
|
|
7309
|
+
react.useEffect(() => register(), [register]);
|
|
7310
|
+
return (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.children });
|
|
7311
|
+
}
|
|
7312
|
+
function useRelationPicker(options) {
|
|
7313
|
+
const app = (0, _burojs_react.useApp)();
|
|
7314
|
+
const runtime = (0, _burojs_react.useDataRuntime)();
|
|
7315
|
+
const frame = (0, _burojs_react.useOptionalRecordFrame)();
|
|
7316
|
+
const frames = (0, _burojs_react.useRecordScopeFrames)();
|
|
7317
|
+
const multiple = options.multiple === true;
|
|
7318
|
+
const fieldName = options.field;
|
|
7319
|
+
let to;
|
|
7320
|
+
let declaredBy;
|
|
7321
|
+
let declaredCandidates;
|
|
7322
|
+
if (fieldName !== void 0) {
|
|
7323
|
+
const meta = ((frame === null ? void 0 : app.registry.get(frame.resource)?.fields)?.[fieldName])?.meta;
|
|
7324
|
+
to = safeKey(meta?.to);
|
|
7325
|
+
declaredBy = typeof meta?.by === "string" ? meta.by : void 0;
|
|
7326
|
+
declaredCandidates = Array.isArray(meta?.candidates) ? meta.candidates : void 0;
|
|
7327
|
+
} else to = safeKey(options.to);
|
|
7328
|
+
const target = to ?? "";
|
|
7329
|
+
const by = options.valueField ?? declaredBy;
|
|
7330
|
+
const scope = options.scope ?? "context";
|
|
7331
|
+
const selection = require_lazy_relation_picker_dialog.useCandidateSelection({
|
|
7332
|
+
to,
|
|
7333
|
+
candidates: options.candidates ?? declaredCandidates,
|
|
7334
|
+
sources: frame?.controller.sources,
|
|
7335
|
+
resource: frame?.resource ?? "",
|
|
7336
|
+
fieldName: fieldName ?? target,
|
|
7337
|
+
fixedFilters: options.fixedFilters
|
|
7338
|
+
});
|
|
7339
|
+
const held = selection.gate !== void 0;
|
|
7340
|
+
const pendingRef = react.useRef(null);
|
|
7341
|
+
const [active, setActive] = react.useState(null);
|
|
7342
|
+
const activeRef = react.useRef(null);
|
|
7343
|
+
activeRef.current = active;
|
|
7344
|
+
const rowsRef = react.useRef(new Map());
|
|
7345
|
+
const createdRowRef = react.useRef(void 0);
|
|
7346
|
+
const alive = react.useRef(true);
|
|
7347
|
+
const mounts = react.useRef(0);
|
|
7348
|
+
const sequence = react.useRef(0);
|
|
7349
|
+
const latest = react.useRef({
|
|
7350
|
+
multiple,
|
|
7351
|
+
select: options.select,
|
|
7352
|
+
idField: "id",
|
|
7353
|
+
valueField: "id",
|
|
7354
|
+
available: false,
|
|
7355
|
+
frames
|
|
7356
|
+
});
|
|
7357
|
+
const project = react.useCallback((row) => {
|
|
7358
|
+
const select = latest.current.select;
|
|
7359
|
+
if (select === void 0) return { ...row };
|
|
7360
|
+
const out = {};
|
|
7361
|
+
const key = row[latest.current.idField] !== void 0 ? row[latest.current.idField] : row.id;
|
|
7362
|
+
if (key !== void 0) out.id = key;
|
|
7363
|
+
const { valueField } = latest.current;
|
|
7364
|
+
if (Object.hasOwn(row, valueField)) out[valueField] = row[valueField];
|
|
7365
|
+
for (const name of select) if (Object.hasOwn(row, name)) out[name] = row[name];
|
|
7366
|
+
return out;
|
|
7367
|
+
}, []);
|
|
7368
|
+
const settle = react.useCallback((result) => {
|
|
7369
|
+
const pending = pendingRef.current;
|
|
7370
|
+
if (pending === null) return;
|
|
7371
|
+
pendingRef.current = null;
|
|
7372
|
+
pending.detach();
|
|
7373
|
+
if (alive.current) setActive(null);
|
|
7374
|
+
pending.resolve(result);
|
|
7375
|
+
}, []);
|
|
7376
|
+
const toggle = react.useCallback((key, row) => {
|
|
7377
|
+
setActive((current) => {
|
|
7378
|
+
if (current === null) return current;
|
|
7379
|
+
const has = current.selected.some((k) => String(k) === String(key));
|
|
7380
|
+
if (has) rowsRef.current.delete(String(key));
|
|
7381
|
+
else if (row !== void 0) rowsRef.current.set(String(key), row);
|
|
7382
|
+
const selected = has ? current.selected.filter((k) => String(k) !== String(key)) : [...current.selected, key];
|
|
7383
|
+
const next = {
|
|
7384
|
+
...current,
|
|
7385
|
+
selected
|
|
7386
|
+
};
|
|
7387
|
+
activeRef.current = next;
|
|
7388
|
+
return next;
|
|
7389
|
+
});
|
|
7390
|
+
}, []);
|
|
7391
|
+
const onValue = react.useCallback((value) => {
|
|
7392
|
+
const row = createdRowRef.current;
|
|
7393
|
+
createdRowRef.current = void 0;
|
|
7394
|
+
if (latest.current.multiple) {
|
|
7395
|
+
const current = activeRef.current;
|
|
7396
|
+
if (current !== null && !current.selected.some((k) => String(k) === String(value))) toggle(value, row);
|
|
7397
|
+
return;
|
|
7398
|
+
}
|
|
7399
|
+
settle({
|
|
7400
|
+
kind: "selected",
|
|
7401
|
+
keys: [value],
|
|
7402
|
+
rows: row === void 0 ? [] : [project(row)]
|
|
7403
|
+
});
|
|
7404
|
+
}, [
|
|
7405
|
+
project,
|
|
7406
|
+
settle,
|
|
7407
|
+
toggle
|
|
7408
|
+
]);
|
|
7409
|
+
const wiring = require_relation_select.useRelationSelect({
|
|
7410
|
+
to: target,
|
|
7411
|
+
by,
|
|
7412
|
+
fixedFilters: selection.fixedFilters,
|
|
7413
|
+
scope,
|
|
7414
|
+
...fieldName === void 0 ? {} : { scopeField: fieldName },
|
|
7415
|
+
held,
|
|
7416
|
+
onValue
|
|
7417
|
+
});
|
|
7418
|
+
latest.current = {
|
|
7419
|
+
multiple,
|
|
7420
|
+
select: options.select,
|
|
7421
|
+
idField: wiring.idField,
|
|
7422
|
+
valueField: wiring.valueField,
|
|
7423
|
+
available: to !== void 0 && wiring.targetDef !== void 0 && !held,
|
|
7424
|
+
frames
|
|
7425
|
+
};
|
|
7426
|
+
const { create: shared } = wiring;
|
|
7427
|
+
const create = react.useMemo(() => ({
|
|
7428
|
+
...shared,
|
|
7429
|
+
start: (openCreate) => shared.start(() => {
|
|
7430
|
+
const opened = openCreate();
|
|
7431
|
+
opened.then((row) => {
|
|
7432
|
+
createdRowRef.current = row === null ? void 0 : { ...row };
|
|
7433
|
+
}, noop);
|
|
7434
|
+
return opened;
|
|
7435
|
+
})
|
|
7436
|
+
}), [shared]);
|
|
7437
|
+
react.useEffect(() => runtime.dataSession.subscribe(() => {
|
|
7438
|
+
const pending = pendingRef.current;
|
|
7439
|
+
if (pending === null) return;
|
|
7440
|
+
const now = sessionIdentity(runtime);
|
|
7441
|
+
if (now.sessionKey !== pending.sessionKey || now.scopeKey !== pending.scopeKey) settle({
|
|
7442
|
+
kind: "cancelled",
|
|
7443
|
+
reason: "session-changed"
|
|
7444
|
+
});
|
|
7445
|
+
}), [runtime, settle]);
|
|
7446
|
+
react.useEffect(() => {
|
|
7447
|
+
alive.current = true;
|
|
7448
|
+
return () => {
|
|
7449
|
+
alive.current = false;
|
|
7450
|
+
settle({
|
|
7451
|
+
kind: "cancelled",
|
|
7452
|
+
reason: "unmounted"
|
|
7453
|
+
});
|
|
7454
|
+
};
|
|
7455
|
+
}, [settle]);
|
|
7456
|
+
react.useEffect(() => {
|
|
7457
|
+
if (held) settle({
|
|
7458
|
+
kind: "cancelled",
|
|
7459
|
+
reason: "unavailable"
|
|
7460
|
+
});
|
|
7461
|
+
}, [held, settle]);
|
|
7462
|
+
const register = react.useCallback(() => {
|
|
7463
|
+
mounts.current += 1;
|
|
7464
|
+
return () => {
|
|
7465
|
+
mounts.current -= 1;
|
|
7466
|
+
if (mounts.current === 0) settle({
|
|
7467
|
+
kind: "cancelled",
|
|
7468
|
+
reason: "unmounted"
|
|
7469
|
+
});
|
|
7470
|
+
};
|
|
7471
|
+
}, [settle]);
|
|
7472
|
+
const open = react.useCallback((opts = {}) => new Promise((resolve) => {
|
|
7473
|
+
settle({
|
|
7474
|
+
kind: "cancelled",
|
|
7475
|
+
reason: "superseded"
|
|
7476
|
+
});
|
|
7477
|
+
if (mounts.current === 0) {
|
|
7478
|
+
if (process.env.NODE_ENV !== "production") console.error("[burojs] useRelationPicker: open() was called but its element is not rendered — render `handle.element` once in your tree.");
|
|
7479
|
+
resolve({
|
|
7480
|
+
kind: "cancelled",
|
|
7481
|
+
reason: "not-mounted"
|
|
7482
|
+
});
|
|
7483
|
+
return;
|
|
7484
|
+
}
|
|
7485
|
+
const { signal } = opts;
|
|
7486
|
+
if (signal?.aborted === true) {
|
|
7487
|
+
resolve({
|
|
7488
|
+
kind: "cancelled",
|
|
7489
|
+
reason: "aborted"
|
|
7490
|
+
});
|
|
7491
|
+
return;
|
|
7492
|
+
}
|
|
7493
|
+
if (!latest.current.available) {
|
|
7494
|
+
resolve({
|
|
7495
|
+
kind: "cancelled",
|
|
7496
|
+
reason: "unavailable"
|
|
7497
|
+
});
|
|
7498
|
+
return;
|
|
7499
|
+
}
|
|
7500
|
+
sequence.current += 1;
|
|
7501
|
+
const id = sequence.current;
|
|
7502
|
+
const onAbort = () => {
|
|
7503
|
+
if (pendingRef.current?.id === id) settle({
|
|
7504
|
+
kind: "cancelled",
|
|
7505
|
+
reason: "aborted"
|
|
7506
|
+
});
|
|
7507
|
+
};
|
|
7508
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
7509
|
+
pendingRef.current = {
|
|
7510
|
+
id,
|
|
7511
|
+
...sessionIdentity(runtime),
|
|
7512
|
+
resolve,
|
|
7513
|
+
detach: () => signal?.removeEventListener("abort", onAbort)
|
|
7514
|
+
};
|
|
7515
|
+
rowsRef.current = new Map();
|
|
7516
|
+
createdRowRef.current = void 0;
|
|
7517
|
+
const next = {
|
|
7518
|
+
id,
|
|
7519
|
+
frames: latest.current.frames,
|
|
7520
|
+
selected: opts.selected ?? []
|
|
7521
|
+
};
|
|
7522
|
+
activeRef.current = next;
|
|
7523
|
+
setActive(next);
|
|
7524
|
+
}), [runtime, settle]);
|
|
7525
|
+
const onSelectRow = react.useCallback((row) => {
|
|
7526
|
+
const field = wiring.valueField;
|
|
7527
|
+
const value = field === "id" ? row.id : row[field];
|
|
7528
|
+
if (typeof value !== "string" && typeof value !== "number") return;
|
|
7529
|
+
settle({
|
|
7530
|
+
kind: "selected",
|
|
7531
|
+
keys: [value],
|
|
7532
|
+
rows: [project(row)]
|
|
7533
|
+
});
|
|
7534
|
+
}, [
|
|
7535
|
+
wiring.valueField,
|
|
7536
|
+
settle,
|
|
7537
|
+
project
|
|
7538
|
+
]);
|
|
7539
|
+
const onDone = react.useCallback(() => {
|
|
7540
|
+
const keys = activeRef.current?.selected ?? [];
|
|
7541
|
+
const rows = keys.flatMap((key) => {
|
|
7542
|
+
const row = rowsRef.current.get(String(key));
|
|
7543
|
+
return row === void 0 ? [] : [project(row)];
|
|
7544
|
+
});
|
|
7545
|
+
settle({
|
|
7546
|
+
kind: "selected",
|
|
7547
|
+
keys,
|
|
7548
|
+
rows
|
|
7549
|
+
});
|
|
7550
|
+
}, [settle, project]);
|
|
7551
|
+
const onOpenChange = react.useCallback((next) => {
|
|
7552
|
+
if (!next) settle({
|
|
7553
|
+
kind: "cancelled",
|
|
7554
|
+
reason: "dismissed"
|
|
7555
|
+
});
|
|
7556
|
+
}, [settle]);
|
|
7557
|
+
return {
|
|
7558
|
+
open,
|
|
7559
|
+
element: (0, react_jsx_runtime.jsx)(PickerHost, {
|
|
7560
|
+
register,
|
|
7561
|
+
children: active === null || held ? null : (0, react_jsx_runtime.jsxs)(_burojs_react.RecordScopeChain, {
|
|
7562
|
+
frames: active.frames,
|
|
7563
|
+
children: [(0, react_jsx_runtime.jsx)(require_lazy_relation_picker_dialog.LazyRelationPickerDialog, {
|
|
7564
|
+
to: target,
|
|
7565
|
+
open: true,
|
|
7566
|
+
onOpenChange,
|
|
7567
|
+
onSelect: noop,
|
|
7568
|
+
onSelectRow,
|
|
7569
|
+
valueField: wiring.valueField,
|
|
7570
|
+
...selection.fixedFilters === void 0 ? {} : { fixedFilters: selection.fixedFilters },
|
|
7571
|
+
scope,
|
|
7572
|
+
...fieldName === void 0 ? {} : { scopeField: fieldName },
|
|
7573
|
+
...options.create === void 0 ? {} : {
|
|
7574
|
+
create,
|
|
7575
|
+
...options.create.seeds === void 0 ? {} : { createSeeds: options.create.seeds }
|
|
7576
|
+
},
|
|
7577
|
+
fieldName: fieldName ?? target,
|
|
7578
|
+
...options.disabledKeys === void 0 ? {} : { disabledKeys: options.disabledKeys },
|
|
7579
|
+
...options.disabledLabel === void 0 ? {} : { disabledLabel: options.disabledLabel },
|
|
7580
|
+
...multiple ? {
|
|
7581
|
+
multiple: true,
|
|
7582
|
+
selected: active.selected,
|
|
7583
|
+
onToggle: (value, row) => toggle(value, row),
|
|
7584
|
+
onDone
|
|
7585
|
+
} : {}
|
|
7586
|
+
}), wiring.reader]
|
|
7587
|
+
}, active.id)
|
|
7588
|
+
})
|
|
7589
|
+
};
|
|
7590
|
+
}
|
|
7591
|
+
//#endregion
|
|
7592
|
+
//#region src/blocks/link-write-summary.tsx
|
|
7593
|
+
function LinkWriteSummary(props) {
|
|
7594
|
+
const { report, titles, onClose } = props;
|
|
7595
|
+
const testid = props.testid ?? "link-write-summary";
|
|
7596
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
7597
|
+
const caps = (0, _burojs_react.useI18nCaps)();
|
|
7598
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
7599
|
+
const heading = t("field.link.partial", { defaultValue: "Some links were not changed" });
|
|
7600
|
+
return (0, react_jsx_runtime.jsx)(require_dialog.Dialog, {
|
|
7601
|
+
open: true,
|
|
7602
|
+
onOpenChange: (open) => {
|
|
7603
|
+
if (!open) onClose();
|
|
7604
|
+
},
|
|
7605
|
+
children: (0, react_jsx_runtime.jsxs)(require_dialog.DialogContent, {
|
|
7606
|
+
"data-testid": testid,
|
|
7607
|
+
className: "flex max-h-[85vh] flex-col overflow-hidden",
|
|
7608
|
+
children: [
|
|
7609
|
+
(0, react_jsx_runtime.jsxs)(require_dialog.DialogHeader, { children: [(0, react_jsx_runtime.jsx)(require_dialog.DialogTitle, { children: heading }), (0, react_jsx_runtime.jsx)(require_dialog.DialogDescription, {
|
|
7610
|
+
className: "sr-only",
|
|
7611
|
+
children: heading
|
|
7612
|
+
})] }),
|
|
7613
|
+
(0, react_jsx_runtime.jsx)("ul", {
|
|
7614
|
+
className: "flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto overscroll-contain",
|
|
7615
|
+
children: report.failed.map(({ id, error }) => (0, react_jsx_runtime.jsxs)("li", {
|
|
7616
|
+
"data-testid": `${testid}:item:${id}`,
|
|
7617
|
+
className: "text-sm",
|
|
7618
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
7619
|
+
className: "font-medium",
|
|
7620
|
+
children: titles[id] ?? id
|
|
7621
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
7622
|
+
className: "text-destructive",
|
|
7623
|
+
children: `: ${(0, _burojs_react.resolveErrorText)(error, caps)}`
|
|
7624
|
+
})]
|
|
7625
|
+
}, id))
|
|
7626
|
+
}),
|
|
7627
|
+
(0, react_jsx_runtime.jsx)(require_dialog.DialogFooter, { children: (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
7628
|
+
type: "button",
|
|
7629
|
+
onClick: onClose,
|
|
7630
|
+
"data-testid": `${testid}:close`,
|
|
7631
|
+
children: chromeT("actions.close", { defaultValue: "Close" })
|
|
7632
|
+
}) })
|
|
7633
|
+
]
|
|
7634
|
+
})
|
|
7635
|
+
});
|
|
7636
|
+
}
|
|
7637
|
+
//#endregion
|
|
7638
|
+
//#region src/blocks/link-attach.tsx
|
|
7639
|
+
const NO_ISSUES = Object.freeze([]);
|
|
7640
|
+
function useLinkPanelWrites(options) {
|
|
7641
|
+
const { owner, junction, target, link, targetKey, valueField, junctionIdField, displayField, scope, record, ownerKey, placement } = options;
|
|
7642
|
+
const app = (0, _burojs_react.useApp)();
|
|
7643
|
+
const runtime = (0, _burojs_react.useDataRuntime)();
|
|
7644
|
+
const t = (0, _burojs_react.useOptionalT)();
|
|
7645
|
+
const rights = (0, _burojs_react.useLinkRights)(owner, link, {
|
|
7646
|
+
surface: "panel",
|
|
7647
|
+
record,
|
|
7648
|
+
...placement === void 0 ? {} : { placement }
|
|
7649
|
+
});
|
|
7650
|
+
const writer = (0, _burojs_react.useLinkWriter)(owner, link);
|
|
7651
|
+
const linkedKeys = (0, _burojs_react.useLinkedKeys)(owner, link);
|
|
7652
|
+
const reverse = (0, react.useMemo)(() => (0, _burojs_core.reverseLinkOf)((name) => app.registry.get(name)?.fields, owner, link), [
|
|
7653
|
+
app.registry,
|
|
7654
|
+
owner,
|
|
7655
|
+
link
|
|
7656
|
+
]);
|
|
7657
|
+
let liveHides = false;
|
|
7658
|
+
if (reverse !== void 0) try {
|
|
7659
|
+
const { providerId } = runtime.app.resolveDataBinding(target);
|
|
7660
|
+
liveHides = runtime.providers.resolve(providerId).provider.readRelations?.links === true && (0, _burojs_react.linkCapabilitiesOf)(runtime, providerId)?.links?.filter.none !== false;
|
|
7661
|
+
} catch {
|
|
7662
|
+
liveHides = false;
|
|
7663
|
+
}
|
|
7664
|
+
const liveHidesRef = (0, react.useRef)(liveHides);
|
|
7665
|
+
liveHidesRef.current = liveHides;
|
|
7666
|
+
const [frozenHides, setFrozenHides] = (0, react.useState)(null);
|
|
7667
|
+
const hides = frozenHides ?? liveHides;
|
|
7668
|
+
const ownerKeyId = JSON.stringify(ownerKey ?? null);
|
|
7669
|
+
const hidden = (0, react.useMemo)(() => hides && reverse !== void 0 ? [{
|
|
7670
|
+
field: reverse,
|
|
7671
|
+
op: "hasNone",
|
|
7672
|
+
value: [ownerKey]
|
|
7673
|
+
}] : void 0, [
|
|
7674
|
+
hides,
|
|
7675
|
+
reverse,
|
|
7676
|
+
ownerKeyId
|
|
7677
|
+
]);
|
|
7678
|
+
const disabledKeys = (0, react.useCallback)((keys, signal) => linkedKeys(record, keys, signal), [linkedKeys, record]);
|
|
7679
|
+
const disabledLabel = (0, react.useCallback)((count) => t("field.link.alreadyLinked", {
|
|
7680
|
+
count,
|
|
7681
|
+
defaultValue: `${count} already linked`
|
|
7682
|
+
}), [t]);
|
|
7683
|
+
const picker = useRelationPicker({
|
|
7684
|
+
to: target,
|
|
7685
|
+
multiple: true,
|
|
7686
|
+
valueField,
|
|
7687
|
+
scope,
|
|
7688
|
+
...hidden === void 0 ? {
|
|
7689
|
+
disabledKeys,
|
|
7690
|
+
disabledLabel
|
|
7691
|
+
} : { fixedFilters: hidden }
|
|
7692
|
+
});
|
|
7693
|
+
const openPicker = picker.open;
|
|
7694
|
+
const [summary, setSummary] = (0, react.useState)(null);
|
|
7695
|
+
const finish = (0, react.useCallback)((report, titles, done) => {
|
|
7696
|
+
if (report.outcome !== "success") {
|
|
7697
|
+
setSummary({
|
|
7698
|
+
report,
|
|
7699
|
+
titles
|
|
7700
|
+
});
|
|
7701
|
+
return;
|
|
7702
|
+
}
|
|
7703
|
+
const count = report.succeeded.length;
|
|
7704
|
+
if (count === 0) return;
|
|
7705
|
+
sonner.toast.success(t(`field.link.${done}`, {
|
|
7706
|
+
count,
|
|
7707
|
+
defaultValue: `${count} ${count === 1 ? "link" : "links"} ${done}`
|
|
7708
|
+
}));
|
|
7709
|
+
}, [t]);
|
|
7710
|
+
const attaching = (0, react.useRef)(false);
|
|
7711
|
+
const [attachWriting, setAttachWriting] = (0, react.useState)(false);
|
|
7712
|
+
const onAttach = (0, react.useCallback)(() => {
|
|
7713
|
+
if (attaching.current) return;
|
|
7714
|
+
attaching.current = true;
|
|
7715
|
+
(async () => {
|
|
7716
|
+
try {
|
|
7717
|
+
setFrozenHides(liveHidesRef.current);
|
|
7718
|
+
let result;
|
|
7719
|
+
try {
|
|
7720
|
+
result = await openPicker();
|
|
7721
|
+
} finally {
|
|
7722
|
+
setFrozenHides(null);
|
|
7723
|
+
}
|
|
7724
|
+
if (result.kind !== "selected" || result.keys.length === 0) return;
|
|
7725
|
+
const titles = {};
|
|
7726
|
+
for (const row of result.rows) {
|
|
7727
|
+
const key = valueField === "id" ? row.id : row[valueField];
|
|
7728
|
+
const title = row[displayField];
|
|
7729
|
+
if (key !== void 0 && key !== null && title !== void 0 && title !== null) titles[String(key)] = String(title);
|
|
7730
|
+
}
|
|
7731
|
+
setAttachWriting(true);
|
|
7732
|
+
try {
|
|
7733
|
+
finish(await writer.attach(result.keys, record), titles, "attached");
|
|
7734
|
+
} finally {
|
|
7735
|
+
setAttachWriting(false);
|
|
7736
|
+
}
|
|
7737
|
+
} finally {
|
|
7738
|
+
attaching.current = false;
|
|
7739
|
+
}
|
|
7740
|
+
})();
|
|
7741
|
+
}, [
|
|
7742
|
+
displayField,
|
|
7743
|
+
finish,
|
|
7744
|
+
openPicker,
|
|
7745
|
+
record,
|
|
7746
|
+
valueField,
|
|
7747
|
+
writer
|
|
7748
|
+
]);
|
|
7749
|
+
const pending = (0, react.useRef)(null);
|
|
7750
|
+
const [confirming, setConfirming] = (0, react.useState)(null);
|
|
7751
|
+
const detaching = (0, react.useRef)(false);
|
|
7752
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
7753
|
+
const onDetach = (0, react.useCallback)((rows) => new Promise((resolve) => {
|
|
7754
|
+
pending.current?.resolve([]);
|
|
7755
|
+
pending.current = {
|
|
7756
|
+
rows,
|
|
7757
|
+
resolve
|
|
7758
|
+
};
|
|
7759
|
+
setConfirming(rows.length);
|
|
7760
|
+
}), []);
|
|
7761
|
+
(0, react.useEffect)(() => () => {
|
|
7762
|
+
pending.current?.resolve([]);
|
|
7763
|
+
pending.current = null;
|
|
7764
|
+
}, []);
|
|
7765
|
+
const cancel = (0, react.useCallback)(() => {
|
|
7766
|
+
if (detaching.current) return;
|
|
7767
|
+
pending.current?.resolve([]);
|
|
7768
|
+
pending.current = null;
|
|
7769
|
+
setConfirming(null);
|
|
7770
|
+
}, []);
|
|
7771
|
+
const proceed = (0, react.useCallback)(() => {
|
|
7772
|
+
const current = pending.current;
|
|
7773
|
+
if (current === null || detaching.current) return;
|
|
7774
|
+
detaching.current = true;
|
|
7775
|
+
setBusy(true);
|
|
7776
|
+
(async () => {
|
|
7777
|
+
try {
|
|
7778
|
+
const titles = {};
|
|
7779
|
+
for (const row of current.rows) {
|
|
7780
|
+
const id = row[junctionIdField];
|
|
7781
|
+
if (id === void 0 || id === null) continue;
|
|
7782
|
+
const title = row[`${targetKey}.${displayField}`] ?? row[targetKey];
|
|
7783
|
+
if (title !== void 0 && title !== null) titles[String(id)] = String(title);
|
|
7784
|
+
}
|
|
7785
|
+
const report = await writer.detach(current.rows, record);
|
|
7786
|
+
pending.current = null;
|
|
7787
|
+
setConfirming(null);
|
|
7788
|
+
finish(report, titles, "detached");
|
|
7789
|
+
const left = new Set(report.succeeded);
|
|
7790
|
+
current.resolve(current.rows.filter((row) => {
|
|
7791
|
+
const id = row[junctionIdField];
|
|
7792
|
+
return id !== void 0 && id !== null && left.has(String(id));
|
|
7793
|
+
}).map((row) => String(row.id)));
|
|
7794
|
+
} finally {
|
|
7795
|
+
detaching.current = false;
|
|
7796
|
+
setBusy(false);
|
|
7797
|
+
}
|
|
7798
|
+
})();
|
|
7799
|
+
}, [
|
|
7800
|
+
displayField,
|
|
7801
|
+
finish,
|
|
7802
|
+
junctionIdField,
|
|
7803
|
+
record,
|
|
7804
|
+
targetKey,
|
|
7805
|
+
writer
|
|
7806
|
+
]);
|
|
7807
|
+
const detachLabel = t("field.link.detach", { defaultValue: "Detach" });
|
|
7808
|
+
const count = confirming ?? 0;
|
|
7809
|
+
const gate = {
|
|
7810
|
+
resource: junction,
|
|
7811
|
+
open: confirming !== null,
|
|
7812
|
+
busy,
|
|
7813
|
+
header: t("field.link.confirmDetach", {
|
|
7814
|
+
count,
|
|
7815
|
+
defaultValue: `Detach ${count} ${count === 1 ? "link" : "links"}? The linked records themselves are not deleted.`
|
|
7816
|
+
}),
|
|
7817
|
+
blockers: NO_ISSUES,
|
|
7818
|
+
confirmable: NO_ISSUES,
|
|
7819
|
+
proceed,
|
|
7820
|
+
cancel
|
|
7821
|
+
};
|
|
7822
|
+
const attachAllowed = rights.attach.allowed;
|
|
7823
|
+
const detachAllowed = rights.detach.allowed;
|
|
7824
|
+
return {
|
|
7825
|
+
linkEditing: (0, react.useMemo)(() => !attachAllowed && !detachAllowed ? void 0 : {
|
|
7826
|
+
...attachAllowed ? { attach: {
|
|
7827
|
+
onAttach,
|
|
7828
|
+
busy: attachWriting
|
|
7829
|
+
} } : {},
|
|
7830
|
+
...detachAllowed ? { detach: { onDetach } } : {}
|
|
7831
|
+
}, [
|
|
7832
|
+
attachAllowed,
|
|
7833
|
+
attachWriting,
|
|
7834
|
+
detachAllowed,
|
|
7835
|
+
onAttach,
|
|
7836
|
+
onDetach
|
|
7837
|
+
]),
|
|
7838
|
+
element: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7839
|
+
picker.element,
|
|
7840
|
+
(0, react_jsx_runtime.jsx)(require_check_confirm_dialog.CheckConfirmDialog, {
|
|
7841
|
+
state: gate,
|
|
7842
|
+
testid: `link-detach-confirm:${junction}`,
|
|
7843
|
+
title: detachLabel,
|
|
7844
|
+
proceedLabel: detachLabel,
|
|
7845
|
+
tone: "destructive"
|
|
7846
|
+
}),
|
|
7847
|
+
summary === null ? null : (0, react_jsx_runtime.jsx)(LinkWriteSummary, {
|
|
7848
|
+
report: summary.report,
|
|
7849
|
+
titles: summary.titles,
|
|
7850
|
+
onClose: () => setSummary(null),
|
|
7851
|
+
testid: `link-write-summary:${junction}`
|
|
7852
|
+
})
|
|
7853
|
+
] })
|
|
7854
|
+
};
|
|
7855
|
+
}
|
|
7856
|
+
//#endregion
|
|
6985
7857
|
//#region src/quick/peek-filter.ts
|
|
6986
7858
|
function peekFieldDefinition(def, name) {
|
|
6987
7859
|
return (0, _burojs_core.declaredField)(def, name);
|
|
@@ -7005,32 +7877,12 @@ function peekRecord(def, row, idField, capabilityFor, fieldVisible) {
|
|
|
7005
7877
|
return peekRow(def, row, idField, capabilityFor, fieldVisible);
|
|
7006
7878
|
}
|
|
7007
7879
|
//#endregion
|
|
7008
|
-
//#region src/blocks/related-list-unbound.tsx
|
|
7009
|
-
function UnboundRelatedList(props) {
|
|
7010
|
-
const t = (0, _burojs_react.useOptionalT)();
|
|
7011
|
-
return (0, react_jsx_runtime.jsxs)("div", {
|
|
7012
|
-
className: "flex flex-col gap-2",
|
|
7013
|
-
"data-testid": `list-unbound:${props.resource}`,
|
|
7014
|
-
children: [props.title === void 0 ? null : (0, react_jsx_runtime.jsx)("h3", {
|
|
7015
|
-
className: "text-sm font-semibold",
|
|
7016
|
-
children: props.title
|
|
7017
|
-
}), (0, react_jsx_runtime.jsx)("p", {
|
|
7018
|
-
className: "text-sm text-muted-foreground",
|
|
7019
|
-
children: t("table.empty", { defaultValue: "No records" })
|
|
7020
|
-
})]
|
|
7021
|
-
});
|
|
7022
|
-
}
|
|
7023
|
-
function placementScope(scope, owner) {
|
|
7024
|
-
return scope ?? (owner === void 0 ? "session" : "none");
|
|
7025
|
-
}
|
|
7026
|
-
//#endregion
|
|
7027
7880
|
//#region src/blocks/link-panel.tsx
|
|
7028
7881
|
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7029
7882
|
const isResourceHandle = (value) => isRecord(value) && value.kind === "resource";
|
|
7030
|
-
function qualify(ref
|
|
7883
|
+
function qualify(ref) {
|
|
7031
7884
|
try {
|
|
7032
|
-
|
|
7033
|
-
return (0, _burojs_core.resourceKey)((0, _burojs_core.normalizeEntityRef)(isResourceHandle(ref) ? ref.ref : ref, { defaultNamespace: namespace }));
|
|
7885
|
+
return (0, _burojs_core.resourceKey)((0, _burojs_core.normalizeEntityRef)(isResourceHandle(ref) ? ref.ref : ref));
|
|
7034
7886
|
} catch {
|
|
7035
7887
|
return;
|
|
7036
7888
|
}
|
|
@@ -7049,7 +7901,7 @@ function linkField(registry, owner, link) {
|
|
|
7049
7901
|
function linkTarget(registry, owner, link) {
|
|
7050
7902
|
const found = linkField(registry, owner, link);
|
|
7051
7903
|
if (found === void 0 || owner === void 0) return void 0;
|
|
7052
|
-
return qualify(found.field.meta?.to
|
|
7904
|
+
return qualify(found.field.meta?.to);
|
|
7053
7905
|
}
|
|
7054
7906
|
function idFieldOf(def) {
|
|
7055
7907
|
const declared = isRecord(def) && isRecord(def.data) ? def.data.idField : void 0;
|
|
@@ -7065,37 +7917,47 @@ function targetColumns(registry, target, def) {
|
|
|
7065
7917
|
const source = def;
|
|
7066
7918
|
const views = isRecord(def.views) ? def.views : void 0;
|
|
7067
7919
|
const list = views !== void 0 && isRecord(views.list) ? views.list : void 0;
|
|
7068
|
-
return (list !== void 0 && Array.isArray(list.columns) ? list.columns.
|
|
7920
|
+
return (list !== void 0 && Array.isArray(list.columns) ? list.columns.flatMap((entry) => {
|
|
7921
|
+
const name = isRecord(entry) ? entry.field : entry;
|
|
7922
|
+
return typeof name === "string" ? [name] : [];
|
|
7923
|
+
}) : (0, _burojs_core.dtoFields)(source, "list")).filter((name) => {
|
|
7069
7924
|
if (name.includes(".")) return name.split(".").length - 1 <= MAX_TARGET_HOPS && (0, _burojs_react.resolveColumnField)(registry, target, name) !== void 0;
|
|
7070
7925
|
const field = peekFieldDefinition(source, name);
|
|
7071
7926
|
return isRecord(field) && !(0, _burojs_core.isRelationField)(field) && (0, _burojs_core.fieldSensitivity)(field) === void 0;
|
|
7072
7927
|
});
|
|
7073
7928
|
}
|
|
7074
7929
|
function LinkPanel(props) {
|
|
7075
|
-
const { link, owner, own } = props;
|
|
7930
|
+
const { link, owner, own, empty } = props;
|
|
7076
7931
|
const app = (0, _burojs_react.useApp)();
|
|
7077
7932
|
const frame = usePlacementFrame();
|
|
7078
7933
|
const routeScreen = useIsRouteScreen();
|
|
7079
7934
|
const record = (0, _burojs_react.useOptionalRecordFrame)()?.record;
|
|
7935
|
+
const runtime = (0, _burojs_react.useOptionalDataRuntime)();
|
|
7080
7936
|
const storage = (0, react.useMemo)(() => {
|
|
7081
7937
|
const found = linkField(app.registry, owner, link);
|
|
7082
7938
|
if (found === void 0) return void 0;
|
|
7083
7939
|
const { declaration } = found;
|
|
7084
|
-
const junction = qualify(declaration.junction
|
|
7085
|
-
const target = qualify(found.field.meta?.to
|
|
7940
|
+
const junction = qualify(declaration.junction);
|
|
7941
|
+
const target = qualify(found.field.meta?.to);
|
|
7086
7942
|
if (junction === void 0 || target === void 0) return void 0;
|
|
7087
7943
|
const junctionDef = app.registry.get(junction);
|
|
7088
7944
|
if (junctionDef === void 0) return void 0;
|
|
7089
7945
|
const junctionFields = junctionDef.fields;
|
|
7946
|
+
const targetDef = app.registry.get(target);
|
|
7947
|
+
const targetBy = byOf(junctionFields[declaration.targetKey]);
|
|
7948
|
+
const declaredScope = found.field.meta?.scope;
|
|
7090
7949
|
return {
|
|
7091
7950
|
junction,
|
|
7092
7951
|
target,
|
|
7093
7952
|
sourceKey: declaration.sourceKey,
|
|
7094
7953
|
targetKey: declaration.targetKey,
|
|
7095
7954
|
ownerField: byOf(junctionFields[declaration.sourceKey]) ?? idFieldOf(app.registry.get(owner)),
|
|
7096
|
-
targetKeyedBy:
|
|
7955
|
+
targetKeyedBy: targetBy !== void 0,
|
|
7956
|
+
targetValueField: targetBy ?? idFieldOf(targetDef),
|
|
7957
|
+
junctionIdField: idFieldOf(junctionDef),
|
|
7097
7958
|
where: declaration.where,
|
|
7098
|
-
targetDef
|
|
7959
|
+
targetDef,
|
|
7960
|
+
pickerScope: declaredScope === "context" || declaredScope === "session" || declaredScope === "none" ? declaredScope : void 0
|
|
7099
7961
|
};
|
|
7100
7962
|
}, [
|
|
7101
7963
|
app.registry,
|
|
@@ -7107,10 +7969,11 @@ function LinkPanel(props) {
|
|
|
7107
7969
|
const fixedFilters = (0, react.useMemo)(() => {
|
|
7108
7970
|
if (storage === void 0 || ownerKey === null || ownerKey === void 0) return void 0;
|
|
7109
7971
|
const { sourceKey, targetKey } = storage;
|
|
7972
|
+
const placed = (0, _burojs_core_internal.whereToFilter)(own.where ?? [], (field) => `${targetKey}.${field}`);
|
|
7110
7973
|
return [
|
|
7111
7974
|
(0, _burojs_core.whereEntryToFilter)(sourceKey, "eq", ownerKey),
|
|
7112
7975
|
...storage.where.map((entry) => (0, _burojs_core.whereEntryToFilter)(entry.field, entry.op, entry.value)),
|
|
7113
|
-
...
|
|
7976
|
+
...placed === void 0 ? [] : [placed]
|
|
7114
7977
|
];
|
|
7115
7978
|
}, [
|
|
7116
7979
|
storage,
|
|
@@ -7120,7 +7983,12 @@ function LinkPanel(props) {
|
|
|
7120
7983
|
const columnsKey = JSON.stringify([own.columns ?? null, own.linkColumns ?? null]);
|
|
7121
7984
|
const columns = (0, react.useMemo)(() => {
|
|
7122
7985
|
if (storage === void 0) return void 0;
|
|
7123
|
-
|
|
7986
|
+
const shown = own.columns ?? targetColumns(app.registry, storage.target, storage.targetDef);
|
|
7987
|
+
const across = (entry) => typeof entry === "string" ? `${storage.targetKey}.${entry}` : {
|
|
7988
|
+
...entry,
|
|
7989
|
+
field: `${storage.targetKey}.${entry.field}`
|
|
7990
|
+
};
|
|
7991
|
+
return [...shown.map(across), ...own.linkColumns ?? []];
|
|
7124
7992
|
}, [
|
|
7125
7993
|
storage,
|
|
7126
7994
|
columnsKey,
|
|
@@ -7130,31 +7998,76 @@ function LinkPanel(props) {
|
|
|
7130
7998
|
resource: storage.target,
|
|
7131
7999
|
field: storage.targetKey
|
|
7132
8000
|
}, [storage]);
|
|
7133
|
-
const unbound = fixedFilters === void 0 || own.where
|
|
8001
|
+
const unbound = fixedFilters === void 0 || own.where !== void 0 && (0, _burojs_core_internal.hasNullRef)(own.where);
|
|
7134
8002
|
if (storage === void 0 || unbound) return (0, react_jsx_runtime.jsx)(UnboundRelatedList, {
|
|
7135
8003
|
resource: storage?.target ?? "",
|
|
7136
|
-
title: own.title
|
|
8004
|
+
title: own.title,
|
|
8005
|
+
...empty === void 0 ? {} : { empty }
|
|
7137
8006
|
});
|
|
7138
8007
|
const state = frame?.state === "url" && routeScreen && !frame.nested ? { url: frame.key } : "memory";
|
|
7139
|
-
|
|
7140
|
-
|
|
8008
|
+
let providerCounts;
|
|
8009
|
+
if (runtime !== null) try {
|
|
8010
|
+
providerCounts = (0, _burojs_react.linkCapabilitiesOf)(runtime, runtime.app.resolveDataBinding(storage.junction).providerId)?.links?.count;
|
|
8011
|
+
} catch {
|
|
8012
|
+
providerCounts = void 0;
|
|
8013
|
+
}
|
|
8014
|
+
const count = own.count === false ? "off" : own.count ?? (providerCounts === false ? "off" : void 0);
|
|
8015
|
+
const layoutId = frame === null ? void 0 : placementLayoutId({
|
|
8016
|
+
owner,
|
|
8017
|
+
key: frame.key
|
|
8018
|
+
});
|
|
8019
|
+
const surface = {
|
|
7141
8020
|
resource: storage.junction,
|
|
7142
8021
|
variant: "placement",
|
|
7143
8022
|
state,
|
|
7144
8023
|
fixedFilters,
|
|
7145
|
-
...own.pageSize === void 0 ? {} : { pageSize: own.pageSize },
|
|
8024
|
+
...own.initial?.pageSize === void 0 ? {} : { initial: { pageSize: own.initial.pageSize } },
|
|
7146
8025
|
...own.search === void 0 ? {} : { search: `${storage.targetKey}.${own.search}` },
|
|
7147
8026
|
...columns === void 0 ? {} : { columns },
|
|
7148
8027
|
open: rowTarget === void 0 || own.open === "none" ? "none" : "page",
|
|
7149
8028
|
...rowTarget === void 0 ? {} : { rowTarget },
|
|
7150
8029
|
...frame === null ? {} : { placementKey: frame.key },
|
|
8030
|
+
...layoutId === void 0 ? {} : { layoutId },
|
|
7151
8031
|
...own.title === void 0 ? {} : { title: own.title },
|
|
8032
|
+
...empty === void 0 ? {} : { empty },
|
|
7152
8033
|
scope: placementScope(own.scope, owner),
|
|
7153
8034
|
...count === void 0 ? {} : { count },
|
|
7154
8035
|
readOnly: true,
|
|
7155
8036
|
exportable: false
|
|
8037
|
+
};
|
|
8038
|
+
if (runtime === null || record === void 0) return (0, react_jsx_runtime.jsx)(ResourceListSurface, { ...surface });
|
|
8039
|
+
return (0, react_jsx_runtime.jsx)(WritableLinkPanel, {
|
|
8040
|
+
surface,
|
|
8041
|
+
owner,
|
|
8042
|
+
link,
|
|
8043
|
+
storage,
|
|
8044
|
+
record,
|
|
8045
|
+
ownerKey,
|
|
8046
|
+
placement: own.linkActions
|
|
7156
8047
|
});
|
|
7157
8048
|
}
|
|
8049
|
+
function WritableLinkPanel(props) {
|
|
8050
|
+
const { surface, owner, link, storage, record, ownerKey, placement } = props;
|
|
8051
|
+
const displayField = isRecord(storage.targetDef) && typeof storage.targetDef.displayField === "string" ? storage.targetDef.displayField : storage.targetValueField;
|
|
8052
|
+
const { linkEditing, element } = useLinkPanelWrites({
|
|
8053
|
+
owner,
|
|
8054
|
+
junction: storage.junction,
|
|
8055
|
+
target: storage.target,
|
|
8056
|
+
link,
|
|
8057
|
+
targetKey: storage.targetKey,
|
|
8058
|
+
valueField: storage.targetValueField,
|
|
8059
|
+
junctionIdField: storage.junctionIdField,
|
|
8060
|
+
displayField,
|
|
8061
|
+
scope: storage.pickerScope ?? "context",
|
|
8062
|
+
record,
|
|
8063
|
+
ownerKey,
|
|
8064
|
+
placement
|
|
8065
|
+
});
|
|
8066
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(ResourceListSurface, {
|
|
8067
|
+
...surface,
|
|
8068
|
+
...linkEditing === void 0 ? {} : { linkEditing }
|
|
8069
|
+
}), element] });
|
|
8070
|
+
}
|
|
7158
8071
|
//#endregion
|
|
7159
8072
|
//#region src/blocks/route-list-context.ts
|
|
7160
8073
|
const RouteListContext = (0, react.createContext)(null);
|
|
@@ -7163,7 +8076,7 @@ function useRouteList() {
|
|
|
7163
8076
|
}
|
|
7164
8077
|
//#endregion
|
|
7165
8078
|
//#region src/blocks/related-list-view.tsx
|
|
7166
|
-
function RelatedListView({ props }) {
|
|
8079
|
+
function RelatedListView({ props, empty }) {
|
|
7167
8080
|
const own = props;
|
|
7168
8081
|
const route = useRouteList();
|
|
7169
8082
|
const frame = usePlacementFrame();
|
|
@@ -7171,7 +8084,7 @@ function RelatedListView({ props }) {
|
|
|
7171
8084
|
const linked = own.link !== void 0;
|
|
7172
8085
|
const resource = linked ? linkTarget(app.registry, frame?.owner, own.link) ?? "" : (0, _burojs_core.resourceKey)(own.resource);
|
|
7173
8086
|
const whereKey = JSON.stringify(own.where ?? []);
|
|
7174
|
-
const fixedFilters = (0, react.useMemo)(() => own.where === void 0
|
|
8087
|
+
const fixedFilters = (0, react.useMemo)(() => own.where === void 0 || own.where.length === 0 ? void 0 : [(0, _burojs_core_internal.whereToFilter)(own.where)], [whereKey]);
|
|
7175
8088
|
const columnsKey = JSON.stringify(own.columns ?? null);
|
|
7176
8089
|
const columns = (0, react.useMemo)(() => own.columns, [columnsKey]);
|
|
7177
8090
|
const routeScreen = useIsRouteScreen();
|
|
@@ -7183,20 +8096,23 @@ function RelatedListView({ props }) {
|
|
|
7183
8096
|
const ownerDef = frame?.owner === void 0 ? void 0 : app.registry.get(frame.owner);
|
|
7184
8097
|
const granted = ownerDef === void 0 ? "unknown" : (0, _burojs_core.grantedPlacementKeys)(ownerDef);
|
|
7185
8098
|
const trusted = frame !== null && !frame.nested && granted !== "unknown" && !granted.has(frame.key);
|
|
7186
|
-
const onCreate = route === null && !linked && trusted && gate(resource, "create").state === "open" && frame !== null ? () => void quick.create(resource, { defaults: placementSeeds(frame.where ?? [], own.where ?? [], frame.closure ?? {}) }) : void 0;
|
|
8099
|
+
const onCreate = route === null && !linked && trusted && gate(resource, "create").state === "open" && own.create !== false && (own.create === void 0 || (0, _burojs_core_internal.actionWhenHolds)(own.create, frame?.sources ?? {})) && frame !== null ? () => void quick.create(resource, { defaults: placementSeeds(frame.where ?? [], own.where ?? [], frame.closure ?? {}) }) : void 0;
|
|
7187
8100
|
useDeepLinkOpen(frame?.key ?? null, resource, route === null && !linked && frame !== null && !frame.nested && routeScreen && (own.open ?? "quick") === "quick");
|
|
7188
|
-
const unbound = own.where
|
|
8101
|
+
const unbound = own.where !== void 0 && (0, _burojs_core_internal.hasNullRef)(own.where);
|
|
7189
8102
|
if (linked) return frame?.owner === void 0 ? (0, react_jsx_runtime.jsx)(UnboundRelatedList, {
|
|
7190
8103
|
resource,
|
|
7191
|
-
title: own.title
|
|
8104
|
+
title: own.title,
|
|
8105
|
+
...empty === void 0 ? {} : { empty }
|
|
7192
8106
|
}) : (0, react_jsx_runtime.jsx)(LinkPanel, {
|
|
7193
8107
|
link: own.link,
|
|
7194
8108
|
owner: frame.owner,
|
|
7195
|
-
own
|
|
8109
|
+
own,
|
|
8110
|
+
...empty === void 0 ? {} : { empty }
|
|
7196
8111
|
});
|
|
7197
8112
|
if (route !== null) return (0, react_jsx_runtime.jsx)(ResourceListSurface, {
|
|
7198
8113
|
resource,
|
|
7199
8114
|
variant: "route",
|
|
8115
|
+
layoutId: "route",
|
|
7200
8116
|
...route.meta === void 0 ? {} : { meta: route.meta },
|
|
7201
8117
|
...route.renderCell === void 0 ? {} : { renderCell: route.renderCell },
|
|
7202
8118
|
...route.emptyState === void 0 ? {} : { emptyState: route.emptyState }
|
|
@@ -7209,24 +8125,28 @@ function RelatedListView({ props }) {
|
|
|
7209
8125
|
});
|
|
7210
8126
|
if (unbound) return (0, react_jsx_runtime.jsx)(UnboundRelatedList, {
|
|
7211
8127
|
resource,
|
|
7212
|
-
title: own.title
|
|
8128
|
+
title: own.title,
|
|
8129
|
+
...empty === void 0 ? {} : { empty }
|
|
7213
8130
|
});
|
|
7214
8131
|
const state = frame?.state === "url" && routeScreen && !frame.nested ? { url: frame.key } : "memory";
|
|
7215
8132
|
const scope = placementScope(own.scope, frame?.owner);
|
|
7216
8133
|
const count = own.count === false ? "off" : own.count;
|
|
8134
|
+
const layoutId = placementLayoutId(frame);
|
|
7217
8135
|
return (0, react_jsx_runtime.jsx)(ResourceListSurface, {
|
|
7218
8136
|
resource,
|
|
7219
8137
|
variant: "placement",
|
|
7220
8138
|
state,
|
|
7221
8139
|
...fixedFilters === void 0 ? {} : { fixedFilters },
|
|
7222
|
-
...own.
|
|
8140
|
+
...own.initial === void 0 ? {} : { initial: own.initial },
|
|
7223
8141
|
...own.search === void 0 ? {} : { search: own.search },
|
|
7224
8142
|
...columns === void 0 ? {} : { columns },
|
|
7225
8143
|
open: own.open ?? "quick",
|
|
7226
8144
|
...own.view === void 0 ? {} : { view: own.view },
|
|
7227
8145
|
...isItemHandle(own.item) ? { item: own.item } : {},
|
|
7228
8146
|
...frame === null ? {} : { placementKey: frame.key },
|
|
8147
|
+
...layoutId === void 0 ? {} : { layoutId },
|
|
7229
8148
|
...own.title === void 0 ? {} : { title: own.title },
|
|
8149
|
+
...empty === void 0 ? {} : { empty },
|
|
7230
8150
|
scope,
|
|
7231
8151
|
...count === void 0 ? {} : { count },
|
|
7232
8152
|
...onCreate === void 0 ? {} : { onCreate }
|
|
@@ -7261,7 +8181,7 @@ function Missing({ text }) {
|
|
|
7261
8181
|
children: text ?? t("table.empty", { defaultValue: "No records" })
|
|
7262
8182
|
});
|
|
7263
8183
|
}
|
|
7264
|
-
function RelatedRecordView({ props }) {
|
|
8184
|
+
function RelatedRecordView({ props, empty }) {
|
|
7265
8185
|
const own = props;
|
|
7266
8186
|
const app = (0, _burojs_react.useApp)();
|
|
7267
8187
|
const resource = (0, _burojs_core.resourceKey)(own.resource);
|
|
@@ -7277,7 +8197,7 @@ function RelatedRecordView({ props }) {
|
|
|
7277
8197
|
});
|
|
7278
8198
|
const result = query.data;
|
|
7279
8199
|
const raw = result?.data;
|
|
7280
|
-
const dtoRow = (0, react.useMemo)(() => raw !== null && typeof raw === "object" && projection !== void 0 ? (0, _burojs_core.projectDto)(
|
|
8200
|
+
const dtoRow = (0, react.useMemo)(() => raw !== null && typeof raw === "object" && projection !== void 0 ? (0, _burojs_react.deriveRecord)(raw, (record) => (0, _burojs_core.projectDto)(record, projection)) : void 0, [raw, projection]);
|
|
7281
8201
|
const access = (0, _burojs_react.useFieldAccess)(resource, "record", dtoRow);
|
|
7282
8202
|
const projected = (0, _burojs_react.useProjectedRecord)(resource, dtoRow, { placeholder: query.isPlaceholderData === true });
|
|
7283
8203
|
const fieldsKey = JSON.stringify(own.fields ?? null);
|
|
@@ -7295,15 +8215,15 @@ function RelatedRecordView({ props }) {
|
|
|
7295
8215
|
capabilityFor,
|
|
7296
8216
|
access
|
|
7297
8217
|
]);
|
|
7298
|
-
if (id === null) return (0, react_jsx_runtime.jsx)(Missing, { text: own.missing });
|
|
8218
|
+
if (id === null) return (0, react_jsx_runtime.jsx)(Missing, { text: own.missing ?? empty });
|
|
7299
8219
|
if (result === void 0) {
|
|
7300
|
-
if (query.error != null) return (0, react_jsx_runtime.jsx)(Missing, { text: own.missing });
|
|
8220
|
+
if (query.error != null) return (0, react_jsx_runtime.jsx)(Missing, { text: own.missing ?? empty });
|
|
7301
8221
|
return (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, {
|
|
7302
8222
|
"data-buro-skeleton": "",
|
|
7303
8223
|
className: "h-9 w-full"
|
|
7304
8224
|
});
|
|
7305
8225
|
}
|
|
7306
|
-
if (dtoRow === void 0) return (0, react_jsx_runtime.jsx)(Missing, { text: own.missing });
|
|
8226
|
+
if (dtoRow === void 0) return (0, react_jsx_runtime.jsx)(Missing, { text: own.missing ?? empty });
|
|
7307
8227
|
if (projected.status === "pending" || projected.value === null) return (0, react_jsx_runtime.jsx)(require_skeleton.Skeleton, {
|
|
7308
8228
|
"data-buro-skeleton": "",
|
|
7309
8229
|
className: "h-9 w-full"
|
|
@@ -7318,10 +8238,7 @@ function RelatedRecordView({ props }) {
|
|
|
7318
8238
|
children: own.title
|
|
7319
8239
|
}), own.toolbar === "item" ? (0, react_jsx_runtime.jsx)(ActionOverflow, {
|
|
7320
8240
|
resource,
|
|
7321
|
-
record: {
|
|
7322
|
-
...dtoRow,
|
|
7323
|
-
id
|
|
7324
|
-
},
|
|
8241
|
+
record: (0, _burojs_react.withRecordKeys)(dtoRow, { id }),
|
|
7325
8242
|
surface: "show"
|
|
7326
8243
|
}) : null]
|
|
7327
8244
|
}), (0, react_jsx_runtime.jsx)("dl", {
|
|
@@ -7336,13 +8253,21 @@ function RelatedRecordView({ props }) {
|
|
|
7336
8253
|
children: (0, _burojs_core.resolveFieldLabel)(caps, name, (0, _burojs_core.declaredText)("field", field, "label"))
|
|
7337
8254
|
}), (0, react_jsx_runtime.jsx)("dd", {
|
|
7338
8255
|
className: "min-w-0 break-words text-sm",
|
|
7339
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
8256
|
+
children: (0, react_jsx_runtime.jsx)(FieldValueFrame, {
|
|
8257
|
+
field: {
|
|
8258
|
+
...field ?? {},
|
|
8259
|
+
name
|
|
8260
|
+
},
|
|
7343
8261
|
value,
|
|
7344
|
-
|
|
7345
|
-
|
|
8262
|
+
surface: "display",
|
|
8263
|
+
children: (0, react_jsx_runtime.jsx)(require_filter_builder.ResolvedFieldDisplay, {
|
|
8264
|
+
resource: own.resource,
|
|
8265
|
+
name,
|
|
8266
|
+
field,
|
|
8267
|
+
value,
|
|
8268
|
+
record: row,
|
|
8269
|
+
fallback: toDisplayText(value).text
|
|
8270
|
+
})
|
|
7346
8271
|
})
|
|
7347
8272
|
})]
|
|
7348
8273
|
}, name);
|
|
@@ -7413,28 +8338,39 @@ function Chrome({ node, size, state, children }) {
|
|
|
7413
8338
|
});
|
|
7414
8339
|
}
|
|
7415
8340
|
function isAuthError(error) {
|
|
7416
|
-
return (0, _burojs_core.
|
|
8341
|
+
return (0, _burojs_core.normalizeDataError)(error).kind === "auth";
|
|
7417
8342
|
}
|
|
7418
|
-
|
|
8343
|
+
const PLACE_NODE_MESSAGES = {
|
|
8344
|
+
failed: "This section could not be loaded.",
|
|
8345
|
+
sessionExpired: "Your session has expired. Sign in again to continue.",
|
|
8346
|
+
notImplemented: "This section is not available."
|
|
8347
|
+
};
|
|
8348
|
+
function FailedPlacement({ node, size, message, retry, error }) {
|
|
7419
8349
|
const t = (0, _burojs_react.useOptionalT)();
|
|
8350
|
+
const chromeT = (0, _burojs_react.useChromeT)();
|
|
8351
|
+
const fallback = {
|
|
8352
|
+
key: `block.${message}`,
|
|
8353
|
+
default: PLACE_NODE_MESSAGES[message]
|
|
8354
|
+
};
|
|
7420
8355
|
return (0, react_jsx_runtime.jsx)(Chrome, {
|
|
7421
8356
|
node,
|
|
7422
8357
|
size,
|
|
7423
8358
|
state: "failed",
|
|
7424
|
-
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
8359
|
+
children: message === "notImplemented" ? (0, react_jsx_runtime.jsxs)("div", {
|
|
7425
8360
|
role: "alert",
|
|
7426
8361
|
className: "flex flex-wrap items-center gap-2 rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground",
|
|
7427
|
-
children: [(0, react_jsx_runtime.jsx)("span", { children: t(
|
|
7428
|
-
failed: "This section could not be loaded.",
|
|
7429
|
-
sessionExpired: "Your session has expired. Sign in again to continue.",
|
|
7430
|
-
notImplemented: "This section is not available."
|
|
7431
|
-
}[message] }) }), retry === void 0 ? null : (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
8362
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: t(fallback.key, { defaultValue: fallback.default }) }), retry === void 0 ? null : (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
7432
8363
|
type: "button",
|
|
7433
8364
|
variant: "outline",
|
|
7434
8365
|
size: "sm",
|
|
7435
8366
|
onClick: retry,
|
|
7436
|
-
children:
|
|
8367
|
+
children: chromeT("actions.retry", { defaultValue: "Retry" })
|
|
7437
8368
|
})]
|
|
8369
|
+
}) : (0, react_jsx_runtime.jsx)(require_relation_create.LoadError, {
|
|
8370
|
+
surface: "block",
|
|
8371
|
+
error,
|
|
8372
|
+
...retry === void 0 ? {} : { retry },
|
|
8373
|
+
fallback
|
|
7438
8374
|
})
|
|
7439
8375
|
});
|
|
7440
8376
|
}
|
|
@@ -7514,7 +8450,8 @@ function ReadyPlacement({ node, size, placement, implementation }) {
|
|
|
7514
8450
|
nested,
|
|
7515
8451
|
...Array.isArray(declaredWhere) ? { where: declaredWhere } : {},
|
|
7516
8452
|
closure: compiled.sourceClosure,
|
|
7517
|
-
...owner === void 0 ? {} : { owner }
|
|
8453
|
+
...owner === void 0 ? {} : { owner },
|
|
8454
|
+
sources: controller.sources
|
|
7518
8455
|
}), [
|
|
7519
8456
|
node.key,
|
|
7520
8457
|
node.id,
|
|
@@ -7522,7 +8459,8 @@ function ReadyPlacement({ node, size, placement, implementation }) {
|
|
|
7522
8459
|
nested,
|
|
7523
8460
|
declaredWhere,
|
|
7524
8461
|
compiled.sourceClosure,
|
|
7525
|
-
owner
|
|
8462
|
+
owner,
|
|
8463
|
+
controller.sources
|
|
7526
8464
|
]);
|
|
7527
8465
|
return (0, react_jsx_runtime.jsx)(PlacementBoundary, {
|
|
7528
8466
|
node,
|
|
@@ -7580,6 +8518,7 @@ function PlaceNode({ node }) {
|
|
|
7580
8518
|
node,
|
|
7581
8519
|
size,
|
|
7582
8520
|
message: isAuthError(placement.error) ? "sessionExpired" : "failed",
|
|
8521
|
+
error: placement.error,
|
|
7583
8522
|
...placement.retry === void 0 ? {} : { retry: placement.retry }
|
|
7584
8523
|
});
|
|
7585
8524
|
if (implementation === void 0) return (0, react_jsx_runtime.jsx)(FailedPlacement, {
|
|
@@ -7691,6 +8630,12 @@ Object.defineProperty(exports, "EnumBadge", {
|
|
|
7691
8630
|
return EnumBadge;
|
|
7692
8631
|
}
|
|
7693
8632
|
});
|
|
8633
|
+
Object.defineProperty(exports, "EnumSettlingRow", {
|
|
8634
|
+
enumerable: true,
|
|
8635
|
+
get: function() {
|
|
8636
|
+
return EnumSettlingRow;
|
|
8637
|
+
}
|
|
8638
|
+
});
|
|
7694
8639
|
Object.defineProperty(exports, "ExportButton", {
|
|
7695
8640
|
enumerable: true,
|
|
7696
8641
|
get: function() {
|
|
@@ -7715,6 +8660,12 @@ Object.defineProperty(exports, "FieldDisplay", {
|
|
|
7715
8660
|
return FieldDisplay;
|
|
7716
8661
|
}
|
|
7717
8662
|
});
|
|
8663
|
+
Object.defineProperty(exports, "FieldValueFrame", {
|
|
8664
|
+
enumerable: true,
|
|
8665
|
+
get: function() {
|
|
8666
|
+
return FieldValueFrame;
|
|
8667
|
+
}
|
|
8668
|
+
});
|
|
7718
8669
|
Object.defineProperty(exports, "FilterRegion", {
|
|
7719
8670
|
enumerable: true,
|
|
7720
8671
|
get: function() {
|
|
@@ -7727,6 +8678,12 @@ Object.defineProperty(exports, "FormActions", {
|
|
|
7727
8678
|
return FormActions;
|
|
7728
8679
|
}
|
|
7729
8680
|
});
|
|
8681
|
+
Object.defineProperty(exports, "FormControlProvider", {
|
|
8682
|
+
enumerable: true,
|
|
8683
|
+
get: function() {
|
|
8684
|
+
return FormControlProvider;
|
|
8685
|
+
}
|
|
8686
|
+
});
|
|
7730
8687
|
Object.defineProperty(exports, "FrameChromeContext", {
|
|
7731
8688
|
enumerable: true,
|
|
7732
8689
|
get: function() {
|
|
@@ -7847,10 +8804,10 @@ Object.defineProperty(exports, "RelatedItem", {
|
|
|
7847
8804
|
return RelatedItem;
|
|
7848
8805
|
}
|
|
7849
8806
|
});
|
|
7850
|
-
Object.defineProperty(exports, "
|
|
8807
|
+
Object.defineProperty(exports, "RelatedTimelineSkeleton", {
|
|
7851
8808
|
enumerable: true,
|
|
7852
8809
|
get: function() {
|
|
7853
|
-
return
|
|
8810
|
+
return RelatedTimelineSkeleton;
|
|
7854
8811
|
}
|
|
7855
8812
|
});
|
|
7856
8813
|
Object.defineProperty(exports, "ResourceList", {
|
|
@@ -7961,24 +8918,6 @@ Object.defineProperty(exports, "isBuiltinRecordView", {
|
|
|
7961
8918
|
return isBuiltinRecordView;
|
|
7962
8919
|
}
|
|
7963
8920
|
});
|
|
7964
|
-
Object.defineProperty(exports, "isShowAvailable", {
|
|
7965
|
-
enumerable: true,
|
|
7966
|
-
get: function() {
|
|
7967
|
-
return isShowAvailable;
|
|
7968
|
-
}
|
|
7969
|
-
});
|
|
7970
|
-
Object.defineProperty(exports, "listTarget", {
|
|
7971
|
-
enumerable: true,
|
|
7972
|
-
get: function() {
|
|
7973
|
-
return listTarget;
|
|
7974
|
-
}
|
|
7975
|
-
});
|
|
7976
|
-
Object.defineProperty(exports, "lowerLegacyField", {
|
|
7977
|
-
enumerable: true,
|
|
7978
|
-
get: function() {
|
|
7979
|
-
return lowerLegacyField;
|
|
7980
|
-
}
|
|
7981
|
-
});
|
|
7982
8921
|
Object.defineProperty(exports, "peekFieldDefinition", {
|
|
7983
8922
|
enumerable: true,
|
|
7984
8923
|
get: function() {
|
|
@@ -8003,22 +8942,16 @@ Object.defineProperty(exports, "peekRow", {
|
|
|
8003
8942
|
return peekRow;
|
|
8004
8943
|
}
|
|
8005
8944
|
});
|
|
8006
|
-
Object.defineProperty(exports, "
|
|
8007
|
-
enumerable: true,
|
|
8008
|
-
get: function() {
|
|
8009
|
-
return recordReturnTarget;
|
|
8010
|
-
}
|
|
8011
|
-
});
|
|
8012
|
-
Object.defineProperty(exports, "recordRouteAvailable", {
|
|
8945
|
+
Object.defineProperty(exports, "resolveFrameView", {
|
|
8013
8946
|
enumerable: true,
|
|
8014
8947
|
get: function() {
|
|
8015
|
-
return
|
|
8948
|
+
return resolveFrameView;
|
|
8016
8949
|
}
|
|
8017
8950
|
});
|
|
8018
|
-
Object.defineProperty(exports, "
|
|
8951
|
+
Object.defineProperty(exports, "resolveResourceTitle", {
|
|
8019
8952
|
enumerable: true,
|
|
8020
8953
|
get: function() {
|
|
8021
|
-
return
|
|
8954
|
+
return resolveResourceTitle;
|
|
8022
8955
|
}
|
|
8023
8956
|
});
|
|
8024
8957
|
Object.defineProperty(exports, "resolveUpdater", {
|
|
@@ -8045,12 +8978,6 @@ Object.defineProperty(exports, "shadcnFrameViews", {
|
|
|
8045
8978
|
return shadcnFrameViews;
|
|
8046
8979
|
}
|
|
8047
8980
|
});
|
|
8048
|
-
Object.defineProperty(exports, "showTarget", {
|
|
8049
|
-
enumerable: true,
|
|
8050
|
-
get: function() {
|
|
8051
|
-
return showTarget;
|
|
8052
|
-
}
|
|
8053
|
-
});
|
|
8054
8981
|
Object.defineProperty(exports, "tanStackSortingToBuro", {
|
|
8055
8982
|
enumerable: true,
|
|
8056
8983
|
get: function() {
|
|
@@ -8069,6 +8996,12 @@ Object.defineProperty(exports, "typography", {
|
|
|
8069
8996
|
return typography;
|
|
8070
8997
|
}
|
|
8071
8998
|
});
|
|
8999
|
+
Object.defineProperty(exports, "unknownEnumValueLabel", {
|
|
9000
|
+
enumerable: true,
|
|
9001
|
+
get: function() {
|
|
9002
|
+
return unknownEnumValueLabel;
|
|
9003
|
+
}
|
|
9004
|
+
});
|
|
8072
9005
|
Object.defineProperty(exports, "useBuroDataTable", {
|
|
8073
9006
|
enumerable: true,
|
|
8074
9007
|
get: function() {
|
|
@@ -8087,6 +9020,18 @@ Object.defineProperty(exports, "useExportRunWatcher", {
|
|
|
8087
9020
|
return useExportRunWatcher;
|
|
8088
9021
|
}
|
|
8089
9022
|
});
|
|
9023
|
+
Object.defineProperty(exports, "useFormControl", {
|
|
9024
|
+
enumerable: true,
|
|
9025
|
+
get: function() {
|
|
9026
|
+
return useFormControl;
|
|
9027
|
+
}
|
|
9028
|
+
});
|
|
9029
|
+
Object.defineProperty(exports, "useFormControlOf", {
|
|
9030
|
+
enumerable: true,
|
|
9031
|
+
get: function() {
|
|
9032
|
+
return useFormControlOf;
|
|
9033
|
+
}
|
|
9034
|
+
});
|
|
8090
9035
|
Object.defineProperty(exports, "useFrameChrome", {
|
|
8091
9036
|
enumerable: true,
|
|
8092
9037
|
get: function() {
|
|
@@ -8111,6 +9056,12 @@ Object.defineProperty(exports, "usePaletteState", {
|
|
|
8111
9056
|
return usePaletteState;
|
|
8112
9057
|
}
|
|
8113
9058
|
});
|
|
9059
|
+
Object.defineProperty(exports, "useRelationPicker", {
|
|
9060
|
+
enumerable: true,
|
|
9061
|
+
get: function() {
|
|
9062
|
+
return useRelationPicker;
|
|
9063
|
+
}
|
|
9064
|
+
});
|
|
8114
9065
|
Object.defineProperty(exports, "useShell", {
|
|
8115
9066
|
enumerable: true,
|
|
8116
9067
|
get: function() {
|
|
@@ -8136,4 +9087,4 @@ Object.defineProperty(exports, "viewOf", {
|
|
|
8136
9087
|
}
|
|
8137
9088
|
});
|
|
8138
9089
|
|
|
8139
|
-
//# sourceMappingURL=place-node-
|
|
9090
|
+
//# sourceMappingURL=place-node-Bhl8B3fF.cjs.map
|