@osdk/react-components 0.40.0 → 0.41.0-main-7e4163b0319ea02499200d07dc4969e11a5cb33c
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 +7 -0
- package/build/browser/object-table/ColumnConfigDialog.js +20 -15
- package/build/browser/object-table/ColumnConfigDialog.js.map +1 -1
- package/build/browser/object-table/EditableCell.js +4 -3
- package/build/browser/object-table/EditableCell.js.map +1 -1
- package/build/browser/object-table/MultiColumnSortDialog.js +15 -12
- package/build/browser/object-table/MultiColumnSortDialog.js.map +1 -1
- package/build/browser/object-table/ObjectTable.js +3 -1
- 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/ObjectTableLabels.js +130 -0
- package/build/browser/object-table/ObjectTableLabels.js.map +1 -0
- package/build/browser/object-table/SelectionCells.js +5 -2
- package/build/browser/object-table/SelectionCells.js.map +1 -1
- package/build/browser/object-table/Table.js +7 -3
- package/build/browser/object-table/Table.js.map +1 -1
- package/build/browser/object-table/TableEditContainer.js +8 -6
- package/build/browser/object-table/TableEditContainer.js.map +1 -1
- package/build/browser/object-table/TableHeaderWithPopover.js +11 -9
- package/build/browser/object-table/TableHeaderWithPopover.js.map +1 -1
- package/build/browser/object-table/components/AsyncValueCell.js +4 -2
- package/build/browser/object-table/components/AsyncValueCell.js.map +1 -1
- package/build/browser/public/experimental/object-table.js.map +1 -1
- package/build/browser/util/UserAgent.js +1 -1
- package/build/browser/util/UserAgent.js.map +1 -1
- package/build/cjs/chunk-323YOMG2.cjs +11 -0
- package/build/cjs/{chunk-4YFH7US6.cjs.map → chunk-323YOMG2.cjs.map} +1 -1
- package/build/cjs/{chunk-AY3WIKRW.cjs → chunk-4SGNGOAP.cjs} +490 -397
- package/build/cjs/chunk-4SGNGOAP.cjs.map +1 -0
- package/build/cjs/{chunk-5U23QYOL.cjs → chunk-6UIKJ4X4.cjs} +4 -4
- package/build/cjs/{chunk-5U23QYOL.cjs.map → chunk-6UIKJ4X4.cjs.map} +1 -1
- package/build/cjs/{chunk-PMQT5CIV.cjs → chunk-74V4AJ4A.cjs} +4 -4
- package/build/cjs/{chunk-PMQT5CIV.cjs.map → chunk-74V4AJ4A.cjs.map} +1 -1
- package/build/cjs/chunk-CWOMGAE4.cjs +11 -0
- package/build/cjs/{chunk-GNOUY65C.cjs.map → chunk-CWOMGAE4.cjs.map} +1 -1
- package/build/cjs/chunk-EMR3I6AL.cjs +11 -0
- package/build/cjs/{chunk-6U4W2HH5.cjs.map → chunk-EMR3I6AL.cjs.map} +1 -1
- package/build/cjs/{chunk-CEDJUDDR.cjs → chunk-GIKFNRWU.cjs} +4 -4
- package/build/cjs/{chunk-CEDJUDDR.cjs.map → chunk-GIKFNRWU.cjs.map} +1 -1
- package/build/cjs/{chunk-UQM4DWUN.cjs → chunk-GNXZZXHI.cjs} +3 -3
- package/build/cjs/chunk-GNXZZXHI.cjs.map +1 -0
- package/build/cjs/{chunk-ZKLRFU6R.cjs → chunk-JQAAJFKE.cjs} +4 -4
- package/build/cjs/{chunk-ZKLRFU6R.cjs.map → chunk-JQAAJFKE.cjs.map} +1 -1
- package/build/cjs/{chunk-IA32Z765.cjs → chunk-LIJJHXK6.cjs} +4 -4
- package/build/cjs/{chunk-IA32Z765.cjs.map → chunk-LIJJHXK6.cjs.map} +1 -1
- package/build/cjs/{chunk-MJC5CXYJ.cjs → chunk-LKDGFSTS.cjs} +4 -4
- package/build/cjs/{chunk-MJC5CXYJ.cjs.map → chunk-LKDGFSTS.cjs.map} +1 -1
- package/build/cjs/{chunk-PXCVMAUL.cjs → chunk-V2YDHJFF.cjs} +4 -4
- package/build/cjs/{chunk-PXCVMAUL.cjs.map → chunk-V2YDHJFF.cjs.map} +1 -1
- package/build/cjs/chunk-VOLJ5FDD.cjs +11 -0
- package/build/cjs/{chunk-XEDHHJ5U.cjs.map → chunk-VOLJ5FDD.cjs.map} +1 -1
- package/build/cjs/chunk-YXCVZKTN.cjs +11 -0
- package/build/cjs/{chunk-ACLCVBDB.cjs.map → chunk-YXCVZKTN.cjs.map} +1 -1
- package/build/cjs/public/experimental/action-form.cjs +4 -4
- package/build/cjs/public/experimental/cbac-picker.cjs +11 -11
- package/build/cjs/public/experimental/document-viewer.cjs +4 -4
- package/build/cjs/public/experimental/email-viewer.cjs +3 -3
- package/build/cjs/public/experimental/excel-viewer.cjs +3 -3
- package/build/cjs/public/experimental/filter-list.cjs +15 -15
- package/build/cjs/public/experimental/image-viewer.cjs +3 -3
- package/build/cjs/public/experimental/markdown-renderer.cjs +3 -3
- package/build/cjs/public/experimental/object-table.cjs +21 -21
- package/build/cjs/public/experimental/object-table.d.cts +136 -4
- package/build/cjs/public/experimental/pdf-viewer.cjs +7 -7
- package/build/cjs/public/experimental/tiff-renderer.cjs +3 -3
- package/build/cjs/public/experimental/video-viewer.cjs +3 -3
- package/build/cjs/public/experimental/xml-viewer.cjs +3 -3
- package/build/cjs/public/experimental.cjs +71 -71
- package/build/cjs/public/experimental.d.cts +1 -1
- package/build/esm/object-table/ColumnConfigDialog.js +20 -15
- package/build/esm/object-table/ColumnConfigDialog.js.map +1 -1
- package/build/esm/object-table/EditableCell.js +4 -3
- package/build/esm/object-table/EditableCell.js.map +1 -1
- package/build/esm/object-table/MultiColumnSortDialog.js +15 -12
- package/build/esm/object-table/MultiColumnSortDialog.js.map +1 -1
- package/build/esm/object-table/ObjectTable.js +3 -1
- 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/ObjectTableLabels.js +130 -0
- package/build/esm/object-table/ObjectTableLabels.js.map +1 -0
- package/build/esm/object-table/SelectionCells.js +5 -2
- package/build/esm/object-table/SelectionCells.js.map +1 -1
- package/build/esm/object-table/Table.js +7 -3
- package/build/esm/object-table/Table.js.map +1 -1
- package/build/esm/object-table/TableEditContainer.js +8 -6
- package/build/esm/object-table/TableEditContainer.js.map +1 -1
- package/build/esm/object-table/TableHeaderWithPopover.js +11 -9
- package/build/esm/object-table/TableHeaderWithPopover.js.map +1 -1
- package/build/esm/object-table/components/AsyncValueCell.js +4 -2
- package/build/esm/object-table/components/AsyncValueCell.js.map +1 -1
- package/build/esm/public/experimental/object-table.js.map +1 -1
- package/build/esm/util/UserAgent.js +1 -1
- package/build/esm/util/UserAgent.js.map +1 -1
- package/build/types/object-table/ColumnConfigDialog.d.ts +10 -1
- package/build/types/object-table/ColumnConfigDialog.d.ts.map +1 -1
- package/build/types/object-table/EditableCell.d.ts.map +1 -1
- package/build/types/object-table/MultiColumnSortDialog.d.ts +10 -1
- package/build/types/object-table/MultiColumnSortDialog.d.ts.map +1 -1
- 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 +9 -0
- package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
- package/build/types/object-table/ObjectTableLabels.d.ts +135 -0
- package/build/types/object-table/ObjectTableLabels.d.ts.map +1 -0
- package/build/types/object-table/SelectionCells.d.ts.map +1 -1
- package/build/types/object-table/Table.d.ts +7 -0
- package/build/types/object-table/Table.d.ts.map +1 -1
- package/build/types/object-table/TableEditContainer.d.ts.map +1 -1
- package/build/types/object-table/TableHeaderWithPopover.d.ts.map +1 -1
- package/build/types/object-table/components/AsyncValueCell.d.ts.map +1 -1
- package/build/types/public/experimental/object-table.d.ts +1 -0
- package/build/types/public/experimental/object-table.d.ts.map +1 -1
- package/docs/ObjectTable.md +1 -0
- package/package.json +6 -6
- package/build/cjs/chunk-4YFH7US6.cjs +0 -11
- package/build/cjs/chunk-6U4W2HH5.cjs +0 -11
- package/build/cjs/chunk-ACLCVBDB.cjs +0 -11
- package/build/cjs/chunk-AY3WIKRW.cjs.map +0 -1
- package/build/cjs/chunk-GNOUY65C.cjs +0 -11
- package/build/cjs/chunk-UQM4DWUN.cjs.map +0 -1
- package/build/cjs/chunk-XEDHHJ5U.cjs +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @osdk/react-components
|
|
2
2
|
|
|
3
|
+
## 0.41.0-main-7e4163b0319ea02499200d07dc4969e11a5cb33c
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3b7e3a5: Add a `labels` prop to `ObjectTable`/`BaseTable` (and the standalone `ColumnConfigDialog`/`MultiColumnSortDialog`) so every user-facing string can be overridden for localization or wording. Any subset can be supplied; unset keys fall back to the built-in English defaults.
|
|
8
|
+
- 7e4163b: Restrict base-ui/react version to <1.4.0
|
|
9
|
+
|
|
3
10
|
## 0.40.0
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
|
@@ -24,8 +24,10 @@ import { Checkbox } from "../base-components/checkbox/Checkbox.js";
|
|
|
24
24
|
import { Dialog } from "../base-components/dialog/Dialog.js";
|
|
25
25
|
import { DraggableList } from "../base-components/draggable-list/DraggableList.js";
|
|
26
26
|
import { SearchBar } from "../base-components/search-bar/SearchBar.js";
|
|
27
|
+
import { useObjectTableLabels, withObjectTableLabels } from "./ObjectTableLabels.js";
|
|
27
28
|
import styles from "./ColumnConfigDialog.module.css.js";
|
|
28
|
-
export
|
|
29
|
+
export const ColumnConfigDialog = withObjectTableLabels(ColumnConfigDialogInner);
|
|
30
|
+
function ColumnConfigDialogInner({
|
|
29
31
|
isOpen,
|
|
30
32
|
onClose,
|
|
31
33
|
columnOptions,
|
|
@@ -34,6 +36,7 @@ export function ColumnConfigDialog({
|
|
|
34
36
|
onApply,
|
|
35
37
|
isValidConfig
|
|
36
38
|
}) {
|
|
39
|
+
const labels = useObjectTableLabels();
|
|
37
40
|
const [visibleColumns, setVisibleColumns] = useState([]);
|
|
38
41
|
const [searchQuery, setSearchQuery] = useState("");
|
|
39
42
|
const allColumns = useMemo(() => {
|
|
@@ -116,15 +119,18 @@ export function ColumnConfigDialog({
|
|
|
116
119
|
}, [allColumns, searchQuery]);
|
|
117
120
|
const footer = useMemo(() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionButton, {
|
|
118
121
|
onClick: onClose
|
|
119
|
-
},
|
|
122
|
+
}, labels.columnConfigCancel), /*#__PURE__*/React.createElement(ActionButton, {
|
|
120
123
|
variant: "primary",
|
|
121
124
|
onClick: handleApply,
|
|
122
125
|
disabled: isApplyDisabled
|
|
123
|
-
},
|
|
126
|
+
}, labels.columnConfigApply)), [onClose, handleApply, isApplyDisabled, labels]);
|
|
127
|
+
const dialogTitle = useMemo(() => /*#__PURE__*/React.createElement("div", {
|
|
128
|
+
className: styles.title
|
|
129
|
+
}, /*#__PURE__*/React.createElement(Cog, null), labels.columnConfigTitle), [labels]);
|
|
124
130
|
return /*#__PURE__*/React.createElement(Dialog, {
|
|
125
131
|
isOpen: isOpen,
|
|
126
132
|
onOpenChange: onClose,
|
|
127
|
-
title:
|
|
133
|
+
title: dialogTitle,
|
|
128
134
|
footer: footer,
|
|
129
135
|
className: styles.columnConfigDialog
|
|
130
136
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -142,9 +148,6 @@ export function ColumnConfigDialog({
|
|
|
142
148
|
filteredColumns: filteredAvailableColumns
|
|
143
149
|
})));
|
|
144
150
|
}
|
|
145
|
-
const DialogTitle = /*#__PURE__*/React.createElement("div", {
|
|
146
|
-
className: styles.title
|
|
147
|
-
}, /*#__PURE__*/React.createElement(Cog, null), "Configure Table Columns");
|
|
148
151
|
const getColumnConfig = (allColumns, visibleColumns) => {
|
|
149
152
|
const hiddenColumns = allColumns.filter(col => !visibleColumns.some(v => v.id === col.id));
|
|
150
153
|
return [...visibleColumns.map(col => ({
|
|
@@ -160,22 +163,23 @@ function VisibleColumnsList({
|
|
|
160
163
|
onReorder,
|
|
161
164
|
onRemove
|
|
162
165
|
}) {
|
|
166
|
+
const labels = useObjectTableLabels();
|
|
163
167
|
return /*#__PURE__*/React.createElement("div", {
|
|
164
168
|
className: styles.visibleColumnsContainer
|
|
165
169
|
}, /*#__PURE__*/React.createElement("div", {
|
|
166
170
|
className: styles.sectionHeader
|
|
167
171
|
}, /*#__PURE__*/React.createElement("div", {
|
|
168
172
|
className: styles.sectionTitle
|
|
169
|
-
}, /*#__PURE__*/React.createElement("span", null,
|
|
173
|
+
}, /*#__PURE__*/React.createElement("span", null, labels.columnConfigVisibleColumns), /*#__PURE__*/React.createElement("span", {
|
|
170
174
|
className: styles.countTag
|
|
171
175
|
}, columns.length)), /*#__PURE__*/React.createElement("div", {
|
|
172
176
|
className: styles.sectionHint
|
|
173
|
-
},
|
|
177
|
+
}, labels.columnConfigDragToReorder)), /*#__PURE__*/React.createElement(DraggableList, {
|
|
174
178
|
items: columns,
|
|
175
179
|
onReorder: onReorder,
|
|
176
180
|
onRemove: onRemove,
|
|
177
181
|
removeIconVariant: "trash",
|
|
178
|
-
emptyMessage:
|
|
182
|
+
emptyMessage: labels.columnConfigNoVisibleColumns,
|
|
179
183
|
className: styles.columnList
|
|
180
184
|
}));
|
|
181
185
|
}
|
|
@@ -191,6 +195,7 @@ function AvailableColumnsList({
|
|
|
191
195
|
const totalCount = filteredColumns.length;
|
|
192
196
|
const allFilteredSelected = filteredColumns.every(col => visibleColumns.some(v => v.id === col.id));
|
|
193
197
|
const someFilteredSelected = filteredColumns.some(col => visibleColumns.some(v => v.id === col.id));
|
|
198
|
+
const labels = useObjectTableLabels();
|
|
194
199
|
const handleSelectAllClick = useCallback(() => {
|
|
195
200
|
onSelectAll(filteredColumns);
|
|
196
201
|
}, [filteredColumns, onSelectAll]);
|
|
@@ -198,11 +203,11 @@ function AvailableColumnsList({
|
|
|
198
203
|
className: styles.availableColumnsContainer
|
|
199
204
|
}, /*#__PURE__*/React.createElement("div", {
|
|
200
205
|
className: classNames(styles.sectionHeader, styles.sectionTitle)
|
|
201
|
-
},
|
|
206
|
+
}, labels.columnConfigAddOrRemoveColumns), /*#__PURE__*/React.createElement(SearchBar, {
|
|
202
207
|
value: searchQuery,
|
|
203
208
|
onChange: onSearchChange,
|
|
204
|
-
placeholder:
|
|
205
|
-
"aria-label":
|
|
209
|
+
placeholder: labels.columnConfigSearchPlaceholder,
|
|
210
|
+
"aria-label": labels.columnConfigSearchAriaLabel,
|
|
206
211
|
className: styles.searchContainer
|
|
207
212
|
}), /*#__PURE__*/React.createElement(Collapsible.Root, {
|
|
208
213
|
defaultOpen: true,
|
|
@@ -216,7 +221,7 @@ function AvailableColumnsList({
|
|
|
216
221
|
indeterminate: someFilteredSelected && !allFilteredSelected,
|
|
217
222
|
onCheckedChange: handleSelectAllClick,
|
|
218
223
|
className: styles.checkbox
|
|
219
|
-
}),
|
|
224
|
+
}), labels.columnConfigAllColumns), /*#__PURE__*/React.createElement(Collapsible.Trigger, {
|
|
220
225
|
className: styles.categoryTrigger
|
|
221
226
|
}, /*#__PURE__*/React.createElement("span", {
|
|
222
227
|
className: styles.categoryCount
|
|
@@ -226,7 +231,7 @@ function AvailableColumnsList({
|
|
|
226
231
|
className: styles.propertyList
|
|
227
232
|
}, filteredColumns.length === 0 ? /*#__PURE__*/React.createElement("div", {
|
|
228
233
|
className: styles.emptyState
|
|
229
|
-
},
|
|
234
|
+
}, labels.columnConfigNoMatchingColumns) : filteredColumns.map(column => /*#__PURE__*/React.createElement(PropertyItem, {
|
|
230
235
|
key: column.id,
|
|
231
236
|
column: column,
|
|
232
237
|
isSelected: visibleColumns.some(v => v.id === column.id),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColumnConfigDialog.js","names":["Collapsible","CaretDown","Cog","SmallInfoSign","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Checkbox","Dialog","DraggableList","SearchBar","styles","ColumnConfigDialog","isOpen","onClose","columnOptions","currentVisibility","currentColumnOrder","onApply","isValidConfig","visibleColumns","setVisibleColumns","searchQuery","setSearchQuery","allColumns","map","opt","isVisible","id","label","name","visibleCols","filter","col","length","sort","a","b","indexA","indexOf","indexB","orderA","Infinity","orderB","handleApply","getColumnConfig","isValid","isApplyDisabled","handleReorderColumns","fromIndex","toIndex","items","handleRemoveColumn","columnId","prev","handleToggleColumn","column","isCurrentlyVisible","some","handleSearchChange","event","target","value","handleSelectAll","columns","allSelected","every","v","newColumns","filteredAvailableColumns","query","toLowerCase","trim","includes","footer","createElement","Fragment","onClick","variant","disabled","onOpenChange","title","DialogTitle","className","columnConfigDialog","dialogLayout","VisibleColumnsList","onReorder","onRemove","AvailableColumnsList","onSearchChange","onToggleColumn","onSelectAll","filteredColumns","hiddenColumns","visibleColumnsContainer","sectionHeader","sectionTitle","countTag","sectionHint","removeIconVariant","emptyMessage","columnList","selectedCount","totalCount","allFilteredSelected","someFilteredSelected","handleSelectAllClick","availableColumnsContainer","onChange","placeholder","searchContainer","Root","defaultOpen","propertiesList","categoryHeader","selectAllLabel","checked","indeterminate","onCheckedChange","checkbox","Trigger","categoryTrigger","categoryCount","caretIcon","Panel","propertyList","emptyState","PropertyItem","key","isSelected","onToggle","showInfoIcon","handleClick","propertyItem","propertyLabel","propertyName","infoIcon"],"sources":["ColumnConfigDialog.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 { Collapsible } from \"@base-ui/react/collapsible\";\nimport { CaretDown, Cog, SmallInfoSign } from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { ColumnOrderState, VisibilityState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Checkbox } from \"../base-components/checkbox/Checkbox.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { DraggableList } from \"../base-components/draggable-list/DraggableList.js\";\nimport { SearchBar } from \"../base-components/search-bar/SearchBar.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./ColumnConfigDialog.module.css\";\n\nexport interface ColumnConfig {\n columnId: string;\n isVisible: boolean;\n}\n\nexport type ColumnConfigOptions = Array<Pick<ColumnOption, \"id\" | \"name\">>;\n\nexport interface ColumnConfigDialogProps {\n isOpen: boolean;\n onClose: () => void;\n columnOptions: ColumnConfigOptions;\n currentVisibility?: VisibilityState;\n currentColumnOrder?: ColumnOrderState;\n onApply: (columns: ColumnConfig[]) => void;\n isValidConfig?: (columns: ColumnConfig[]) => boolean;\n}\n\ninterface ColumnItem {\n id: string;\n label: string;\n isVisible: boolean;\n}\n\nexport function ColumnConfigDialog({\n isOpen,\n onClose,\n columnOptions,\n currentVisibility,\n currentColumnOrder,\n onApply,\n isValidConfig,\n}: ColumnConfigDialogProps): React.ReactElement | null {\n const [visibleColumns, setVisibleColumns] = useState<ColumnItem[]>([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const allColumns: ColumnItem[] = useMemo(() => {\n return columnOptions.map((opt) => {\n const isVisible = currentVisibility ? currentVisibility[opt.id] : false;\n\n return {\n id: opt.id,\n label: opt.name,\n isVisible,\n };\n });\n }, [columnOptions, currentVisibility]);\n\n // Sync local state with prop when dialog is opened\n useEffect(() => {\n if (isOpen) {\n const visibleCols = allColumns.filter((col) => col.isVisible);\n\n // Sort by current column order if available\n if (!!currentColumnOrder?.length) {\n visibleCols.sort((a, b) => {\n const indexA = currentColumnOrder.indexOf(a.id);\n const indexB = currentColumnOrder.indexOf(b.id);\n // If not in order array, put at end\n const orderA = indexA === -1 ? Infinity : indexA;\n const orderB = indexB === -1 ? Infinity : indexB;\n return orderA - orderB;\n });\n }\n\n setVisibleColumns(visibleCols);\n setSearchQuery(\"\");\n }\n }, [isOpen, allColumns, currentColumnOrder]);\n\n const handleApply = useCallback(() => {\n onApply(getColumnConfig(allColumns, visibleColumns));\n onClose();\n }, [allColumns, visibleColumns, onApply, onClose]);\n\n // If no condition provided, default to valid\n const isValid = isValidConfig\n ? isValidConfig(getColumnConfig(allColumns, visibleColumns))\n : true;\n\n const isApplyDisabled = visibleColumns.length === 0 || !isValid;\n\n const handleReorderColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setVisibleColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleRemoveColumn = useCallback((columnId: string) => {\n setVisibleColumns((prev) => prev.filter((col) => col.id !== columnId));\n }, []);\n\n const handleToggleColumn = useCallback((column: ColumnItem) => {\n setVisibleColumns((prev) => {\n const isCurrentlyVisible = prev.some((col) => col.id === column.id);\n if (isCurrentlyVisible) {\n return prev.filter((col) => col.id !== column.id);\n } else {\n return [...prev, column];\n }\n });\n }, []);\n\n const handleSearchChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchQuery(event.target.value);\n },\n []\n );\n\n const handleSelectAll = useCallback((columns: ColumnItem[]) => {\n setVisibleColumns((prev) => {\n const allSelected = columns.every((col) =>\n prev.some((v) => v.id === col.id)\n );\n if (allSelected) {\n // Deselect all filtered columns\n return prev.filter((v) => !columns.some((col) => col.id === v.id));\n } else {\n // Select all filtered columns that aren't already selected\n const newColumns = columns.filter(\n (col) => !prev.some((v) => v.id === col.id)\n );\n return [...prev, ...newColumns];\n }\n });\n }, []);\n\n const filteredAvailableColumns = useMemo(() => {\n const query = searchQuery.toLowerCase().trim();\n if (!query) {\n return allColumns;\n }\n return allColumns.filter(\n (col) =>\n (col.label?.toLowerCase().includes(query) ?? false) ||\n col.id.toLowerCase().includes(query)\n );\n }, [allColumns, searchQuery]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>Cancel</ActionButton>\n <ActionButton\n variant=\"primary\"\n onClick={handleApply}\n disabled={isApplyDisabled}\n >\n Apply\n </ActionButton>\n </>\n ),\n [onClose, handleApply, isApplyDisabled]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={DialogTitle}\n footer={footer}\n className={styles.columnConfigDialog}\n >\n <div className={styles.dialogLayout}>\n <VisibleColumnsList\n columns={visibleColumns}\n onReorder={handleReorderColumns}\n onRemove={handleRemoveColumn}\n />\n <AvailableColumnsList\n visibleColumns={visibleColumns}\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n onToggleColumn={handleToggleColumn}\n onSelectAll={handleSelectAll}\n filteredColumns={filteredAvailableColumns}\n />\n </div>\n </Dialog>\n );\n}\n\nconst DialogTitle = (\n <div className={styles.title}>\n <Cog />\n Configure Table Columns\n </div>\n);\n\nconst getColumnConfig = (\n allColumns: ColumnItem[],\n visibleColumns: ColumnItem[]\n): ColumnConfig[] => {\n const hiddenColumns = allColumns.filter(\n (col) => !visibleColumns.some((v) => v.id === col.id)\n );\n\n return [\n ...visibleColumns.map((col) => ({ columnId: col.id, isVisible: true })),\n ...hiddenColumns.map((col) => ({ columnId: col.id, isVisible: false })),\n ];\n};\n\ninterface VisibleColumnsListProps {\n columns: ColumnItem[];\n onReorder: (fromIndex: number, toIndex: number) => void;\n onRemove: (columnId: string) => void;\n}\n\nfunction VisibleColumnsList({\n columns,\n onReorder,\n onRemove,\n}: VisibleColumnsListProps): React.ReactElement {\n return (\n <div className={styles.visibleColumnsContainer}>\n <div className={styles.sectionHeader}>\n <div className={styles.sectionTitle}>\n <span>Visible Columns</span>\n <span className={styles.countTag}>{columns.length}</span>\n </div>\n <div className={styles.sectionHint}>Drag to reorder</div>\n </div>\n <DraggableList\n items={columns}\n onReorder={onReorder}\n onRemove={onRemove}\n removeIconVariant=\"trash\"\n emptyMessage=\"No visible columns\"\n className={styles.columnList}\n />\n </div>\n );\n}\n\ninterface AvailableColumnsListProps {\n visibleColumns: ColumnItem[];\n searchQuery: string;\n onSearchChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n onToggleColumn: (column: ColumnItem) => void;\n onSelectAll: (columns: ColumnItem[]) => void;\n filteredColumns: ColumnItem[];\n}\n\nfunction AvailableColumnsList({\n visibleColumns,\n searchQuery,\n onSearchChange,\n onToggleColumn,\n onSelectAll,\n filteredColumns,\n}: AvailableColumnsListProps): React.ReactElement {\n const selectedCount = visibleColumns.length;\n const totalCount = filteredColumns.length;\n const allFilteredSelected = filteredColumns.every((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n const someFilteredSelected = filteredColumns.some((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n\n const handleSelectAllClick = useCallback(() => {\n onSelectAll(filteredColumns);\n }, [filteredColumns, onSelectAll]);\n\n return (\n <div className={styles.availableColumnsContainer}>\n <div className={classNames(styles.sectionHeader, styles.sectionTitle)}>\n Add or Remove Columns\n </div>\n <SearchBar\n value={searchQuery}\n onChange={onSearchChange}\n placeholder=\"Search...\"\n aria-label=\"Search available columns\"\n className={styles.searchContainer}\n />\n <Collapsible.Root defaultOpen={true} className={styles.propertiesList}>\n <div className={styles.categoryHeader}>\n <label className={styles.selectAllLabel}>\n <Checkbox\n checked={allFilteredSelected}\n indeterminate={someFilteredSelected && !allFilteredSelected}\n onCheckedChange={handleSelectAllClick}\n className={styles.checkbox}\n />\n All Columns\n </label>\n <Collapsible.Trigger className={styles.categoryTrigger}>\n <span className={styles.categoryCount}>\n {selectedCount}/{totalCount}\n </span>\n <CaretDown className={styles.caretIcon} />\n </Collapsible.Trigger>\n </div>\n <Collapsible.Panel className={styles.propertyList}>\n {filteredColumns.length === 0 ? (\n <div className={styles.emptyState}>No matching columns found</div>\n ) : (\n filteredColumns.map((column) => (\n <PropertyItem\n key={column.id}\n column={column}\n isSelected={visibleColumns.some((v) => v.id === column.id)}\n onToggle={onToggleColumn}\n />\n ))\n )}\n </Collapsible.Panel>\n </Collapsible.Root>\n </div>\n );\n}\n\ninterface PropertyItemProps {\n column: ColumnItem;\n isSelected: boolean;\n onToggle: (column: ColumnItem) => void;\n showInfoIcon?: boolean;\n}\n\nfunction PropertyItem({\n column,\n isSelected,\n onToggle,\n showInfoIcon = false,\n}: PropertyItemProps): React.ReactElement {\n const handleClick = useCallback(() => {\n onToggle(column);\n }, [onToggle, column]);\n\n return (\n <div className={styles.propertyItem}>\n <label className={styles.propertyLabel}>\n <Checkbox\n checked={isSelected}\n onCheckedChange={handleClick}\n className={styles.checkbox}\n />\n <span className={styles.propertyName}>{column.label}</span>\n </label>\n {showInfoIcon && <SmallInfoSign className={styles.infoIcon} />}\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"ColumnConfigDialog.js","names":["Collapsible","CaretDown","Cog","SmallInfoSign","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Checkbox","Dialog","DraggableList","SearchBar","useObjectTableLabels","withObjectTableLabels","styles","ColumnConfigDialog","ColumnConfigDialogInner","isOpen","onClose","columnOptions","currentVisibility","currentColumnOrder","onApply","isValidConfig","labels","visibleColumns","setVisibleColumns","searchQuery","setSearchQuery","allColumns","map","opt","isVisible","id","label","name","visibleCols","filter","col","length","sort","a","b","indexA","indexOf","indexB","orderA","Infinity","orderB","handleApply","getColumnConfig","isValid","isApplyDisabled","handleReorderColumns","fromIndex","toIndex","items","handleRemoveColumn","columnId","prev","handleToggleColumn","column","isCurrentlyVisible","some","handleSearchChange","event","target","value","handleSelectAll","columns","allSelected","every","v","newColumns","filteredAvailableColumns","query","toLowerCase","trim","includes","footer","createElement","Fragment","onClick","columnConfigCancel","variant","disabled","columnConfigApply","dialogTitle","className","title","columnConfigTitle","onOpenChange","columnConfigDialog","dialogLayout","VisibleColumnsList","onReorder","onRemove","AvailableColumnsList","onSearchChange","onToggleColumn","onSelectAll","filteredColumns","hiddenColumns","visibleColumnsContainer","sectionHeader","sectionTitle","columnConfigVisibleColumns","countTag","sectionHint","columnConfigDragToReorder","removeIconVariant","emptyMessage","columnConfigNoVisibleColumns","columnList","selectedCount","totalCount","allFilteredSelected","someFilteredSelected","handleSelectAllClick","availableColumnsContainer","columnConfigAddOrRemoveColumns","onChange","placeholder","columnConfigSearchPlaceholder","columnConfigSearchAriaLabel","searchContainer","Root","defaultOpen","propertiesList","categoryHeader","selectAllLabel","checked","indeterminate","onCheckedChange","checkbox","columnConfigAllColumns","Trigger","categoryTrigger","categoryCount","caretIcon","Panel","propertyList","emptyState","columnConfigNoMatchingColumns","PropertyItem","key","isSelected","onToggle","showInfoIcon","handleClick","propertyItem","propertyLabel","propertyName","infoIcon"],"sources":["ColumnConfigDialog.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 { Collapsible } from \"@base-ui/react/collapsible\";\nimport { CaretDown, Cog, SmallInfoSign } from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { ColumnOrderState, VisibilityState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Checkbox } from \"../base-components/checkbox/Checkbox.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { DraggableList } from \"../base-components/draggable-list/DraggableList.js\";\nimport { SearchBar } from \"../base-components/search-bar/SearchBar.js\";\nimport type { ObjectTableLabels } from \"./ObjectTableLabels.js\";\nimport {\n useObjectTableLabels,\n withObjectTableLabels,\n} from \"./ObjectTableLabels.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./ColumnConfigDialog.module.css\";\n\nexport interface ColumnConfig {\n columnId: string;\n isVisible: boolean;\n}\n\nexport type ColumnConfigOptions = Array<Pick<ColumnOption, \"id\" | \"name\">>;\n\nexport interface ColumnConfigDialogProps {\n isOpen: boolean;\n onClose: () => void;\n columnOptions: ColumnConfigOptions;\n currentVisibility?: VisibilityState;\n currentColumnOrder?: ColumnOrderState;\n onApply: (columns: ColumnConfig[]) => void;\n isValidConfig?: (columns: ColumnConfig[]) => boolean;\n /**\n * Overrides for the dialog's user-facing strings. Provide any subset; unset\n * keys fall back to the built-in English defaults. When this dialog is\n * rendered inside a `BaseTable`/`ObjectTable`, it inherits that table's\n * `labels` and this prop is only needed to override further. See\n * {@link ObjectTableLabels}.\n */\n labels?: Partial<ObjectTableLabels>;\n}\n\ninterface ColumnItem {\n id: string;\n label: string;\n isVisible: boolean;\n}\n\nexport const ColumnConfigDialog: React.FC<ColumnConfigDialogProps> =\n withObjectTableLabels(ColumnConfigDialogInner);\n\nfunction ColumnConfigDialogInner({\n isOpen,\n onClose,\n columnOptions,\n currentVisibility,\n currentColumnOrder,\n onApply,\n isValidConfig,\n}: Omit<ColumnConfigDialogProps, \"labels\">): React.ReactElement {\n const labels = useObjectTableLabels();\n const [visibleColumns, setVisibleColumns] = useState<ColumnItem[]>([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const allColumns: ColumnItem[] = useMemo(() => {\n return columnOptions.map((opt) => {\n const isVisible = currentVisibility ? currentVisibility[opt.id] : false;\n\n return {\n id: opt.id,\n label: opt.name,\n isVisible,\n };\n });\n }, [columnOptions, currentVisibility]);\n\n // Sync local state with prop when dialog is opened\n useEffect(() => {\n if (isOpen) {\n const visibleCols = allColumns.filter((col) => col.isVisible);\n\n // Sort by current column order if available\n if (!!currentColumnOrder?.length) {\n visibleCols.sort((a, b) => {\n const indexA = currentColumnOrder.indexOf(a.id);\n const indexB = currentColumnOrder.indexOf(b.id);\n // If not in order array, put at end\n const orderA = indexA === -1 ? Infinity : indexA;\n const orderB = indexB === -1 ? Infinity : indexB;\n return orderA - orderB;\n });\n }\n\n setVisibleColumns(visibleCols);\n setSearchQuery(\"\");\n }\n }, [isOpen, allColumns, currentColumnOrder]);\n\n const handleApply = useCallback(() => {\n onApply(getColumnConfig(allColumns, visibleColumns));\n onClose();\n }, [allColumns, visibleColumns, onApply, onClose]);\n\n // If no condition provided, default to valid\n const isValid = isValidConfig\n ? isValidConfig(getColumnConfig(allColumns, visibleColumns))\n : true;\n\n const isApplyDisabled = visibleColumns.length === 0 || !isValid;\n\n const handleReorderColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setVisibleColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleRemoveColumn = useCallback((columnId: string) => {\n setVisibleColumns((prev) => prev.filter((col) => col.id !== columnId));\n }, []);\n\n const handleToggleColumn = useCallback((column: ColumnItem) => {\n setVisibleColumns((prev) => {\n const isCurrentlyVisible = prev.some((col) => col.id === column.id);\n if (isCurrentlyVisible) {\n return prev.filter((col) => col.id !== column.id);\n } else {\n return [...prev, column];\n }\n });\n }, []);\n\n const handleSearchChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchQuery(event.target.value);\n },\n []\n );\n\n const handleSelectAll = useCallback((columns: ColumnItem[]) => {\n setVisibleColumns((prev) => {\n const allSelected = columns.every((col) =>\n prev.some((v) => v.id === col.id)\n );\n if (allSelected) {\n // Deselect all filtered columns\n return prev.filter((v) => !columns.some((col) => col.id === v.id));\n } else {\n // Select all filtered columns that aren't already selected\n const newColumns = columns.filter(\n (col) => !prev.some((v) => v.id === col.id)\n );\n return [...prev, ...newColumns];\n }\n });\n }, []);\n\n const filteredAvailableColumns = useMemo(() => {\n const query = searchQuery.toLowerCase().trim();\n if (!query) {\n return allColumns;\n }\n return allColumns.filter(\n (col) =>\n (col.label?.toLowerCase().includes(query) ?? false) ||\n col.id.toLowerCase().includes(query)\n );\n }, [allColumns, searchQuery]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>\n {labels.columnConfigCancel}\n </ActionButton>\n <ActionButton\n variant=\"primary\"\n onClick={handleApply}\n disabled={isApplyDisabled}\n >\n {labels.columnConfigApply}\n </ActionButton>\n </>\n ),\n [onClose, handleApply, isApplyDisabled, labels]\n );\n\n const dialogTitle = useMemo(\n () => (\n <div className={styles.title}>\n <Cog />\n {labels.columnConfigTitle}\n </div>\n ),\n [labels]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={dialogTitle}\n footer={footer}\n className={styles.columnConfigDialog}\n >\n <div className={styles.dialogLayout}>\n <VisibleColumnsList\n columns={visibleColumns}\n onReorder={handleReorderColumns}\n onRemove={handleRemoveColumn}\n />\n <AvailableColumnsList\n visibleColumns={visibleColumns}\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n onToggleColumn={handleToggleColumn}\n onSelectAll={handleSelectAll}\n filteredColumns={filteredAvailableColumns}\n />\n </div>\n </Dialog>\n );\n}\n\nconst getColumnConfig = (\n allColumns: ColumnItem[],\n visibleColumns: ColumnItem[]\n): ColumnConfig[] => {\n const hiddenColumns = allColumns.filter(\n (col) => !visibleColumns.some((v) => v.id === col.id)\n );\n\n return [\n ...visibleColumns.map((col) => ({ columnId: col.id, isVisible: true })),\n ...hiddenColumns.map((col) => ({ columnId: col.id, isVisible: false })),\n ];\n};\n\ninterface VisibleColumnsListProps {\n columns: ColumnItem[];\n onReorder: (fromIndex: number, toIndex: number) => void;\n onRemove: (columnId: string) => void;\n}\n\nfunction VisibleColumnsList({\n columns,\n onReorder,\n onRemove,\n}: VisibleColumnsListProps): React.ReactElement {\n const labels = useObjectTableLabels();\n return (\n <div className={styles.visibleColumnsContainer}>\n <div className={styles.sectionHeader}>\n <div className={styles.sectionTitle}>\n <span>{labels.columnConfigVisibleColumns}</span>\n <span className={styles.countTag}>{columns.length}</span>\n </div>\n <div className={styles.sectionHint}>\n {labels.columnConfigDragToReorder}\n </div>\n </div>\n <DraggableList\n items={columns}\n onReorder={onReorder}\n onRemove={onRemove}\n removeIconVariant=\"trash\"\n emptyMessage={labels.columnConfigNoVisibleColumns}\n className={styles.columnList}\n />\n </div>\n );\n}\n\ninterface AvailableColumnsListProps {\n visibleColumns: ColumnItem[];\n searchQuery: string;\n onSearchChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n onToggleColumn: (column: ColumnItem) => void;\n onSelectAll: (columns: ColumnItem[]) => void;\n filteredColumns: ColumnItem[];\n}\n\nfunction AvailableColumnsList({\n visibleColumns,\n searchQuery,\n onSearchChange,\n onToggleColumn,\n onSelectAll,\n filteredColumns,\n}: AvailableColumnsListProps): React.ReactElement {\n const selectedCount = visibleColumns.length;\n const totalCount = filteredColumns.length;\n const allFilteredSelected = filteredColumns.every((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n const someFilteredSelected = filteredColumns.some((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n\n const labels = useObjectTableLabels();\n\n const handleSelectAllClick = useCallback(() => {\n onSelectAll(filteredColumns);\n }, [filteredColumns, onSelectAll]);\n\n return (\n <div className={styles.availableColumnsContainer}>\n <div className={classNames(styles.sectionHeader, styles.sectionTitle)}>\n {labels.columnConfigAddOrRemoveColumns}\n </div>\n <SearchBar\n value={searchQuery}\n onChange={onSearchChange}\n placeholder={labels.columnConfigSearchPlaceholder}\n aria-label={labels.columnConfigSearchAriaLabel}\n className={styles.searchContainer}\n />\n <Collapsible.Root defaultOpen={true} className={styles.propertiesList}>\n <div className={styles.categoryHeader}>\n <label className={styles.selectAllLabel}>\n <Checkbox\n checked={allFilteredSelected}\n indeterminate={someFilteredSelected && !allFilteredSelected}\n onCheckedChange={handleSelectAllClick}\n className={styles.checkbox}\n />\n {labels.columnConfigAllColumns}\n </label>\n <Collapsible.Trigger className={styles.categoryTrigger}>\n <span className={styles.categoryCount}>\n {selectedCount}/{totalCount}\n </span>\n <CaretDown className={styles.caretIcon} />\n </Collapsible.Trigger>\n </div>\n <Collapsible.Panel className={styles.propertyList}>\n {filteredColumns.length === 0 ? (\n <div className={styles.emptyState}>\n {labels.columnConfigNoMatchingColumns}\n </div>\n ) : (\n filteredColumns.map((column) => (\n <PropertyItem\n key={column.id}\n column={column}\n isSelected={visibleColumns.some((v) => v.id === column.id)}\n onToggle={onToggleColumn}\n />\n ))\n )}\n </Collapsible.Panel>\n </Collapsible.Root>\n </div>\n );\n}\n\ninterface PropertyItemProps {\n column: ColumnItem;\n isSelected: boolean;\n onToggle: (column: ColumnItem) => void;\n showInfoIcon?: boolean;\n}\n\nfunction PropertyItem({\n column,\n isSelected,\n onToggle,\n showInfoIcon = false,\n}: PropertyItemProps): React.ReactElement {\n const handleClick = useCallback(() => {\n onToggle(column);\n }, [onToggle, column]);\n\n return (\n <div className={styles.propertyItem}>\n <label className={styles.propertyLabel}>\n <Checkbox\n checked={isSelected}\n onCheckedChange={handleClick}\n className={styles.checkbox}\n />\n <span className={styles.propertyName}>{column.label}</span>\n </label>\n {showInfoIcon && <SmallInfoSign className={styles.infoIcon} />}\n </div>\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,WAAW,QAAQ,4BAA4B;AACxD,SAASC,SAAS,EAAEC,GAAG,EAAEC,aAAa,QAAQ,oBAAoB;AAClE,SAASC,SAAS,QAAQ,mBAAmB;AAE7C,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAOC,KAAK,IAAIC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,OAAO;AAExE,SAASC,YAAY,QAAQ,kDAAkD;AAC/E,SAASC,QAAQ,QAAQ,yCAAyC;AAClE,SAASC,MAAM,QAAQ,qCAAqC;AAC5D,SAASC,aAAa,QAAQ,oDAAoD;AAClF,SAASC,SAAS,QAAQ,4CAA4C;AAEtE,SACEC,oBAAoB,EACpBC,qBAAqB,QAChB,wBAAwB;AAG/B,OAAOC,MAAM,MAAM,iCAAiC;AAiCpD,OAAO,MAAMC,kBAAqD,GAChEF,qBAAqB,CAACG,uBAAuB,CAAC;AAEhD,SAASA,uBAAuBA,CAAC;EAC/BC,MAAM;EACNC,OAAO;EACPC,aAAa;EACbC,iBAAiB;EACjBC,kBAAkB;EAClBC,OAAO;EACPC;AACuC,CAAC,EAAsB;EAC9D,MAAMC,MAAM,GAAGZ,oBAAoB,CAAC,CAAC;EACrC,MAAM,CAACa,cAAc,EAAEC,iBAAiB,CAAC,GAAGpB,QAAQ,CAAe,EAAE,CAAC;EACtE,MAAM,CAACqB,WAAW,EAAEC,cAAc,CAAC,GAAGtB,QAAQ,CAAC,EAAE,CAAC;EAElD,MAAMuB,UAAwB,GAAGxB,OAAO,CAAC,MAAM;IAC7C,OAAOc,aAAa,CAACW,GAAG,CAAEC,GAAG,IAAK;MAChC,MAAMC,SAAS,GAAGZ,iBAAiB,GAAGA,iBAAiB,CAACW,GAAG,CAACE,EAAE,CAAC,GAAG,KAAK;MAEvE,OAAO;QACLA,EAAE,EAAEF,GAAG,CAACE,EAAE;QACVC,KAAK,EAAEH,GAAG,CAACI,IAAI;QACfH;MACF,CAAC;IACH,CAAC,CAAC;EACJ,CAAC,EAAE,CAACb,aAAa,EAAEC,iBAAiB,CAAC,CAAC;;EAEtC;EACAhB,SAAS,CAAC,MAAM;IACd,IAAIa,MAAM,EAAE;MACV,MAAMmB,WAAW,GAAGP,UAAU,CAACQ,MAAM,CAAEC,GAAG,IAAKA,GAAG,CAACN,SAAS,CAAC;;MAE7D;MACA,IAAI,CAAC,CAACX,kBAAkB,EAAEkB,MAAM,EAAE;QAChCH,WAAW,CAACI,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAK;UACzB,MAAMC,MAAM,GAAGtB,kBAAkB,CAACuB,OAAO,CAACH,CAAC,CAACR,EAAE,CAAC;UAC/C,MAAMY,MAAM,GAAGxB,kBAAkB,CAACuB,OAAO,CAACF,CAAC,CAACT,EAAE,CAAC;UAC/C;UACA,MAAMa,MAAM,GAAGH,MAAM,KAAK,CAAC,CAAC,GAAGI,QAAQ,GAAGJ,MAAM;UAChD,MAAMK,MAAM,GAAGH,MAAM,KAAK,CAAC,CAAC,GAAGE,QAAQ,GAAGF,MAAM;UAChD,OAAOC,MAAM,GAAGE,MAAM;QACxB,CAAC,CAAC;MACJ;MAEAtB,iBAAiB,CAACU,WAAW,CAAC;MAC9BR,cAAc,CAAC,EAAE,CAAC;IACpB;EACF,CAAC,EAAE,CAACX,MAAM,EAAEY,UAAU,EAAER,kBAAkB,CAAC,CAAC;EAE5C,MAAM4B,WAAW,GAAG9C,WAAW,CAAC,MAAM;IACpCmB,OAAO,CAAC4B,eAAe,CAACrB,UAAU,EAAEJ,cAAc,CAAC,CAAC;IACpDP,OAAO,CAAC,CAAC;EACX,CAAC,EAAE,CAACW,UAAU,EAAEJ,cAAc,EAAEH,OAAO,EAAEJ,OAAO,CAAC,CAAC;;EAElD;EACA,MAAMiC,OAAO,GAAG5B,aAAa,GACzBA,aAAa,CAAC2B,eAAe,CAACrB,UAAU,EAAEJ,cAAc,CAAC,CAAC,GAC1D,IAAI;EAER,MAAM2B,eAAe,GAAG3B,cAAc,CAACc,MAAM,KAAK,CAAC,IAAI,CAACY,OAAO;EAE/D,MAAME,oBAAoB,GAAGlD,WAAW,CACtC,CAACmD,SAAiB,EAAEC,OAAe,KAAK;IACtC7B,iBAAiB,CAAE8B,KAAK,IAAKxD,SAAS,CAACwD,KAAK,EAAEF,SAAS,EAAEC,OAAO,CAAC,CAAC;EACpE,CAAC,EACD,EACF,CAAC;EAED,MAAME,kBAAkB,GAAGtD,WAAW,CAAEuD,QAAgB,IAAK;IAC3DhC,iBAAiB,CAAEiC,IAAI,IAAKA,IAAI,CAACtB,MAAM,CAAEC,GAAG,IAAKA,GAAG,CAACL,EAAE,KAAKyB,QAAQ,CAAC,CAAC;EACxE,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,kBAAkB,GAAGzD,WAAW,CAAE0D,MAAkB,IAAK;IAC7DnC,iBAAiB,CAAEiC,IAAI,IAAK;MAC1B,MAAMG,kBAAkB,GAAGH,IAAI,CAACI,IAAI,CAAEzB,GAAG,IAAKA,GAAG,CAACL,EAAE,KAAK4B,MAAM,CAAC5B,EAAE,CAAC;MACnE,IAAI6B,kBAAkB,EAAE;QACtB,OAAOH,IAAI,CAACtB,MAAM,CAAEC,GAAG,IAAKA,GAAG,CAACL,EAAE,KAAK4B,MAAM,CAAC5B,EAAE,CAAC;MACnD,CAAC,MAAM;QACL,OAAO,CAAC,GAAG0B,IAAI,EAAEE,MAAM,CAAC;MAC1B;IACF,CAAC,CAAC;EACJ,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMG,kBAAkB,GAAG7D,WAAW,CACnC8D,KAA0C,IAAK;IAC9CrC,cAAc,CAACqC,KAAK,CAACC,MAAM,CAACC,KAAK,CAAC;EACpC,CAAC,EACD,EACF,CAAC;EAED,MAAMC,eAAe,GAAGjE,WAAW,CAAEkE,OAAqB,IAAK;IAC7D3C,iBAAiB,CAAEiC,IAAI,IAAK;MAC1B,MAAMW,WAAW,GAAGD,OAAO,CAACE,KAAK,CAAEjC,GAAG,IACpCqB,IAAI,CAACI,IAAI,CAAES,CAAC,IAAKA,CAAC,CAACvC,EAAE,KAAKK,GAAG,CAACL,EAAE,CAClC,CAAC;MACD,IAAIqC,WAAW,EAAE;QACf;QACA,OAAOX,IAAI,CAACtB,MAAM,CAAEmC,CAAC,IAAK,CAACH,OAAO,CAACN,IAAI,CAAEzB,GAAG,IAAKA,GAAG,CAACL,EAAE,KAAKuC,CAAC,CAACvC,EAAE,CAAC,CAAC;MACpE,CAAC,MAAM;QACL;QACA,MAAMwC,UAAU,GAAGJ,OAAO,CAAChC,MAAM,CAC9BC,GAAG,IAAK,CAACqB,IAAI,CAACI,IAAI,CAAES,CAAC,IAAKA,CAAC,CAACvC,EAAE,KAAKK,GAAG,CAACL,EAAE,CAC5C,CAAC;QACD,OAAO,CAAC,GAAG0B,IAAI,EAAE,GAAGc,UAAU,CAAC;MACjC;IACF,CAAC,CAAC;EACJ,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMC,wBAAwB,GAAGrE,OAAO,CAAC,MAAM;IAC7C,MAAMsE,KAAK,GAAGhD,WAAW,CAACiD,WAAW,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC;IAC9C,IAAI,CAACF,KAAK,EAAE;MACV,OAAO9C,UAAU;IACnB;IACA,OAAOA,UAAU,CAACQ,MAAM,CACrBC,GAAG,IACF,CAACA,GAAG,CAACJ,KAAK,EAAE0C,WAAW,CAAC,CAAC,CAACE,QAAQ,CAACH,KAAK,CAAC,IAAI,KAAK,KAClDrC,GAAG,CAACL,EAAE,CAAC2C,WAAW,CAAC,CAAC,CAACE,QAAQ,CAACH,KAAK,CACvC,CAAC;EACH,CAAC,EAAE,CAAC9C,UAAU,EAAEF,WAAW,CAAC,CAAC;EAE7B,MAAMoD,MAAM,GAAG1E,OAAO,CACpB,mBACEH,KAAA,CAAA8E,aAAA,CAAA9E,KAAA,CAAA+E,QAAA,qBACE/E,KAAA,CAAA8E,aAAA,CAACzE,YAAY;IAAC2E,OAAO,EAAEhE;EAAQ,GAC5BM,MAAM,CAAC2D,kBACI,CAAC,eACfjF,KAAA,CAAA8E,aAAA,CAACzE,YAAY;IACX6E,OAAO,EAAC,SAAS;IACjBF,OAAO,EAAEjC,WAAY;IACrBoC,QAAQ,EAAEjC;EAAgB,GAEzB5B,MAAM,CAAC8D,iBACI,CACd,CACH,EACD,CAACpE,OAAO,EAAE+B,WAAW,EAAEG,eAAe,EAAE5B,MAAM,CAChD,CAAC;EAED,MAAM+D,WAAW,GAAGlF,OAAO,CACzB,mBACEH,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAAC2E;EAAM,gBAC3BvF,KAAA,CAAA8E,aAAA,CAAClF,GAAG,MAAE,CAAC,EACN0B,MAAM,CAACkE,iBACL,CACN,EACD,CAAClE,MAAM,CACT,CAAC;EAED,oBACEtB,KAAA,CAAA8E,aAAA,CAACvE,MAAM;IACLQ,MAAM,EAAEA,MAAO;IACf0E,YAAY,EAAEzE,OAAQ;IACtBuE,KAAK,EAAEF,WAAY;IACnBR,MAAM,EAAEA,MAAO;IACfS,SAAS,EAAE1E,MAAM,CAAC8E;EAAmB,gBAErC1F,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAAC+E;EAAa,gBAClC3F,KAAA,CAAA8E,aAAA,CAACc,kBAAkB;IACjBzB,OAAO,EAAE5C,cAAe;IACxBsE,SAAS,EAAE1C,oBAAqB;IAChC2C,QAAQ,EAAEvC;EAAmB,CAC9B,CAAC,eACFvD,KAAA,CAAA8E,aAAA,CAACiB,oBAAoB;IACnBxE,cAAc,EAAEA,cAAe;IAC/BE,WAAW,EAAEA,WAAY;IACzBuE,cAAc,EAAElC,kBAAmB;IACnCmC,cAAc,EAAEvC,kBAAmB;IACnCwC,WAAW,EAAEhC,eAAgB;IAC7BiC,eAAe,EAAE3B;EAAyB,CAC3C,CACE,CACC,CAAC;AAEb;AAEA,MAAMxB,eAAe,GAAGA,CACtBrB,UAAwB,EACxBJ,cAA4B,KACT;EACnB,MAAM6E,aAAa,GAAGzE,UAAU,CAACQ,MAAM,CACpCC,GAAG,IAAK,CAACb,cAAc,CAACsC,IAAI,CAAES,CAAC,IAAKA,CAAC,CAACvC,EAAE,KAAKK,GAAG,CAACL,EAAE,CACtD,CAAC;EAED,OAAO,CACL,GAAGR,cAAc,CAACK,GAAG,CAAEQ,GAAG,KAAM;IAAEoB,QAAQ,EAAEpB,GAAG,CAACL,EAAE;IAAED,SAAS,EAAE;EAAK,CAAC,CAAC,CAAC,EACvE,GAAGsE,aAAa,CAACxE,GAAG,CAAEQ,GAAG,KAAM;IAAEoB,QAAQ,EAAEpB,GAAG,CAACL,EAAE;IAAED,SAAS,EAAE;EAAM,CAAC,CAAC,CAAC,CACxE;AACH,CAAC;AAQD,SAAS8D,kBAAkBA,CAAC;EAC1BzB,OAAO;EACP0B,SAAS;EACTC;AACuB,CAAC,EAAsB;EAC9C,MAAMxE,MAAM,GAAGZ,oBAAoB,CAAC,CAAC;EACrC,oBACEV,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAACyF;EAAwB,gBAC7CrG,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAAC0F;EAAc,gBACnCtG,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAAC2F;EAAa,gBAClCvG,KAAA,CAAA8E,aAAA,eAAOxD,MAAM,CAACkF,0BAAiC,CAAC,eAChDxG,KAAA,CAAA8E,aAAA;IAAMQ,SAAS,EAAE1E,MAAM,CAAC6F;EAAS,GAAEtC,OAAO,CAAC9B,MAAa,CACrD,CAAC,eACNrC,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAAC8F;EAAY,GAChCpF,MAAM,CAACqF,yBACL,CACF,CAAC,eACN3G,KAAA,CAAA8E,aAAA,CAACtE,aAAa;IACZ8C,KAAK,EAAEa,OAAQ;IACf0B,SAAS,EAAEA,SAAU;IACrBC,QAAQ,EAAEA,QAAS;IACnBc,iBAAiB,EAAC,OAAO;IACzBC,YAAY,EAAEvF,MAAM,CAACwF,4BAA6B;IAClDxB,SAAS,EAAE1E,MAAM,CAACmG;EAAW,CAC9B,CACE,CAAC;AAEV;AAWA,SAAShB,oBAAoBA,CAAC;EAC5BxE,cAAc;EACdE,WAAW;EACXuE,cAAc;EACdC,cAAc;EACdC,WAAW;EACXC;AACyB,CAAC,EAAsB;EAChD,MAAMa,aAAa,GAAGzF,cAAc,CAACc,MAAM;EAC3C,MAAM4E,UAAU,GAAGd,eAAe,CAAC9D,MAAM;EACzC,MAAM6E,mBAAmB,GAAGf,eAAe,CAAC9B,KAAK,CAAEjC,GAAG,IACpDb,cAAc,CAACsC,IAAI,CAAES,CAAC,IAAKA,CAAC,CAACvC,EAAE,KAAKK,GAAG,CAACL,EAAE,CAC5C,CAAC;EACD,MAAMoF,oBAAoB,GAAGhB,eAAe,CAACtC,IAAI,CAAEzB,GAAG,IACpDb,cAAc,CAACsC,IAAI,CAAES,CAAC,IAAKA,CAAC,CAACvC,EAAE,KAAKK,GAAG,CAACL,EAAE,CAC5C,CAAC;EAED,MAAMT,MAAM,GAAGZ,oBAAoB,CAAC,CAAC;EAErC,MAAM0G,oBAAoB,GAAGnH,WAAW,CAAC,MAAM;IAC7CiG,WAAW,CAACC,eAAe,CAAC;EAC9B,CAAC,EAAE,CAACA,eAAe,EAAED,WAAW,CAAC,CAAC;EAElC,oBACElG,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAACyG;EAA0B,gBAC/CrH,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAEvF,UAAU,CAACa,MAAM,CAAC0F,aAAa,EAAE1F,MAAM,CAAC2F,YAAY;EAAE,GACnEjF,MAAM,CAACgG,8BACL,CAAC,eACNtH,KAAA,CAAA8E,aAAA,CAACrE,SAAS;IACRwD,KAAK,EAAExC,WAAY;IACnB8F,QAAQ,EAAEvB,cAAe;IACzBwB,WAAW,EAAElG,MAAM,CAACmG,6BAA8B;IAClD,cAAYnG,MAAM,CAACoG,2BAA4B;IAC/CpC,SAAS,EAAE1E,MAAM,CAAC+G;EAAgB,CACnC,CAAC,eACF3H,KAAA,CAAA8E,aAAA,CAACpF,WAAW,CAACkI,IAAI;IAACC,WAAW,EAAE,IAAK;IAACvC,SAAS,EAAE1E,MAAM,CAACkH;EAAe,gBACpE9H,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAACmH;EAAe,gBACpC/H,KAAA,CAAA8E,aAAA;IAAOQ,SAAS,EAAE1E,MAAM,CAACoH;EAAe,gBACtChI,KAAA,CAAA8E,aAAA,CAACxE,QAAQ;IACP2H,OAAO,EAAEf,mBAAoB;IAC7BgB,aAAa,EAAEf,oBAAoB,IAAI,CAACD,mBAAoB;IAC5DiB,eAAe,EAAEf,oBAAqB;IACtC9B,SAAS,EAAE1E,MAAM,CAACwH;EAAS,CAC5B,CAAC,EACD9G,MAAM,CAAC+G,sBACH,CAAC,eACRrI,KAAA,CAAA8E,aAAA,CAACpF,WAAW,CAAC4I,OAAO;IAAChD,SAAS,EAAE1E,MAAM,CAAC2H;EAAgB,gBACrDvI,KAAA,CAAA8E,aAAA;IAAMQ,SAAS,EAAE1E,MAAM,CAAC4H;EAAc,GACnCxB,aAAa,EAAC,GAAC,EAACC,UACb,CAAC,eACPjH,KAAA,CAAA8E,aAAA,CAACnF,SAAS;IAAC2F,SAAS,EAAE1E,MAAM,CAAC6H;EAAU,CAAE,CACtB,CAClB,CAAC,eACNzI,KAAA,CAAA8E,aAAA,CAACpF,WAAW,CAACgJ,KAAK;IAACpD,SAAS,EAAE1E,MAAM,CAAC+H;EAAa,GAC/CxC,eAAe,CAAC9D,MAAM,KAAK,CAAC,gBAC3BrC,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAACgI;EAAW,GAC/BtH,MAAM,CAACuH,6BACL,CAAC,GAEN1C,eAAe,CAACvE,GAAG,CAAE+B,MAAM,iBACzB3D,KAAA,CAAA8E,aAAA,CAACgE,YAAY;IACXC,GAAG,EAAEpF,MAAM,CAAC5B,EAAG;IACf4B,MAAM,EAAEA,MAAO;IACfqF,UAAU,EAAEzH,cAAc,CAACsC,IAAI,CAAES,CAAC,IAAKA,CAAC,CAACvC,EAAE,KAAK4B,MAAM,CAAC5B,EAAE,CAAE;IAC3DkH,QAAQ,EAAEhD;EAAe,CAC1B,CACF,CAEc,CACH,CACf,CAAC;AAEV;AASA,SAAS6C,YAAYA,CAAC;EACpBnF,MAAM;EACNqF,UAAU;EACVC,QAAQ;EACRC,YAAY,GAAG;AACE,CAAC,EAAsB;EACxC,MAAMC,WAAW,GAAGlJ,WAAW,CAAC,MAAM;IACpCgJ,QAAQ,CAACtF,MAAM,CAAC;EAClB,CAAC,EAAE,CAACsF,QAAQ,EAAEtF,MAAM,CAAC,CAAC;EAEtB,oBACE3D,KAAA,CAAA8E,aAAA;IAAKQ,SAAS,EAAE1E,MAAM,CAACwI;EAAa,gBAClCpJ,KAAA,CAAA8E,aAAA;IAAOQ,SAAS,EAAE1E,MAAM,CAACyI;EAAc,gBACrCrJ,KAAA,CAAA8E,aAAA,CAACxE,QAAQ;IACP2H,OAAO,EAAEe,UAAW;IACpBb,eAAe,EAAEgB,WAAY;IAC7B7D,SAAS,EAAE1E,MAAM,CAACwH;EAAS,CAC5B,CAAC,eACFpI,KAAA,CAAA8E,aAAA;IAAMQ,SAAS,EAAE1E,MAAM,CAAC0I;EAAa,GAAE3F,MAAM,CAAC3B,KAAY,CACrD,CAAC,EACPkH,YAAY,iBAAIlJ,KAAA,CAAA8E,aAAA,CAACjF,aAAa;IAACyF,SAAS,EAAE1E,MAAM,CAAC2I;EAAS,CAAE,CAC1D,CAAC;AAEV","ignoreList":[]}
|
|
@@ -20,11 +20,11 @@ import { Tooltip } from "../base-components/tooltip/Tooltip.js";
|
|
|
20
20
|
import { DatePickerCellField } from "./components/DatePickerCellField.js";
|
|
21
21
|
import { DropdownCellField } from "./components/DropdownCellField.js";
|
|
22
22
|
import { TextInputCellField } from "./components/TextInputCellField.js";
|
|
23
|
+
import { useObjectTableLabels } from "./ObjectTableLabels.js";
|
|
23
24
|
import { cellValuesEqual } from "./utils/editableUtils.js";
|
|
24
25
|
import styles from "./EditableCell.module.css.js";
|
|
25
26
|
const NUMBER_TYPES = ["double", "integer", "long", "float", "decimal", "byte", "short"];
|
|
26
27
|
const DATE_TYPES = ["datetime", "timestamp"];
|
|
27
|
-
const VALIDATION_ERROR_MESSAGE = "Validation error";
|
|
28
28
|
function valueToString(value) {
|
|
29
29
|
if (value == null) {
|
|
30
30
|
return "";
|
|
@@ -65,6 +65,7 @@ function EditableCellInner({
|
|
|
65
65
|
rowCellEdits,
|
|
66
66
|
isRowFocused = false
|
|
67
67
|
}) {
|
|
68
|
+
const labels = useObjectTableLabels();
|
|
68
69
|
const [inputValue, setInputValue] = useState(valueToString(currentValue));
|
|
69
70
|
const isCancelled = useRef(false);
|
|
70
71
|
const validationAbortControllerRef = useRef(null);
|
|
@@ -108,10 +109,10 @@ function EditableCellInner({
|
|
|
108
109
|
}
|
|
109
110
|
}, error => {
|
|
110
111
|
if (!controller.signal.aborted && error.name !== "AbortError") {
|
|
111
|
-
onCellValidationError?.(cellId,
|
|
112
|
+
onCellValidationError?.(cellId, labels.cellValidationError);
|
|
112
113
|
}
|
|
113
114
|
});
|
|
114
|
-
}, [validateEdit, onCellValidationError, clearCellValidationError, cellId]);
|
|
115
|
+
}, [validateEdit, onCellValidationError, clearCellValidationError, cellId, labels]);
|
|
115
116
|
const commitEdit = useCallback(newValue => {
|
|
116
117
|
abortValidation();
|
|
117
118
|
onCellEdit(cellId, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditableCell.js","names":["Error","React","useCallback","useEffect","useMemo","useRef","useState","Tooltip","DatePickerCellField","DropdownCellField","TextInputCellField","cellValuesEqual","styles","NUMBER_TYPES","DATE_TYPES","VALIDATION_ERROR_MESSAGE","valueToString","value","JSON","stringify","String","parseValueByType","dataType","includes","parsedNumber","Number","isNaN","EditableCellInner","initialValue","currentValue","cellId","onCellEdit","onCellValidationError","clearCellValidationError","originalRowData","rowId","columnId","validateEdit","validationError","editFieldConfig","rowCellEdits","isRowFocused","inputValue","setInputValue","isCancelled","validationAbortControllerRef","abortValidation","current","abort","hasValidationError","isEdited","runValidation","parsedValue","controller","AbortController","validationPromise","Promise","race","_","reject","signal","addEventListener","DOMException","then","errorMessage","aborted","error","name","commitEdit","newValue","oldValue","handleBlur","handleInputChange","handleKeyDown","e","key","currentTarget","blur","handleCommit","inputType","dropdownFieldProps","fieldComponent","getFieldComponentProps","undefined","datePickerFieldProps","createElement","Provider","Root","disabled","Trigger","className","osdkEditableCellTrigger","render","osdkTooltipTriggerWrapper","fieldComponentProps","onChange","onValueChange","onBlur","onKeyDown","Portal","Positioner","sideOffset","side","Popup","errorIcon","Arrow","EditableCell","memo"],"sources":["EditableCell.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 { Error } from \"@blueprintjs/icons\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { DatePickerCellField } from \"./components/DatePickerCellField.js\";\nimport { DropdownCellField } from \"./components/DropdownCellField.js\";\nimport { TextInputCellField } from \"./components/TextInputCellField.js\";\nimport { cellValuesEqual } from \"./utils/editableUtils.js\";\nimport type { CellEditInfo, EditFieldConfig } from \"./utils/types.js\";\n\nimport styles from \"./EditableCell.module.css\";\n\nconst NUMBER_TYPES: readonly string[] = [\n \"double\",\n \"integer\",\n \"long\",\n \"float\",\n \"decimal\",\n \"byte\",\n \"short\",\n];\n\nconst DATE_TYPES: readonly string[] = [\"datetime\", \"timestamp\"];\n\nconst VALIDATION_ERROR_MESSAGE = \"Validation error\";\n\nexport interface EditableCellProps<TData extends RowData, CellValue = unknown> {\n initialValue: CellValue;\n currentValue: CellValue;\n cellId: string;\n dataType?: string;\n onCellEdit: (cellId: string, info: CellEditInfo<TData, CellValue>) => void;\n onCellValidationError?: (cellId: string, error: string) => void;\n clearCellValidationError?: (cellId: string) => void;\n validationError?: string;\n originalRowData: TData;\n rowId: string;\n columnId: string;\n validateEdit?: (value: unknown) => Promise<string | undefined>;\n editFieldConfig?: EditFieldConfig<TData>;\n /**\n * Pending edits for this row, keyed by `columnId`. Forwarded to\n * `EditFieldConfig#getFieldComponentProps`. Filtering happens in\n * `DefaultCellRenderer` so unedited rows receive a stable `undefined`\n * reference and `React.memo` can skip them.\n */\n rowCellEdits?: Record<string, CellEditInfo<TData, unknown>>;\n isRowFocused?: boolean;\n}\n\nfunction valueToString(value: unknown): string {\n if (value == null) {\n return \"\";\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n // At this point, value is a primitive (string, number, boolean, symbol, bigint)\n return String(value as string | number | boolean | symbol | bigint);\n}\n\nfunction parseValueByType(value: string, dataType?: string): unknown {\n if (!dataType || !NUMBER_TYPES.includes(dataType)) {\n return value;\n }\n\n if (value === \"\") {\n return null;\n }\n\n const parsedNumber = Number(value);\n\n if (isNaN(parsedNumber)) {\n return value;\n }\n\n return parsedNumber;\n}\n\nfunction EditableCellInner<TData extends RowData, CellValue = unknown>({\n initialValue,\n currentValue,\n cellId,\n dataType,\n onCellEdit,\n onCellValidationError,\n clearCellValidationError,\n originalRowData,\n rowId,\n columnId,\n validateEdit,\n validationError,\n editFieldConfig,\n rowCellEdits,\n isRowFocused = false,\n}: EditableCellProps<TData, CellValue>): React.ReactElement {\n const [inputValue, setInputValue] = useState<string>(\n valueToString(currentValue)\n );\n const isCancelled = useRef(false);\n const validationAbortControllerRef = useRef<AbortController | null>(null);\n\n const abortValidation = useCallback(() => {\n if (validationAbortControllerRef.current) {\n validationAbortControllerRef.current.abort();\n validationAbortControllerRef.current = null;\n }\n }, []);\n\n const hasValidationError = validationError != null;\n const isEdited = !cellValuesEqual(currentValue, initialValue);\n\n useEffect(() => {\n setInputValue(valueToString(currentValue));\n }, [currentValue]);\n\n useEffect(() => {\n return () => {\n abortValidation();\n };\n }, [abortValidation]);\n\n const runValidation = useCallback(\n (parsedValue: unknown) => {\n if (!validateEdit) {\n return;\n }\n\n const controller = new AbortController();\n validationAbortControllerRef.current = controller;\n\n const validationPromise = validateEdit(parsedValue);\n\n // Race between validation and abort\n Promise.race([\n validationPromise,\n new Promise<string | undefined>((_, reject) => {\n controller.signal.addEventListener(\"abort\", () => {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n });\n }),\n ]).then(\n (errorMessage) => {\n if (controller.signal.aborted) {\n return;\n }\n if (errorMessage) {\n onCellValidationError?.(cellId, errorMessage);\n } else {\n clearCellValidationError?.(cellId);\n }\n },\n (error) => {\n if (!controller.signal.aborted && error.name !== \"AbortError\") {\n onCellValidationError?.(cellId, VALIDATION_ERROR_MESSAGE);\n }\n }\n );\n },\n [validateEdit, onCellValidationError, clearCellValidationError, cellId]\n );\n\n const commitEdit = useCallback(\n (newValue: CellValue) => {\n abortValidation();\n\n onCellEdit(cellId, {\n rowId,\n columnId,\n newValue,\n oldValue: initialValue,\n originalRowData,\n });\n\n runValidation(newValue);\n },\n [\n abortValidation,\n onCellEdit,\n cellId,\n rowId,\n columnId,\n initialValue,\n originalRowData,\n runValidation,\n ]\n );\n\n // Text/number input: commit on blur\n const handleBlur = useCallback(() => {\n if (isCancelled.current) {\n isCancelled.current = false;\n return;\n }\n\n // No-op when the input wasn't actually changed by the user\n if (inputValue === valueToString(currentValue)) {\n return;\n }\n\n const parsedValue = parseValueByType(inputValue, dataType) as CellValue;\n commitEdit(parsedValue);\n }, [inputValue, currentValue, dataType, commitEdit]);\n\n const handleInputChange = useCallback(\n (value: string) => {\n // Cancel any in-flight validation\n abortValidation();\n setInputValue(value);\n },\n [abortValidation]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.currentTarget.blur();\n }\n if (e.key === \"Escape\") {\n isCancelled.current = true;\n setInputValue(valueToString(currentValue));\n e.currentTarget.blur();\n }\n },\n [currentValue]\n );\n\n const handleCommit = useCallback(\n (newValue: unknown) => {\n // No-op if the value hasn't actually moved from what the cell already\n // displays. null and undefined are treated as the same empty state so\n // a dropdown that clears a never-set cell doesn't fire; \"\" stays\n // distinct since an empty string can be meaningful data.\n if (cellValuesEqual(newValue, currentValue)) return;\n commitEdit(newValue as CellValue);\n },\n [commitEdit, currentValue]\n );\n\n const inputType =\n dataType && NUMBER_TYPES.includes(dataType) ? \"number\" : \"text\";\n\n // Compute field-component props once per (editFieldConfig, originalRowData, rowCellEdits).\n // The narrowed return type is preserved in each useMemo\n const dropdownFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DROPDOWN\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const datePickerFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DATE_PICKER\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const renderFieldInput = () => {\n switch (editFieldConfig?.fieldComponent) {\n case \"DROPDOWN\":\n return (\n <DropdownCellField\n fieldComponentProps={dropdownFieldProps!}\n isRowFocused={isRowFocused}\n inputValue={inputValue}\n value={currentValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n case \"DATE_PICKER\":\n return (\n <DatePickerCellField\n fieldComponentProps={datePickerFieldProps}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n default:\n if (dataType != null && DATE_TYPES.includes(dataType)) {\n return (\n <DatePickerCellField\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n dataType={dataType}\n />\n );\n }\n return (\n <TextInputCellField\n inputType={inputType}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onValueChange={handleInputChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n />\n );\n }\n };\n\n return (\n <Tooltip.Provider>\n <Tooltip.Root disabled={!hasValidationError}>\n <Tooltip.Trigger\n className={styles.osdkEditableCellTrigger}\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {renderFieldInput()}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner sideOffset={4} side={\"bottom\"}>\n <Tooltip.Popup>\n <div className={styles.validationError}>\n <Error className={styles.errorIcon} />\n {validationError}\n </div>\n <Tooltip.Arrow />\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n </Tooltip.Provider>\n );\n}\n\nexport const EditableCell = React.memo(\n EditableCellInner\n) as typeof EditableCellInner;\n(\"\");\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"EditableCell.js","names":["Error","React","useCallback","useEffect","useMemo","useRef","useState","Tooltip","DatePickerCellField","DropdownCellField","TextInputCellField","useObjectTableLabels","cellValuesEqual","styles","NUMBER_TYPES","DATE_TYPES","valueToString","value","JSON","stringify","String","parseValueByType","dataType","includes","parsedNumber","Number","isNaN","EditableCellInner","initialValue","currentValue","cellId","onCellEdit","onCellValidationError","clearCellValidationError","originalRowData","rowId","columnId","validateEdit","validationError","editFieldConfig","rowCellEdits","isRowFocused","labels","inputValue","setInputValue","isCancelled","validationAbortControllerRef","abortValidation","current","abort","hasValidationError","isEdited","runValidation","parsedValue","controller","AbortController","validationPromise","Promise","race","_","reject","signal","addEventListener","DOMException","then","errorMessage","aborted","error","name","cellValidationError","commitEdit","newValue","oldValue","handleBlur","handleInputChange","handleKeyDown","e","key","currentTarget","blur","handleCommit","inputType","dropdownFieldProps","fieldComponent","getFieldComponentProps","undefined","datePickerFieldProps","createElement","Provider","Root","disabled","Trigger","className","osdkEditableCellTrigger","render","osdkTooltipTriggerWrapper","fieldComponentProps","onChange","onValueChange","onBlur","onKeyDown","Portal","Positioner","sideOffset","side","Popup","errorIcon","Arrow","EditableCell","memo"],"sources":["EditableCell.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 { Error } from \"@blueprintjs/icons\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { DatePickerCellField } from \"./components/DatePickerCellField.js\";\nimport { DropdownCellField } from \"./components/DropdownCellField.js\";\nimport { TextInputCellField } from \"./components/TextInputCellField.js\";\nimport { useObjectTableLabels } from \"./ObjectTableLabels.js\";\nimport { cellValuesEqual } from \"./utils/editableUtils.js\";\nimport type { CellEditInfo, EditFieldConfig } from \"./utils/types.js\";\n\nimport styles from \"./EditableCell.module.css\";\n\nconst NUMBER_TYPES: readonly string[] = [\n \"double\",\n \"integer\",\n \"long\",\n \"float\",\n \"decimal\",\n \"byte\",\n \"short\",\n];\n\nconst DATE_TYPES: readonly string[] = [\"datetime\", \"timestamp\"];\n\nexport interface EditableCellProps<TData extends RowData, CellValue = unknown> {\n initialValue: CellValue;\n currentValue: CellValue;\n cellId: string;\n dataType?: string;\n onCellEdit: (cellId: string, info: CellEditInfo<TData, CellValue>) => void;\n onCellValidationError?: (cellId: string, error: string) => void;\n clearCellValidationError?: (cellId: string) => void;\n validationError?: string;\n originalRowData: TData;\n rowId: string;\n columnId: string;\n validateEdit?: (value: unknown) => Promise<string | undefined>;\n editFieldConfig?: EditFieldConfig<TData>;\n /**\n * Pending edits for this row, keyed by `columnId`. Forwarded to\n * `EditFieldConfig#getFieldComponentProps`. Filtering happens in\n * `DefaultCellRenderer` so unedited rows receive a stable `undefined`\n * reference and `React.memo` can skip them.\n */\n rowCellEdits?: Record<string, CellEditInfo<TData, unknown>>;\n isRowFocused?: boolean;\n}\n\nfunction valueToString(value: unknown): string {\n if (value == null) {\n return \"\";\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n // At this point, value is a primitive (string, number, boolean, symbol, bigint)\n return String(value as string | number | boolean | symbol | bigint);\n}\n\nfunction parseValueByType(value: string, dataType?: string): unknown {\n if (!dataType || !NUMBER_TYPES.includes(dataType)) {\n return value;\n }\n\n if (value === \"\") {\n return null;\n }\n\n const parsedNumber = Number(value);\n\n if (isNaN(parsedNumber)) {\n return value;\n }\n\n return parsedNumber;\n}\n\nfunction EditableCellInner<TData extends RowData, CellValue = unknown>({\n initialValue,\n currentValue,\n cellId,\n dataType,\n onCellEdit,\n onCellValidationError,\n clearCellValidationError,\n originalRowData,\n rowId,\n columnId,\n validateEdit,\n validationError,\n editFieldConfig,\n rowCellEdits,\n isRowFocused = false,\n}: EditableCellProps<TData, CellValue>): React.ReactElement {\n const labels = useObjectTableLabels();\n const [inputValue, setInputValue] = useState<string>(\n valueToString(currentValue)\n );\n const isCancelled = useRef(false);\n const validationAbortControllerRef = useRef<AbortController | null>(null);\n\n const abortValidation = useCallback(() => {\n if (validationAbortControllerRef.current) {\n validationAbortControllerRef.current.abort();\n validationAbortControllerRef.current = null;\n }\n }, []);\n\n const hasValidationError = validationError != null;\n const isEdited = !cellValuesEqual(currentValue, initialValue);\n\n useEffect(() => {\n setInputValue(valueToString(currentValue));\n }, [currentValue]);\n\n useEffect(() => {\n return () => {\n abortValidation();\n };\n }, [abortValidation]);\n\n const runValidation = useCallback(\n (parsedValue: unknown) => {\n if (!validateEdit) {\n return;\n }\n\n const controller = new AbortController();\n validationAbortControllerRef.current = controller;\n\n const validationPromise = validateEdit(parsedValue);\n\n // Race between validation and abort\n Promise.race([\n validationPromise,\n new Promise<string | undefined>((_, reject) => {\n controller.signal.addEventListener(\"abort\", () => {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n });\n }),\n ]).then(\n (errorMessage) => {\n if (controller.signal.aborted) {\n return;\n }\n if (errorMessage) {\n onCellValidationError?.(cellId, errorMessage);\n } else {\n clearCellValidationError?.(cellId);\n }\n },\n (error) => {\n if (!controller.signal.aborted && error.name !== \"AbortError\") {\n onCellValidationError?.(cellId, labels.cellValidationError);\n }\n }\n );\n },\n [\n validateEdit,\n onCellValidationError,\n clearCellValidationError,\n cellId,\n labels,\n ]\n );\n\n const commitEdit = useCallback(\n (newValue: CellValue) => {\n abortValidation();\n\n onCellEdit(cellId, {\n rowId,\n columnId,\n newValue,\n oldValue: initialValue,\n originalRowData,\n });\n\n runValidation(newValue);\n },\n [\n abortValidation,\n onCellEdit,\n cellId,\n rowId,\n columnId,\n initialValue,\n originalRowData,\n runValidation,\n ]\n );\n\n // Text/number input: commit on blur\n const handleBlur = useCallback(() => {\n if (isCancelled.current) {\n isCancelled.current = false;\n return;\n }\n\n // No-op when the input wasn't actually changed by the user\n if (inputValue === valueToString(currentValue)) {\n return;\n }\n\n const parsedValue = parseValueByType(inputValue, dataType) as CellValue;\n commitEdit(parsedValue);\n }, [inputValue, currentValue, dataType, commitEdit]);\n\n const handleInputChange = useCallback(\n (value: string) => {\n // Cancel any in-flight validation\n abortValidation();\n setInputValue(value);\n },\n [abortValidation]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.currentTarget.blur();\n }\n if (e.key === \"Escape\") {\n isCancelled.current = true;\n setInputValue(valueToString(currentValue));\n e.currentTarget.blur();\n }\n },\n [currentValue]\n );\n\n const handleCommit = useCallback(\n (newValue: unknown) => {\n // No-op if the value hasn't actually moved from what the cell already\n // displays. null and undefined are treated as the same empty state so\n // a dropdown that clears a never-set cell doesn't fire; \"\" stays\n // distinct since an empty string can be meaningful data.\n if (cellValuesEqual(newValue, currentValue)) return;\n commitEdit(newValue as CellValue);\n },\n [commitEdit, currentValue]\n );\n\n const inputType =\n dataType && NUMBER_TYPES.includes(dataType) ? \"number\" : \"text\";\n\n // Compute field-component props once per (editFieldConfig, originalRowData, rowCellEdits).\n // The narrowed return type is preserved in each useMemo\n const dropdownFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DROPDOWN\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const datePickerFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DATE_PICKER\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const renderFieldInput = () => {\n switch (editFieldConfig?.fieldComponent) {\n case \"DROPDOWN\":\n return (\n <DropdownCellField\n fieldComponentProps={dropdownFieldProps!}\n isRowFocused={isRowFocused}\n inputValue={inputValue}\n value={currentValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n case \"DATE_PICKER\":\n return (\n <DatePickerCellField\n fieldComponentProps={datePickerFieldProps}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n default:\n if (dataType != null && DATE_TYPES.includes(dataType)) {\n return (\n <DatePickerCellField\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n dataType={dataType}\n />\n );\n }\n return (\n <TextInputCellField\n inputType={inputType}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onValueChange={handleInputChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n />\n );\n }\n };\n\n return (\n <Tooltip.Provider>\n <Tooltip.Root disabled={!hasValidationError}>\n <Tooltip.Trigger\n className={styles.osdkEditableCellTrigger}\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {renderFieldInput()}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner sideOffset={4} side={\"bottom\"}>\n <Tooltip.Popup>\n <div className={styles.validationError}>\n <Error className={styles.errorIcon} />\n {validationError}\n </div>\n <Tooltip.Arrow />\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n </Tooltip.Provider>\n );\n}\n\nexport const EditableCell = React.memo(\n EditableCellInner\n) as typeof EditableCellInner;\n(\"\");\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,KAAK,QAAQ,oBAAoB;AAE1C,OAAOC,KAAK,IACVC,WAAW,EACXC,SAAS,EACTC,OAAO,EACPC,MAAM,EACNC,QAAQ,QACH,OAAO;AAEd,SAASC,OAAO,QAAQ,uCAAuC;AAC/D,SAASC,mBAAmB,QAAQ,qCAAqC;AACzE,SAASC,iBAAiB,QAAQ,mCAAmC;AACrE,SAASC,kBAAkB,QAAQ,oCAAoC;AACvE,SAASC,oBAAoB,QAAQ,wBAAwB;AAC7D,SAASC,eAAe,QAAQ,0BAA0B;AAG1D,OAAOC,MAAM,MAAM,2BAA2B;AAE9C,MAAMC,YAA+B,GAAG,CACtC,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,OAAO,CACR;AAED,MAAMC,UAA6B,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC;AA0B/D,SAASC,aAAaA,CAACC,KAAc,EAAU;EAC7C,IAAIA,KAAK,IAAI,IAAI,EAAE;IACjB,OAAO,EAAE;EACX;EACA,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;IAC7B,OAAOC,IAAI,CAACC,SAAS,CAACF,KAAK,CAAC;EAC9B;EACA;EACA,OAAOG,MAAM,CAACH,KAAoD,CAAC;AACrE;AAEA,SAASI,gBAAgBA,CAACJ,KAAa,EAAEK,QAAiB,EAAW;EACnE,IAAI,CAACA,QAAQ,IAAI,CAACR,YAAY,CAACS,QAAQ,CAACD,QAAQ,CAAC,EAAE;IACjD,OAAOL,KAAK;EACd;EAEA,IAAIA,KAAK,KAAK,EAAE,EAAE;IAChB,OAAO,IAAI;EACb;EAEA,MAAMO,YAAY,GAAGC,MAAM,CAACR,KAAK,CAAC;EAElC,IAAIS,KAAK,CAACF,YAAY,CAAC,EAAE;IACvB,OAAOP,KAAK;EACd;EAEA,OAAOO,YAAY;AACrB;AAEA,SAASG,iBAAiBA,CAA6C;EACrEC,YAAY;EACZC,YAAY;EACZC,MAAM;EACNR,QAAQ;EACRS,UAAU;EACVC,qBAAqB;EACrBC,wBAAwB;EACxBC,eAAe;EACfC,KAAK;EACLC,QAAQ;EACRC,YAAY;EACZC,eAAe;EACfC,eAAe;EACfC,YAAY;EACZC,YAAY,GAAG;AACoB,CAAC,EAAsB;EAC1D,MAAMC,MAAM,GAAG/B,oBAAoB,CAAC,CAAC;EACrC,MAAM,CAACgC,UAAU,EAAEC,aAAa,CAAC,GAAGtC,QAAQ,CAC1CU,aAAa,CAACa,YAAY,CAC5B,CAAC;EACD,MAAMgB,WAAW,GAAGxC,MAAM,CAAC,KAAK,CAAC;EACjC,MAAMyC,4BAA4B,GAAGzC,MAAM,CAAyB,IAAI,CAAC;EAEzE,MAAM0C,eAAe,GAAG7C,WAAW,CAAC,MAAM;IACxC,IAAI4C,4BAA4B,CAACE,OAAO,EAAE;MACxCF,4BAA4B,CAACE,OAAO,CAACC,KAAK,CAAC,CAAC;MAC5CH,4BAA4B,CAACE,OAAO,GAAG,IAAI;IAC7C;EACF,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,kBAAkB,GAAGZ,eAAe,IAAI,IAAI;EAClD,MAAMa,QAAQ,GAAG,CAACvC,eAAe,CAACiB,YAAY,EAAED,YAAY,CAAC;EAE7DzB,SAAS,CAAC,MAAM;IACdyC,aAAa,CAAC5B,aAAa,CAACa,YAAY,CAAC,CAAC;EAC5C,CAAC,EAAE,CAACA,YAAY,CAAC,CAAC;EAElB1B,SAAS,CAAC,MAAM;IACd,OAAO,MAAM;MACX4C,eAAe,CAAC,CAAC;IACnB,CAAC;EACH,CAAC,EAAE,CAACA,eAAe,CAAC,CAAC;EAErB,MAAMK,aAAa,GAAGlD,WAAW,CAC9BmD,WAAoB,IAAK;IACxB,IAAI,CAAChB,YAAY,EAAE;MACjB;IACF;IAEA,MAAMiB,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;IACxCT,4BAA4B,CAACE,OAAO,GAAGM,UAAU;IAEjD,MAAME,iBAAiB,GAAGnB,YAAY,CAACgB,WAAW,CAAC;;IAEnD;IACAI,OAAO,CAACC,IAAI,CAAC,CACXF,iBAAiB,EACjB,IAAIC,OAAO,CAAqB,CAACE,CAAC,EAAEC,MAAM,KAAK;MAC7CN,UAAU,CAACO,MAAM,CAACC,gBAAgB,CAAC,OAAO,EAAE,MAAM;QAChDF,MAAM,CAAC,IAAIG,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;MACnD,CAAC,CAAC;IACJ,CAAC,CAAC,CACH,CAAC,CAACC,IAAI,CACJC,YAAY,IAAK;MAChB,IAAIX,UAAU,CAACO,MAAM,CAACK,OAAO,EAAE;QAC7B;MACF;MACA,IAAID,YAAY,EAAE;QAChBjC,qBAAqB,GAAGF,MAAM,EAAEmC,YAAY,CAAC;MAC/C,CAAC,MAAM;QACLhC,wBAAwB,GAAGH,MAAM,CAAC;MACpC;IACF,CAAC,EACAqC,KAAK,IAAK;MACT,IAAI,CAACb,UAAU,CAACO,MAAM,CAACK,OAAO,IAAIC,KAAK,CAACC,IAAI,KAAK,YAAY,EAAE;QAC7DpC,qBAAqB,GAAGF,MAAM,EAAEY,MAAM,CAAC2B,mBAAmB,CAAC;MAC7D;IACF,CACF,CAAC;EACH,CAAC,EACD,CACEhC,YAAY,EACZL,qBAAqB,EACrBC,wBAAwB,EACxBH,MAAM,EACNY,MAAM,CAEV,CAAC;EAED,MAAM4B,UAAU,GAAGpE,WAAW,CAC3BqE,QAAmB,IAAK;IACvBxB,eAAe,CAAC,CAAC;IAEjBhB,UAAU,CAACD,MAAM,EAAE;MACjBK,KAAK;MACLC,QAAQ;MACRmC,QAAQ;MACRC,QAAQ,EAAE5C,YAAY;MACtBM;IACF,CAAC,CAAC;IAEFkB,aAAa,CAACmB,QAAQ,CAAC;EACzB,CAAC,EACD,CACExB,eAAe,EACfhB,UAAU,EACVD,MAAM,EACNK,KAAK,EACLC,QAAQ,EACRR,YAAY,EACZM,eAAe,EACfkB,aAAa,CAEjB,CAAC;;EAED;EACA,MAAMqB,UAAU,GAAGvE,WAAW,CAAC,MAAM;IACnC,IAAI2C,WAAW,CAACG,OAAO,EAAE;MACvBH,WAAW,CAACG,OAAO,GAAG,KAAK;MAC3B;IACF;;IAEA;IACA,IAAIL,UAAU,KAAK3B,aAAa,CAACa,YAAY,CAAC,EAAE;MAC9C;IACF;IAEA,MAAMwB,WAAW,GAAGhC,gBAAgB,CAACsB,UAAU,EAAErB,QAAQ,CAAc;IACvEgD,UAAU,CAACjB,WAAW,CAAC;EACzB,CAAC,EAAE,CAACV,UAAU,EAAEd,YAAY,EAAEP,QAAQ,EAAEgD,UAAU,CAAC,CAAC;EAEpD,MAAMI,iBAAiB,GAAGxE,WAAW,CAClCe,KAAa,IAAK;IACjB;IACA8B,eAAe,CAAC,CAAC;IACjBH,aAAa,CAAC3B,KAAK,CAAC;EACtB,CAAC,EACD,CAAC8B,eAAe,CAClB,CAAC;EAED,MAAM4B,aAAa,GAAGzE,WAAW,CAC9B0E,CAAwC,IAAK;IAC5C,IAAIA,CAAC,CAACC,GAAG,KAAK,OAAO,EAAE;MACrBD,CAAC,CAACE,aAAa,CAACC,IAAI,CAAC,CAAC;IACxB;IACA,IAAIH,CAAC,CAACC,GAAG,KAAK,QAAQ,EAAE;MACtBhC,WAAW,CAACG,OAAO,GAAG,IAAI;MAC1BJ,aAAa,CAAC5B,aAAa,CAACa,YAAY,CAAC,CAAC;MAC1C+C,CAAC,CAACE,aAAa,CAACC,IAAI,CAAC,CAAC;IACxB;EACF,CAAC,EACD,CAAClD,YAAY,CACf,CAAC;EAED,MAAMmD,YAAY,GAAG9E,WAAW,CAC7BqE,QAAiB,IAAK;IACrB;IACA;IACA;IACA;IACA,IAAI3D,eAAe,CAAC2D,QAAQ,EAAE1C,YAAY,CAAC,EAAE;IAC7CyC,UAAU,CAACC,QAAqB,CAAC;EACnC,CAAC,EACD,CAACD,UAAU,EAAEzC,YAAY,CAC3B,CAAC;EAED,MAAMoD,SAAS,GACb3D,QAAQ,IAAIR,YAAY,CAACS,QAAQ,CAACD,QAAQ,CAAC,GAAG,QAAQ,GAAG,MAAM;;EAEjE;EACA;EACA,MAAM4D,kBAAkB,GAAG9E,OAAO,CAChC,MACEmC,eAAe,EAAE4C,cAAc,KAAK,UAAU,GAC1C5C,eAAe,CAAC6C,sBAAsB,CAAClD,eAAe,EAAEM,YAAY,CAAC,GACrE6C,SAAS,EACf,CAAC9C,eAAe,EAAEL,eAAe,EAAEM,YAAY,CACjD,CAAC;EAED,MAAM8C,oBAAoB,GAAGlF,OAAO,CAClC,MACEmC,eAAe,EAAE4C,cAAc,KAAK,aAAa,GAC7C5C,eAAe,CAAC6C,sBAAsB,CAAClD,eAAe,EAAEM,YAAY,CAAC,GACrE6C,SAAS,EACf,CAAC9C,eAAe,EAAEL,eAAe,EAAEM,YAAY,CACjD,CAAC;EAoDD,oBACEvC,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAACiF,QAAQ,qBACfvF,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAACkF,IAAI;IAACC,QAAQ,EAAE,CAACxC;EAAmB,gBAC1CjD,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAACoF,OAAO;IACdC,SAAS,EAAE/E,MAAM,CAACgF,uBAAwB;IAC1CC,MAAM,eAAE7F,KAAA,CAAAsF,aAAA;MAAMK,SAAS,EAAE/E,MAAM,CAACkF;IAA0B,CAAE;EAAE,GAE7D,CAzDgB,MAAM;IAC7B,QAAQxD,eAAe,EAAE4C,cAAc;MACrC,KAAK,UAAU;QACb,oBACElF,KAAA,CAAAsF,aAAA,CAAC9E,iBAAiB;UAChBuF,mBAAmB,EAAEd,kBAAoB;UACzCzC,YAAY,EAAEA,YAAa;UAC3BE,UAAU,EAAEA,UAAW;UACvB1B,KAAK,EAAEY,YAAa;UACpBqB,kBAAkB,EAAEA,kBAAmB;UACvCC,QAAQ,EAAEA,QAAS;UACnB8C,QAAQ,EAAEjB;QAAa,CACxB,CAAC;MAEN,KAAK,aAAa;QAChB,oBACE/E,KAAA,CAAAsF,aAAA,CAAC/E,mBAAmB;UAClBwF,mBAAmB,EAAEV,oBAAqB;UAC1C3C,UAAU,EAAEA,UAAW;UACvBO,kBAAkB,EAAEA,kBAAmB;UACvCC,QAAQ,EAAEA,QAAS;UACnB8C,QAAQ,EAAEjB;QAAa,CACxB,CAAC;MAEN;QACE,IAAI1D,QAAQ,IAAI,IAAI,IAAIP,UAAU,CAACQ,QAAQ,CAACD,QAAQ,CAAC,EAAE;UACrD,oBACErB,KAAA,CAAAsF,aAAA,CAAC/E,mBAAmB;YAClBmC,UAAU,EAAEA,UAAW;YACvBO,kBAAkB,EAAEA,kBAAmB;YACvCC,QAAQ,EAAEA,QAAS;YACnB8C,QAAQ,EAAEjB,YAAa;YACvB1D,QAAQ,EAAEA;UAAS,CACpB,CAAC;QAEN;QACA,oBACErB,KAAA,CAAAsF,aAAA,CAAC7E,kBAAkB;UACjBuE,SAAS,EAAEA,SAAU;UACrBtC,UAAU,EAAEA,UAAW;UACvBO,kBAAkB,EAAEA,kBAAmB;UACvCC,QAAQ,EAAEA,QAAS;UACnB+C,aAAa,EAAExB,iBAAkB;UACjCyB,MAAM,EAAE1B,UAAW;UACnB2B,SAAS,EAAEzB;QAAc,CAC1B,CAAC;IAER;EACF,CAAC,EASyB,CACH,CAAC,eAClB1E,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAAC8F,MAAM,qBACbpG,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAAC+F,UAAU;IAACC,UAAU,EAAE,CAAE;IAACC,IAAI,EAAE;EAAS,gBAChDvG,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAACkG,KAAK,qBACZxG,KAAA,CAAAsF,aAAA;IAAKK,SAAS,EAAE/E,MAAM,CAACyB;EAAgB,gBACrCrC,KAAA,CAAAsF,aAAA,CAACvF,KAAK;IAAC4F,SAAS,EAAE/E,MAAM,CAAC6F;EAAU,CAAE,CAAC,EACrCpE,eACE,CAAC,eACNrC,KAAA,CAAAsF,aAAA,CAAChF,OAAO,CAACoG,KAAK,MAAE,CACH,CACG,CACN,CACJ,CACE,CAAC;AAEvB;AAEA,OAAO,MAAMC,YAAY,gBAAG3G,KAAK,CAAC4G,IAAI,CACpClF,iBACF,CAA6B","ignoreList":[]}
|
|
@@ -22,15 +22,18 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
22
22
|
import { ActionButton } from "../base-components/action-button/ActionButton.js";
|
|
23
23
|
import { Dialog } from "../base-components/dialog/Dialog.js";
|
|
24
24
|
import { SearchableMenu } from "../base-components/searchable-menu/SearchableMenu.js";
|
|
25
|
+
import { useObjectTableLabels, withObjectTableLabels } from "./ObjectTableLabels.js";
|
|
25
26
|
import { SortableItemsList } from "./SortableItemsList.js";
|
|
26
27
|
import styles from "./MultiColumnSortDialog.module.css.js";
|
|
27
|
-
export
|
|
28
|
+
export const MultiColumnSortDialog = withObjectTableLabels(MultiColumnSortDialogInner);
|
|
29
|
+
function MultiColumnSortDialogInner({
|
|
28
30
|
isOpen,
|
|
29
31
|
onClose,
|
|
30
32
|
onApply,
|
|
31
33
|
currentSorting,
|
|
32
34
|
columnOptions
|
|
33
35
|
}) {
|
|
36
|
+
const labels = useObjectTableLabels();
|
|
34
37
|
const [selectedSortColumns, setSelectedSortColumns] = useState([]);
|
|
35
38
|
// Initialize selected sort columns from current sorting
|
|
36
39
|
useEffect(() => {
|
|
@@ -96,24 +99,27 @@ export function MultiColumnSortDialog({
|
|
|
96
99
|
}, item.name), /*#__PURE__*/React.createElement(Button, {
|
|
97
100
|
className: styles.sortDirectionButton,
|
|
98
101
|
onClick: () => handleToggleSortDirection(item.id),
|
|
99
|
-
"aria-label":
|
|
102
|
+
"aria-label": labels.sortDialogToggleDirection(item.name)
|
|
100
103
|
}, item.direction === "asc" ? /*#__PURE__*/React.createElement(SortAlphabetical, {
|
|
101
104
|
className: styles.sortIcon
|
|
102
105
|
}) : /*#__PURE__*/React.createElement(SortAlphabeticalDesc, {
|
|
103
106
|
className: styles.sortIcon
|
|
104
107
|
})))
|
|
105
108
|
}));
|
|
106
|
-
}, [selectedSortColumns, handleToggleSortDirection]);
|
|
109
|
+
}, [selectedSortColumns, handleToggleSortDirection, labels]);
|
|
107
110
|
const footer = useMemo(() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionButton, {
|
|
108
111
|
onClick: onClose
|
|
109
|
-
},
|
|
112
|
+
}, labels.sortDialogCancel), /*#__PURE__*/React.createElement(ActionButton, {
|
|
110
113
|
variant: "primary",
|
|
111
114
|
onClick: handleApply
|
|
112
|
-
},
|
|
115
|
+
}, labels.sortDialogApply)), [handleApply, onClose, labels]);
|
|
116
|
+
const dialogTitle = useMemo(() => /*#__PURE__*/React.createElement("div", {
|
|
117
|
+
className: styles.title
|
|
118
|
+
}, /*#__PURE__*/React.createElement(Cog, null), labels.sortDialogTitle), [labels]);
|
|
113
119
|
return /*#__PURE__*/React.createElement(Dialog, {
|
|
114
120
|
isOpen: isOpen,
|
|
115
121
|
onOpenChange: onClose,
|
|
116
|
-
title:
|
|
122
|
+
title: dialogTitle,
|
|
117
123
|
footer: footer
|
|
118
124
|
}, /*#__PURE__*/React.createElement("div", {
|
|
119
125
|
className: styles.sortColumnsList
|
|
@@ -129,14 +135,11 @@ export function MultiColumnSortDialog({
|
|
|
129
135
|
className: styles.addIcon
|
|
130
136
|
}), /*#__PURE__*/React.createElement("span", {
|
|
131
137
|
className: styles.addColumnText
|
|
132
|
-
},
|
|
138
|
+
}, labels.sortDialogAddColumnToSort), /*#__PURE__*/React.createElement(CaretDown, null)),
|
|
133
139
|
triggerClassName: styles.addColumnButton,
|
|
134
140
|
disabled: availableColumns.length === 0,
|
|
135
|
-
searchPlaceholder:
|
|
136
|
-
emptyMessage:
|
|
141
|
+
searchPlaceholder: labels.sortDialogSearchPlaceholder,
|
|
142
|
+
emptyMessage: labels.sortDialogNoMatchingColumns
|
|
137
143
|
})));
|
|
138
144
|
}
|
|
139
|
-
const DialogTitle = /*#__PURE__*/React.createElement("div", {
|
|
140
|
-
className: styles.title
|
|
141
|
-
}, /*#__PURE__*/React.createElement(Cog, null), "Sort on Multiple Columns");
|
|
142
145
|
//# sourceMappingURL=MultiColumnSortDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiColumnSortDialog.js","names":["Button","Add","CaretDown","Cog","SortAlphabetical","SortAlphabeticalDesc","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Dialog","SearchableMenu","SortableItemsList","styles","MultiColumnSortDialog","isOpen","onClose","onApply","currentSorting","columnOptions","selectedSortColumns","setSelectedSortColumns","selectedColumns","sort","column","find","col","id","push","direction","desc","handleAddColumn","prev","handleRemoveSortColumn","filter","item","handleReorderSortColumns","fromIndex","toIndex","items","handleToggleSortDirection","map","handleApply","sortingState","availableColumns","canSort","some","selected","searchableMenuItems","key","label","name","handleMenuItemSelected","sortableItems","content","createElement","className","sortColumnItem","sortColumnName","truncate","sortDirectionButton","onClick","sortIcon","footer","Fragment","variant","onOpenChange","title","DialogTitle","sortColumnsList","onReorder","onRemove","sortableList","onItemSelected","trigger","addIcon","addColumnText","triggerClassName","addColumnButton","disabled","length","searchPlaceholder","emptyMessage"],"sources":["MultiColumnSortDialog.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 { Button } from \"@base-ui/react/button\";\nimport {\n Add,\n CaretDown,\n Cog,\n SortAlphabetical,\n SortAlphabeticalDesc,\n} from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { SortingState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { SearchableMenu } from \"../base-components/searchable-menu/SearchableMenu.js\";\nimport { type SortableItem, SortableItemsList } from \"./SortableItemsList.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./MultiColumnSortDialog.module.css\";\n\nexport interface SortColumnItem extends ColumnOption {\n direction: \"asc\" | \"desc\";\n}\n\nexport interface MultiColumnSortDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onApply: (sortColumns: SortingState) => void;\n currentSorting: SortingState;\n columnOptions: ColumnOption[];\n}\n\nexport function MultiColumnSortDialog({\n isOpen,\n onClose,\n onApply,\n currentSorting,\n columnOptions,\n}: MultiColumnSortDialogProps): React.ReactElement {\n const [selectedSortColumns, setSelectedSortColumns] = useState<\n SortColumnItem[]\n >([]);\n // Initialize selected sort columns from current sorting\n useEffect(() => {\n if (isOpen) {\n const selectedColumns: SortColumnItem[] = [];\n for (const sort of currentSorting) {\n const column = columnOptions.find((col) => col.id === sort.id);\n if (column) {\n selectedColumns.push({\n ...column,\n direction: sort.desc ? \"desc\" : \"asc\",\n });\n }\n }\n setSelectedSortColumns(selectedColumns);\n }\n }, [isOpen, currentSorting, columnOptions]);\n\n const handleAddColumn = useCallback((column: ColumnOption) => {\n setSelectedSortColumns((prev) => [\n ...prev,\n { ...column, direction: \"asc\" },\n ]);\n }, []);\n\n const handleRemoveSortColumn = useCallback((id: string) => {\n setSelectedSortColumns((prev) => prev.filter((item) => item.id !== id));\n }, []);\n\n const handleReorderSortColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setSelectedSortColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleToggleSortDirection = useCallback((id: string) => {\n setSelectedSortColumns((prev) =>\n prev.map((item) =>\n item.id === id\n ? { ...item, direction: item.direction === \"asc\" ? \"desc\" : \"asc\" }\n : item\n )\n );\n }, []);\n\n const handleApply = useCallback(() => {\n const sortingState: SortingState = selectedSortColumns.map((col) => ({\n id: col.id,\n desc: col.direction === \"desc\",\n }));\n onApply(sortingState);\n onClose();\n }, [selectedSortColumns, onApply, onClose]);\n\n const availableColumns = useMemo(\n () =>\n columnOptions.filter(\n (col) =>\n col.canSort &&\n !selectedSortColumns.some((selected) => selected.id === col.id)\n ),\n [columnOptions, selectedSortColumns]\n );\n\n const searchableMenuItems = useMemo(\n () => availableColumns.map((col) => ({ key: col.id, label: col.name })),\n [availableColumns]\n );\n\n const handleMenuItemSelected = useCallback(\n (key: string) => {\n const column = availableColumns.find((col) => col.id === key);\n if (column) {\n handleAddColumn(column);\n }\n },\n [availableColumns, handleAddColumn]\n );\n\n const sortableItems: SortableItem[] = useMemo(() => {\n return selectedSortColumns.map((item) => ({\n id: item.id,\n label: item.name,\n content: (\n <div className={styles.sortColumnItem}>\n <span className={classNames(styles.sortColumnName, styles.truncate)}>\n {item.name}\n </span>\n <Button\n className={styles.sortDirectionButton}\n onClick={() => handleToggleSortDirection(item.id)}\n aria-label={`Toggle sort direction for ${item.name}`}\n >\n {item.direction === \"asc\" ? (\n <SortAlphabetical className={styles.sortIcon} />\n ) : (\n <SortAlphabeticalDesc className={styles.sortIcon} />\n )}\n </Button>\n </div>\n ),\n }));\n }, [selectedSortColumns, handleToggleSortDirection]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>Cancel</ActionButton>\n <ActionButton variant=\"primary\" onClick={handleApply}>\n Apply\n </ActionButton>\n </>\n ),\n [handleApply, onClose]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={DialogTitle}\n footer={footer}\n >\n <div className={styles.sortColumnsList}>\n <SortableItemsList\n items={sortableItems}\n onReorder={handleReorderSortColumns}\n onRemove={handleRemoveSortColumn}\n className={styles.sortableList}\n />\n <SearchableMenu\n items={searchableMenuItems}\n onItemSelected={handleMenuItemSelected}\n trigger={\n <>\n <Add className={styles.addIcon} />\n <span className={styles.addColumnText}>Add Column to Sort</span>\n <CaretDown />\n </>\n }\n triggerClassName={styles.addColumnButton}\n disabled={availableColumns.length === 0}\n searchPlaceholder=\"Search columns\"\n emptyMessage=\"No matching columns\"\n />\n </div>\n </Dialog>\n );\n}\n\nconst DialogTitle = (\n <div className={styles.title}>\n <Cog />\n Sort on Multiple Columns\n </div>\n);\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MultiColumnSortDialog.js","names":["Button","Add","CaretDown","Cog","SortAlphabetical","SortAlphabeticalDesc","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Dialog","SearchableMenu","useObjectTableLabels","withObjectTableLabels","SortableItemsList","styles","MultiColumnSortDialog","MultiColumnSortDialogInner","isOpen","onClose","onApply","currentSorting","columnOptions","labels","selectedSortColumns","setSelectedSortColumns","selectedColumns","sort","column","find","col","id","push","direction","desc","handleAddColumn","prev","handleRemoveSortColumn","filter","item","handleReorderSortColumns","fromIndex","toIndex","items","handleToggleSortDirection","map","handleApply","sortingState","availableColumns","canSort","some","selected","searchableMenuItems","key","label","name","handleMenuItemSelected","sortableItems","content","createElement","className","sortColumnItem","sortColumnName","truncate","sortDirectionButton","onClick","sortDialogToggleDirection","sortIcon","footer","Fragment","sortDialogCancel","variant","sortDialogApply","dialogTitle","title","sortDialogTitle","onOpenChange","sortColumnsList","onReorder","onRemove","sortableList","onItemSelected","trigger","addIcon","addColumnText","sortDialogAddColumnToSort","triggerClassName","addColumnButton","disabled","length","searchPlaceholder","sortDialogSearchPlaceholder","emptyMessage","sortDialogNoMatchingColumns"],"sources":["MultiColumnSortDialog.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 { Button } from \"@base-ui/react/button\";\nimport {\n Add,\n CaretDown,\n Cog,\n SortAlphabetical,\n SortAlphabeticalDesc,\n} from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { SortingState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { SearchableMenu } from \"../base-components/searchable-menu/SearchableMenu.js\";\nimport type { ObjectTableLabels } from \"./ObjectTableLabels.js\";\nimport {\n useObjectTableLabels,\n withObjectTableLabels,\n} from \"./ObjectTableLabels.js\";\nimport { type SortableItem, SortableItemsList } from \"./SortableItemsList.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./MultiColumnSortDialog.module.css\";\n\nexport interface SortColumnItem extends ColumnOption {\n direction: \"asc\" | \"desc\";\n}\n\nexport interface MultiColumnSortDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onApply: (sortColumns: SortingState) => void;\n currentSorting: SortingState;\n columnOptions: ColumnOption[];\n /**\n * Overrides for the dialog's user-facing strings. Provide any subset; unset\n * keys fall back to the built-in English defaults. When this dialog is\n * rendered inside a `BaseTable`/`ObjectTable`, it inherits that table's\n * `labels` and this prop is only needed to override further. See\n * {@link ObjectTableLabels}.\n */\n labels?: Partial<ObjectTableLabels>;\n}\n\nexport const MultiColumnSortDialog: React.FC<MultiColumnSortDialogProps> =\n withObjectTableLabels(MultiColumnSortDialogInner);\n\nfunction MultiColumnSortDialogInner({\n isOpen,\n onClose,\n onApply,\n currentSorting,\n columnOptions,\n}: Omit<MultiColumnSortDialogProps, \"labels\">): React.ReactElement {\n const labels = useObjectTableLabels();\n const [selectedSortColumns, setSelectedSortColumns] = useState<\n SortColumnItem[]\n >([]);\n // Initialize selected sort columns from current sorting\n useEffect(() => {\n if (isOpen) {\n const selectedColumns: SortColumnItem[] = [];\n for (const sort of currentSorting) {\n const column = columnOptions.find((col) => col.id === sort.id);\n if (column) {\n selectedColumns.push({\n ...column,\n direction: sort.desc ? \"desc\" : \"asc\",\n });\n }\n }\n setSelectedSortColumns(selectedColumns);\n }\n }, [isOpen, currentSorting, columnOptions]);\n\n const handleAddColumn = useCallback((column: ColumnOption) => {\n setSelectedSortColumns((prev) => [\n ...prev,\n { ...column, direction: \"asc\" },\n ]);\n }, []);\n\n const handleRemoveSortColumn = useCallback((id: string) => {\n setSelectedSortColumns((prev) => prev.filter((item) => item.id !== id));\n }, []);\n\n const handleReorderSortColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setSelectedSortColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleToggleSortDirection = useCallback((id: string) => {\n setSelectedSortColumns((prev) =>\n prev.map((item) =>\n item.id === id\n ? { ...item, direction: item.direction === \"asc\" ? \"desc\" : \"asc\" }\n : item\n )\n );\n }, []);\n\n const handleApply = useCallback(() => {\n const sortingState: SortingState = selectedSortColumns.map((col) => ({\n id: col.id,\n desc: col.direction === \"desc\",\n }));\n onApply(sortingState);\n onClose();\n }, [selectedSortColumns, onApply, onClose]);\n\n const availableColumns = useMemo(\n () =>\n columnOptions.filter(\n (col) =>\n col.canSort &&\n !selectedSortColumns.some((selected) => selected.id === col.id)\n ),\n [columnOptions, selectedSortColumns]\n );\n\n const searchableMenuItems = useMemo(\n () => availableColumns.map((col) => ({ key: col.id, label: col.name })),\n [availableColumns]\n );\n\n const handleMenuItemSelected = useCallback(\n (key: string) => {\n const column = availableColumns.find((col) => col.id === key);\n if (column) {\n handleAddColumn(column);\n }\n },\n [availableColumns, handleAddColumn]\n );\n\n const sortableItems: SortableItem[] = useMemo(() => {\n return selectedSortColumns.map((item) => ({\n id: item.id,\n label: item.name,\n content: (\n <div className={styles.sortColumnItem}>\n <span className={classNames(styles.sortColumnName, styles.truncate)}>\n {item.name}\n </span>\n <Button\n className={styles.sortDirectionButton}\n onClick={() => handleToggleSortDirection(item.id)}\n aria-label={labels.sortDialogToggleDirection(item.name)}\n >\n {item.direction === \"asc\" ? (\n <SortAlphabetical className={styles.sortIcon} />\n ) : (\n <SortAlphabeticalDesc className={styles.sortIcon} />\n )}\n </Button>\n </div>\n ),\n }));\n }, [selectedSortColumns, handleToggleSortDirection, labels]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>{labels.sortDialogCancel}</ActionButton>\n <ActionButton variant=\"primary\" onClick={handleApply}>\n {labels.sortDialogApply}\n </ActionButton>\n </>\n ),\n [handleApply, onClose, labels]\n );\n\n const dialogTitle = useMemo(\n () => (\n <div className={styles.title}>\n <Cog />\n {labels.sortDialogTitle}\n </div>\n ),\n [labels]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={dialogTitle}\n footer={footer}\n >\n <div className={styles.sortColumnsList}>\n <SortableItemsList\n items={sortableItems}\n onReorder={handleReorderSortColumns}\n onRemove={handleRemoveSortColumn}\n className={styles.sortableList}\n />\n <SearchableMenu\n items={searchableMenuItems}\n onItemSelected={handleMenuItemSelected}\n trigger={\n <>\n <Add className={styles.addIcon} />\n <span className={styles.addColumnText}>\n {labels.sortDialogAddColumnToSort}\n </span>\n <CaretDown />\n </>\n }\n triggerClassName={styles.addColumnButton}\n disabled={availableColumns.length === 0}\n searchPlaceholder={labels.sortDialogSearchPlaceholder}\n emptyMessage={labels.sortDialogNoMatchingColumns}\n />\n </div>\n </Dialog>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -61,6 +61,7 @@ export function ObjectTable({
|
|
|
61
61
|
focusedRow,
|
|
62
62
|
onFocusedRowChanged,
|
|
63
63
|
tableRef,
|
|
64
|
+
labels,
|
|
64
65
|
...props
|
|
65
66
|
}) {
|
|
66
67
|
const {
|
|
@@ -230,7 +231,8 @@ export function ObjectTable({
|
|
|
230
231
|
getRowAttributes: props.getRowAttributes,
|
|
231
232
|
showEditFooter: props.showEditFooter,
|
|
232
233
|
focusedRowId: focusedRow == null ? focusedRow : getRowIdFromPrimaryKey(focusedRow),
|
|
233
|
-
onFocusedRowChanged: onFocusedRowChanged
|
|
234
|
+
onFocusedRowChanged: onFocusedRowChanged,
|
|
235
|
+
labels: labels
|
|
234
236
|
});
|
|
235
237
|
}
|
|
236
238
|
//# sourceMappingURL=ObjectTable.js.map
|