@object-ui/plugin-tree 17.1.0 → 17.3.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 +146 -0
- package/dist/ObjectTree.d.ts.map +1 -1
- package/dist/index.js +93 -91
- package/dist/index.umd.cjs +1 -1
- package/package.json +12 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,151 @@
|
|
|
1
1
|
# @object-ui/plugin-tree
|
|
2
2
|
|
|
3
|
+
## 17.3.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- aa36e60: Localize the record-detail headings that `ObjectKanban`, `ObjectTree` and
|
|
8
|
+
`ObjectView` build themselves (objectui#3459)
|
|
9
|
+
|
|
10
|
+
#3426 / PR #3457 keyed `ListView` and `ObjectGrid`; a repo-wide grep found the
|
|
11
|
+
same pattern in three more hosts, each string-building an English heading in
|
|
12
|
+
TypeScript so the surrounding drawer/panel was fully localized with one English
|
|
13
|
+
phrase on top of it.
|
|
14
|
+
|
|
15
|
+
- `packages/plugin-kanban/src/ObjectKanban.tsx` — the object-derived heading of
|
|
16
|
+
the card-detail drawer
|
|
17
|
+
- `packages/plugin-tree/src/ObjectTree.tsx` — the bare literal
|
|
18
|
+
`"Record Details"` handed to `NavigationOverlay`
|
|
19
|
+
- `packages/plugin-view/src/ObjectView.tsx` — `` `${objectLabel} Detail` `` on
|
|
20
|
+
the `mode: 'split'` panel
|
|
21
|
+
|
|
22
|
+
All three are user-reachable, each verified by a test that drives the real
|
|
23
|
+
interaction (render the block, click a card/row, read the heading), not by
|
|
24
|
+
inspection:
|
|
25
|
+
|
|
26
|
+
- `object-kanban` is a public page block whose `navigation` config DEFAULTS to
|
|
27
|
+
`{ mode: 'drawer' }`, so a board needs no authoring at all to open this
|
|
28
|
+
drawer on card click;
|
|
29
|
+
- `object-tree` needs `navigation: { mode: 'drawer' }` authored explicitly, and
|
|
30
|
+
every row's click is wired to `navigation.handleClick`;
|
|
31
|
+
- `object-view` declares `navigation` as an authorable input and maps
|
|
32
|
+
`mode: 'split'` onto the branch that renders this heading.
|
|
33
|
+
|
|
34
|
+
## What changed
|
|
35
|
+
|
|
36
|
+
Each call site now keys its heading through the existing `detail.*` pair —
|
|
37
|
+
`detail.recordDetailWithLabel` (`'{{label}} Detail'`) where an object label is
|
|
38
|
+
available, `detail.recordDetail` where none is. No new locale keys: both
|
|
39
|
+
already ship in all ten packs from #3457, and reusing them keeps one heading on
|
|
40
|
+
one control instead of minting per-plugin twins that drift.
|
|
41
|
+
|
|
42
|
+
Each plugin gains its own English defaults map, which is what
|
|
43
|
+
`createSafeTranslation` falls back to with no `I18nProvider` mounted;
|
|
44
|
+
`@object-ui/plugin-tree` gains a dependency on `@object-ui/i18n` for it.
|
|
45
|
+
|
|
46
|
+
## Visible English change
|
|
47
|
+
|
|
48
|
+
One, deliberate: the tree overlay's heading goes from the plural
|
|
49
|
+
`Record Details` to the singular `Record Detail` — the spelling the whole
|
|
50
|
+
`detail.*` family, including `NavigationOverlay`'s own default, already uses.
|
|
51
|
+
The maintainer ruled on normalizing the stray plurals rather than minting a
|
|
52
|
+
plural key; a repo-wide grep confirmed no `e2e/` spec and no unit test
|
|
53
|
+
addressed the old string.
|
|
54
|
+
|
|
55
|
+
Every other branch is byte-identical in English (`Contacts Detail`,
|
|
56
|
+
`Support cases Detail`, `Contacts Detail`), with and without a provider —
|
|
57
|
+
pinned by a provider-less test file per plugin, kept separate because
|
|
58
|
+
`initReactI18next` registers its instance as a module global that outlives
|
|
59
|
+
`cleanup()`.
|
|
60
|
+
|
|
61
|
+
The kanban's other former plural (`'Card Details'`) is NOT a visible change: it
|
|
62
|
+
sat on a branch that fires only when the board has no `objectName`, while the
|
|
63
|
+
drawer consuming it returns `null` on that very condition. It is keyed anyway
|
|
64
|
+
so the literal cannot leak if that guard ever relaxes, and it deliberately has
|
|
65
|
+
no test — an assertion there would pass because nothing renders.
|
|
66
|
+
|
|
67
|
+
- Updated dependencies [18cd432]
|
|
68
|
+
- Updated dependencies [532cf8b]
|
|
69
|
+
- Updated dependencies [680080a]
|
|
70
|
+
- Updated dependencies [a7651e6]
|
|
71
|
+
- Updated dependencies [d915c47]
|
|
72
|
+
- Updated dependencies [b71fc92]
|
|
73
|
+
- Updated dependencies [65516ba]
|
|
74
|
+
- Updated dependencies [94c5b7c]
|
|
75
|
+
- Updated dependencies [ca0fa8f]
|
|
76
|
+
- Updated dependencies [34595eb]
|
|
77
|
+
- Updated dependencies [3889ffb]
|
|
78
|
+
- Updated dependencies [5781fb1]
|
|
79
|
+
- Updated dependencies [7e2406a]
|
|
80
|
+
- Updated dependencies [9e9e9a9]
|
|
81
|
+
- Updated dependencies [56409c2]
|
|
82
|
+
- Updated dependencies [042e09d]
|
|
83
|
+
- Updated dependencies [9cbcbf4]
|
|
84
|
+
- Updated dependencies [85c4c9c]
|
|
85
|
+
- Updated dependencies [fd54c3e]
|
|
86
|
+
- Updated dependencies [4eeb932]
|
|
87
|
+
- Updated dependencies [5c856ec]
|
|
88
|
+
- Updated dependencies [23018cc]
|
|
89
|
+
- Updated dependencies [53811d1]
|
|
90
|
+
- Updated dependencies [68b6a28]
|
|
91
|
+
- Updated dependencies [0554e88]
|
|
92
|
+
- Updated dependencies [d915c47]
|
|
93
|
+
- Updated dependencies [f44d872]
|
|
94
|
+
- Updated dependencies [28b2e65]
|
|
95
|
+
- Updated dependencies [509104a]
|
|
96
|
+
- Updated dependencies [825bbe3]
|
|
97
|
+
- Updated dependencies [6195841]
|
|
98
|
+
- Updated dependencies [5dd0127]
|
|
99
|
+
- Updated dependencies [06632e9]
|
|
100
|
+
- Updated dependencies [a415684]
|
|
101
|
+
- Updated dependencies [a4cff5b]
|
|
102
|
+
- Updated dependencies [175bd79]
|
|
103
|
+
- Updated dependencies [5af2852]
|
|
104
|
+
- Updated dependencies [f833d3a]
|
|
105
|
+
- Updated dependencies [a6ec93d]
|
|
106
|
+
- Updated dependencies [2a9513d]
|
|
107
|
+
- Updated dependencies [71be406]
|
|
108
|
+
- Updated dependencies [d22ae31]
|
|
109
|
+
- Updated dependencies [c7ed4c3]
|
|
110
|
+
- Updated dependencies [2409e1d]
|
|
111
|
+
- Updated dependencies [789fe3e]
|
|
112
|
+
- Updated dependencies [8d8094a]
|
|
113
|
+
- @object-ui/core@17.3.0
|
|
114
|
+
- @object-ui/components@17.3.0
|
|
115
|
+
- @object-ui/types@17.3.0
|
|
116
|
+
- @object-ui/i18n@17.3.0
|
|
117
|
+
- @object-ui/react@17.3.0
|
|
118
|
+
|
|
119
|
+
## 17.2.0
|
|
120
|
+
|
|
121
|
+
### Patch Changes
|
|
122
|
+
|
|
123
|
+
- Updated dependencies [4ae0ac4]
|
|
124
|
+
- Updated dependencies [696e3c1]
|
|
125
|
+
- Updated dependencies [bca45cc]
|
|
126
|
+
- Updated dependencies [a889e31]
|
|
127
|
+
- Updated dependencies [09d30a4]
|
|
128
|
+
- Updated dependencies [4bf612c]
|
|
129
|
+
- Updated dependencies [335041c]
|
|
130
|
+
- Updated dependencies [b414983]
|
|
131
|
+
- Updated dependencies [256f8cc]
|
|
132
|
+
- Updated dependencies [d9668a7]
|
|
133
|
+
- Updated dependencies [cb82705]
|
|
134
|
+
- Updated dependencies [f572849]
|
|
135
|
+
- Updated dependencies [f6e8d78]
|
|
136
|
+
- Updated dependencies [ea96284]
|
|
137
|
+
- Updated dependencies [d3584c6]
|
|
138
|
+
- Updated dependencies [a8ad6c0]
|
|
139
|
+
- Updated dependencies [444457c]
|
|
140
|
+
- Updated dependencies [850033c]
|
|
141
|
+
- Updated dependencies [022e4c3]
|
|
142
|
+
- Updated dependencies [009e25d]
|
|
143
|
+
- Updated dependencies [726b89c]
|
|
144
|
+
- @object-ui/types@17.2.0
|
|
145
|
+
- @object-ui/components@17.2.0
|
|
146
|
+
- @object-ui/core@17.2.0
|
|
147
|
+
- @object-ui/react@17.2.0
|
|
148
|
+
|
|
3
149
|
## 17.1.0
|
|
4
150
|
|
|
5
151
|
### Patch Changes
|
package/dist/ObjectTree.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectTree.d.ts","sourceRoot":"","sources":["../src/ObjectTree.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ObjectTree.d.ts","sourceRoot":"","sources":["../src/ObjectTree.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,kBAAkB,CAAC;AA+B7D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6KD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgRhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,12 @@ import { useEffect as e, useMemo as t, useState as n } from "react";
|
|
|
2
2
|
import { ComponentRegistry as r, buildExpandFields as i, columnIdentity as a, extractRecords as o } from "@object-ui/core";
|
|
3
3
|
import { useNavigationOverlay as s, useSafeFieldLabel as c, useSchemaContext as l } from "@object-ui/react";
|
|
4
4
|
import { NavigationOverlay as u, cn as d } from "@object-ui/components";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { createSafeTranslation as f } from "@object-ui/i18n";
|
|
6
|
+
import { ChevronDown as p, ChevronRight as m } from "lucide-react";
|
|
7
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
7
8
|
//#region src/ObjectTree.tsx
|
|
8
|
-
|
|
9
|
+
var _ = f({ "detail.recordDetail": "Record Detail" }, "detail.recordDetail");
|
|
10
|
+
function v(e) {
|
|
9
11
|
return e.data ? e.data : e.staticData ? {
|
|
10
12
|
provider: "value",
|
|
11
13
|
items: e.staticData
|
|
@@ -14,19 +16,19 @@ function g(e) {
|
|
|
14
16
|
object: e.objectName
|
|
15
17
|
} : null;
|
|
16
18
|
}
|
|
17
|
-
function
|
|
19
|
+
function y(e) {
|
|
18
20
|
return a(e) || (e && typeof e == "object" ? e.key : void 0) || void 0;
|
|
19
21
|
}
|
|
20
|
-
function
|
|
22
|
+
function b(e) {
|
|
21
23
|
let t = e.tree || e.filter?.tree || {}, n = Array.isArray(e.fields) ? e.fields : Array.isArray(t.fields) ? t.fields : [];
|
|
22
24
|
return {
|
|
23
|
-
parentField:
|
|
24
|
-
labelField:
|
|
25
|
-
fields: n.map(
|
|
25
|
+
parentField: y(e.parentField ?? t.parentField),
|
|
26
|
+
labelField: y(e.labelField ?? t.labelField ?? e.titleField) ?? "name",
|
|
27
|
+
fields: n.map(y).filter((e) => !!e),
|
|
26
28
|
defaultExpandedDepth: e.defaultExpandedDepth ?? t.defaultExpandedDepth
|
|
27
29
|
};
|
|
28
30
|
}
|
|
29
|
-
function
|
|
31
|
+
function x(e, t) {
|
|
30
32
|
let n = e?.fields;
|
|
31
33
|
if (!n || typeof n != "object") return;
|
|
32
34
|
let r;
|
|
@@ -37,11 +39,11 @@ function y(e, t) {
|
|
|
37
39
|
}
|
|
38
40
|
return r;
|
|
39
41
|
}
|
|
40
|
-
function
|
|
42
|
+
function S(e) {
|
|
41
43
|
let t = e?.id ?? e?._id;
|
|
42
44
|
return t == null ? void 0 : String(t);
|
|
43
45
|
}
|
|
44
|
-
function
|
|
46
|
+
function C(e, t) {
|
|
45
47
|
if (!t) return;
|
|
46
48
|
let n = e?.[t];
|
|
47
49
|
if (n != null) {
|
|
@@ -52,10 +54,10 @@ function x(e, t) {
|
|
|
52
54
|
return String(n);
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
|
-
function
|
|
57
|
+
function w(e, t) {
|
|
56
58
|
let n = /* @__PURE__ */ new Map(), r = [];
|
|
57
59
|
for (let t of e) {
|
|
58
|
-
let e =
|
|
60
|
+
let e = S(t);
|
|
59
61
|
e != null && (n.set(e, {
|
|
60
62
|
id: e,
|
|
61
63
|
record: t,
|
|
@@ -65,7 +67,7 @@ function S(e, t) {
|
|
|
65
67
|
}
|
|
66
68
|
let i = [];
|
|
67
69
|
for (let e of r) {
|
|
68
|
-
let r = n.get(e), a =
|
|
70
|
+
let r = n.get(e), a = C(r.record, t), o = a == null ? void 0 : n.get(a);
|
|
69
71
|
o && o !== r ? o.children.push(r) : i.push(r);
|
|
70
72
|
}
|
|
71
73
|
let a = (e, t) => {
|
|
@@ -73,32 +75,32 @@ function S(e, t) {
|
|
|
73
75
|
};
|
|
74
76
|
return a(i, 0), i;
|
|
75
77
|
}
|
|
76
|
-
function
|
|
78
|
+
function T(e, t) {
|
|
77
79
|
let n = [], r = (e) => {
|
|
78
80
|
for (let i of e) n.push(i), i.children.length > 0 && t.has(i.id) && r(i.children);
|
|
79
81
|
};
|
|
80
82
|
return r(e), n;
|
|
81
83
|
}
|
|
82
|
-
function
|
|
84
|
+
function E(e, t) {
|
|
83
85
|
let n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
84
86
|
for (let i of e) i.children.length !== 0 && (t == null || i.depth < t) && (n.add(i.id), r(i.children));
|
|
85
87
|
};
|
|
86
88
|
return r(e), n;
|
|
87
89
|
}
|
|
88
|
-
function
|
|
90
|
+
function D(e) {
|
|
89
91
|
return e == null ? "" : String(typeof e == "object" ? e.name ?? e.label ?? e.id ?? e._id ?? "" : e);
|
|
90
92
|
}
|
|
91
|
-
var
|
|
92
|
-
let [
|
|
93
|
+
var O = ({ schema: r, dataSource: a, className: l, onRowClick: f, ...y }) => {
|
|
94
|
+
let [S, C] = n([]), [O, k] = n(!0), [A, j] = n(null), [M, N] = n(null), P = t(() => v(r), [r]), F = Array.isArray(y.data) || Array.isArray(r.data) || P?.provider === "value";
|
|
93
95
|
e(() => {
|
|
94
96
|
let e = !1;
|
|
95
|
-
return
|
|
97
|
+
return F || (async () => {
|
|
96
98
|
try {
|
|
97
99
|
if (!a || typeof a.getObjectSchema != "function") return;
|
|
98
|
-
let t =
|
|
100
|
+
let t = P?.provider === "object" ? P.object : r.objectName;
|
|
99
101
|
if (!t) return;
|
|
100
102
|
let n = await a.getObjectSchema(t);
|
|
101
|
-
e ||
|
|
103
|
+
e || N(n);
|
|
102
104
|
} catch (e) {
|
|
103
105
|
console.error("[ObjectTree] Failed to fetch object schema:", e);
|
|
104
106
|
}
|
|
@@ -108,142 +110,142 @@ var E = ({ schema: r, dataSource: a, className: l, onRowClick: _, ...b }) => {
|
|
|
108
110
|
}, [
|
|
109
111
|
r.objectName,
|
|
110
112
|
a,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
P,
|
|
114
|
+
F
|
|
113
115
|
]), e(() => {
|
|
114
116
|
let e = !1;
|
|
115
117
|
return (async () => {
|
|
116
118
|
try {
|
|
117
|
-
if (
|
|
118
|
-
let t = i(
|
|
119
|
+
if (k(!0), j(null), P?.provider === "object" && a && typeof a.find == "function") {
|
|
120
|
+
let t = i(M?.fields), n = await a.find(P.object, {
|
|
119
121
|
$filter: r.filter,
|
|
120
122
|
...t.length > 0 ? { $expand: t } : {}
|
|
121
123
|
});
|
|
122
|
-
e || (
|
|
124
|
+
e || (C(o(n)), k(!1));
|
|
123
125
|
return;
|
|
124
126
|
}
|
|
125
|
-
let t =
|
|
127
|
+
let t = y.data ?? r.data;
|
|
126
128
|
if (Array.isArray(t)) {
|
|
127
|
-
e || (
|
|
129
|
+
e || (C(t), k(!1));
|
|
128
130
|
return;
|
|
129
131
|
}
|
|
130
|
-
if (
|
|
131
|
-
e || (
|
|
132
|
+
if (P?.provider === "value") {
|
|
133
|
+
e || (C(P.items ?? []), k(!1));
|
|
132
134
|
return;
|
|
133
135
|
}
|
|
134
|
-
e || (
|
|
136
|
+
e || (C([]), k(!1));
|
|
135
137
|
} catch (t) {
|
|
136
|
-
e || (
|
|
138
|
+
e || (j(t), k(!1));
|
|
137
139
|
}
|
|
138
140
|
})(), () => {
|
|
139
141
|
e = !0;
|
|
140
142
|
};
|
|
141
143
|
}, [
|
|
142
|
-
|
|
144
|
+
P,
|
|
143
145
|
a,
|
|
144
146
|
r.filter,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
M,
|
|
148
|
+
y.data
|
|
147
149
|
]);
|
|
148
|
-
let
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
let I = t(() => b(r), [r]), L = t(() => I.parentField ?? x(M, r.objectName), [
|
|
151
|
+
I.parentField,
|
|
152
|
+
M,
|
|
151
153
|
r.objectName
|
|
152
|
-
]),
|
|
154
|
+
]), R = t(() => w(S, L), [S, L]), [z, B] = n(/* @__PURE__ */ new Set());
|
|
153
155
|
e(() => {
|
|
154
|
-
|
|
155
|
-
}, [
|
|
156
|
-
let
|
|
156
|
+
B(E(R, I.defaultExpandedDepth));
|
|
157
|
+
}, [R, I.defaultExpandedDepth]);
|
|
158
|
+
let V = (e) => B((t) => {
|
|
157
159
|
let n = new Set(t);
|
|
158
160
|
return n.has(e) ? n.delete(e) : n.add(e), n;
|
|
159
|
-
}),
|
|
160
|
-
let t =
|
|
161
|
-
return
|
|
162
|
-
},
|
|
161
|
+
}), H = t(() => T(R, z), [R, z]), U = c(), W = (P?.provider === "object" ? P.object : void 0) ?? r.objectName, G = (e) => {
|
|
162
|
+
let t = M?.fields?.[e]?.label || e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
|
|
163
|
+
return W ? U.fieldLabel(W, e, t) : t;
|
|
164
|
+
}, K = s({
|
|
163
165
|
navigation: r.navigation,
|
|
164
166
|
objectName: r.objectName,
|
|
165
|
-
onRowClick:
|
|
166
|
-
});
|
|
167
|
-
return
|
|
167
|
+
onRowClick: f
|
|
168
|
+
}), { t: q } = _();
|
|
169
|
+
return A ? /* @__PURE__ */ h("div", {
|
|
168
170
|
className: d("flex items-center justify-center h-40 text-destructive", l),
|
|
169
|
-
children: /* @__PURE__ */
|
|
170
|
-
}) :
|
|
171
|
+
children: /* @__PURE__ */ g("p", { children: ["Failed to load tree: ", A.message] })
|
|
172
|
+
}) : O ? /* @__PURE__ */ h("div", {
|
|
171
173
|
className: d("flex items-center justify-center h-40 text-muted-foreground", l),
|
|
172
|
-
children: /* @__PURE__ */
|
|
173
|
-
}) :
|
|
174
|
+
children: /* @__PURE__ */ h("p", { children: "Loading…" })
|
|
175
|
+
}) : S.length === 0 ? /* @__PURE__ */ h("div", {
|
|
174
176
|
className: d("flex items-center justify-center h-40 text-muted-foreground", l),
|
|
175
|
-
children: /* @__PURE__ */
|
|
176
|
-
}) : /* @__PURE__ */
|
|
177
|
+
children: /* @__PURE__ */ h("p", { children: "No records" })
|
|
178
|
+
}) : /* @__PURE__ */ g("div", {
|
|
177
179
|
className: d("w-full overflow-auto", l),
|
|
178
180
|
"data-testid": "object-tree",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
181
|
+
children: [/* @__PURE__ */ g("table", {
|
|
180
182
|
className: "w-full border-collapse text-sm",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
183
|
+
children: [/* @__PURE__ */ h("thead", { children: /* @__PURE__ */ g("tr", {
|
|
182
184
|
className: "border-b text-left text-muted-foreground",
|
|
183
|
-
children: [/* @__PURE__ */
|
|
185
|
+
children: [/* @__PURE__ */ h("th", {
|
|
184
186
|
className: "px-3 py-2 font-medium",
|
|
185
|
-
children:
|
|
186
|
-
}),
|
|
187
|
+
children: G(I.labelField)
|
|
188
|
+
}), I.fields.filter((e) => e !== I.labelField).map((e) => /* @__PURE__ */ h("th", {
|
|
187
189
|
className: "px-3 py-2 font-medium",
|
|
188
|
-
children:
|
|
190
|
+
children: G(e)
|
|
189
191
|
}, e))]
|
|
190
|
-
}) }), /* @__PURE__ */
|
|
191
|
-
let t = e.children.length > 0, n =
|
|
192
|
-
return /* @__PURE__ */
|
|
192
|
+
}) }), /* @__PURE__ */ h("tbody", { children: H.map((e) => {
|
|
193
|
+
let t = e.children.length > 0, n = z.has(e.id);
|
|
194
|
+
return /* @__PURE__ */ g("tr", {
|
|
193
195
|
className: "border-b hover:bg-accent/50 cursor-pointer",
|
|
194
196
|
"data-testid": "object-tree-row",
|
|
195
197
|
"data-depth": e.depth,
|
|
196
|
-
onClick: (t) =>
|
|
197
|
-
children: [/* @__PURE__ */
|
|
198
|
+
onClick: (t) => K.handleClick(e.record, t),
|
|
199
|
+
children: [/* @__PURE__ */ h("td", {
|
|
198
200
|
className: "px-3 py-2",
|
|
199
|
-
children: /* @__PURE__ */
|
|
201
|
+
children: /* @__PURE__ */ g("div", {
|
|
200
202
|
className: "flex items-center gap-1",
|
|
201
203
|
style: { paddingLeft: `${e.depth * 20}px` },
|
|
202
|
-
children: [t ? /* @__PURE__ */
|
|
204
|
+
children: [t ? /* @__PURE__ */ h("button", {
|
|
203
205
|
type: "button",
|
|
204
206
|
"aria-label": n ? "Collapse" : "Expand",
|
|
205
207
|
className: "flex h-5 w-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted",
|
|
206
208
|
onClick: (t) => {
|
|
207
|
-
t.stopPropagation(),
|
|
209
|
+
t.stopPropagation(), V(e.id);
|
|
208
210
|
},
|
|
209
|
-
children:
|
|
210
|
-
}) : /* @__PURE__ */
|
|
211
|
+
children: h(n ? p : m, { className: "h-4 w-4" })
|
|
212
|
+
}) : /* @__PURE__ */ h("span", { className: "inline-block h-5 w-5" }), /* @__PURE__ */ h("span", {
|
|
211
213
|
className: "truncate",
|
|
212
|
-
children:
|
|
214
|
+
children: D(e.record[I.labelField]) || "—"
|
|
213
215
|
})]
|
|
214
216
|
})
|
|
215
|
-
}),
|
|
217
|
+
}), I.fields.filter((e) => e !== I.labelField).map((t) => /* @__PURE__ */ h("td", {
|
|
216
218
|
className: "px-3 py-2 text-muted-foreground",
|
|
217
|
-
children:
|
|
219
|
+
children: D(e.record[t])
|
|
218
220
|
}, t))]
|
|
219
221
|
}, e.id);
|
|
220
222
|
}) })]
|
|
221
|
-
}),
|
|
222
|
-
...
|
|
223
|
-
title: "
|
|
224
|
-
children: (e) => /* @__PURE__ */
|
|
223
|
+
}), K.isOverlay && /* @__PURE__ */ h(u, {
|
|
224
|
+
...K,
|
|
225
|
+
title: q("detail.recordDetail"),
|
|
226
|
+
children: (e) => /* @__PURE__ */ h("div", {
|
|
225
227
|
className: "space-y-3",
|
|
226
|
-
children: Object.entries(e).map(([e, t]) => /* @__PURE__ */
|
|
228
|
+
children: Object.entries(e).map(([e, t]) => /* @__PURE__ */ g("div", {
|
|
227
229
|
className: "flex flex-col",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
230
|
+
children: [/* @__PURE__ */ h("span", {
|
|
229
231
|
className: "text-xs font-medium text-muted-foreground uppercase tracking-wide",
|
|
230
232
|
children: e.replace(/_/g, " ")
|
|
231
|
-
}), /* @__PURE__ */
|
|
233
|
+
}), /* @__PURE__ */ h("span", {
|
|
232
234
|
className: "text-sm",
|
|
233
|
-
children:
|
|
235
|
+
children: D(t) || "—"
|
|
234
236
|
})]
|
|
235
237
|
}, e))
|
|
236
238
|
})
|
|
237
239
|
})]
|
|
238
240
|
});
|
|
239
|
-
},
|
|
241
|
+
}, k = ({ schema: e, ...t }) => {
|
|
240
242
|
let { dataSource: n } = l() || {};
|
|
241
|
-
return /* @__PURE__ */
|
|
243
|
+
return /* @__PURE__ */ h(O, {
|
|
242
244
|
schema: e,
|
|
243
245
|
dataSource: n,
|
|
244
246
|
...t
|
|
245
247
|
});
|
|
246
|
-
},
|
|
248
|
+
}, A = [{
|
|
247
249
|
name: "objectName",
|
|
248
250
|
type: "string",
|
|
249
251
|
label: "Object Name",
|
|
@@ -254,16 +256,16 @@ var E = ({ schema: r, dataSource: a, className: l, onRowClick: _, ...b }) => {
|
|
|
254
256
|
label: "Tree Config",
|
|
255
257
|
description: "parentField, labelField, fields, defaultExpandedDepth"
|
|
256
258
|
}];
|
|
257
|
-
r.register("object-tree",
|
|
259
|
+
r.register("object-tree", k, {
|
|
258
260
|
namespace: "plugin-tree",
|
|
259
261
|
label: "Object Tree",
|
|
260
262
|
category: "view",
|
|
261
|
-
inputs:
|
|
262
|
-
}), r.register("tree",
|
|
263
|
+
inputs: A
|
|
264
|
+
}), r.register("tree", k, {
|
|
263
265
|
namespace: "view",
|
|
264
266
|
label: "Tree View",
|
|
265
267
|
category: "view",
|
|
266
|
-
inputs:
|
|
268
|
+
inputs: A
|
|
267
269
|
});
|
|
268
270
|
//#endregion
|
|
269
|
-
export {
|
|
271
|
+
export { O as ObjectTree, k 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("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
|
|
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});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-tree",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Tree / tree-grid visualization plugin for Object UI",
|
|
@@ -24,23 +24,24 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@objectstack/spec": "^17.0.0-rc.
|
|
28
|
-
"lucide-react": "^1.
|
|
29
|
-
"@object-ui/components": "17.
|
|
30
|
-
"@object-ui/core": "17.
|
|
31
|
-
"@object-ui/
|
|
32
|
-
"@object-ui/
|
|
27
|
+
"@objectstack/spec": "^17.0.0-rc.2",
|
|
28
|
+
"lucide-react": "^1.28.0",
|
|
29
|
+
"@object-ui/components": "17.3.0",
|
|
30
|
+
"@object-ui/core": "17.3.0",
|
|
31
|
+
"@object-ui/i18n": "17.3.0",
|
|
32
|
+
"@object-ui/react": "17.3.0",
|
|
33
|
+
"@object-ui/types": "17.3.0"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
36
|
"react": "^18.0.0 || ^19.0.0",
|
|
36
37
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@types/react": "19.2.
|
|
40
|
-
"@types/react-dom": "19.2.
|
|
41
|
-
"@vitejs/plugin-react": "^6.0.
|
|
40
|
+
"@types/react": "19.2.18",
|
|
41
|
+
"@types/react-dom": "19.2.4",
|
|
42
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
42
43
|
"typescript": "^6.0.3",
|
|
43
|
-
"vite": "^8.
|
|
44
|
+
"vite": "^8.2.0",
|
|
44
45
|
"vite-plugin-dts": "^5.0.3"
|
|
45
46
|
},
|
|
46
47
|
"keywords": [
|