@osdk/react-components 0.1.0-beta.1 → 0.1.0-beta.2
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 +15 -0
- package/build/browser/object-table/CellContextMenu.js +48 -0
- package/build/browser/object-table/CellContextMenu.js.map +1 -0
- package/build/browser/object-table/ObjectTable.js +53 -9
- package/build/browser/object-table/ObjectTable.js.map +1 -1
- package/build/browser/object-table/ObjectTableApi.js.map +1 -1
- package/build/browser/object-table/SelectionCells.js +67 -0
- package/build/browser/object-table/SelectionCells.js.map +1 -0
- package/build/browser/object-table/Table.js +8 -4
- package/build/browser/object-table/Table.js.map +1 -1
- package/build/browser/object-table/TableBody.js +3 -1
- package/build/browser/object-table/TableBody.js.map +1 -1
- package/build/browser/object-table/TableCell.js +51 -0
- package/build/browser/object-table/TableCell.js.map +1 -0
- package/build/browser/object-table/TableHeader.js +20 -4
- package/build/browser/object-table/TableHeader.js.map +1 -1
- package/build/browser/object-table/TableRow.js +7 -9
- package/build/browser/object-table/TableRow.js.map +1 -1
- package/build/browser/object-table/hooks/__tests__/useCellContextMenu.test.js +147 -0
- package/build/browser/object-table/hooks/__tests__/useCellContextMenu.test.js.map +1 -0
- package/build/browser/object-table/hooks/__tests__/useObjectTableData.test.js +12 -0
- package/build/browser/object-table/hooks/__tests__/useObjectTableData.test.js.map +1 -1
- package/build/browser/object-table/hooks/__tests__/useRowSelection.test.js +548 -0
- package/build/browser/object-table/hooks/__tests__/useRowSelection.test.js.map +1 -0
- package/build/browser/object-table/hooks/__tests__/useSelectionColumn.test.js +274 -0
- package/build/browser/object-table/hooks/__tests__/useSelectionColumn.test.js.map +1 -0
- package/build/browser/object-table/hooks/useCellContextMenu.js +48 -0
- package/build/browser/object-table/hooks/useCellContextMenu.js.map +1 -0
- package/build/browser/object-table/hooks/useColumnDefs.js.map +1 -1
- package/build/browser/object-table/hooks/useObjectTableData.js +3 -2
- package/build/browser/object-table/hooks/useObjectTableData.js.map +1 -1
- package/build/browser/object-table/hooks/useRowSelection.js +180 -0
- package/build/browser/object-table/hooks/useRowSelection.js.map +1 -0
- package/build/browser/object-table/hooks/useSelectionColumn.js +51 -0
- package/build/browser/object-table/hooks/useSelectionColumn.js.map +1 -0
- package/build/browser/object-table/utils/getRowId.js +21 -0
- package/build/browser/object-table/utils/getRowId.js.map +1 -0
- package/build/browser/public/experimental.js +1 -0
- package/build/browser/public/experimental.js.map +1 -1
- package/build/cjs/public/experimental.cjs +406 -30
- package/build/cjs/public/experimental.cjs.map +1 -1
- package/build/cjs/public/experimental.d.cts +6 -11
- package/build/esm/object-table/CellContextMenu.js +48 -0
- package/build/esm/object-table/CellContextMenu.js.map +1 -0
- package/build/esm/object-table/ObjectTable.js +53 -9
- package/build/esm/object-table/ObjectTable.js.map +1 -1
- package/build/esm/object-table/ObjectTableApi.js.map +1 -1
- package/build/esm/object-table/SelectionCells.js +67 -0
- package/build/esm/object-table/SelectionCells.js.map +1 -0
- package/build/esm/object-table/Table.js +8 -4
- package/build/esm/object-table/Table.js.map +1 -1
- package/build/esm/object-table/TableBody.js +3 -1
- package/build/esm/object-table/TableBody.js.map +1 -1
- package/build/esm/object-table/TableCell.js +51 -0
- package/build/esm/object-table/TableCell.js.map +1 -0
- package/build/esm/object-table/TableHeader.js +20 -4
- package/build/esm/object-table/TableHeader.js.map +1 -1
- package/build/esm/object-table/TableRow.js +7 -9
- package/build/esm/object-table/TableRow.js.map +1 -1
- package/build/esm/object-table/hooks/__tests__/useCellContextMenu.test.js +147 -0
- package/build/esm/object-table/hooks/__tests__/useCellContextMenu.test.js.map +1 -0
- package/build/esm/object-table/hooks/__tests__/useObjectTableData.test.js +12 -0
- package/build/esm/object-table/hooks/__tests__/useObjectTableData.test.js.map +1 -1
- package/build/esm/object-table/hooks/__tests__/useRowSelection.test.js +548 -0
- package/build/esm/object-table/hooks/__tests__/useRowSelection.test.js.map +1 -0
- package/build/esm/object-table/hooks/__tests__/useSelectionColumn.test.js +274 -0
- package/build/esm/object-table/hooks/__tests__/useSelectionColumn.test.js.map +1 -0
- package/build/esm/object-table/hooks/useCellContextMenu.js +48 -0
- package/build/esm/object-table/hooks/useCellContextMenu.js.map +1 -0
- package/build/esm/object-table/hooks/useColumnDefs.js.map +1 -1
- package/build/esm/object-table/hooks/useObjectTableData.js +3 -2
- package/build/esm/object-table/hooks/useObjectTableData.js.map +1 -1
- package/build/esm/object-table/hooks/useRowSelection.js +180 -0
- package/build/esm/object-table/hooks/useRowSelection.js.map +1 -0
- package/build/esm/object-table/hooks/useSelectionColumn.js +51 -0
- package/build/esm/object-table/hooks/useSelectionColumn.js.map +1 -0
- package/build/esm/object-table/utils/getRowId.js +21 -0
- package/build/esm/object-table/utils/getRowId.js.map +1 -0
- package/build/esm/public/experimental.js +1 -0
- package/build/esm/public/experimental.js.map +1 -1
- package/build/types/object-table/CellContextMenu.d.ts +11 -0
- package/build/types/object-table/CellContextMenu.d.ts.map +1 -0
- package/build/types/object-table/ObjectTable.d.ts +1 -1
- package/build/types/object-table/ObjectTable.d.ts.map +1 -1
- package/build/types/object-table/ObjectTableApi.d.ts +5 -10
- package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
- package/build/types/object-table/SelectionCells.d.ts +14 -0
- package/build/types/object-table/SelectionCells.d.ts.map +1 -0
- package/build/types/object-table/Table.d.ts +4 -3
- package/build/types/object-table/Table.d.ts.map +1 -1
- package/build/types/object-table/TableBody.d.ts +3 -2
- package/build/types/object-table/TableBody.d.ts.map +1 -1
- package/build/types/object-table/TableCell.d.ts +8 -0
- package/build/types/object-table/TableCell.d.ts.map +1 -0
- package/build/types/object-table/TableHeader.d.ts +3 -3
- package/build/types/object-table/TableHeader.d.ts.map +1 -1
- package/build/types/object-table/TableRow.d.ts +3 -2
- package/build/types/object-table/TableRow.d.ts.map +1 -1
- package/build/types/object-table/hooks/__tests__/useCellContextMenu.test.d.ts +1 -0
- package/build/types/object-table/hooks/__tests__/useCellContextMenu.test.d.ts.map +1 -0
- package/build/types/object-table/hooks/__tests__/useRowSelection.test.d.ts +1 -0
- package/build/types/object-table/hooks/__tests__/useRowSelection.test.d.ts.map +1 -0
- package/build/types/object-table/hooks/__tests__/useSelectionColumn.test.d.ts +1 -0
- package/build/types/object-table/hooks/__tests__/useSelectionColumn.test.d.ts.map +1 -0
- package/build/types/object-table/hooks/useCellContextMenu.d.ts +17 -0
- package/build/types/object-table/hooks/useCellContextMenu.d.ts.map +1 -0
- package/build/types/object-table/hooks/useObjectTableData.d.ts +2 -2
- package/build/types/object-table/hooks/useObjectTableData.d.ts.map +1 -1
- package/build/types/object-table/hooks/useRowSelection.d.ts +22 -0
- package/build/types/object-table/hooks/useRowSelection.d.ts.map +1 -0
- package/build/types/object-table/hooks/useSelectionColumn.d.ts +15 -0
- package/build/types/object-table/hooks/useSelectionColumn.d.ts.map +1 -0
- package/build/types/object-table/utils/getRowId.d.ts +6 -0
- package/build/types/object-table/utils/getRowId.d.ts.map +1 -0
- package/build/types/public/experimental.d.ts.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { renderHook } from "@testing-library/react";
|
|
18
|
+
import { describe, expect, it, vi } from "vitest";
|
|
19
|
+
import { SELECTION_COLUMN_ID, useSelectionColumn } from "../useSelectionColumn.js";
|
|
20
|
+
const TestObjectType = {
|
|
21
|
+
type: "object",
|
|
22
|
+
apiName: "TestObject"
|
|
23
|
+
};
|
|
24
|
+
describe("useSelectionColumn", () => {
|
|
25
|
+
describe("selectionMode: 'none'", () => {
|
|
26
|
+
it("returns null when selection is disabled", () => {
|
|
27
|
+
const {
|
|
28
|
+
result
|
|
29
|
+
} = renderHook(() => useSelectionColumn({
|
|
30
|
+
selectionMode: "none",
|
|
31
|
+
isAllSelected: false,
|
|
32
|
+
hasSelection: false,
|
|
33
|
+
onToggleAll: vi.fn(),
|
|
34
|
+
onToggleRow: vi.fn()
|
|
35
|
+
}));
|
|
36
|
+
expect(result.current).toBeNull();
|
|
37
|
+
});
|
|
38
|
+
it("returns null even with selection state", () => {
|
|
39
|
+
const {
|
|
40
|
+
result
|
|
41
|
+
} = renderHook(() => useSelectionColumn({
|
|
42
|
+
selectionMode: "none",
|
|
43
|
+
isAllSelected: true,
|
|
44
|
+
hasSelection: true,
|
|
45
|
+
onToggleAll: vi.fn(),
|
|
46
|
+
onToggleRow: vi.fn()
|
|
47
|
+
}));
|
|
48
|
+
expect(result.current).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("selectionMode: 'single'", () => {
|
|
52
|
+
it("returns column definition with correct properties", () => {
|
|
53
|
+
const {
|
|
54
|
+
result
|
|
55
|
+
} = renderHook(() => useSelectionColumn({
|
|
56
|
+
selectionMode: "single",
|
|
57
|
+
isAllSelected: false,
|
|
58
|
+
hasSelection: false,
|
|
59
|
+
onToggleAll: vi.fn(),
|
|
60
|
+
onToggleRow: vi.fn()
|
|
61
|
+
}));
|
|
62
|
+
expect(result.current).not.toBeNull();
|
|
63
|
+
expect(result.current).toMatchObject({
|
|
64
|
+
id: SELECTION_COLUMN_ID,
|
|
65
|
+
size: 50,
|
|
66
|
+
minSize: 50,
|
|
67
|
+
maxSize: 50,
|
|
68
|
+
enableSorting: false,
|
|
69
|
+
enableResizing: false
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it("has header function that returns null for single mode", () => {
|
|
73
|
+
const {
|
|
74
|
+
result
|
|
75
|
+
} = renderHook(() => useSelectionColumn({
|
|
76
|
+
selectionMode: "single",
|
|
77
|
+
isAllSelected: false,
|
|
78
|
+
hasSelection: false,
|
|
79
|
+
onToggleAll: vi.fn(),
|
|
80
|
+
onToggleRow: vi.fn()
|
|
81
|
+
}));
|
|
82
|
+
const columnDef = result.current;
|
|
83
|
+
expect(columnDef).not.toBeNull();
|
|
84
|
+
|
|
85
|
+
// Call header function
|
|
86
|
+
const headerResult = typeof columnDef?.header === "function" ? columnDef.header({}) : null;
|
|
87
|
+
expect(headerResult).toBeNull();
|
|
88
|
+
});
|
|
89
|
+
it("has cell function defined", () => {
|
|
90
|
+
const onToggleRow = vi.fn();
|
|
91
|
+
const {
|
|
92
|
+
result
|
|
93
|
+
} = renderHook(() => useSelectionColumn({
|
|
94
|
+
selectionMode: "single",
|
|
95
|
+
isAllSelected: false,
|
|
96
|
+
hasSelection: false,
|
|
97
|
+
onToggleAll: vi.fn(),
|
|
98
|
+
onToggleRow
|
|
99
|
+
}));
|
|
100
|
+
const columnDef = result.current;
|
|
101
|
+
expect(columnDef).not.toBeNull();
|
|
102
|
+
expect(columnDef?.cell).toBeDefined();
|
|
103
|
+
});
|
|
104
|
+
it("memoizes column definition based on dependencies", () => {
|
|
105
|
+
const onToggleRow = vi.fn();
|
|
106
|
+
const onToggleAll = vi.fn();
|
|
107
|
+
const {
|
|
108
|
+
result,
|
|
109
|
+
rerender
|
|
110
|
+
} = renderHook(({
|
|
111
|
+
isAllSelected,
|
|
112
|
+
hasSelection
|
|
113
|
+
}) => useSelectionColumn({
|
|
114
|
+
selectionMode: "single",
|
|
115
|
+
isAllSelected,
|
|
116
|
+
hasSelection,
|
|
117
|
+
onToggleAll,
|
|
118
|
+
onToggleRow
|
|
119
|
+
}), {
|
|
120
|
+
initialProps: {
|
|
121
|
+
isAllSelected: false,
|
|
122
|
+
hasSelection: false
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
const firstResult = result.current;
|
|
126
|
+
|
|
127
|
+
// Rerender with same props
|
|
128
|
+
rerender({
|
|
129
|
+
isAllSelected: false,
|
|
130
|
+
hasSelection: false
|
|
131
|
+
});
|
|
132
|
+
expect(result.current).toBe(firstResult);
|
|
133
|
+
|
|
134
|
+
// Rerender with different hasSelection
|
|
135
|
+
rerender({
|
|
136
|
+
isAllSelected: false,
|
|
137
|
+
hasSelection: true
|
|
138
|
+
});
|
|
139
|
+
expect(result.current).not.toBe(firstResult);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
describe("selectionMode: 'multiple'", () => {
|
|
143
|
+
it("returns column definition with correct properties", () => {
|
|
144
|
+
const {
|
|
145
|
+
result
|
|
146
|
+
} = renderHook(() => useSelectionColumn({
|
|
147
|
+
selectionMode: "multiple",
|
|
148
|
+
isAllSelected: false,
|
|
149
|
+
hasSelection: false,
|
|
150
|
+
onToggleAll: vi.fn(),
|
|
151
|
+
onToggleRow: vi.fn()
|
|
152
|
+
}));
|
|
153
|
+
expect(result.current).not.toBeNull();
|
|
154
|
+
expect(result.current).toMatchObject({
|
|
155
|
+
id: SELECTION_COLUMN_ID,
|
|
156
|
+
size: 50,
|
|
157
|
+
minSize: 50,
|
|
158
|
+
maxSize: 50,
|
|
159
|
+
enableSorting: false,
|
|
160
|
+
enableResizing: false
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
it("has header function that renders SelectionHeaderCell", () => {
|
|
164
|
+
const onToggleAll = vi.fn();
|
|
165
|
+
const {
|
|
166
|
+
result
|
|
167
|
+
} = renderHook(() => useSelectionColumn({
|
|
168
|
+
selectionMode: "multiple",
|
|
169
|
+
isAllSelected: false,
|
|
170
|
+
hasSelection: false,
|
|
171
|
+
onToggleAll,
|
|
172
|
+
onToggleRow: vi.fn()
|
|
173
|
+
}));
|
|
174
|
+
const columnDef = result.current;
|
|
175
|
+
expect(columnDef).not.toBeNull();
|
|
176
|
+
|
|
177
|
+
// Render header
|
|
178
|
+
const headerResult = typeof columnDef?.header === "function" ? columnDef.header({}) : null;
|
|
179
|
+
expect(headerResult).not.toBeNull();
|
|
180
|
+
});
|
|
181
|
+
it("has cell function defined", () => {
|
|
182
|
+
const onToggleRow = vi.fn();
|
|
183
|
+
const {
|
|
184
|
+
result
|
|
185
|
+
} = renderHook(() => useSelectionColumn({
|
|
186
|
+
selectionMode: "multiple",
|
|
187
|
+
isAllSelected: false,
|
|
188
|
+
hasSelection: false,
|
|
189
|
+
onToggleAll: vi.fn(),
|
|
190
|
+
onToggleRow
|
|
191
|
+
}));
|
|
192
|
+
const columnDef = result.current;
|
|
193
|
+
expect(columnDef).not.toBeNull();
|
|
194
|
+
expect(columnDef?.cell).toBeDefined();
|
|
195
|
+
});
|
|
196
|
+
it("memoizes column when dependencies don't change", () => {
|
|
197
|
+
const onToggleRow = vi.fn();
|
|
198
|
+
const onToggleAll = vi.fn();
|
|
199
|
+
const {
|
|
200
|
+
result,
|
|
201
|
+
rerender
|
|
202
|
+
} = renderHook(({
|
|
203
|
+
isAllSelected,
|
|
204
|
+
hasSelection
|
|
205
|
+
}) => useSelectionColumn({
|
|
206
|
+
selectionMode: "multiple",
|
|
207
|
+
isAllSelected,
|
|
208
|
+
hasSelection,
|
|
209
|
+
onToggleAll,
|
|
210
|
+
onToggleRow
|
|
211
|
+
}), {
|
|
212
|
+
initialProps: {
|
|
213
|
+
isAllSelected: false,
|
|
214
|
+
hasSelection: false
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
const firstResult = result.current;
|
|
218
|
+
|
|
219
|
+
// Rerender with same props
|
|
220
|
+
rerender({
|
|
221
|
+
isAllSelected: false,
|
|
222
|
+
hasSelection: false
|
|
223
|
+
});
|
|
224
|
+
expect(result.current).toBe(firstResult);
|
|
225
|
+
});
|
|
226
|
+
it("updates column when dependencies change", () => {
|
|
227
|
+
const onToggleRow = vi.fn();
|
|
228
|
+
const onToggleAll = vi.fn();
|
|
229
|
+
const {
|
|
230
|
+
result,
|
|
231
|
+
rerender
|
|
232
|
+
} = renderHook(({
|
|
233
|
+
isAllSelected,
|
|
234
|
+
hasSelection
|
|
235
|
+
}) => useSelectionColumn({
|
|
236
|
+
selectionMode: "multiple",
|
|
237
|
+
isAllSelected,
|
|
238
|
+
hasSelection,
|
|
239
|
+
onToggleAll,
|
|
240
|
+
onToggleRow
|
|
241
|
+
}), {
|
|
242
|
+
initialProps: {
|
|
243
|
+
isAllSelected: false,
|
|
244
|
+
hasSelection: false
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
const firstResult = result.current;
|
|
248
|
+
|
|
249
|
+
// Change isAllSelected
|
|
250
|
+
rerender({
|
|
251
|
+
isAllSelected: true,
|
|
252
|
+
hasSelection: true
|
|
253
|
+
});
|
|
254
|
+
expect(result.current).not.toBe(firstResult);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
describe("column definition structure", () => {
|
|
258
|
+
it("disables sorting and resizing", () => {
|
|
259
|
+
const {
|
|
260
|
+
result
|
|
261
|
+
} = renderHook(() => useSelectionColumn({
|
|
262
|
+
selectionMode: "multiple",
|
|
263
|
+
isAllSelected: false,
|
|
264
|
+
hasSelection: false,
|
|
265
|
+
onToggleAll: vi.fn(),
|
|
266
|
+
onToggleRow: vi.fn()
|
|
267
|
+
}));
|
|
268
|
+
const columnDef = result.current;
|
|
269
|
+
expect(columnDef?.enableSorting).toBe(false);
|
|
270
|
+
expect(columnDef?.enableResizing).toBe(false);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
//# sourceMappingURL=useSelectionColumn.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelectionColumn.test.js","names":["renderHook","describe","expect","it","vi","SELECTION_COLUMN_ID","useSelectionColumn","TestObjectType","type","apiName","result","selectionMode","isAllSelected","hasSelection","onToggleAll","fn","onToggleRow","current","toBeNull","not","toMatchObject","id","size","minSize","maxSize","enableSorting","enableResizing","columnDef","headerResult","header","cell","toBeDefined","rerender","initialProps","firstResult","toBe"],"sources":["useSelectionColumn.test.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ObjectTypeDefinition } from \"@osdk/api\";\nimport { renderHook } from \"@testing-library/react\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport {\n SELECTION_COLUMN_ID,\n useSelectionColumn,\n} from \"../useSelectionColumn.js\";\n\nconst TestObjectType = {\n type: \"object\",\n apiName: \"TestObject\",\n} as const satisfies ObjectTypeDefinition;\n\ntype TestObject = typeof TestObjectType;\n\ndescribe(\"useSelectionColumn\", () => {\n describe(\"selectionMode: 'none'\", () => {\n it(\"returns null when selection is disabled\", () => {\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"none\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow: vi.fn(),\n })\n );\n\n expect(result.current).toBeNull();\n });\n\n it(\"returns null even with selection state\", () => {\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"none\",\n isAllSelected: true,\n hasSelection: true,\n onToggleAll: vi.fn(),\n onToggleRow: vi.fn(),\n })\n );\n\n expect(result.current).toBeNull();\n });\n });\n\n describe(\"selectionMode: 'single'\", () => {\n it(\"returns column definition with correct properties\", () => {\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"single\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow: vi.fn(),\n })\n );\n\n expect(result.current).not.toBeNull();\n expect(result.current).toMatchObject({\n id: SELECTION_COLUMN_ID,\n size: 50,\n minSize: 50,\n maxSize: 50,\n enableSorting: false,\n enableResizing: false,\n });\n });\n\n it(\"has header function that returns null for single mode\", () => {\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"single\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow: vi.fn(),\n })\n );\n\n const columnDef = result.current;\n expect(columnDef).not.toBeNull();\n\n // Call header function\n const headerResult = typeof columnDef?.header === \"function\"\n ? columnDef.header({} as any)\n : null;\n\n expect(headerResult).toBeNull();\n });\n\n it(\"has cell function defined\", () => {\n const onToggleRow = vi.fn();\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"single\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow,\n })\n );\n\n const columnDef = result.current;\n expect(columnDef).not.toBeNull();\n expect(columnDef?.cell).toBeDefined();\n });\n\n it(\"memoizes column definition based on dependencies\", () => {\n const onToggleRow = vi.fn();\n const onToggleAll = vi.fn();\n\n const { result, rerender } = renderHook(\n ({ isAllSelected, hasSelection }) =>\n useSelectionColumn<TestObject>({\n selectionMode: \"single\",\n isAllSelected,\n hasSelection,\n onToggleAll,\n onToggleRow,\n }),\n {\n initialProps: { isAllSelected: false, hasSelection: false },\n },\n );\n\n const firstResult = result.current;\n\n // Rerender with same props\n rerender({ isAllSelected: false, hasSelection: false });\n expect(result.current).toBe(firstResult);\n\n // Rerender with different hasSelection\n rerender({ isAllSelected: false, hasSelection: true });\n expect(result.current).not.toBe(firstResult);\n });\n });\n\n describe(\"selectionMode: 'multiple'\", () => {\n it(\"returns column definition with correct properties\", () => {\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"multiple\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow: vi.fn(),\n })\n );\n\n expect(result.current).not.toBeNull();\n expect(result.current).toMatchObject({\n id: SELECTION_COLUMN_ID,\n size: 50,\n minSize: 50,\n maxSize: 50,\n enableSorting: false,\n enableResizing: false,\n });\n });\n\n it(\"has header function that renders SelectionHeaderCell\", () => {\n const onToggleAll = vi.fn();\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"multiple\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll,\n onToggleRow: vi.fn(),\n })\n );\n\n const columnDef = result.current;\n expect(columnDef).not.toBeNull();\n\n // Render header\n const headerResult = typeof columnDef?.header === \"function\"\n ? columnDef.header({} as any)\n : null;\n\n expect(headerResult).not.toBeNull();\n });\n\n it(\"has cell function defined\", () => {\n const onToggleRow = vi.fn();\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"multiple\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow,\n })\n );\n\n const columnDef = result.current;\n expect(columnDef).not.toBeNull();\n expect(columnDef?.cell).toBeDefined();\n });\n\n it(\"memoizes column when dependencies don't change\", () => {\n const onToggleRow = vi.fn();\n const onToggleAll = vi.fn();\n\n const { result, rerender } = renderHook(\n ({ isAllSelected, hasSelection }) =>\n useSelectionColumn<TestObject>({\n selectionMode: \"multiple\",\n isAllSelected,\n hasSelection,\n onToggleAll,\n onToggleRow,\n }),\n {\n initialProps: { isAllSelected: false, hasSelection: false },\n },\n );\n\n const firstResult = result.current;\n\n // Rerender with same props\n rerender({ isAllSelected: false, hasSelection: false });\n expect(result.current).toBe(firstResult);\n });\n\n it(\"updates column when dependencies change\", () => {\n const onToggleRow = vi.fn();\n const onToggleAll = vi.fn();\n\n const { result, rerender } = renderHook(\n ({ isAllSelected, hasSelection }) =>\n useSelectionColumn<TestObject>({\n selectionMode: \"multiple\",\n isAllSelected,\n hasSelection,\n onToggleAll,\n onToggleRow,\n }),\n {\n initialProps: { isAllSelected: false, hasSelection: false },\n },\n );\n\n const firstResult = result.current;\n\n // Change isAllSelected\n rerender({ isAllSelected: true, hasSelection: true });\n expect(result.current).not.toBe(firstResult);\n });\n });\n\n describe(\"column definition structure\", () => {\n it(\"disables sorting and resizing\", () => {\n const { result } = renderHook(() =>\n useSelectionColumn<TestObject>({\n selectionMode: \"multiple\",\n isAllSelected: false,\n hasSelection: false,\n onToggleAll: vi.fn(),\n onToggleRow: vi.fn(),\n })\n );\n\n const columnDef = result.current;\n expect(columnDef?.enableSorting).toBe(false);\n expect(columnDef?.enableResizing).toBe(false);\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { useCallback, useState } from "react";
|
|
18
|
+
export const useCellContextMenu = ({
|
|
19
|
+
tdRef
|
|
20
|
+
}) => {
|
|
21
|
+
const [popoverPosition, setPopoverPosition] = useState(null);
|
|
22
|
+
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);
|
|
23
|
+
const handleOpenContextMenu = useCallback(event => {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
event.stopPropagation();
|
|
26
|
+
if (tdRef.current) {
|
|
27
|
+
const rect = tdRef.current.getBoundingClientRect();
|
|
28
|
+
const position = {
|
|
29
|
+
left: rect.left,
|
|
30
|
+
top: rect.bottom,
|
|
31
|
+
width: rect.width
|
|
32
|
+
};
|
|
33
|
+
setPopoverPosition(position);
|
|
34
|
+
setIsContextMenuOpen(true);
|
|
35
|
+
}
|
|
36
|
+
}, [tdRef]);
|
|
37
|
+
const handleCloseContextMenu = useCallback(() => {
|
|
38
|
+
setIsContextMenuOpen(false);
|
|
39
|
+
setPopoverPosition(null);
|
|
40
|
+
}, []);
|
|
41
|
+
return {
|
|
42
|
+
isContextMenuOpen,
|
|
43
|
+
handleOpenContextMenu,
|
|
44
|
+
handleCloseContextMenu,
|
|
45
|
+
popoverPosition
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=useCellContextMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCellContextMenu.js","names":["useCallback","useState","useCellContextMenu","tdRef","popoverPosition","setPopoverPosition","isContextMenuOpen","setIsContextMenuOpen","handleOpenContextMenu","event","preventDefault","stopPropagation","current","rect","getBoundingClientRect","position","left","top","bottom","width","handleCloseContextMenu"],"sources":["useCellContextMenu.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { MouseEventHandler, RefObject } from \"react\";\nimport { useCallback, useState } from \"react\";\n\nexport interface PopoverPosition {\n left: number;\n top: number;\n width: number;\n}\n\ninterface UseCellContextMenuProps {\n tdRef: RefObject<HTMLTableCellElement>;\n}\n\ninterface UseCellContextMenuResults {\n isContextMenuOpen: boolean;\n handleOpenContextMenu: MouseEventHandler<HTMLTableCellElement>;\n handleCloseContextMenu: () => void;\n popoverPosition: PopoverPosition | null;\n}\n\nexport const useCellContextMenu = ({\n tdRef,\n}: UseCellContextMenuProps): UseCellContextMenuResults => {\n const [popoverPosition, setPopoverPosition] = useState<\n PopoverPosition | null\n >(null);\n const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);\n\n const handleOpenContextMenu = useCallback((event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n if (tdRef.current) {\n const rect = tdRef.current.getBoundingClientRect();\n const position = {\n left: rect.left,\n top: rect.bottom,\n width: rect.width,\n };\n setPopoverPosition(position);\n setIsContextMenuOpen(true);\n }\n }, [tdRef]);\n\n const handleCloseContextMenu = useCallback(() => {\n setIsContextMenuOpen(false);\n setPopoverPosition(null);\n }, []);\n\n return {\n isContextMenuOpen,\n handleOpenContextMenu,\n handleCloseContextMenu,\n popoverPosition,\n };\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,WAAW,EAAEC,QAAQ,QAAQ,OAAO;AAmB7C,OAAO,MAAMC,kBAAkB,GAAGA,CAAC;EACjCC;AACuB,CAAC,KAAgC;EACxD,MAAM,CAACC,eAAe,EAAEC,kBAAkB,CAAC,GAAGJ,QAAQ,CAEpD,IAAI,CAAC;EACP,MAAM,CAACK,iBAAiB,EAAEC,oBAAoB,CAAC,GAAGN,QAAQ,CAAC,KAAK,CAAC;EAEjE,MAAMO,qBAAqB,GAAGR,WAAW,CAAES,KAAuB,IAAK;IACrEA,KAAK,CAACC,cAAc,CAAC,CAAC;IACtBD,KAAK,CAACE,eAAe,CAAC,CAAC;IAEvB,IAAIR,KAAK,CAACS,OAAO,EAAE;MACjB,MAAMC,IAAI,GAAGV,KAAK,CAACS,OAAO,CAACE,qBAAqB,CAAC,CAAC;MAClD,MAAMC,QAAQ,GAAG;QACfC,IAAI,EAAEH,IAAI,CAACG,IAAI;QACfC,GAAG,EAAEJ,IAAI,CAACK,MAAM;QAChBC,KAAK,EAAEN,IAAI,CAACM;MACd,CAAC;MACDd,kBAAkB,CAACU,QAAQ,CAAC;MAC5BR,oBAAoB,CAAC,IAAI,CAAC;IAC5B;EACF,CAAC,EAAE,CAACJ,KAAK,CAAC,CAAC;EAEX,MAAMiB,sBAAsB,GAAGpB,WAAW,CAAC,MAAM;IAC/CO,oBAAoB,CAAC,KAAK,CAAC;IAC3BF,kBAAkB,CAAC,IAAI,CAAC;EAC1B,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IACLC,iBAAiB;IACjBE,qBAAqB;IACrBY,sBAAsB;IACtBhB;EACF,CAAC;AACH,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useColumnDefs.js","names":["useOsdkMetadata","useMemo","useColumnDefs","objectType","columnDefinitions","metadata","loading","error","columns","objectProperties","properties","getColumnsFromColumnDefinitions","getDefaultColumns","map","col","locator","width","minWidth","maxWidth","resizable","orderable","filterable","renderCell","renderHeader","propertyMetadata","type","id","undefined","colKey","colDef","accessorKey","header","displayName","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","cell","cellContext","object","row","original","getValue","Object","entries","key","property"],"sources":["useColumnDefs.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ObjectMetadata,\n ObjectTypeDefinition,\n Osdk,\n PropertyKeys,\n QueryDefinition,\n SimplePropertyDef,\n} from \"@osdk/api\";\nimport { useOsdkMetadata } from \"@osdk/react\";\nimport type { AccessorColumnDef } from \"@tanstack/react-table\";\nimport { useMemo } from \"react\";\nimport type { ColumnDefinition } from \"../ObjectTableApi.js\";\n\ninterface UseColumnDefsResult<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n> {\n columns: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >[];\n\n loading: boolean;\n\n error: string | undefined;\n}\n\n/**\n * Hook which builds column definitions for tanstack-table given the objectSet\n */\nexport function useColumnDefs<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectType: Q,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n): UseColumnDefsResult<Q, RDPs> {\n const { metadata, loading, error } = useOsdkMetadata(objectType);\n\n const columns = useMemo(() => {\n const objectProperties = metadata?.properties;\n // If columnDefinitions is provided, construct colDefs with it\n if (columnDefinitions) {\n return getColumnsFromColumnDefinitions<Q, RDPs, FunctionColumns>(\n columnDefinitions,\n objectProperties,\n );\n }\n\n // If not, return the default columns from the object properties\n return getDefaultColumns<Q, RDPs>(objectProperties);\n }, [columnDefinitions, metadata?.properties]);\n\n return { columns, loading, error };\n}\n\nfunction getColumnsFromColumnDefinitions<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n columnDefinitions: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n objectProperties?: Record<any, ObjectMetadata.Property>,\n): Array<\n AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >\n> {\n return columnDefinitions.map((col) => {\n const {\n locator,\n width,\n minWidth,\n maxWidth,\n resizable,\n orderable,\n filterable,\n renderCell,\n renderHeader,\n } = col;\n\n const propertyMetadata = locator.type === \"property\"\n ? objectProperties?.[locator.id]\n : undefined;\n\n const colKey = locator.id as string;\n\n const colDef: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n > = {\n id: colKey,\n accessorKey: colKey,\n header: renderHeader ?? propertyMetadata?.displayName,\n size: width,\n minSize: minWidth,\n maxSize: maxWidth,\n enableResizing: resizable,\n enableSorting: orderable,\n enableColumnFilter: filterable,\n cell: (cellContext) => {\n const object: Osdk.Instance<\n Q,\n \"$allBaseProperties\",\n PropertyKeys<Q>,\n RDPs\n > = cellContext.row.original;\n\n return renderCell\n ? renderCell(object, locator)\n : cellContext.getValue();\n },\n };\n\n return colDef;\n });\n}\n\nfunction getDefaultColumns<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n>(\n objectProperties?: Record<any, ObjectMetadata.Property>,\n): Array<\n AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >\n> {\n if (!objectProperties) return [];\n\n return Object.entries(objectProperties).map(([key, property]) => {\n const colDef: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n > = {\n accessorKey: key,\n header: property.displayName ?? key,\n };\n return colDef;\n });\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA,SAASA,eAAe,QAAQ,aAAa;AAE7C,SAASC,OAAO,QAAQ,OAAO;AAmB/B;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAW3BC,UAAa,EACbC,iBAAqE,EACvC;EAC9B,MAAM;IAAEC,QAAQ;IAAEC,OAAO;IAAEC;EAAM,CAAC,GAAGP,eAAe,CAACG,UAAU,CAAC;EAEhE,MAAMK,
|
|
1
|
+
{"version":3,"file":"useColumnDefs.js","names":["useOsdkMetadata","useMemo","useColumnDefs","objectType","columnDefinitions","metadata","loading","error","columns","objectProperties","properties","getColumnsFromColumnDefinitions","getDefaultColumns","map","col","locator","width","minWidth","maxWidth","resizable","orderable","filterable","renderCell","renderHeader","propertyMetadata","type","id","undefined","colKey","colDef","accessorKey","header","displayName","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","cell","cellContext","object","row","original","getValue","Object","entries","key","property"],"sources":["useColumnDefs.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ObjectMetadata,\n ObjectTypeDefinition,\n Osdk,\n PropertyKeys,\n QueryDefinition,\n SimplePropertyDef,\n} from \"@osdk/api\";\nimport { useOsdkMetadata } from \"@osdk/react\";\nimport type { AccessorColumnDef } from \"@tanstack/react-table\";\nimport { useMemo } from \"react\";\nimport type { ColumnDefinition } from \"../ObjectTableApi.js\";\n\ninterface UseColumnDefsResult<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n> {\n columns: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >[];\n\n loading: boolean;\n\n error: string | undefined;\n}\n\n/**\n * Hook which builds column definitions for tanstack-table given the objectSet\n */\nexport function useColumnDefs<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectType: Q,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n): UseColumnDefsResult<Q, RDPs> {\n const { metadata, loading, error } = useOsdkMetadata(objectType);\n\n const columns: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >[] = useMemo(() => {\n const objectProperties = metadata?.properties;\n // If columnDefinitions is provided, construct colDefs with it\n if (columnDefinitions) {\n return getColumnsFromColumnDefinitions<Q, RDPs, FunctionColumns>(\n columnDefinitions,\n objectProperties,\n );\n }\n\n // If not, return the default columns from the object properties\n return getDefaultColumns<Q, RDPs>(objectProperties);\n }, [columnDefinitions, metadata?.properties]);\n\n return { columns, loading, error };\n}\n\nfunction getColumnsFromColumnDefinitions<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n columnDefinitions: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n objectProperties?: Record<any, ObjectMetadata.Property>,\n): Array<\n AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >\n> {\n return columnDefinitions.map((col) => {\n const {\n locator,\n width,\n minWidth,\n maxWidth,\n resizable,\n orderable,\n filterable,\n renderCell,\n renderHeader,\n } = col;\n\n const propertyMetadata = locator.type === \"property\"\n ? objectProperties?.[locator.id]\n : undefined;\n\n const colKey = locator.id as string;\n\n const colDef: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n > = {\n id: colKey,\n accessorKey: colKey,\n header: renderHeader ?? propertyMetadata?.displayName,\n size: width,\n minSize: minWidth,\n maxSize: maxWidth,\n enableResizing: resizable,\n enableSorting: orderable,\n enableColumnFilter: filterable,\n cell: (cellContext) => {\n const object: Osdk.Instance<\n Q,\n \"$allBaseProperties\",\n PropertyKeys<Q>,\n RDPs\n > = cellContext.row.original;\n\n return renderCell\n ? renderCell(object, locator)\n : cellContext.getValue();\n },\n };\n\n return colDef;\n });\n}\n\nfunction getDefaultColumns<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n>(\n objectProperties?: Record<any, ObjectMetadata.Property>,\n): Array<\n AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n >\n> {\n if (!objectProperties) return [];\n\n return Object.entries(objectProperties).map(([key, property]) => {\n const colDef: AccessorColumnDef<\n Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>\n > = {\n accessorKey: key,\n header: property.displayName ?? key,\n };\n return colDef;\n });\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA,SAASA,eAAe,QAAQ,aAAa;AAE7C,SAASC,OAAO,QAAQ,OAAO;AAmB/B;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAW3BC,UAAa,EACbC,iBAAqE,EACvC;EAC9B,MAAM;IAAEC,QAAQ;IAAEC,OAAO;IAAEC;EAAM,CAAC,GAAGP,eAAe,CAACG,UAAU,CAAC;EAEhE,MAAMK,OAEH,GAAGP,OAAO,CAAC,MAAM;IAClB,MAAMQ,gBAAgB,GAAGJ,QAAQ,EAAEK,UAAU;IAC7C;IACA,IAAIN,iBAAiB,EAAE;MACrB,OAAOO,+BAA+B,CACpCP,iBAAiB,EACjBK,gBACF,CAAC;IACH;;IAEA;IACA,OAAOG,iBAAiB,CAAUH,gBAAgB,CAAC;EACrD,CAAC,EAAE,CAACL,iBAAiB,EAAEC,QAAQ,EAAEK,UAAU,CAAC,CAAC;EAE7C,OAAO;IAAEF,OAAO;IAAEF,OAAO;IAAEC;EAAM,CAAC;AACpC;AAEA,SAASI,+BAA+BA,CAWtCP,iBAAoE,EACpEK,gBAAuD,EAKvD;EACA,OAAOL,iBAAiB,CAACS,GAAG,CAAEC,GAAG,IAAK;IACpC,MAAM;MACJC,OAAO;MACPC,KAAK;MACLC,QAAQ;MACRC,QAAQ;MACRC,SAAS;MACTC,SAAS;MACTC,UAAU;MACVC,UAAU;MACVC;IACF,CAAC,GAAGT,GAAG;IAEP,MAAMU,gBAAgB,GAAGT,OAAO,CAACU,IAAI,KAAK,UAAU,GAChDhB,gBAAgB,GAAGM,OAAO,CAACW,EAAE,CAAC,GAC9BC,SAAS;IAEb,MAAMC,MAAM,GAAGb,OAAO,CAACW,EAAY;IAEnC,MAAMG,MAEL,GAAG;MACFH,EAAE,EAAEE,MAAM;MACVE,WAAW,EAAEF,MAAM;MACnBG,MAAM,EAAER,YAAY,IAAIC,gBAAgB,EAAEQ,WAAW;MACrDC,IAAI,EAAEjB,KAAK;MACXkB,OAAO,EAAEjB,QAAQ;MACjBkB,OAAO,EAAEjB,QAAQ;MACjBkB,cAAc,EAAEjB,SAAS;MACzBkB,aAAa,EAAEjB,SAAS;MACxBkB,kBAAkB,EAAEjB,UAAU;MAC9BkB,IAAI,EAAGC,WAAW,IAAK;QACrB,MAAMC,MAKL,GAAGD,WAAW,CAACE,GAAG,CAACC,QAAQ;QAE5B,OAAOrB,UAAU,GACbA,UAAU,CAACmB,MAAM,EAAE1B,OAAO,CAAC,GAC3ByB,WAAW,CAACI,QAAQ,CAAC,CAAC;MAC5B;IACF,CAAC;IAED,OAAOf,MAAM;EACf,CAAC,CAAC;AACJ;AAEA,SAASjB,iBAAiBA,CAOxBH,gBAAuD,EAKvD;EACA,IAAI,CAACA,gBAAgB,EAAE,OAAO,EAAE;EAEhC,OAAOoC,MAAM,CAACC,OAAO,CAACrC,gBAAgB,CAAC,CAACI,GAAG,CAAC,CAAC,CAACkC,GAAG,EAAEC,QAAQ,CAAC,KAAK;IAC/D,MAAMnB,MAEL,GAAG;MACFC,WAAW,EAAEiB,GAAG;MAChBhB,MAAM,EAAEiB,QAAQ,CAAChB,WAAW,IAAIe;IAClC,CAAC;IACD,OAAOlB,MAAM;EACf,CAAC,CAAC;AACJ","ignoreList":[]}
|
|
@@ -24,7 +24,7 @@ const PAGE_SIZE = 50;
|
|
|
24
24
|
* to return data containing the derived properties.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
export function useObjectTableData(objectSet, columnDefinitions) {
|
|
27
|
+
export function useObjectTableData(objectSet, columnDefinitions, filter) {
|
|
28
28
|
// Extract derived properties definition to be passed to useObjectSet hook
|
|
29
29
|
const withProperties = useMemo(() => {
|
|
30
30
|
if (!columnDefinitions) {
|
|
@@ -42,7 +42,8 @@ export function useObjectTableData(objectSet, columnDefinitions) {
|
|
|
42
42
|
}, [columnDefinitions]);
|
|
43
43
|
return useObjectSet(objectSet, {
|
|
44
44
|
withProperties,
|
|
45
|
-
pageSize: PAGE_SIZE
|
|
45
|
+
pageSize: PAGE_SIZE,
|
|
46
|
+
where: filter
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
//# sourceMappingURL=useObjectTableData.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useObjectTableData.js","names":["useObjectSet","useMemo","PAGE_SIZE","useObjectTableData","objectSet","columnDefinitions","withProperties","rdpColumns","map","colDef","locator","
|
|
1
|
+
{"version":3,"file":"useObjectTableData.js","names":["useObjectSet","useMemo","PAGE_SIZE","useObjectTableData","objectSet","columnDefinitions","filter","withProperties","rdpColumns","map","colDef","locator","colLocator","type","reduce","acc","cur","id","creator","pageSize","where"],"sources":["useObjectTableData.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n DerivedProperty,\n ObjectSet,\n ObjectTypeDefinition,\n QueryDefinition,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\nimport { useObjectSet } from \"@osdk/react/experimental\";\nimport { useMemo } from \"react\";\nimport type { ColumnDefinition } from \"../ObjectTableApi.js\";\n\nconst PAGE_SIZE = 50;\n\n/**\n * This hook is a wrapper around useObjectSet\n * It extracts RDP locators from columnDefinitions and calls useObjectSet + withProperties\n * to return data containing the derived properties.\n */\n\nexport function useObjectTableData<\n Q extends ObjectTypeDefinition,\n RDPs extends Record<string, SimplePropertyDef>,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectSet: ObjectSet<Q>,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n filter?: WhereClause<Q, RDPs>,\n): ReturnType<typeof useObjectSet<Q, never, RDPs>> {\n // Extract derived properties definition to be passed to useObjectSet hook\n const withProperties = useMemo(() => {\n if (!columnDefinitions) {\n return;\n }\n\n const rdpColumns = columnDefinitions.map(colDef => colDef.locator).filter(\n (colLocator) => {\n return colLocator.type === \"rdp\";\n },\n );\n\n return rdpColumns.reduce<\n { [K in keyof RDPs]: DerivedProperty.Creator<Q, RDPs[K]> }\n >(\n (acc, cur) => {\n return {\n ...acc,\n [cur.id]: cur.creator,\n };\n },\n {} as {\n [K in keyof RDPs]: DerivedProperty.Creator<Q, RDPs[K]>;\n },\n );\n }, [columnDefinitions]);\n\n return useObjectSet<Q, never, RDPs>(\n objectSet,\n {\n withProperties,\n pageSize: PAGE_SIZE,\n where: filter,\n },\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA,SAASA,YAAY,QAAQ,0BAA0B;AACvD,SAASC,OAAO,QAAQ,OAAO;AAG/B,MAAMC,SAAS,GAAG,EAAE;;AAEpB;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASC,kBAAkBA,CAQhCC,SAAuB,EACvBC,iBAAqE,EACrEC,MAA6B,EACoB;EACjD;EACA,MAAMC,cAAc,GAAGN,OAAO,CAAC,MAAM;IACnC,IAAI,CAACI,iBAAiB,EAAE;MACtB;IACF;IAEA,MAAMG,UAAU,GAAGH,iBAAiB,CAACI,GAAG,CAACC,MAAM,IAAIA,MAAM,CAACC,OAAO,CAAC,CAACL,MAAM,CACtEM,UAAU,IAAK;MACd,OAAOA,UAAU,CAACC,IAAI,KAAK,KAAK;IAClC,CACF,CAAC;IAED,OAAOL,UAAU,CAACM,MAAM,CAGtB,CAACC,GAAG,EAAEC,GAAG,KAAK;MACZ,OAAO;QACL,GAAGD,GAAG;QACN,CAACC,GAAG,CAACC,EAAE,GAAGD,GAAG,CAACE;MAChB,CAAC;IACH,CAAC,EACD,CAAC,CAGH,CAAC;EACH,CAAC,EAAE,CAACb,iBAAiB,CAAC,CAAC;EAEvB,OAAOL,YAAY,CACjBI,SAAS,EACT;IACEG,cAAc;IACdY,QAAQ,EAAEjB,SAAS;IACnBkB,KAAK,EAAEd;EACT,CACF,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { useCallback, useMemo, useState } from "react";
|
|
18
|
+
import { getRowId, getRowIdFromPrimaryKey } from "../utils/getRowId.js";
|
|
19
|
+
export function useRowSelection({
|
|
20
|
+
selectionMode = "none",
|
|
21
|
+
selectedRows,
|
|
22
|
+
onRowSelection,
|
|
23
|
+
data
|
|
24
|
+
}) {
|
|
25
|
+
// The rowSelectionState in uncontrolled mode
|
|
26
|
+
const [internalRowSelection, setInternalRowSelection] = useState({});
|
|
27
|
+
|
|
28
|
+
// Used for shift-click behavior in "multiple" mode
|
|
29
|
+
const [lastSelectedRowIndex, setLastSelectedRowIndex] = useState(null);
|
|
30
|
+
const isControlled = selectedRows !== undefined;
|
|
31
|
+
const isSelectionEnabled = selectionMode !== "none";
|
|
32
|
+
|
|
33
|
+
// Row selection state
|
|
34
|
+
// If controlled mode, return the state from selectedRows prop
|
|
35
|
+
// If uncontrolled, return the internalRowSelection state
|
|
36
|
+
const rowSelectionState = useMemo(() => {
|
|
37
|
+
if (!isSelectionEnabled) return {};
|
|
38
|
+
if (isControlled && selectedRows) {
|
|
39
|
+
return getRowSelectionState(selectedRows);
|
|
40
|
+
}
|
|
41
|
+
return internalRowSelection;
|
|
42
|
+
}, [isSelectionEnabled, isControlled, selectedRows, internalRowSelection]);
|
|
43
|
+
const selectedCount = Object.values(rowSelectionState).filter(Boolean).length;
|
|
44
|
+
const totalCount = data?.length ?? 0;
|
|
45
|
+
const isAllSelected = totalCount > 0 && selectedCount === totalCount;
|
|
46
|
+
const onToggleAll = useCallback(() => {
|
|
47
|
+
if (!isSelectionEnabled || !data) return;
|
|
48
|
+
const newSelectedRows = isAllSelected ? [] : data.map(item => item.$primaryKey);
|
|
49
|
+
if (!isControlled) {
|
|
50
|
+
setInternalRowSelection(getRowSelectionState(newSelectedRows));
|
|
51
|
+
}
|
|
52
|
+
onRowSelection?.(newSelectedRows);
|
|
53
|
+
}, [isSelectionEnabled, data, isAllSelected, isControlled, onRowSelection]);
|
|
54
|
+
const onToggleRow = useCallback((rowId, rowIndex, isShiftClick = false) => {
|
|
55
|
+
if (!isSelectionEnabled || !data) return;
|
|
56
|
+
let newSelectedRows = [];
|
|
57
|
+
if (selectionMode === "single") {
|
|
58
|
+
newSelectedRows = getSingleSelectionRows({
|
|
59
|
+
rowId,
|
|
60
|
+
rowIndex,
|
|
61
|
+
data,
|
|
62
|
+
rowSelectionState
|
|
63
|
+
});
|
|
64
|
+
setLastSelectedRowIndex(rowIndex);
|
|
65
|
+
} else {
|
|
66
|
+
// Multiple selection mode
|
|
67
|
+
|
|
68
|
+
// When user does shiftClick but lastSelectedRowIndex is null,
|
|
69
|
+
// it is treated as a normal click in multiple selection
|
|
70
|
+
if (isShiftClick && lastSelectedRowIndex != null) {
|
|
71
|
+
newSelectedRows = getRangeSelectionRows({
|
|
72
|
+
rowId,
|
|
73
|
+
rowIndex,
|
|
74
|
+
data,
|
|
75
|
+
lastSelectedRowIndex,
|
|
76
|
+
rowSelectionState
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
newSelectedRows = getMultipleSelectionRows({
|
|
80
|
+
rowId,
|
|
81
|
+
rowIndex,
|
|
82
|
+
data,
|
|
83
|
+
rowSelectionState
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
setLastSelectedRowIndex(rowIndex);
|
|
87
|
+
}
|
|
88
|
+
if (!isControlled) {
|
|
89
|
+
setInternalRowSelection(getRowSelectionState(newSelectedRows));
|
|
90
|
+
}
|
|
91
|
+
onRowSelection?.(newSelectedRows);
|
|
92
|
+
}, [isSelectionEnabled, data, selectionMode, lastSelectedRowIndex, isControlled, rowSelectionState, onRowSelection]);
|
|
93
|
+
return {
|
|
94
|
+
rowSelection: rowSelectionState,
|
|
95
|
+
isAllSelected,
|
|
96
|
+
hasSelection: selectedCount > 0,
|
|
97
|
+
onToggleAll,
|
|
98
|
+
onToggleRow
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function getSingleSelectionRows({
|
|
102
|
+
rowId,
|
|
103
|
+
rowIndex,
|
|
104
|
+
data,
|
|
105
|
+
rowSelectionState
|
|
106
|
+
}) {
|
|
107
|
+
const primaryKey = data[rowIndex].$primaryKey;
|
|
108
|
+
// Toggle row selection in single selection mode
|
|
109
|
+
const newSelectedRows = rowSelectionState[rowId] ? [] : [primaryKey];
|
|
110
|
+
return newSelectedRows;
|
|
111
|
+
}
|
|
112
|
+
function getRangeSelectionRows({
|
|
113
|
+
lastSelectedRowIndex,
|
|
114
|
+
rowIndex,
|
|
115
|
+
data,
|
|
116
|
+
rowSelectionState
|
|
117
|
+
}) {
|
|
118
|
+
// This function is only called if lastSelectedRowIndex is not null
|
|
119
|
+
// This condition is added for typechecks only
|
|
120
|
+
if (lastSelectedRowIndex != null) {
|
|
121
|
+
const rowsInRange = getRowsInRange(data, lastSelectedRowIndex, rowIndex);
|
|
122
|
+
const primaryKeysInRange = rowsInRange.map(item => item.$primaryKey);
|
|
123
|
+
const currentlySelected = getSelectedPrimaryKeys(rowSelectionState, data);
|
|
124
|
+
|
|
125
|
+
// Add all rows in range to selectedRows if not yet selected
|
|
126
|
+
const newSelectedRows = [...currentlySelected];
|
|
127
|
+
primaryKeysInRange.forEach(item => {
|
|
128
|
+
if (!newSelectedRows.includes(item)) {
|
|
129
|
+
newSelectedRows.push(item);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return newSelectedRows;
|
|
133
|
+
}
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
function getMultipleSelectionRows({
|
|
137
|
+
rowIndex,
|
|
138
|
+
data,
|
|
139
|
+
rowSelectionState
|
|
140
|
+
}) {
|
|
141
|
+
const primaryKey = data[rowIndex].$primaryKey;
|
|
142
|
+
const currentlySelected = getSelectedPrimaryKeys(rowSelectionState, data);
|
|
143
|
+
// Handles single row toggle in multiple selection mode
|
|
144
|
+
const newSelectedRows = currentlySelected.includes(primaryKey) ? currentlySelected.filter(i => i !== primaryKey) : [...currentlySelected, primaryKey];
|
|
145
|
+
return newSelectedRows;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Builds a range of rows from startIndex to endIndex
|
|
150
|
+
*/
|
|
151
|
+
function getRowsInRange(data, startIndex, endIndex) {
|
|
152
|
+
const start = Math.min(startIndex, endIndex);
|
|
153
|
+
const end = Math.max(startIndex, endIndex);
|
|
154
|
+
const rows = [];
|
|
155
|
+
for (let i = start; i <= end; i++) {
|
|
156
|
+
const item = data[i];
|
|
157
|
+
if (item) {
|
|
158
|
+
rows.push(item);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return rows;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Converts an array of primary keys to a RowSelectionState object
|
|
166
|
+
*/
|
|
167
|
+
function getRowSelectionState(primaryKeys) {
|
|
168
|
+
return primaryKeys.reduce((acc, primaryKey) => {
|
|
169
|
+
acc[getRowIdFromPrimaryKey(primaryKey)] = true;
|
|
170
|
+
return acc;
|
|
171
|
+
}, {});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Converts from a RowSelectionState object back to an array of primary keys
|
|
176
|
+
*/
|
|
177
|
+
function getSelectedPrimaryKeys(selectionState, data) {
|
|
178
|
+
return data.filter(item => selectionState[getRowId(item)]).map(item => item.$primaryKey);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=useRowSelection.js.map
|