@object-ui/plugin-tree 17.6.0 → 18.0.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/CHANGELOG.md +2628 -0
- package/README.md +153 -20
- package/dist/ObjectTree.d.ts +45 -3
- package/dist/ObjectTree.d.ts.map +1 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +293 -182
- package/dist/index.umd.cjs +1 -1
- package/package.json +16 -11
package/dist/index.js
CHANGED
|
@@ -1,49 +1,46 @@
|
|
|
1
1
|
import { useEffect as e, useMemo as t, useState as n } from "react";
|
|
2
|
-
import { ComponentRegistry as r,
|
|
3
|
-
import { useNavigationOverlay as
|
|
4
|
-
import { NavigationOverlay as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { ComponentRegistry as r, ValueDataSource as i, applyNonGridRowCeiling as a, buildExpandFields as o, columnIdentity as s, getRecordDisplayName as c, humanizeLabel as l, isDeadlineSettled as ee, isExpandableFieldType as u, nonGridRowCeilingQuery as d, resolveRecordSourceConfig as te, resolveRecordSourceObjectName as f } from "@object-ui/core";
|
|
3
|
+
import { NonGridRowCeilingNote as p, useDataInvalidation as ne, useFilterScope as re, useNavigationOverlay as ie, usePredicateScope as m, useResolvedFilter as ae, useSafeFieldLabel as oe, useSchemaContext as h, useSettledSchema as se } from "@object-ui/react";
|
|
4
|
+
import { NavigationOverlay as ce, RefreshIndicator as le, cn as g, legacyRecordDrawerWidthKey as ue, recordOverlayWidthStorageKey as de, useOverlayAnchor as fe } from "@object-ui/components";
|
|
5
|
+
import { RECORD_OVERLAY_DEFAULT_WIDTH as pe, RecordDetailPanel as _ } from "@object-ui/plugin-detail";
|
|
6
|
+
import { createSafeTranslation as v } from "@object-ui/i18n";
|
|
7
|
+
import { getCellRenderer as y, resolveCellRendererType as b } from "@object-ui/fields";
|
|
8
|
+
import { usePermissions as me } from "@object-ui/permissions";
|
|
9
|
+
import { ChevronDown as he, ChevronRight as ge } from "lucide-react";
|
|
10
|
+
import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
8
11
|
//#region src/ObjectTree.tsx
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
provider: "object",
|
|
16
|
-
object: e.objectName
|
|
17
|
-
} : null;
|
|
12
|
+
var w = v({
|
|
13
|
+
"detail.recordDetail": "Record Detail",
|
|
14
|
+
"grid.refreshing": "Refreshing…"
|
|
15
|
+
}, "detail.recordDetail"), _e = [];
|
|
16
|
+
function T(e) {
|
|
17
|
+
return s(e) || (e && typeof e == "object" ? e.key : void 0) || void 0;
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
function b(e) {
|
|
23
|
-
let t = e.tree || e.filter?.tree || {}, n = Array.isArray(e.fields) ? e.fields : Array.isArray(t.fields) ? t.fields : [];
|
|
19
|
+
function ve(e) {
|
|
20
|
+
let t = e.tree || {}, n = Array.isArray(e.fields) ? e.fields : Array.isArray(t.fields) ? t.fields : [];
|
|
24
21
|
return {
|
|
25
|
-
parentField:
|
|
26
|
-
labelField:
|
|
27
|
-
fields: n.map(
|
|
22
|
+
parentField: T(e.parentField ?? t.parentField),
|
|
23
|
+
labelField: T(e.labelField ?? t.labelField) ?? "name",
|
|
24
|
+
fields: n.map(T).filter((e) => !!e),
|
|
28
25
|
defaultExpandedDepth: e.defaultExpandedDepth ?? t.defaultExpandedDepth
|
|
29
26
|
};
|
|
30
27
|
}
|
|
31
|
-
function
|
|
28
|
+
function ye(e, t) {
|
|
32
29
|
let n = e?.fields;
|
|
33
30
|
if (!n || typeof n != "object") return;
|
|
34
31
|
let r;
|
|
35
32
|
for (let [e, i] of Object.entries(n)) {
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
let n = i?.reference;
|
|
34
|
+
if (i?.type === "tree" && (n === void 0 || t && n === t)) return e;
|
|
38
35
|
!r && (i?.type === "lookup" || i?.type === "master_detail") && n && t && n === t && (r = e);
|
|
39
36
|
}
|
|
40
37
|
return r;
|
|
41
38
|
}
|
|
42
|
-
function
|
|
39
|
+
function E(e) {
|
|
43
40
|
let t = e?.id ?? e?._id;
|
|
44
41
|
return t == null ? void 0 : String(t);
|
|
45
42
|
}
|
|
46
|
-
function
|
|
43
|
+
function D(e, t) {
|
|
47
44
|
if (!t) return;
|
|
48
45
|
let n = e?.[t];
|
|
49
46
|
if (n != null) {
|
|
@@ -54,10 +51,10 @@ function C(e, t) {
|
|
|
54
51
|
return String(n);
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
|
-
function
|
|
54
|
+
function be(e, t) {
|
|
58
55
|
let n = /* @__PURE__ */ new Map(), r = [];
|
|
59
56
|
for (let t of e) {
|
|
60
|
-
let e =
|
|
57
|
+
let e = E(t);
|
|
61
58
|
e != null && (n.set(e, {
|
|
62
59
|
id: e,
|
|
63
60
|
record: t,
|
|
@@ -67,7 +64,7 @@ function w(e, t) {
|
|
|
67
64
|
}
|
|
68
65
|
let i = [];
|
|
69
66
|
for (let e of r) {
|
|
70
|
-
let r = n.get(e), a =
|
|
67
|
+
let r = n.get(e), a = D(r.record, t), o = a == null ? void 0 : n.get(a);
|
|
71
68
|
o && o !== r ? o.children.push(r) : i.push(r);
|
|
72
69
|
}
|
|
73
70
|
let a = (e, t) => {
|
|
@@ -75,197 +72,311 @@ function w(e, t) {
|
|
|
75
72
|
};
|
|
76
73
|
return a(i, 0), i;
|
|
77
74
|
}
|
|
78
|
-
function
|
|
75
|
+
function xe(e, t) {
|
|
79
76
|
let n = [], r = (e) => {
|
|
80
77
|
for (let i of e) n.push(i), i.children.length > 0 && t.has(i.id) && r(i.children);
|
|
81
78
|
};
|
|
82
79
|
return r(e), n;
|
|
83
80
|
}
|
|
84
|
-
function
|
|
81
|
+
function O(e, t) {
|
|
85
82
|
let n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
86
83
|
for (let i of e) i.children.length !== 0 && (t == null || i.depth < t) && (n.add(i.id), r(i.children));
|
|
87
84
|
};
|
|
88
85
|
return r(e), n;
|
|
89
86
|
}
|
|
90
|
-
function
|
|
91
|
-
|
|
87
|
+
function Se(e, t, n) {
|
|
88
|
+
let r = O(e, t);
|
|
89
|
+
if (n.size === 0) return r;
|
|
90
|
+
let i = (e) => {
|
|
91
|
+
for (let t of e) {
|
|
92
|
+
let e = n.get(t.id);
|
|
93
|
+
e === !0 ? r.add(t.id) : e === !1 && r.delete(t.id), i(t.children);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
return i(e), r;
|
|
92
97
|
}
|
|
93
|
-
|
|
94
|
-
let
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
function k(e, t, n = "") {
|
|
99
|
+
let r = t.fieldDef, i = typeof r?.type == "string" ? r.type : "";
|
|
100
|
+
if (!i) return A(e, t) || n;
|
|
101
|
+
let a = b({
|
|
102
|
+
type: i,
|
|
103
|
+
format: r.format
|
|
104
|
+
}), o = y(a), s = Array.isArray(r.options) ? t.objectName ? t.translateOptions(t.objectName, t.fieldName, r.options) : r.options : void 0, c = {
|
|
105
|
+
...r,
|
|
106
|
+
name: t.fieldName,
|
|
107
|
+
type: a,
|
|
108
|
+
label: t.columnLabel,
|
|
109
|
+
...s ? { options: s } : {}
|
|
110
|
+
};
|
|
111
|
+
return /* @__PURE__ */ S(o, {
|
|
112
|
+
value: e,
|
|
113
|
+
field: c,
|
|
114
|
+
deadlineSettled: t.deadlineSettled
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function A(e, t) {
|
|
118
|
+
if (e == null) return "";
|
|
119
|
+
let n = Array.isArray(t?.fieldDef?.options) ? t.fieldDef.options : null;
|
|
120
|
+
if (n && n.length > 0) {
|
|
121
|
+
let r = t.objectName ? t.translateOptions(t.objectName, t.fieldName, n) : n, i = (e) => {
|
|
122
|
+
let t = r.find((t) => t?.value === e);
|
|
123
|
+
if (t) return String(t.label ?? e);
|
|
124
|
+
let n = String(e).toLowerCase(), i = r.find((e) => String(e?.value).toLowerCase() === n);
|
|
125
|
+
return i ? String(i.label ?? e) : l(String(e));
|
|
109
126
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
]),
|
|
127
|
+
return Array.isArray(e) ? e.filter((e) => e != null).map(i).join(", ") : i(e);
|
|
128
|
+
}
|
|
129
|
+
return typeof e == "object" && u(t?.fieldDef) ? c(void 0, e) : String(typeof e == "object" ? e.name ?? e.label ?? e.id ?? e._id ?? "" : e);
|
|
130
|
+
}
|
|
131
|
+
var j = ({ schema: r, dataSource: s, className: c, onRowClick: l, ...u }) => {
|
|
132
|
+
let [h, v] = n(null), [y, b] = n(null), [T, E] = n(!0), [D, O] = n(null), j = t(() => te(r, "view-data"), [r]), M = f(r, j) ?? "", { ready: N, def: P } = se(M, s), F = j?.provider, I = j?.provider === "object" ? j.object : void 0, L = j?.provider === "value" ? j.items : void 0, R = me(), Ce = re(), z = ae(r.filter, Ce), we = ne(s ? I : void 0);
|
|
133
|
+
e(() => {
|
|
116
134
|
let e = !1;
|
|
117
135
|
return (async () => {
|
|
118
136
|
try {
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
137
|
+
if (E(!0), O(null), F === "object" && s && typeof s.find == "function") {
|
|
138
|
+
if (!N) return;
|
|
139
|
+
let t = o(P?.fields), n = R?.isLoaded ? t.filter((e) => R.checkField(I, e, "read")) : t, r = await s.find(I, {
|
|
140
|
+
$filter: z,
|
|
141
|
+
...d(),
|
|
142
|
+
...n.length > 0 ? { $expand: n } : {}
|
|
143
|
+
}), i = a(r);
|
|
144
|
+
e || (v({
|
|
145
|
+
provider: F,
|
|
146
|
+
object: I,
|
|
147
|
+
rows: i.rows
|
|
148
|
+
}), b(i), E(!1));
|
|
125
149
|
return;
|
|
126
150
|
}
|
|
127
|
-
let t =
|
|
151
|
+
let t = u.data;
|
|
128
152
|
if (Array.isArray(t)) {
|
|
129
|
-
e || (
|
|
153
|
+
e || (v({
|
|
154
|
+
provider: F,
|
|
155
|
+
object: I,
|
|
156
|
+
rows: t
|
|
157
|
+
}), b(null), E(!1));
|
|
130
158
|
return;
|
|
131
159
|
}
|
|
132
|
-
if (
|
|
133
|
-
|
|
160
|
+
if (F === "value") {
|
|
161
|
+
let t = await new i({ items: L ?? [] }).find("", {
|
|
162
|
+
$filter: z,
|
|
163
|
+
...d()
|
|
164
|
+
}), n = a(t);
|
|
165
|
+
e || (v({
|
|
166
|
+
provider: F,
|
|
167
|
+
object: I,
|
|
168
|
+
rows: n.rows
|
|
169
|
+
}), b(n), E(!1));
|
|
134
170
|
return;
|
|
135
171
|
}
|
|
136
|
-
e || (
|
|
172
|
+
e || (v({
|
|
173
|
+
provider: F,
|
|
174
|
+
object: I,
|
|
175
|
+
rows: []
|
|
176
|
+
}), E(!1));
|
|
137
177
|
} catch (t) {
|
|
138
|
-
e || (
|
|
178
|
+
e || (O(t), E(!1));
|
|
139
179
|
}
|
|
140
180
|
})(), () => {
|
|
141
181
|
e = !0;
|
|
142
182
|
};
|
|
143
183
|
}, [
|
|
184
|
+
F,
|
|
185
|
+
I,
|
|
186
|
+
L,
|
|
187
|
+
s,
|
|
188
|
+
z,
|
|
144
189
|
P,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
190
|
+
N,
|
|
191
|
+
u.data,
|
|
192
|
+
R,
|
|
193
|
+
we
|
|
149
194
|
]);
|
|
150
|
-
let
|
|
151
|
-
|
|
152
|
-
|
|
195
|
+
let B = t(() => ve(r), [r]), V = t(() => B.parentField ?? ye(P, r.objectName), [
|
|
196
|
+
B.parentField,
|
|
197
|
+
P,
|
|
153
198
|
r.objectName
|
|
154
|
-
]),
|
|
155
|
-
|
|
156
|
-
B
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
let
|
|
160
|
-
return
|
|
161
|
-
}),
|
|
162
|
-
let t =
|
|
163
|
-
return
|
|
164
|
-
},
|
|
199
|
+
]), H = h && h.provider === F && h.object === I ? h.rows : null, U = t(() => be(H ?? _e, V), [H, V]), [W, Te] = n(() => /* @__PURE__ */ new Map()), G = t(() => Se(U, B.defaultExpandedDepth, W), [
|
|
200
|
+
U,
|
|
201
|
+
B.defaultExpandedDepth,
|
|
202
|
+
W
|
|
203
|
+
]), Ee = (e, t) => Te((n) => {
|
|
204
|
+
let r = new Map(n);
|
|
205
|
+
return r.set(e, !t), r;
|
|
206
|
+
}), De = t(() => xe(U, G), [U, G]), K = oe(), Oe = m(), q = f(r, j) ?? r.objectName, J = (e) => {
|
|
207
|
+
let t = P?.fields?.[e]?.label || e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
|
|
208
|
+
return q ? K.fieldLabel(q, e, t) : t;
|
|
209
|
+
}, Y = (e, t) => ({
|
|
210
|
+
fieldDef: P?.fields?.[e],
|
|
211
|
+
fieldName: e,
|
|
212
|
+
columnLabel: J(e),
|
|
213
|
+
objectName: q,
|
|
214
|
+
translateOptions: K.translateOptions,
|
|
215
|
+
deadlineSettled: ee(P?.fields?.[e], t, {
|
|
216
|
+
scope: Oe,
|
|
217
|
+
fields: P?.fields
|
|
218
|
+
})
|
|
219
|
+
}), X = ie({
|
|
165
220
|
navigation: r.navigation,
|
|
166
|
-
objectName: r.objectName,
|
|
167
|
-
onRowClick:
|
|
168
|
-
}), { t:
|
|
169
|
-
|
|
170
|
-
className:
|
|
171
|
-
children: /* @__PURE__ */
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
221
|
+
objectName: f(r, j) ?? r.objectName,
|
|
222
|
+
onRowClick: l
|
|
223
|
+
}), { anchorRef: ke, captureAnchor: Ae } = fe(), { t: Z } = w();
|
|
224
|
+
if (D) return /* @__PURE__ */ S("div", {
|
|
225
|
+
className: g("flex items-center justify-center h-40 text-destructive", c),
|
|
226
|
+
children: /* @__PURE__ */ C("p", { children: ["Failed to load tree: ", D.message] })
|
|
227
|
+
});
|
|
228
|
+
if (H === null || T && H.length === 0) return /* @__PURE__ */ S("div", {
|
|
229
|
+
className: g("flex items-center justify-center h-40 text-muted-foreground", c),
|
|
230
|
+
children: /* @__PURE__ */ S("p", { children: "Loading…" })
|
|
231
|
+
});
|
|
232
|
+
if (H.length === 0) return /* @__PURE__ */ S("div", {
|
|
233
|
+
className: g("flex items-center justify-center h-40 text-muted-foreground", c),
|
|
234
|
+
children: /* @__PURE__ */ S("p", { children: "No records" })
|
|
235
|
+
});
|
|
236
|
+
let Q = (e) => {
|
|
237
|
+
if (!X.isOverlay) return null;
|
|
238
|
+
let t = f(r, j) ?? r.objectName;
|
|
239
|
+
return /* @__PURE__ */ S(ce, {
|
|
240
|
+
...X,
|
|
241
|
+
title: Z("detail.recordDetail"),
|
|
242
|
+
mainContent: e,
|
|
243
|
+
popoverAnchorRef: ke,
|
|
244
|
+
storageKey: t ? de(t) : void 0,
|
|
245
|
+
legacyStorageKey: t ? ue(t) : void 0,
|
|
246
|
+
width: X.width ?? pe,
|
|
247
|
+
children: (e) => {
|
|
248
|
+
let n = e, r = n.id ?? n._id, i = !!P?.fields && Object.keys(P.fields).length > 0;
|
|
249
|
+
return !t || r == null || !i ? /* @__PURE__ */ S("div", {
|
|
250
|
+
className: "space-y-3 p-4",
|
|
251
|
+
children: Object.entries(n).map(([e, t]) => /* @__PURE__ */ C("div", {
|
|
252
|
+
className: "flex flex-col",
|
|
253
|
+
children: [/* @__PURE__ */ S("span", {
|
|
254
|
+
className: "text-xs font-medium text-muted-foreground uppercase tracking-wide",
|
|
255
|
+
children: e.replace(/_/g, " ")
|
|
256
|
+
}), /* @__PURE__ */ S("span", {
|
|
257
|
+
className: "text-sm",
|
|
258
|
+
children: A(t, Y(e)) || "—"
|
|
259
|
+
})]
|
|
260
|
+
}, e))
|
|
261
|
+
}) : /* @__PURE__ */ S("div", {
|
|
262
|
+
className: "px-6 pt-6 pb-6",
|
|
263
|
+
children: /* @__PURE__ */ S(_, {
|
|
264
|
+
record: n,
|
|
265
|
+
objectName: t,
|
|
266
|
+
recordId: r,
|
|
267
|
+
dataSource: s,
|
|
268
|
+
objectSchema: P,
|
|
269
|
+
onClose: X.close
|
|
270
|
+
})
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}, $ = /* @__PURE__ */ C("div", {
|
|
275
|
+
className: g("w-full overflow-auto", c),
|
|
180
276
|
"data-testid": "object-tree",
|
|
181
|
-
children: [
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
children
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
className: "text-sm",
|
|
235
|
-
children: D(t) || "—"
|
|
236
|
-
})]
|
|
237
|
-
}, e))
|
|
238
|
-
})
|
|
239
|
-
})]
|
|
277
|
+
children: [
|
|
278
|
+
/* @__PURE__ */ S(le, {
|
|
279
|
+
active: T && H.length > 0,
|
|
280
|
+
ariaLabel: Z("grid.refreshing"),
|
|
281
|
+
className: "sticky -mb-0.5"
|
|
282
|
+
}),
|
|
283
|
+
/* @__PURE__ */ C("table", {
|
|
284
|
+
className: "w-full border-collapse text-sm",
|
|
285
|
+
children: [/* @__PURE__ */ S("thead", { children: /* @__PURE__ */ C("tr", {
|
|
286
|
+
className: "border-b text-left text-muted-foreground",
|
|
287
|
+
children: [/* @__PURE__ */ S("th", {
|
|
288
|
+
className: "px-3 py-2 font-medium",
|
|
289
|
+
children: J(B.labelField)
|
|
290
|
+
}), B.fields.filter((e) => e !== B.labelField).map((e) => /* @__PURE__ */ S("th", {
|
|
291
|
+
className: "px-3 py-2 font-medium",
|
|
292
|
+
children: J(e)
|
|
293
|
+
}, e))]
|
|
294
|
+
}) }), /* @__PURE__ */ S("tbody", { children: De.map((e) => {
|
|
295
|
+
let t = e.children.length > 0, n = G.has(e.id);
|
|
296
|
+
return /* @__PURE__ */ C("tr", {
|
|
297
|
+
className: "border-b hover:bg-accent/50 cursor-pointer",
|
|
298
|
+
"data-testid": "object-tree-row",
|
|
299
|
+
"data-depth": e.depth,
|
|
300
|
+
onClick: (t) => {
|
|
301
|
+
Ae(t), X.handleClick(e.record, t);
|
|
302
|
+
},
|
|
303
|
+
children: [/* @__PURE__ */ S("td", {
|
|
304
|
+
className: "px-3 py-2",
|
|
305
|
+
children: /* @__PURE__ */ C("div", {
|
|
306
|
+
className: "flex items-center gap-1",
|
|
307
|
+
style: { paddingLeft: `${e.depth * 20}px` },
|
|
308
|
+
children: [t ? /* @__PURE__ */ S("button", {
|
|
309
|
+
type: "button",
|
|
310
|
+
"aria-label": n ? "Collapse" : "Expand",
|
|
311
|
+
className: "flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted",
|
|
312
|
+
onClick: (t) => {
|
|
313
|
+
t.stopPropagation(), Ee(e.id, n);
|
|
314
|
+
},
|
|
315
|
+
children: S(n ? he : ge, { className: "h-4 w-4" })
|
|
316
|
+
}) : /* @__PURE__ */ S("span", { className: "inline-block h-5 w-5" }), /* @__PURE__ */ S("span", {
|
|
317
|
+
className: "truncate",
|
|
318
|
+
children: k(e.record[B.labelField], Y(B.labelField, e.record), "—")
|
|
319
|
+
})]
|
|
320
|
+
})
|
|
321
|
+
}), B.fields.filter((e) => e !== B.labelField).map((t) => /* @__PURE__ */ S("td", {
|
|
322
|
+
className: "px-3 py-2 text-muted-foreground",
|
|
323
|
+
children: k(e.record[t], Y(t, e.record))
|
|
324
|
+
}, t))]
|
|
325
|
+
}, e.id);
|
|
326
|
+
}) })]
|
|
327
|
+
}),
|
|
328
|
+
y && /* @__PURE__ */ S(p, { result: y })
|
|
329
|
+
]
|
|
240
330
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
331
|
+
if (X.isOverlay && X.mode === "split" && X.isOpen && X.selectedRecord) {
|
|
332
|
+
let e = Q($);
|
|
333
|
+
if (e) return /* @__PURE__ */ S(x, { children: e });
|
|
334
|
+
}
|
|
335
|
+
return /* @__PURE__ */ C(x, { children: [$, Q()] });
|
|
336
|
+
}, M = ({ schema: e, ...t }) => {
|
|
337
|
+
let { dataSource: n } = h() || {};
|
|
338
|
+
return /* @__PURE__ */ S(j, {
|
|
244
339
|
schema: e,
|
|
245
340
|
dataSource: n,
|
|
246
341
|
...t
|
|
247
342
|
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
type: "string",
|
|
251
|
-
label: "Object Name",
|
|
252
|
-
required: !0
|
|
253
|
-
}, {
|
|
254
|
-
name: "tree",
|
|
255
|
-
type: "object",
|
|
256
|
-
label: "Tree Config",
|
|
257
|
-
description: "parentField, labelField, fields, defaultExpandedDepth"
|
|
258
|
-
}];
|
|
259
|
-
r.register("object-tree", k, {
|
|
343
|
+
};
|
|
344
|
+
r.register("object-tree", M, {
|
|
260
345
|
namespace: "plugin-tree",
|
|
261
346
|
label: "Object Tree",
|
|
262
347
|
category: "view",
|
|
263
|
-
inputs:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
348
|
+
inputs: [
|
|
349
|
+
{
|
|
350
|
+
name: "objectName",
|
|
351
|
+
type: "string",
|
|
352
|
+
description: "ObjectQL object name. The record source is one of `data`, `staticData` and `objectName`, read in that order: a tree on `data` or `staticData` never queries this object. On a tree whose rows are inline it still names the record page a new-tab click opens."
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: "tree",
|
|
356
|
+
type: "object",
|
|
357
|
+
description: "The field configuration: `parentField` names the field holding each record’s parent id (auto-detected from the object’s self-referencing field when omitted), `labelField` the field drawn indented in the first column (default `name`), `fields` the further fields drawn as flat columns after it, and `defaultExpandedDepth` how many levels open on first draw (`0` shows roots only; omitted, every level is open)."
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
name: "data",
|
|
361
|
+
type: "object",
|
|
362
|
+
description: "A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a tree carrying one never reaches `staticData` and never queries `objectName`. `{ provider: 'value', items }` draws those records and `{ provider: 'object', object }` queries that object, both narrowed by `filter`. The `api` and `schema` providers draw no rows on the tree. A bare array is not this key’s shape and is not a record source: the tree falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`."
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
name: "staticData",
|
|
366
|
+
type: "array",
|
|
367
|
+
description: "Inline records, read SECOND on the record-source ladder: a `data` configuration wins and this key is then never reached, while `objectName` is read AFTER it, so a tree carrying both draws these rows and never queries that object. Each record is placed under the record its `parentField` value names, and one naming no record is drawn as a root. `filter` narrows these rows exactly as it does fetched ones."
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
name: "filter",
|
|
371
|
+
type: "array",
|
|
372
|
+
description: "Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the records the tree draws — fetched rows and inline (`staticData`, `{ provider: 'value' }`) rows alike. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. A record whose parent the filter removed is drawn as a root. The MongoDB-style record form is not this key’s shape."
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: "navigation",
|
|
376
|
+
type: "object",
|
|
377
|
+
description: "What a row click opens — the `{ mode, size, openNewTab, preventNavigation }` block a list view declares. With the key ABSENT a click opens nothing: this renderer supplies no drawer default. `mode` is an overlay (`drawer`, `modal`, `split`, `popover`), `new_window`, `page` or `none`, and a block written without `mode` takes the spec’s `page` default. `drawer`, `modal` and `popover` open the row’s record in that overlay, and `split` opens it beside the tree; `new_window` opens the record page in a new tab; `none` opens nothing. `page` opens the record page of `data.object` when `data` is the object provider, else of the tree’s `objectName`, through the record navigator the host publishes (the console publishes one on its custom pages, record pages and list views); under a host that publishes none, such as an embedded renderer, or on a tree that names neither (inline rows with no `objectName`), there is no record page to open and the click opens nothing. `preventNavigation: true` opens nothing whatever the mode, `openNewTab: true` opens the record page in a new tab and outranks every mode except `none`, and `size` sets the overlay width. A click handler from a parent view outranks the whole key."
|
|
378
|
+
}
|
|
379
|
+
]
|
|
269
380
|
});
|
|
270
381
|
//#endregion
|
|
271
|
-
export {
|
|
382
|
+
export { j as ObjectTree, M as ObjectTreeRenderer };
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/components"),require("@object-ui/i18n"),require("lucide-react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/core`,`@object-ui/react`,`@object-ui/components`,`@object-ui/i18n`,`lucide-react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ObjectUIPluginTree={},e.React,e.ObjectUICore,e.ObjectUIReact,e.ObjectUIComponents,e.ObjectUII18n,e.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r,i,a,o,s){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var c=Object.create,l=Object.defineProperty,u=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyNames,f=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty,m=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=d(t),a=0,o=i.length,s;a<o;a++)s=i[a],!p.call(e,s)&&s!==n&&l(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=u(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:c(f(e)),m(t||!e||!e.__esModule||!p.call(e,`default`)?l(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var h=(0,a.createSafeTranslation)({"detail.recordDetail":`Record Detail`},`detail.recordDetail`);function g(e){return e.data?e.data:e.staticData?{provider:`value`,items:e.staticData}:e.objectName?{provider:`object`,object:e.objectName}:null}function _(e){return(0,n.columnIdentity)(e)||(e&&typeof e==`object`?e.key:void 0)||void 0}function v(e){let t=e.tree||e.filter?.tree||{},n=Array.isArray(e.fields)?e.fields:Array.isArray(t.fields)?t.fields:[];return{parentField:_(e.parentField??t.parentField),labelField:_(e.labelField??t.labelField??e.titleField)??`name`,fields:n.map(_).filter(e=>!!e),defaultExpandedDepth:e.defaultExpandedDepth??t.defaultExpandedDepth}}function y(e,t){let n=e?.fields;if(!n||typeof n!=`object`)return;let r;for(let[e,i]of Object.entries(n)){if(i?.type===`tree`)return e;let n=i?.reference||i?.reference_to||i?.referenceTo;!r&&(i?.type===`lookup`||i?.type===`master_detail`)&&n&&t&&n===t&&(r=e)}return r}function b(e){let t=e?.id??e?._id;return t==null?void 0:String(t)}function x(e,t){if(!t)return;let n=e?.[t];if(n!=null){if(typeof n==`object`){let e=n.id??n._id;return e==null?void 0:String(e)}return String(n)}}function S(e,t){let n=new Map,r=[];for(let t of e){let e=b(t);e!=null&&(n.set(e,{id:e,record:t,depth:0,children:[]}),r.push(e))}let i=[];for(let e of r){let r=n.get(e),a=x(r.record,t),o=a==null?void 0:n.get(a);o&&o!==r?o.children.push(r):i.push(r)}let a=(e,t)=>{for(let n of e)n.depth=t,a(n.children,t+1)};return a(i,0),i}function C(e,t){let n=[],r=e=>{for(let i of e)n.push(i),i.children.length>0&&t.has(i.id)&&r(i.children)};return r(e),n}function w(e,t){let n=new Set,r=e=>{for(let i of e)i.children.length!==0&&(t==null||i.depth<t)&&(n.add(i.id),r(i.children))};return r(e),n}function T(e){return e==null?``:String(typeof e==`object`?e.name??e.label??e.id??e._id??``:e)}var E=({schema:e,dataSource:a,className:c,onRowClick:l,...u})=>{let[d,f]=(0,t.useState)([]),[p,m]=(0,t.useState)(!0),[_,b]=(0,t.useState)(null),[x,E]=(0,t.useState)(null),D=(0,t.useMemo)(()=>g(e),[e]),O=Array.isArray(u.data)||Array.isArray(e.data)||D?.provider===`value`;(0,t.useEffect)(()=>{let t=!1;return O||(async()=>{try{if(!a||typeof a.getObjectSchema!=`function`)return;let n=D?.provider===`object`?D.object:e.objectName;if(!n)return;let r=await a.getObjectSchema(n);t||E(r)}catch(e){console.error(`[ObjectTree] Failed to fetch object schema:`,e)}})(),()=>{t=!0}},[e.objectName,a,D,O]),(0,t.useEffect)(()=>{let t=!1;return(async()=>{try{if(m(!0),b(null),D?.provider===`object`&&a&&typeof a.find==`function`){let r=(0,n.buildExpandFields)(x?.fields),i=await a.find(D.object,{$filter:e.filter,...r.length>0?{$expand:r}:{}});t||(f((0,n.extractRecords)(i)),m(!1));return}let r=u.data??e.data;if(Array.isArray(r)){t||(f(r),m(!1));return}if(D?.provider===`value`){t||(f(D.items??[]),m(!1));return}t||(f([]),m(!1))}catch(e){t||(b(e),m(!1))}})(),()=>{t=!0}},[D,a,e.filter,x,u.data]);let k=(0,t.useMemo)(()=>v(e),[e]),A=(0,t.useMemo)(()=>k.parentField??y(x,e.objectName),[k.parentField,x,e.objectName]),j=(0,t.useMemo)(()=>S(d,A),[d,A]),[M,N]=(0,t.useState)(new Set);(0,t.useEffect)(()=>{N(w(j,k.defaultExpandedDepth))},[j,k.defaultExpandedDepth]);let P=e=>N(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),F=(0,t.useMemo)(()=>C(j,M),[j,M]),I=(0,r.useSafeFieldLabel)(),L=(D?.provider===`object`?D.object:void 0)??e.objectName,R=e=>{let t=x?.fields?.[e]?.label||e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase());return L?I.fieldLabel(L,e,t):t},z=(0,r.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l}),{t:B}=h();return _?(0,s.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-destructive`,c),children:(0,s.jsxs)(`p`,{children:[`Failed to load tree: `,_.message]})}):p?(0,s.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,s.jsx)(`p`,{children:`Loading…`})}):d.length===0?(0,s.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,s.jsx)(`p`,{children:`No records`})}):(0,s.jsxs)(`div`,{className:(0,i.cn)(`w-full overflow-auto`,c),"data-testid":`object-tree`,children:[(0,s.jsxs)(`table`,{className:`w-full border-collapse text-sm`,children:[(0,s.jsx)(`thead`,{children:(0,s.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,s.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:R(k.labelField)}),k.fields.filter(e=>e!==k.labelField).map(e=>(0,s.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:R(e)},e))]})}),(0,s.jsx)(`tbody`,{children:F.map(e=>{let t=e.children.length>0,n=M.has(e.id);return(0,s.jsxs)(`tr`,{className:`border-b hover:bg-accent/50 cursor-pointer`,"data-testid":`object-tree-row`,"data-depth":e.depth,onClick:t=>z.handleClick(e.record,t),children:[(0,s.jsx)(`td`,{className:`px-3 py-2`,children:(0,s.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingLeft:`${e.depth*20}px`},children:[t?(0,s.jsx)(`button`,{type:`button`,"aria-label":n?`Collapse`:`Expand`,className:`flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted`,onClick:t=>{t.stopPropagation(),P(e.id)},children:n?(0,s.jsx)(o.ChevronDown,{className:`h-4 w-4`}):(0,s.jsx)(o.ChevronRight,{className:`h-4 w-4`})}):(0,s.jsx)(`span`,{className:`inline-block h-5 w-5`}),(0,s.jsx)(`span`,{className:`truncate`,children:T(e.record[k.labelField])||`—`})]})}),k.fields.filter(e=>e!==k.labelField).map(t=>(0,s.jsx)(`td`,{className:`px-3 py-2 text-muted-foreground`,children:T(e.record[t])},t))]},e.id)})})]}),z.isOverlay&&(0,s.jsx)(i.NavigationOverlay,{...z,title:B(`detail.recordDetail`),children:e=>(0,s.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,s.jsxs)(`div`,{className:`flex flex-col`,children:[(0,s.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,s.jsx)(`span`,{className:`text-sm`,children:T(t)||`—`})]},e))})})]})},D=({schema:e,...t})=>{let{dataSource:n}=(0,r.useSchemaContext)()||{};return(0,s.jsx)(E,{schema:e,dataSource:n,...t})},O=[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`tree`,type:`object`,label:`Tree Config`,description:`parentField, labelField, fields, defaultExpandedDepth`}];n.ComponentRegistry.register(`object-tree`,D,{namespace:`plugin-tree`,label:`Object Tree`,category:`view`,inputs:O}),n.ComponentRegistry.register(`tree`,D,{namespace:`view`,label:`Tree View`,category:`view`,inputs:O}),e.ObjectTree=E,e.ObjectTreeRenderer=D});
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/components"),require("@object-ui/plugin-detail"),require("@object-ui/i18n"),require("@object-ui/fields"),require("@object-ui/permissions"),require("lucide-react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/core`,`@object-ui/react`,`@object-ui/components`,`@object-ui/plugin-detail`,`@object-ui/i18n`,`@object-ui/fields`,`@object-ui/permissions`,`lucide-react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ObjectUIPluginTree={},e.React,e.ObjectUICore,e.ObjectUIReact,e.ObjectUIComponents,e._object_ui_plugin_detail,e.ObjectUII18n,e._object_ui_fields,e._object_ui_permissions,e.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r,i,a,o,s,c,l,u){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var d=Object.create,f=Object.defineProperty,p=Object.getOwnPropertyDescriptor,m=Object.getOwnPropertyNames,h=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty,_=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=m(t),a=0,o=i.length,s;a<o;a++)s=i[a],!g.call(e,s)&&s!==n&&f(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=p(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:d(h(e)),_(t||!e||!e.__esModule||!g.call(e,`default`)?f(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var v=(0,o.createSafeTranslation)({"detail.recordDetail":`Record Detail`,"grid.refreshing":`Refreshing…`},`detail.recordDetail`),y=[];function b(e){return(0,n.columnIdentity)(e)||(e&&typeof e==`object`?e.key:void 0)||void 0}function ee(e){let t=e.tree||{},n=Array.isArray(e.fields)?e.fields:Array.isArray(t.fields)?t.fields:[];return{parentField:b(e.parentField??t.parentField),labelField:b(e.labelField??t.labelField)??`name`,fields:n.map(b).filter(e=>!!e),defaultExpandedDepth:e.defaultExpandedDepth??t.defaultExpandedDepth}}function te(e,t){let n=e?.fields;if(!n||typeof n!=`object`)return;let r;for(let[e,i]of Object.entries(n)){let n=i?.reference;if(i?.type===`tree`&&(n===void 0||t&&n===t))return e;!r&&(i?.type===`lookup`||i?.type===`master_detail`)&&n&&t&&n===t&&(r=e)}return r}function x(e){let t=e?.id??e?._id;return t==null?void 0:String(t)}function S(e,t){if(!t)return;let n=e?.[t];if(n!=null){if(typeof n==`object`){let e=n.id??n._id;return e==null?void 0:String(e)}return String(n)}}function C(e,t){let n=new Map,r=[];for(let t of e){let e=x(t);e!=null&&(n.set(e,{id:e,record:t,depth:0,children:[]}),r.push(e))}let i=[];for(let e of r){let r=n.get(e),a=S(r.record,t),o=a==null?void 0:n.get(a);o&&o!==r?o.children.push(r):i.push(r)}let a=(e,t)=>{for(let n of e)n.depth=t,a(n.children,t+1)};return a(i,0),i}function ne(e,t){let n=[],r=e=>{for(let i of e)n.push(i),i.children.length>0&&t.has(i.id)&&r(i.children)};return r(e),n}function w(e,t){let n=new Set,r=e=>{for(let i of e)i.children.length!==0&&(t==null||i.depth<t)&&(n.add(i.id),r(i.children))};return r(e),n}function re(e,t,n){let r=w(e,t);if(n.size===0)return r;let i=e=>{for(let t of e){let e=n.get(t.id);e===!0?r.add(t.id):e===!1&&r.delete(t.id),i(t.children)}};return i(e),r}function T(e,t,n=``){let r=t.fieldDef,i=typeof r?.type==`string`?r.type:``;if(!i)return E(e,t)||n;let a=(0,s.resolveCellRendererType)({type:i,format:r.format}),o=(0,s.getCellRenderer)(a),c=Array.isArray(r.options)?t.objectName?t.translateOptions(t.objectName,t.fieldName,r.options):r.options:void 0,l={...r,name:t.fieldName,type:a,label:t.columnLabel,...c?{options:c}:{}};return(0,u.jsx)(o,{value:e,field:l,deadlineSettled:t.deadlineSettled})}function E(e,t){if(e==null)return``;let r=Array.isArray(t?.fieldDef?.options)?t.fieldDef.options:null;if(r&&r.length>0){let i=t.objectName?t.translateOptions(t.objectName,t.fieldName,r):r,a=e=>{let t=i.find(t=>t?.value===e);if(t)return String(t.label??e);let r=String(e).toLowerCase(),a=i.find(e=>String(e?.value).toLowerCase()===r);return a?String(a.label??e):(0,n.humanizeLabel)(String(e))};return Array.isArray(e)?e.filter(e=>e!=null).map(a).join(`, `):a(e)}return typeof e==`object`&&(0,n.isExpandableFieldType)(t?.fieldDef)?(0,n.getRecordDisplayName)(void 0,e):String(typeof e==`object`?e.name??e.label??e.id??e._id??``:e)}var D=({schema:e,dataSource:o,className:s,onRowClick:d,...f})=>{let[p,m]=(0,t.useState)(null),[h,g]=(0,t.useState)(null),[_,b]=(0,t.useState)(!0),[x,S]=(0,t.useState)(null),w=(0,t.useMemo)(()=>(0,n.resolveRecordSourceConfig)(e,`view-data`),[e]),D=(0,n.resolveRecordSourceObjectName)(e,w)??``,{ready:O,def:k}=(0,r.useSettledSchema)(D,o),A=w?.provider,j=w?.provider===`object`?w.object:void 0,M=w?.provider===`value`?w.items:void 0,N=(0,c.usePermissions)(),P=(0,r.useFilterScope)(),F=(0,r.useResolvedFilter)(e.filter,P),I=(0,r.useDataInvalidation)(o?j:void 0);(0,t.useEffect)(()=>{let e=!1;return(async()=>{try{if(b(!0),S(null),A===`object`&&o&&typeof o.find==`function`){if(!O)return;let t=(0,n.buildExpandFields)(k?.fields),r=N?.isLoaded?t.filter(e=>N.checkField(j,e,`read`)):t,i=await o.find(j,{$filter:F,...(0,n.nonGridRowCeilingQuery)(),...r.length>0?{$expand:r}:{}}),a=(0,n.applyNonGridRowCeiling)(i);e||(m({provider:A,object:j,rows:a.rows}),g(a),b(!1));return}let t=f.data;if(Array.isArray(t)){e||(m({provider:A,object:j,rows:t}),g(null),b(!1));return}if(A===`value`){let t=await new n.ValueDataSource({items:M??[]}).find(``,{$filter:F,...(0,n.nonGridRowCeilingQuery)()}),r=(0,n.applyNonGridRowCeiling)(t);e||(m({provider:A,object:j,rows:r.rows}),g(r),b(!1));return}e||(m({provider:A,object:j,rows:[]}),b(!1))}catch(t){e||(S(t),b(!1))}})(),()=>{e=!0}},[A,j,M,o,F,k,O,f.data,N,I]);let L=(0,t.useMemo)(()=>ee(e),[e]),R=(0,t.useMemo)(()=>L.parentField??te(k,e.objectName),[L.parentField,k,e.objectName]),z=p&&p.provider===A&&p.object===j?p.rows:null,B=(0,t.useMemo)(()=>C(z??y,R),[z,R]),[V,ie]=(0,t.useState)(()=>new Map),H=(0,t.useMemo)(()=>re(B,L.defaultExpandedDepth,V),[B,L.defaultExpandedDepth,V]),U=(e,t)=>ie(n=>{let r=new Map(n);return r.set(e,!t),r}),W=(0,t.useMemo)(()=>ne(B,H),[B,H]),G=(0,r.useSafeFieldLabel)(),K=(0,r.usePredicateScope)(),q=(0,n.resolveRecordSourceObjectName)(e,w)??e.objectName,J=e=>{let t=k?.fields?.[e]?.label||e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase());return q?G.fieldLabel(q,e,t):t},Y=(e,t)=>({fieldDef:k?.fields?.[e],fieldName:e,columnLabel:J(e),objectName:q,translateOptions:G.translateOptions,deadlineSettled:(0,n.isDeadlineSettled)(k?.fields?.[e],t,{scope:K,fields:k?.fields})}),X=(0,r.useNavigationOverlay)({navigation:e.navigation,objectName:(0,n.resolveRecordSourceObjectName)(e,w)??e.objectName,onRowClick:d}),{anchorRef:ae,captureAnchor:oe}=(0,i.useOverlayAnchor)(),{t:Z}=v();if(x)return(0,u.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-destructive`,s),children:(0,u.jsxs)(`p`,{children:[`Failed to load tree: `,x.message]})});if(z===null||_&&z.length===0)return(0,u.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,s),children:(0,u.jsx)(`p`,{children:`Loading…`})});if(z.length===0)return(0,u.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,s),children:(0,u.jsx)(`p`,{children:`No records`})});let Q=t=>{if(!X.isOverlay)return null;let r=(0,n.resolveRecordSourceObjectName)(e,w)??e.objectName;return(0,u.jsx)(i.NavigationOverlay,{...X,title:Z(`detail.recordDetail`),mainContent:t,popoverAnchorRef:ae,storageKey:r?(0,i.recordOverlayWidthStorageKey)(r):void 0,legacyStorageKey:r?(0,i.legacyRecordDrawerWidthKey)(r):void 0,width:X.width??a.RECORD_OVERLAY_DEFAULT_WIDTH,children:e=>{let t=e,n=t.id??t._id,i=!!k?.fields&&Object.keys(k.fields).length>0;return!r||n==null||!i?(0,u.jsx)(`div`,{className:`space-y-3 p-4`,children:Object.entries(t).map(([e,t])=>(0,u.jsxs)(`div`,{className:`flex flex-col`,children:[(0,u.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,u.jsx)(`span`,{className:`text-sm`,children:E(t,Y(e))||`—`})]},e))}):(0,u.jsx)(`div`,{className:`px-6 pt-6 pb-6`,children:(0,u.jsx)(a.RecordDetailPanel,{record:t,objectName:r,recordId:n,dataSource:o,objectSchema:k,onClose:X.close})})}})},$=(0,u.jsxs)(`div`,{className:(0,i.cn)(`w-full overflow-auto`,s),"data-testid":`object-tree`,children:[(0,u.jsx)(i.RefreshIndicator,{active:_&&z.length>0,ariaLabel:Z(`grid.refreshing`),className:`sticky -mb-0.5`}),(0,u.jsxs)(`table`,{className:`w-full border-collapse text-sm`,children:[(0,u.jsx)(`thead`,{children:(0,u.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,u.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:J(L.labelField)}),L.fields.filter(e=>e!==L.labelField).map(e=>(0,u.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:J(e)},e))]})}),(0,u.jsx)(`tbody`,{children:W.map(e=>{let t=e.children.length>0,n=H.has(e.id);return(0,u.jsxs)(`tr`,{className:`border-b hover:bg-accent/50 cursor-pointer`,"data-testid":`object-tree-row`,"data-depth":e.depth,onClick:t=>{oe(t),X.handleClick(e.record,t)},children:[(0,u.jsx)(`td`,{className:`px-3 py-2`,children:(0,u.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingLeft:`${e.depth*20}px`},children:[t?(0,u.jsx)(`button`,{type:`button`,"aria-label":n?`Collapse`:`Expand`,className:`flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted`,onClick:t=>{t.stopPropagation(),U(e.id,n)},children:n?(0,u.jsx)(l.ChevronDown,{className:`h-4 w-4`}):(0,u.jsx)(l.ChevronRight,{className:`h-4 w-4`})}):(0,u.jsx)(`span`,{className:`inline-block h-5 w-5`}),(0,u.jsx)(`span`,{className:`truncate`,children:T(e.record[L.labelField],Y(L.labelField,e.record),`—`)})]})}),L.fields.filter(e=>e!==L.labelField).map(t=>(0,u.jsx)(`td`,{className:`px-3 py-2 text-muted-foreground`,children:T(e.record[t],Y(t,e.record))},t))]},e.id)})})]}),h&&(0,u.jsx)(r.NonGridRowCeilingNote,{result:h})]});if(X.isOverlay&&X.mode===`split`&&X.isOpen&&X.selectedRecord){let e=Q($);if(e)return(0,u.jsx)(u.Fragment,{children:e})}return(0,u.jsxs)(u.Fragment,{children:[$,Q()]})},O=({schema:e,...t})=>{let{dataSource:n}=(0,r.useSchemaContext)()||{};return(0,u.jsx)(D,{schema:e,dataSource:n,...t})};n.ComponentRegistry.register(`object-tree`,O,{namespace:`plugin-tree`,label:`Object Tree`,category:`view`,inputs:[{name:`objectName`,type:`string`,description:"ObjectQL object name. The record source is one of `data`, `staticData` and `objectName`, read in that order: a tree on `data` or `staticData` never queries this object. On a tree whose rows are inline it still names the record page a new-tab click opens."},{name:`tree`,type:`object`,description:"The field configuration: `parentField` names the field holding each record’s parent id (auto-detected from the object’s self-referencing field when omitted), `labelField` the field drawn indented in the first column (default `name`), `fields` the further fields drawn as flat columns after it, and `defaultExpandedDepth` how many levels open on first draw (`0` shows roots only; omitted, every level is open)."},{name:`data`,type:`object`,description:"A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a tree carrying one never reaches `staticData` and never queries `objectName`. `{ provider: 'value', items }` draws those records and `{ provider: 'object', object }` queries that object, both narrowed by `filter`. The `api` and `schema` providers draw no rows on the tree. A bare array is not this key’s shape and is not a record source: the tree falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`."},{name:`staticData`,type:`array`,description:"Inline records, read SECOND on the record-source ladder: a `data` configuration wins and this key is then never reached, while `objectName` is read AFTER it, so a tree carrying both draws these rows and never queries that object. Each record is placed under the record its `parentField` value names, and one naming no record is drawn as a root. `filter` narrows these rows exactly as it does fetched ones."},{name:`filter`,type:`array`,description:"Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the records the tree draws — fetched rows and inline (`staticData`, `{ provider: 'value' }`) rows alike. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. A record whose parent the filter removed is drawn as a root. The MongoDB-style record form is not this key’s shape."},{name:`navigation`,type:`object`,description:"What a row click opens — the `{ mode, size, openNewTab, preventNavigation }` block a list view declares. With the key ABSENT a click opens nothing: this renderer supplies no drawer default. `mode` is an overlay (`drawer`, `modal`, `split`, `popover`), `new_window`, `page` or `none`, and a block written without `mode` takes the spec’s `page` default. `drawer`, `modal` and `popover` open the row’s record in that overlay, and `split` opens it beside the tree; `new_window` opens the record page in a new tab; `none` opens nothing. `page` opens the record page of `data.object` when `data` is the object provider, else of the tree’s `objectName`, through the record navigator the host publishes (the console publishes one on its custom pages, record pages and list views); under a host that publishes none, such as an embedded renderer, or on a tree that names neither (inline rows with no `objectName`), there is no record page to open and the click opens nothing. `preventNavigation: true` opens nothing whatever the mode, `openNewTab: true` opens the record page in a new tab and outranks every mode except `none`, and `size` sets the overlay width. A click handler from a parent view outranks the whole key."}]}),e.ObjectTree=D,e.ObjectTreeRenderer=O});
|