@object-ui/plugin-tree 16.1.0 → 17.2.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 CHANGED
@@ -1,5 +1,190 @@
1
1
  # @object-ui/plugin-tree
2
2
 
3
+ ## 17.2.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [4ae0ac4]
8
+ - Updated dependencies [696e3c1]
9
+ - Updated dependencies [bca45cc]
10
+ - Updated dependencies [a889e31]
11
+ - Updated dependencies [09d30a4]
12
+ - Updated dependencies [4bf612c]
13
+ - Updated dependencies [335041c]
14
+ - Updated dependencies [b414983]
15
+ - Updated dependencies [256f8cc]
16
+ - Updated dependencies [d9668a7]
17
+ - Updated dependencies [cb82705]
18
+ - Updated dependencies [f572849]
19
+ - Updated dependencies [f6e8d78]
20
+ - Updated dependencies [ea96284]
21
+ - Updated dependencies [d3584c6]
22
+ - Updated dependencies [a8ad6c0]
23
+ - Updated dependencies [444457c]
24
+ - Updated dependencies [850033c]
25
+ - Updated dependencies [022e4c3]
26
+ - Updated dependencies [009e25d]
27
+ - Updated dependencies [726b89c]
28
+ - @object-ui/types@17.2.0
29
+ - @object-ui/components@17.2.0
30
+ - @object-ui/core@17.2.0
31
+ - @object-ui/react@17.2.0
32
+
33
+ ## 17.1.0
34
+
35
+ ### Patch Changes
36
+
37
+ - 95b7214: fix(list,grid,detail,tree,core): every column resolver reads one key (#3104 PR2)
38
+
39
+ PR1 (#3119) put a canonicalizing fold at ListView's ingestion boundary. This
40
+ converges the 22 read sites themselves onto `columnIdentity()` from
41
+ `@object-ui/core`, so a surface that is NOT downstream of that fold resolves
42
+ the same identity anyway.
43
+
44
+ That distinction is the user-visible part. A standalone `object-grid` node —
45
+ authored directly on a page, with no `list-view` above it — never passed
46
+ through `normalizeListViewSchema`. Its `getSelectFields` read `c.field` alone
47
+ while the `ensureId` probe one line above read `f?.name || f?.field`, so a
48
+ legacy `{ name: 'account' }` column reached `$select` as a literal `undefined`
49
+ hole: the server never returned the field and every cell in that column came
50
+ back empty. Same for `ObjectTree`, `RelatedList` and the `record:details` /
51
+ `record:related_list` renderers.
52
+
53
+ Converged:
54
+
55
+ | Surface | Was | Now |
56
+ | ---------------------------------------- | ---------------------------------------------- | ----------------------------------- |
57
+ | `ListView` ×9 + its 2 request builders | `name \|\| fieldName \|\| field` vs `f?.field` | `columnIdentity()` |
58
+ | `RelatedList` ×8 | `accessorKey \|\| field \|\| name` | `accessorKey \|\| columnIdentity()` |
59
+ | `ObjectGrid` | name-first probe vs `c.field` projection | `columnIdentity()` |
60
+ | `ObjectTree` | `name \|\| fieldName \|\| field \|\| key` | `columnIdentity() \|\| key` |
61
+ | `buildExpandFields` | `field ?? name ?? fieldName` | `columnIdentity()` |
62
+ | `record-details` / `record-related-list` | `field \|\| name (\|\| key)` | `columnIdentity() (\|\| key)` |
63
+
64
+ `accessorKey` keeps its precedence in `RelatedList` — it is TanStack Table's
65
+ column key, not ObjectStack metadata identity, and only the `field || name`
66
+ tail was converged. `key` stays a tail fallback in `ObjectTree` and
67
+ `record-related-list` for the same reason: it is a generic entry key.
68
+
69
+ Two incidental fixes that TypeScript surfaced once the resolver stopped
70
+ returning `any`: ListView's filter-field options and its hide-fields popover
71
+ both built entries keyed `undefined` for a column with no resolvable identity.
72
+ Those entries could never match a column; they are now dropped.
73
+
74
+ **Inventory re-triage.** PR1 recorded 24 family members. Two were mis-classified
75
+ and are reclassified here rather than converged — reading what they actually
76
+ feed shows they are not column reads at all:
77
+
78
+ - `ViewPreview.tsx` adapts a ViewItem **form** section to what `object-form`
79
+ selects by (`field` → `name`) — the #3090 two-layer join.
80
+ - `SchemaForm.tsx` renders an arbitrary metadata **array** into a popover
81
+ summary and guesses at a display key; the entries are validations, actions,
82
+ or whatever the JSON schema declares.
83
+
84
+ So the family was 22, and it is now **0**. The ratchet asserts that, asserts
85
+ each converged surface actually routes through the shared reader (a surface
86
+ that dropped identity resolution instead of converging it goes red), and pins
87
+ `accessorKey`'s precedence in `RelatedList`.
88
+
89
+ - Updated dependencies [62311b6]
90
+ - Updated dependencies [fc0272a]
91
+ - Updated dependencies [9e7349e]
92
+ - Updated dependencies [8864971]
93
+ - Updated dependencies [c785740]
94
+ - Updated dependencies [b41f401]
95
+ - Updated dependencies [19e9fa0]
96
+ - Updated dependencies [95b7214]
97
+ - Updated dependencies [7d9734d]
98
+ - Updated dependencies [6ae818e]
99
+ - Updated dependencies [9eb932b]
100
+ - Updated dependencies [746dd00]
101
+ - Updated dependencies [aebfa4f]
102
+ - Updated dependencies [38ca8be]
103
+ - Updated dependencies [68ef584]
104
+ - Updated dependencies [4952edf]
105
+ - Updated dependencies [7f0252e]
106
+ - Updated dependencies [c4d7b20]
107
+ - Updated dependencies [c769d3d]
108
+ - Updated dependencies [7639a61]
109
+ - Updated dependencies [94e63ef]
110
+ - Updated dependencies [c735bf7]
111
+ - Updated dependencies [02aef0c]
112
+ - Updated dependencies [6f29aa5]
113
+ - Updated dependencies [c4db402]
114
+ - Updated dependencies [5319bf1]
115
+ - Updated dependencies [49e5671]
116
+ - Updated dependencies [9a04d25]
117
+ - Updated dependencies [b5b97e2]
118
+ - Updated dependencies [f59f2c1]
119
+ - Updated dependencies [07de839]
120
+ - Updated dependencies [2a40b5e]
121
+ - Updated dependencies [df613fa]
122
+ - Updated dependencies [4874117]
123
+ - Updated dependencies [ad0183a]
124
+ - Updated dependencies [ce08d55]
125
+ - Updated dependencies [eb4b740]
126
+ - Updated dependencies [5b084eb]
127
+ - Updated dependencies [aa1240a]
128
+ - Updated dependencies [2374a49]
129
+ - Updated dependencies [390c071]
130
+ - Updated dependencies [d10f526]
131
+ - Updated dependencies [2d5d594]
132
+ - Updated dependencies [ea7f477]
133
+ - Updated dependencies [379728f]
134
+ - Updated dependencies [7f23cd0]
135
+ - Updated dependencies [0ded602]
136
+ - Updated dependencies [24e0e0a]
137
+ - Updated dependencies [3a6cf24]
138
+ - Updated dependencies [aa35561]
139
+ - Updated dependencies [03bd53b]
140
+ - Updated dependencies [3c1f321]
141
+ - Updated dependencies [a045a32]
142
+ - Updated dependencies [912496d]
143
+ - Updated dependencies [80edbd4]
144
+ - Updated dependencies [9867281]
145
+ - @object-ui/core@17.1.0
146
+ - @object-ui/components@17.1.0
147
+ - @object-ui/react@17.1.0
148
+ - @object-ui/types@17.1.0
149
+
150
+ ## 17.0.0
151
+
152
+ ### Patch Changes
153
+
154
+ - Updated dependencies [7b21891]
155
+ - Updated dependencies [952b978]
156
+ - Updated dependencies [de5e40c]
157
+ - Updated dependencies [1767124]
158
+ - Updated dependencies [8ecf5a6]
159
+ - Updated dependencies [7b35e4b]
160
+ - Updated dependencies [8fb1295]
161
+ - Updated dependencies [e16ed2d]
162
+ - Updated dependencies [f9bbddb]
163
+ - Updated dependencies [dfd3705]
164
+ - Updated dependencies [c77108c]
165
+ - Updated dependencies [2735de6]
166
+ - Updated dependencies [c19ac11]
167
+ - Updated dependencies [6dee2cb]
168
+ - Updated dependencies [c7cff19]
169
+ - Updated dependencies [cd09a7b]
170
+ - Updated dependencies [f1abf0e]
171
+ - Updated dependencies [f05b84e]
172
+ - Updated dependencies [2f947e4]
173
+ - Updated dependencies [7d46648]
174
+ - Updated dependencies [9b53d72]
175
+ - Updated dependencies [662bdf9]
176
+ - Updated dependencies [059a052]
177
+ - Updated dependencies [53642d4]
178
+ - Updated dependencies [8aae006]
179
+ - Updated dependencies [c6cfdf1]
180
+ - Updated dependencies [d147a13]
181
+ - Updated dependencies [c6aaed8]
182
+ - Updated dependencies [dc334da]
183
+ - @object-ui/components@17.0.0
184
+ - @object-ui/react@17.0.0
185
+ - @object-ui/types@17.0.0
186
+ - @object-ui/core@17.0.0
187
+
3
188
  ## 16.1.0
4
189
 
5
190
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { useEffect as e, useMemo as t, useState as n } from "react";
2
- import { ComponentRegistry as r, buildExpandFields as i, extractRecords as a } from "@object-ui/core";
3
- import { useNavigationOverlay as o, useSafeFieldLabel as s, useSchemaContext as c } from "@object-ui/react";
4
- import { NavigationOverlay as l, cn as u } from "@object-ui/components";
5
- import { ChevronDown as d, ChevronRight as f } from "lucide-react";
6
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
2
+ import { ComponentRegistry as r, buildExpandFields as i, columnIdentity as a, extractRecords as o } from "@object-ui/core";
3
+ import { useNavigationOverlay as s, useSafeFieldLabel as c, useSchemaContext as l } from "@object-ui/react";
4
+ import { NavigationOverlay as u, cn as d } from "@object-ui/components";
5
+ import { ChevronDown as f, ChevronRight as p } from "lucide-react";
6
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
7
7
  //#region src/ObjectTree.tsx
8
- function h(e) {
8
+ function g(e) {
9
9
  return e.data ? e.data : e.staticData ? {
10
10
  provider: "value",
11
11
  items: e.staticData
@@ -14,20 +14,19 @@ function h(e) {
14
14
  object: e.objectName
15
15
  } : null;
16
16
  }
17
- function g(e) {
18
- if (typeof e == "string") return e;
19
- if (e && typeof e == "object") return e.name || e.fieldName || e.field || e.key;
20
- }
21
17
  function _(e) {
18
+ return a(e) || (e && typeof e == "object" ? e.key : void 0) || void 0;
19
+ }
20
+ function v(e) {
22
21
  let t = e.tree || e.filter?.tree || {}, n = Array.isArray(e.fields) ? e.fields : Array.isArray(t.fields) ? t.fields : [];
23
22
  return {
24
- parentField: g(e.parentField ?? t.parentField),
25
- labelField: g(e.labelField ?? t.labelField ?? e.titleField) ?? "name",
26
- fields: n.map(g).filter((e) => !!e),
23
+ parentField: _(e.parentField ?? t.parentField),
24
+ labelField: _(e.labelField ?? t.labelField ?? e.titleField) ?? "name",
25
+ fields: n.map(_).filter((e) => !!e),
27
26
  defaultExpandedDepth: e.defaultExpandedDepth ?? t.defaultExpandedDepth
28
27
  };
29
28
  }
30
- function v(e, t) {
29
+ function y(e, t) {
31
30
  let n = e?.fields;
32
31
  if (!n || typeof n != "object") return;
33
32
  let r;
@@ -38,11 +37,11 @@ function v(e, t) {
38
37
  }
39
38
  return r;
40
39
  }
41
- function y(e) {
40
+ function b(e) {
42
41
  let t = e?.id ?? e?._id;
43
42
  return t == null ? void 0 : String(t);
44
43
  }
45
- function b(e, t) {
44
+ function x(e, t) {
46
45
  if (!t) return;
47
46
  let n = e?.[t];
48
47
  if (n != null) {
@@ -53,10 +52,10 @@ function b(e, t) {
53
52
  return String(n);
54
53
  }
55
54
  }
56
- function x(e, t) {
55
+ function S(e, t) {
57
56
  let n = /* @__PURE__ */ new Map(), r = [];
58
57
  for (let t of e) {
59
- let e = y(t);
58
+ let e = b(t);
60
59
  e != null && (n.set(e, {
61
60
  id: e,
62
61
  record: t,
@@ -66,7 +65,7 @@ function x(e, t) {
66
65
  }
67
66
  let i = [];
68
67
  for (let e of r) {
69
- let r = n.get(e), a = b(r.record, t), o = a == null ? void 0 : n.get(a);
68
+ let r = n.get(e), a = x(r.record, t), o = a == null ? void 0 : n.get(a);
70
69
  o && o !== r ? o.children.push(r) : i.push(r);
71
70
  }
72
71
  let a = (e, t) => {
@@ -74,31 +73,31 @@ function x(e, t) {
74
73
  };
75
74
  return a(i, 0), i;
76
75
  }
77
- function S(e, t) {
76
+ function C(e, t) {
78
77
  let n = [], r = (e) => {
79
78
  for (let i of e) n.push(i), i.children.length > 0 && t.has(i.id) && r(i.children);
80
79
  };
81
80
  return r(e), n;
82
81
  }
83
- function C(e, t) {
82
+ function w(e, t) {
84
83
  let n = /* @__PURE__ */ new Set(), r = (e) => {
85
84
  for (let i of e) i.children.length !== 0 && (t == null || i.depth < t) && (n.add(i.id), r(i.children));
86
85
  };
87
86
  return r(e), n;
88
87
  }
89
- function w(e) {
88
+ function T(e) {
90
89
  return e == null ? "" : String(typeof e == "object" ? e.name ?? e.label ?? e.id ?? e._id ?? "" : e);
91
90
  }
92
- var T = ({ schema: r, dataSource: c, className: g, onRowClick: y, ...b }) => {
93
- let [T, E] = n([]), [D, O] = n(!0), [k, A] = n(null), [j, M] = n(null), N = t(() => h(r), [r]), P = Array.isArray(b.data) || Array.isArray(r.data) || N?.provider === "value";
91
+ var E = ({ schema: r, dataSource: a, className: l, onRowClick: _, ...b }) => {
92
+ let [x, E] = n([]), [D, O] = n(!0), [k, A] = n(null), [j, M] = n(null), N = t(() => g(r), [r]), P = Array.isArray(b.data) || Array.isArray(r.data) || N?.provider === "value";
94
93
  e(() => {
95
94
  let e = !1;
96
95
  return P || (async () => {
97
96
  try {
98
- if (!c || typeof c.getObjectSchema != "function") return;
97
+ if (!a || typeof a.getObjectSchema != "function") return;
99
98
  let t = N?.provider === "object" ? N.object : r.objectName;
100
99
  if (!t) return;
101
- let n = await c.getObjectSchema(t);
100
+ let n = await a.getObjectSchema(t);
102
101
  e || M(n);
103
102
  } catch (e) {
104
103
  console.error("[ObjectTree] Failed to fetch object schema:", e);
@@ -108,19 +107,19 @@ var T = ({ schema: r, dataSource: c, className: g, onRowClick: y, ...b }) => {
108
107
  };
109
108
  }, [
110
109
  r.objectName,
111
- c,
110
+ a,
112
111
  N,
113
112
  P
114
113
  ]), e(() => {
115
114
  let e = !1;
116
115
  return (async () => {
117
116
  try {
118
- if (O(!0), A(null), N?.provider === "object" && c && typeof c.find == "function") {
119
- let t = i(j?.fields), n = await c.find(N.object, {
117
+ if (O(!0), A(null), N?.provider === "object" && a && typeof a.find == "function") {
118
+ let t = i(j?.fields), n = await a.find(N.object, {
120
119
  $filter: r.filter,
121
120
  ...t.length > 0 ? { $expand: t } : {}
122
121
  });
123
- e || (E(a(n)), O(!1));
122
+ e || (E(o(n)), O(!1));
124
123
  return;
125
124
  }
126
125
  let t = b.data ?? r.data;
@@ -141,110 +140,110 @@ var T = ({ schema: r, dataSource: c, className: g, onRowClick: y, ...b }) => {
141
140
  };
142
141
  }, [
143
142
  N,
144
- c,
143
+ a,
145
144
  r.filter,
146
145
  j,
147
146
  b.data
148
147
  ]);
149
- let F = t(() => _(r), [r]), I = t(() => F.parentField ?? v(j, r.objectName), [
148
+ let F = t(() => v(r), [r]), I = t(() => F.parentField ?? y(j, r.objectName), [
150
149
  F.parentField,
151
150
  j,
152
151
  r.objectName
153
- ]), L = t(() => x(T, I), [T, I]), [R, z] = n(/* @__PURE__ */ new Set());
152
+ ]), L = t(() => S(x, I), [x, I]), [R, z] = n(/* @__PURE__ */ new Set());
154
153
  e(() => {
155
- z(C(L, F.defaultExpandedDepth));
154
+ z(w(L, F.defaultExpandedDepth));
156
155
  }, [L, F.defaultExpandedDepth]);
157
156
  let B = (e) => z((t) => {
158
157
  let n = new Set(t);
159
158
  return n.has(e) ? n.delete(e) : n.add(e), n;
160
- }), V = t(() => S(L, R), [L, R]), H = s(), U = (N?.provider === "object" ? N.object : void 0) ?? r.objectName, W = (e) => {
159
+ }), V = t(() => C(L, R), [L, R]), H = c(), U = (N?.provider === "object" ? N.object : void 0) ?? r.objectName, W = (e) => {
161
160
  let t = j?.fields?.[e]?.label || e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
162
161
  return U ? H.fieldLabel(U, e, t) : t;
163
- }, G = o({
162
+ }, G = s({
164
163
  navigation: r.navigation,
165
164
  objectName: r.objectName,
166
- onRowClick: y
165
+ onRowClick: _
167
166
  });
168
- return k ? /* @__PURE__ */ p("div", {
169
- className: u("flex items-center justify-center h-40 text-destructive", g),
170
- children: /* @__PURE__ */ m("p", { children: ["Failed to load tree: ", k.message] })
171
- }) : D ? /* @__PURE__ */ p("div", {
172
- className: u("flex items-center justify-center h-40 text-muted-foreground", g),
173
- children: /* @__PURE__ */ p("p", { children: "Loading…" })
174
- }) : T.length === 0 ? /* @__PURE__ */ p("div", {
175
- className: u("flex items-center justify-center h-40 text-muted-foreground", g),
176
- children: /* @__PURE__ */ p("p", { children: "No records" })
177
- }) : /* @__PURE__ */ m("div", {
178
- className: u("w-full overflow-auto", g),
167
+ return k ? /* @__PURE__ */ m("div", {
168
+ className: d("flex items-center justify-center h-40 text-destructive", l),
169
+ children: /* @__PURE__ */ h("p", { children: ["Failed to load tree: ", k.message] })
170
+ }) : D ? /* @__PURE__ */ m("div", {
171
+ className: d("flex items-center justify-center h-40 text-muted-foreground", l),
172
+ children: /* @__PURE__ */ m("p", { children: "Loading…" })
173
+ }) : x.length === 0 ? /* @__PURE__ */ m("div", {
174
+ className: d("flex items-center justify-center h-40 text-muted-foreground", l),
175
+ children: /* @__PURE__ */ m("p", { children: "No records" })
176
+ }) : /* @__PURE__ */ h("div", {
177
+ className: d("w-full overflow-auto", l),
179
178
  "data-testid": "object-tree",
180
- children: [/* @__PURE__ */ m("table", {
179
+ children: [/* @__PURE__ */ h("table", {
181
180
  className: "w-full border-collapse text-sm",
182
- children: [/* @__PURE__ */ p("thead", { children: /* @__PURE__ */ m("tr", {
181
+ children: [/* @__PURE__ */ m("thead", { children: /* @__PURE__ */ h("tr", {
183
182
  className: "border-b text-left text-muted-foreground",
184
- children: [/* @__PURE__ */ p("th", {
183
+ children: [/* @__PURE__ */ m("th", {
185
184
  className: "px-3 py-2 font-medium",
186
185
  children: W(F.labelField)
187
- }), F.fields.filter((e) => e !== F.labelField).map((e) => /* @__PURE__ */ p("th", {
186
+ }), F.fields.filter((e) => e !== F.labelField).map((e) => /* @__PURE__ */ m("th", {
188
187
  className: "px-3 py-2 font-medium",
189
188
  children: W(e)
190
189
  }, e))]
191
- }) }), /* @__PURE__ */ p("tbody", { children: V.map((e) => {
190
+ }) }), /* @__PURE__ */ m("tbody", { children: V.map((e) => {
192
191
  let t = e.children.length > 0, n = R.has(e.id);
193
- return /* @__PURE__ */ m("tr", {
192
+ return /* @__PURE__ */ h("tr", {
194
193
  className: "border-b hover:bg-accent/50 cursor-pointer",
195
194
  "data-testid": "object-tree-row",
196
195
  "data-depth": e.depth,
197
196
  onClick: (t) => G.handleClick(e.record, t),
198
- children: [/* @__PURE__ */ p("td", {
197
+ children: [/* @__PURE__ */ m("td", {
199
198
  className: "px-3 py-2",
200
- children: /* @__PURE__ */ m("div", {
199
+ children: /* @__PURE__ */ h("div", {
201
200
  className: "flex items-center gap-1",
202
201
  style: { paddingLeft: `${e.depth * 20}px` },
203
- children: [t ? /* @__PURE__ */ p("button", {
202
+ children: [t ? /* @__PURE__ */ m("button", {
204
203
  type: "button",
205
204
  "aria-label": n ? "Collapse" : "Expand",
206
205
  className: "flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted",
207
206
  onClick: (t) => {
208
207
  t.stopPropagation(), B(e.id);
209
208
  },
210
- children: p(n ? d : f, { className: "h-4 w-4" })
211
- }) : /* @__PURE__ */ p("span", { className: "inline-block h-5 w-5" }), /* @__PURE__ */ p("span", {
209
+ children: m(n ? f : p, { className: "h-4 w-4" })
210
+ }) : /* @__PURE__ */ m("span", { className: "inline-block h-5 w-5" }), /* @__PURE__ */ m("span", {
212
211
  className: "truncate",
213
- children: w(e.record[F.labelField]) || "—"
212
+ children: T(e.record[F.labelField]) || "—"
214
213
  })]
215
214
  })
216
- }), F.fields.filter((e) => e !== F.labelField).map((t) => /* @__PURE__ */ p("td", {
215
+ }), F.fields.filter((e) => e !== F.labelField).map((t) => /* @__PURE__ */ m("td", {
217
216
  className: "px-3 py-2 text-muted-foreground",
218
- children: w(e.record[t])
217
+ children: T(e.record[t])
219
218
  }, t))]
220
219
  }, e.id);
221
220
  }) })]
222
- }), G.isOverlay && /* @__PURE__ */ p(l, {
221
+ }), G.isOverlay && /* @__PURE__ */ m(u, {
223
222
  ...G,
224
223
  title: "Record Details",
225
- children: (e) => /* @__PURE__ */ p("div", {
224
+ children: (e) => /* @__PURE__ */ m("div", {
226
225
  className: "space-y-3",
227
- children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ m("div", {
226
+ children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ h("div", {
228
227
  className: "flex flex-col",
229
- children: [/* @__PURE__ */ p("span", {
228
+ children: [/* @__PURE__ */ m("span", {
230
229
  className: "text-xs font-medium text-muted-foreground uppercase tracking-wide",
231
230
  children: e.replace(/_/g, " ")
232
- }), /* @__PURE__ */ p("span", {
231
+ }), /* @__PURE__ */ m("span", {
233
232
  className: "text-sm",
234
- children: w(t) || "—"
233
+ children: T(t) || "—"
235
234
  })]
236
235
  }, e))
237
236
  })
238
237
  })]
239
238
  });
240
- }, E = ({ schema: e, ...t }) => {
241
- let { dataSource: n } = c() || {};
242
- return /* @__PURE__ */ p(T, {
239
+ }, D = ({ schema: e, ...t }) => {
240
+ let { dataSource: n } = l() || {};
241
+ return /* @__PURE__ */ m(E, {
243
242
  schema: e,
244
243
  dataSource: n,
245
244
  ...t
246
245
  });
247
- }, D = [{
246
+ }, O = [{
248
247
  name: "objectName",
249
248
  type: "string",
250
249
  label: "Object Name",
@@ -255,16 +254,16 @@ var T = ({ schema: r, dataSource: c, className: g, onRowClick: y, ...b }) => {
255
254
  label: "Tree Config",
256
255
  description: "parentField, labelField, fields, defaultExpandedDepth"
257
256
  }];
258
- r.register("object-tree", E, {
257
+ r.register("object-tree", D, {
259
258
  namespace: "plugin-tree",
260
259
  label: "Object Tree",
261
260
  category: "view",
262
- inputs: D
263
- }), r.register("tree", E, {
261
+ inputs: O
262
+ }), r.register("tree", D, {
264
263
  namespace: "view",
265
264
  label: "Tree View",
266
265
  category: "view",
267
- inputs: D
266
+ inputs: O
268
267
  });
269
268
  //#endregion
270
- export { T as ObjectTree, E as ObjectTreeRenderer };
269
+ export { E as ObjectTree, D as ObjectTreeRenderer };
@@ -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("lucide-react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/core`,`@object-ui/react`,`@object-ui/components`,`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.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r,i,a,o){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var s=Object.create,c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty,p=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=u(t),a=0,o=i.length,s;a<o;a++)s=i[a],!f.call(e,s)&&s!==n&&c(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=l(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:s(d(e)),p(t||!e||!e.__esModule?c(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);function m(e){return e.data?e.data:e.staticData?{provider:`value`,items:e.staticData}:e.objectName?{provider:`object`,object:e.objectName}:null}function h(e){if(typeof e==`string`)return e;if(e&&typeof e==`object`)return e.name||e.fieldName||e.field||e.key}function g(e){let t=e.tree||e.filter?.tree||{},n=Array.isArray(e.fields)?e.fields:Array.isArray(t.fields)?t.fields:[];return{parentField:h(e.parentField??t.parentField),labelField:h(e.labelField??t.labelField??e.titleField)??`name`,fields:n.map(h).filter(e=>!!e),defaultExpandedDepth:e.defaultExpandedDepth??t.defaultExpandedDepth}}function _(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 v(e){let t=e?.id??e?._id;return t==null?void 0:String(t)}function y(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 b(e,t){let n=new Map,r=[];for(let t of e){let e=v(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=y(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 x(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 S(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 C(e){return e==null?``:String(typeof e==`object`?e.name??e.label??e.id??e._id??``:e)}var w=({schema:e,dataSource:s,className:c,onRowClick:l,...u})=>{let[d,f]=(0,t.useState)([]),[p,h]=(0,t.useState)(!0),[v,y]=(0,t.useState)(null),[w,T]=(0,t.useState)(null),E=(0,t.useMemo)(()=>m(e),[e]),D=Array.isArray(u.data)||Array.isArray(e.data)||E?.provider===`value`;(0,t.useEffect)(()=>{let t=!1;return D||(async()=>{try{if(!s||typeof s.getObjectSchema!=`function`)return;let n=E?.provider===`object`?E.object:e.objectName;if(!n)return;let r=await s.getObjectSchema(n);t||T(r)}catch(e){console.error(`[ObjectTree] Failed to fetch object schema:`,e)}})(),()=>{t=!0}},[e.objectName,s,E,D]),(0,t.useEffect)(()=>{let t=!1;return(async()=>{try{if(h(!0),y(null),E?.provider===`object`&&s&&typeof s.find==`function`){let r=(0,n.buildExpandFields)(w?.fields),i=await s.find(E.object,{$filter:e.filter,...r.length>0?{$expand:r}:{}});t||(f((0,n.extractRecords)(i)),h(!1));return}let r=u.data??e.data;if(Array.isArray(r)){t||(f(r),h(!1));return}if(E?.provider===`value`){t||(f(E.items??[]),h(!1));return}t||(f([]),h(!1))}catch(e){t||(y(e),h(!1))}})(),()=>{t=!0}},[E,s,e.filter,w,u.data]);let O=(0,t.useMemo)(()=>g(e),[e]),k=(0,t.useMemo)(()=>O.parentField??_(w,e.objectName),[O.parentField,w,e.objectName]),A=(0,t.useMemo)(()=>b(d,k),[d,k]),[j,M]=(0,t.useState)(new Set);(0,t.useEffect)(()=>{M(S(A,O.defaultExpandedDepth))},[A,O.defaultExpandedDepth]);let N=e=>M(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),P=(0,t.useMemo)(()=>x(A,j),[A,j]),F=(0,r.useSafeFieldLabel)(),I=(E?.provider===`object`?E.object:void 0)??e.objectName,L=e=>{let t=w?.fields?.[e]?.label||e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase());return I?F.fieldLabel(I,e,t):t},R=(0,r.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l});return v?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-destructive`,c),children:(0,o.jsxs)(`p`,{children:[`Failed to load tree: `,v.message]})}):p?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,o.jsx)(`p`,{children:`Loading…`})}):d.length===0?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,o.jsx)(`p`,{children:`No records`})}):(0,o.jsxs)(`div`,{className:(0,i.cn)(`w-full overflow-auto`,c),"data-testid":`object-tree`,children:[(0,o.jsxs)(`table`,{className:`w-full border-collapse text-sm`,children:[(0,o.jsx)(`thead`,{children:(0,o.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,o.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:L(O.labelField)}),O.fields.filter(e=>e!==O.labelField).map(e=>(0,o.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:L(e)},e))]})}),(0,o.jsx)(`tbody`,{children:P.map(e=>{let t=e.children.length>0,n=j.has(e.id);return(0,o.jsxs)(`tr`,{className:`border-b hover:bg-accent/50 cursor-pointer`,"data-testid":`object-tree-row`,"data-depth":e.depth,onClick:t=>R.handleClick(e.record,t),children:[(0,o.jsx)(`td`,{className:`px-3 py-2`,children:(0,o.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingLeft:`${e.depth*20}px`},children:[t?(0,o.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(),N(e.id)},children:n?(0,o.jsx)(a.ChevronDown,{className:`h-4 w-4`}):(0,o.jsx)(a.ChevronRight,{className:`h-4 w-4`})}):(0,o.jsx)(`span`,{className:`inline-block h-5 w-5`}),(0,o.jsx)(`span`,{className:`truncate`,children:C(e.record[O.labelField])||`—`})]})}),O.fields.filter(e=>e!==O.labelField).map(t=>(0,o.jsx)(`td`,{className:`px-3 py-2 text-muted-foreground`,children:C(e.record[t])},t))]},e.id)})})]}),R.isOverlay&&(0,o.jsx)(i.NavigationOverlay,{...R,title:`Record Details`,children:e=>(0,o.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,o.jsxs)(`div`,{className:`flex flex-col`,children:[(0,o.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,o.jsx)(`span`,{className:`text-sm`,children:C(t)||`—`})]},e))})})]})},T=({schema:e,...t})=>{let{dataSource:n}=(0,r.useSchemaContext)()||{};return(0,o.jsx)(w,{schema:e,dataSource:n,...t})},E=[{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`,T,{namespace:`plugin-tree`,label:`Object Tree`,category:`view`,inputs:E}),n.ComponentRegistry.register(`tree`,T,{namespace:`view`,label:`Tree View`,category:`view`,inputs:E}),e.ObjectTree=w,e.ObjectTreeRenderer=T});
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("lucide-react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/core`,`@object-ui/react`,`@object-ui/components`,`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.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r,i,a,o){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var s=Object.create,c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty,p=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=u(t),a=0,o=i.length,s;a<o;a++)s=i[a],!f.call(e,s)&&s!==n&&c(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=l(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:s(d(e)),p(t||!e||!e.__esModule?c(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);function m(e){return e.data?e.data:e.staticData?{provider:`value`,items:e.staticData}:e.objectName?{provider:`object`,object:e.objectName}:null}function h(e){return(0,n.columnIdentity)(e)||(e&&typeof e==`object`?e.key:void 0)||void 0}function g(e){let t=e.tree||e.filter?.tree||{},n=Array.isArray(e.fields)?e.fields:Array.isArray(t.fields)?t.fields:[];return{parentField:h(e.parentField??t.parentField),labelField:h(e.labelField??t.labelField??e.titleField)??`name`,fields:n.map(h).filter(e=>!!e),defaultExpandedDepth:e.defaultExpandedDepth??t.defaultExpandedDepth}}function _(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 v(e){let t=e?.id??e?._id;return t==null?void 0:String(t)}function y(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 b(e,t){let n=new Map,r=[];for(let t of e){let e=v(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=y(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 x(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 S(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 C(e){return e==null?``:String(typeof e==`object`?e.name??e.label??e.id??e._id??``:e)}var w=({schema:e,dataSource:s,className:c,onRowClick:l,...u})=>{let[d,f]=(0,t.useState)([]),[p,h]=(0,t.useState)(!0),[v,y]=(0,t.useState)(null),[w,T]=(0,t.useState)(null),E=(0,t.useMemo)(()=>m(e),[e]),D=Array.isArray(u.data)||Array.isArray(e.data)||E?.provider===`value`;(0,t.useEffect)(()=>{let t=!1;return D||(async()=>{try{if(!s||typeof s.getObjectSchema!=`function`)return;let n=E?.provider===`object`?E.object:e.objectName;if(!n)return;let r=await s.getObjectSchema(n);t||T(r)}catch(e){console.error(`[ObjectTree] Failed to fetch object schema:`,e)}})(),()=>{t=!0}},[e.objectName,s,E,D]),(0,t.useEffect)(()=>{let t=!1;return(async()=>{try{if(h(!0),y(null),E?.provider===`object`&&s&&typeof s.find==`function`){let r=(0,n.buildExpandFields)(w?.fields),i=await s.find(E.object,{$filter:e.filter,...r.length>0?{$expand:r}:{}});t||(f((0,n.extractRecords)(i)),h(!1));return}let r=u.data??e.data;if(Array.isArray(r)){t||(f(r),h(!1));return}if(E?.provider===`value`){t||(f(E.items??[]),h(!1));return}t||(f([]),h(!1))}catch(e){t||(y(e),h(!1))}})(),()=>{t=!0}},[E,s,e.filter,w,u.data]);let O=(0,t.useMemo)(()=>g(e),[e]),k=(0,t.useMemo)(()=>O.parentField??_(w,e.objectName),[O.parentField,w,e.objectName]),A=(0,t.useMemo)(()=>b(d,k),[d,k]),[j,M]=(0,t.useState)(new Set);(0,t.useEffect)(()=>{M(S(A,O.defaultExpandedDepth))},[A,O.defaultExpandedDepth]);let N=e=>M(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),P=(0,t.useMemo)(()=>x(A,j),[A,j]),F=(0,r.useSafeFieldLabel)(),I=(E?.provider===`object`?E.object:void 0)??e.objectName,L=e=>{let t=w?.fields?.[e]?.label||e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase());return I?F.fieldLabel(I,e,t):t},R=(0,r.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l});return v?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-destructive`,c),children:(0,o.jsxs)(`p`,{children:[`Failed to load tree: `,v.message]})}):p?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,o.jsx)(`p`,{children:`Loading…`})}):d.length===0?(0,o.jsx)(`div`,{className:(0,i.cn)(`flex items-center justify-center h-40 text-muted-foreground`,c),children:(0,o.jsx)(`p`,{children:`No records`})}):(0,o.jsxs)(`div`,{className:(0,i.cn)(`w-full overflow-auto`,c),"data-testid":`object-tree`,children:[(0,o.jsxs)(`table`,{className:`w-full border-collapse text-sm`,children:[(0,o.jsx)(`thead`,{children:(0,o.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,o.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:L(O.labelField)}),O.fields.filter(e=>e!==O.labelField).map(e=>(0,o.jsx)(`th`,{className:`px-3 py-2 font-medium`,children:L(e)},e))]})}),(0,o.jsx)(`tbody`,{children:P.map(e=>{let t=e.children.length>0,n=j.has(e.id);return(0,o.jsxs)(`tr`,{className:`border-b hover:bg-accent/50 cursor-pointer`,"data-testid":`object-tree-row`,"data-depth":e.depth,onClick:t=>R.handleClick(e.record,t),children:[(0,o.jsx)(`td`,{className:`px-3 py-2`,children:(0,o.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingLeft:`${e.depth*20}px`},children:[t?(0,o.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(),N(e.id)},children:n?(0,o.jsx)(a.ChevronDown,{className:`h-4 w-4`}):(0,o.jsx)(a.ChevronRight,{className:`h-4 w-4`})}):(0,o.jsx)(`span`,{className:`inline-block h-5 w-5`}),(0,o.jsx)(`span`,{className:`truncate`,children:C(e.record[O.labelField])||`—`})]})}),O.fields.filter(e=>e!==O.labelField).map(t=>(0,o.jsx)(`td`,{className:`px-3 py-2 text-muted-foreground`,children:C(e.record[t])},t))]},e.id)})})]}),R.isOverlay&&(0,o.jsx)(i.NavigationOverlay,{...R,title:`Record Details`,children:e=>(0,o.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,o.jsxs)(`div`,{className:`flex flex-col`,children:[(0,o.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,o.jsx)(`span`,{className:`text-sm`,children:C(t)||`—`})]},e))})})]})},T=({schema:e,...t})=>{let{dataSource:n}=(0,r.useSchemaContext)()||{};return(0,o.jsx)(w,{schema:e,dataSource:n,...t})},E=[{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`,T,{namespace:`plugin-tree`,label:`Object Tree`,category:`view`,inputs:E}),n.ComponentRegistry.register(`tree`,T,{namespace:`view`,label:`Tree View`,category:`view`,inputs:E}),e.ObjectTree=w,e.ObjectTreeRenderer=T});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-tree",
3
- "version": "16.1.0",
3
+ "version": "17.2.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Tree / tree-grid visualization plugin for Object UI",
@@ -24,12 +24,12 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@objectstack/spec": "^16.0.0-rc.0",
27
+ "@objectstack/spec": "^17.0.0-rc.1",
28
28
  "lucide-react": "^1.25.0",
29
- "@object-ui/components": "16.1.0",
30
- "@object-ui/core": "16.1.0",
31
- "@object-ui/react": "16.1.0",
32
- "@object-ui/types": "16.1.0"
29
+ "@object-ui/components": "17.2.0",
30
+ "@object-ui/core": "17.2.0",
31
+ "@object-ui/react": "17.2.0",
32
+ "@object-ui/types": "17.2.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "^18.0.0 || ^19.0.0",
@@ -38,7 +38,7 @@
38
38
  "devDependencies": {
39
39
  "@types/react": "19.2.17",
40
40
  "@types/react-dom": "19.2.3",
41
- "@vitejs/plugin-react": "^6.0.3",
41
+ "@vitejs/plugin-react": "^6.0.4",
42
42
  "typescript": "^6.0.3",
43
43
  "vite": "^8.1.5",
44
44
  "vite-plugin-dts": "^5.0.3"
@@ -70,7 +70,7 @@
70
70
  "build": "vite build",
71
71
  "test": "vitest run",
72
72
  "test:watch": "vitest",
73
- "type-check": "tsc --noEmit",
73
+ "type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
74
74
  "lint": "eslint ."
75
75
  }
76
76
  }