qantler-flaz-dataview 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -0
- package/src/FlazDataView.css +4423 -0
- package/src/FlazDataView.jsx +2943 -0
- package/src/FlazDataViewList.jsx +787 -0
- package/src/MdtActiveFilterBar.jsx +263 -0
- package/src/MdtBulkSelectionBar.jsx +91 -0
- package/src/MdtColumnPickerPopup.jsx +59 -0
- package/src/MdtColumnVisibilityList.jsx +38 -0
- package/src/MdtCreateViewModal.jsx +280 -0
- package/src/MdtDatetimeValueEditor.jsx +259 -0
- package/src/MdtDeleteViewConfirmModal.jsx +83 -0
- package/src/MdtDisplayPopup.jsx +170 -0
- package/src/MdtEmptyState.jsx +20 -0
- package/src/MdtFilterColumnPicker.jsx +66 -0
- package/src/MdtFilterOperatorDropdown.jsx +58 -0
- package/src/MdtFilterSection.jsx +73 -0
- package/src/MdtFilterToolbar.jsx +81 -0
- package/src/MdtInlineField.css +221 -0
- package/src/MdtInlineField.jsx +187 -0
- package/src/MdtInlineFieldRow.jsx +71 -0
- package/src/MdtNoDataIllustration.jsx +64 -0
- package/src/MdtPopupChecklist.jsx +70 -0
- package/src/MdtRowActionsMenu.jsx +281 -0
- package/src/MdtSidebarNav.jsx +26 -0
- package/src/MdtTabsRow.jsx +354 -0
- package/src/MdtTabsSection.jsx +35 -0
- package/src/MdtTruncateWithTooltip.jsx +82 -0
- package/src/MdtValueEditorPopup.jsx +950 -0
- package/src/filterDisplayUtils.jsx +96 -0
- package/src/mdtClientSideFilter.js +68 -0
- package/src/mdtColumnEditUtils.js +403 -0
- package/src/mdtDateFilterUtils.js +135 -0
- package/src/mdtExportUtils.js +234 -0
- package/src/mdtFilterUtils.js +56 -0
- package/src/mdtInlineFieldDisplay.js +66 -0
- package/src/mdtMobilePopupPosition.js +107 -0
- package/src/mdtMultiSelectDisplay.jsx +279 -0
- package/src/mdtSavedViewFilterMatch.js +154 -0
- package/src/mdtTabChangeUtils.js +12 -0
- package/src/mdtTabStatusRules.js +111 -0
- package/src/mdtTableConstants.js +2 -0
- package/src/mdtTooltipFormat.js +44 -0
- package/src/renderInlineFieldValue.jsx +183 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { ListFilterPlus, X } from "lucide-react";
|
|
3
|
+
import { renderColumnIcon, resolveFilterColumnIcon } from "../../ui/tableColumnIcons";
|
|
4
|
+
import MdtValueEditorPopup from "./MdtValueEditorPopup";
|
|
5
|
+
import MdtFilterColumnPicker from "./MdtFilterColumnPicker";
|
|
6
|
+
import MdtFilterOperatorDropdown from "./MdtFilterOperatorDropdown";
|
|
7
|
+
import { renderFilterChipDisplayValue } from "./filterDisplayUtils";
|
|
8
|
+
import { EDIT_MODE, getColumnFieldVariant } from "./mdtColumnEditUtils";
|
|
9
|
+
import { resolveFilterConfig, getAvailableFilterColumns } from "./mdtFilterUtils";
|
|
10
|
+
import {
|
|
11
|
+
DEFAULT_DATE_FILTER_OPERATOR,
|
|
12
|
+
getDateFilterOperatorLabel,
|
|
13
|
+
isDateLikeFilterColumn,
|
|
14
|
+
} from "./mdtDateFilterUtils";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Active filter chips bar — reusable in table page and Create View modal.
|
|
18
|
+
*/
|
|
19
|
+
const MdtActiveFilterBar = ({
|
|
20
|
+
filterConfig: filterConfigProp,
|
|
21
|
+
/** Prefer filterableColumns; visibleColumns kept for backward compatibility. */
|
|
22
|
+
filterableColumns: filterableColumnsProp,
|
|
23
|
+
visibleColumns,
|
|
24
|
+
activeFilters,
|
|
25
|
+
replacingFilterId,
|
|
26
|
+
setReplacingFilterId,
|
|
27
|
+
replaceSearch,
|
|
28
|
+
setReplaceSearch,
|
|
29
|
+
valueEditId,
|
|
30
|
+
setValueEditId,
|
|
31
|
+
showInnerFilterDropdown,
|
|
32
|
+
setShowInnerFilterDropdown,
|
|
33
|
+
innerFilterSearch,
|
|
34
|
+
setInnerFilterSearch,
|
|
35
|
+
chipReplaceRef,
|
|
36
|
+
chipValueRef,
|
|
37
|
+
innerFilterRef,
|
|
38
|
+
onRemoveFilter,
|
|
39
|
+
onClearAll,
|
|
40
|
+
onAddFilter,
|
|
41
|
+
onUpdateFilterValue,
|
|
42
|
+
onUpdateFilterOperator,
|
|
43
|
+
onReplaceFilterKey,
|
|
44
|
+
onCloseOtherPopups,
|
|
45
|
+
onCloseColumnSortPopup,
|
|
46
|
+
showSaveAs: showSaveAsProp,
|
|
47
|
+
hasAnyFilterValue = false,
|
|
48
|
+
onSaveAs,
|
|
49
|
+
className = "",
|
|
50
|
+
}) => {
|
|
51
|
+
const config = resolveFilterConfig(filterConfigProp);
|
|
52
|
+
const columns = filterableColumnsProp ?? visibleColumns ?? [];
|
|
53
|
+
const showSaveAs = showSaveAsProp ?? config.showSaveAs;
|
|
54
|
+
|
|
55
|
+
const replaceColumns = getAvailableFilterColumns(
|
|
56
|
+
columns,
|
|
57
|
+
activeFilters.filter((f) => f.id !== replacingFilterId),
|
|
58
|
+
replaceSearch,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const addColumns = getAvailableFilterColumns(columns, activeFilters, innerFilterSearch);
|
|
62
|
+
const [operatorEditId, setOperatorEditId] = useState(null);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div className={`mdt-filter-inner${className ? ` ${className}` : ""}`.trim()}>
|
|
66
|
+
<div className="mdt-filter-left">
|
|
67
|
+
{activeFilters.map((filter) => {
|
|
68
|
+
const col = columns.find((c) => c.accessorKey === filter.key);
|
|
69
|
+
const isDateFilter = isDateLikeFilterColumn(col);
|
|
70
|
+
const filterOperator =
|
|
71
|
+
filter.operator ?? DEFAULT_DATE_FILTER_OPERATOR;
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div
|
|
75
|
+
className="mdt-filter-chip"
|
|
76
|
+
key={filter.id}
|
|
77
|
+
style={{ position: "relative" }}
|
|
78
|
+
ref={replacingFilterId === filter.id ? chipReplaceRef : null}
|
|
79
|
+
>
|
|
80
|
+
{config.showChipFieldReplace && (
|
|
81
|
+
<button
|
|
82
|
+
type="button"
|
|
83
|
+
className="mdt-chip-label mdt-chip-label-btn"
|
|
84
|
+
onClick={() => {
|
|
85
|
+
setReplacingFilterId(replacingFilterId === filter.id ? null : filter.id);
|
|
86
|
+
setReplaceSearch("");
|
|
87
|
+
onCloseOtherPopups?.();
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
<span className="mdt-chip-icon">
|
|
91
|
+
{renderColumnIcon(resolveFilterColumnIcon(filter, columns), {
|
|
92
|
+
className: "mdt-chip-svg",
|
|
93
|
+
})}
|
|
94
|
+
</span>
|
|
95
|
+
<span className="mdt-chip-label-text">{filter.label}</span>
|
|
96
|
+
</button>
|
|
97
|
+
)}
|
|
98
|
+
|
|
99
|
+
{config.showChipFieldReplace && replacingFilterId === filter.id && (
|
|
100
|
+
<MdtFilterColumnPicker
|
|
101
|
+
columns={replaceColumns}
|
|
102
|
+
search={replaceSearch}
|
|
103
|
+
onSearchChange={setReplaceSearch}
|
|
104
|
+
onSelectColumn={(col) => {
|
|
105
|
+
onReplaceFilterKey(filter.id, col);
|
|
106
|
+
setReplacingFilterId(null);
|
|
107
|
+
setReplaceSearch("");
|
|
108
|
+
setValueEditId(filter.id);
|
|
109
|
+
}}
|
|
110
|
+
searchPlaceholder={config.searchPlaceholder}
|
|
111
|
+
emptyMessage={config.emptyColumnsMessage}
|
|
112
|
+
dropdownClassName="mdt-filter-dropdown mdt-fd-left mdt-chip-replace-dropdown"
|
|
113
|
+
align="left"
|
|
114
|
+
/>
|
|
115
|
+
)}
|
|
116
|
+
|
|
117
|
+
{isDateFilter ? (
|
|
118
|
+
<div
|
|
119
|
+
className="mdt-chip-op-wrap"
|
|
120
|
+
style={{ position: "relative" }}
|
|
121
|
+
>
|
|
122
|
+
<button
|
|
123
|
+
type="button"
|
|
124
|
+
className="mdt-chip-op mdt-chip-op-btn"
|
|
125
|
+
onMouseDown={(e) => e.stopPropagation()}
|
|
126
|
+
onClick={(e) => {
|
|
127
|
+
e.stopPropagation();
|
|
128
|
+
const opening = operatorEditId !== filter.id;
|
|
129
|
+
setOperatorEditId(opening ? filter.id : null);
|
|
130
|
+
setReplacingFilterId(null);
|
|
131
|
+
onCloseOtherPopups?.();
|
|
132
|
+
if (opening) setValueEditId(null);
|
|
133
|
+
}}
|
|
134
|
+
>
|
|
135
|
+
{getDateFilterOperatorLabel(filterOperator)}
|
|
136
|
+
</button>
|
|
137
|
+
{operatorEditId === filter.id && (
|
|
138
|
+
<MdtFilterOperatorDropdown
|
|
139
|
+
operator={filterOperator}
|
|
140
|
+
onSelect={(op) => {
|
|
141
|
+
onUpdateFilterOperator?.(filter.id, op);
|
|
142
|
+
setOperatorEditId(null);
|
|
143
|
+
setValueEditId(filter.id);
|
|
144
|
+
}}
|
|
145
|
+
onClose={() => setOperatorEditId(null)}
|
|
146
|
+
/>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
) : (
|
|
150
|
+
<div className="mdt-chip-op">{config.operatorLabel}</div>
|
|
151
|
+
)}
|
|
152
|
+
|
|
153
|
+
<div
|
|
154
|
+
className="mdt-chip-value-wrap"
|
|
155
|
+
ref={
|
|
156
|
+
valueEditId === filter.id && operatorEditId !== filter.id
|
|
157
|
+
? chipValueRef
|
|
158
|
+
: null
|
|
159
|
+
}
|
|
160
|
+
style={{ position: "relative" }}
|
|
161
|
+
>
|
|
162
|
+
<button
|
|
163
|
+
type="button"
|
|
164
|
+
className="mdt-chip-value"
|
|
165
|
+
onMouseDown={(e) => e.stopPropagation()}
|
|
166
|
+
onClick={(e) => {
|
|
167
|
+
e.stopPropagation();
|
|
168
|
+
const isOpening = valueEditId !== filter.id;
|
|
169
|
+
setValueEditId(isOpening ? filter.id : null);
|
|
170
|
+
setReplacingFilterId(null);
|
|
171
|
+
onCloseOtherPopups?.();
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
{renderFilterChipDisplayValue(
|
|
175
|
+
filter,
|
|
176
|
+
columns.find((c) => c.accessorKey === filter.key),
|
|
177
|
+
)}
|
|
178
|
+
</button>
|
|
179
|
+
|
|
180
|
+
{valueEditId === filter.id && operatorEditId !== filter.id && col && (
|
|
181
|
+
<MdtValueEditorPopup
|
|
182
|
+
column={col}
|
|
183
|
+
mode={EDIT_MODE.FILTER}
|
|
184
|
+
value={filter.value}
|
|
185
|
+
filterOperator={isDateFilter ? filterOperator : undefined}
|
|
186
|
+
onApply={(v) => {
|
|
187
|
+
onUpdateFilterValue(filter.id, v);
|
|
188
|
+
const variant =
|
|
189
|
+
getColumnFieldVariant(col, EDIT_MODE.FILTER) || "text";
|
|
190
|
+
const isMulti =
|
|
191
|
+
variant === "select" && col?.filterMulti !== false;
|
|
192
|
+
if (variant !== "select" || !isMulti) {
|
|
193
|
+
setValueEditId(null);
|
|
194
|
+
}
|
|
195
|
+
}}
|
|
196
|
+
onCancel={() => setValueEditId(null)}
|
|
197
|
+
/>
|
|
198
|
+
)}
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
{config.showChipRemove && (
|
|
202
|
+
<button
|
|
203
|
+
type="button"
|
|
204
|
+
className="mdt-chip-remove"
|
|
205
|
+
onClick={() => onRemoveFilter(filter.id)}
|
|
206
|
+
>
|
|
207
|
+
<X size={14} />
|
|
208
|
+
</button>
|
|
209
|
+
)}
|
|
210
|
+
</div>
|
|
211
|
+
);
|
|
212
|
+
})}
|
|
213
|
+
|
|
214
|
+
{config.showAddFilter && (
|
|
215
|
+
<div className="mdt-filter-button-wrap" ref={innerFilterRef}>
|
|
216
|
+
<button
|
|
217
|
+
type="button"
|
|
218
|
+
className="mdt-add-filter"
|
|
219
|
+
onClick={() => {
|
|
220
|
+
onCloseColumnSortPopup?.();
|
|
221
|
+
setShowInnerFilterDropdown((v) => !v);
|
|
222
|
+
}}
|
|
223
|
+
>
|
|
224
|
+
<ListFilterPlus size={16} />
|
|
225
|
+
</button>
|
|
226
|
+
|
|
227
|
+
{showInnerFilterDropdown && (
|
|
228
|
+
<MdtFilterColumnPicker
|
|
229
|
+
columns={addColumns}
|
|
230
|
+
search={innerFilterSearch}
|
|
231
|
+
onSearchChange={setInnerFilterSearch}
|
|
232
|
+
onSelectColumn={(col) => {
|
|
233
|
+
onAddFilter(col);
|
|
234
|
+
setShowInnerFilterDropdown(false);
|
|
235
|
+
setInnerFilterSearch("");
|
|
236
|
+
}}
|
|
237
|
+
searchPlaceholder={config.searchPlaceholder}
|
|
238
|
+
emptyMessage={config.emptyMoreMessage}
|
|
239
|
+
dropdownClassName="mdt-filter-dropdown mdt-fd-left"
|
|
240
|
+
align="left"
|
|
241
|
+
/>
|
|
242
|
+
)}
|
|
243
|
+
</div>
|
|
244
|
+
)}
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<div className="mdt-filter-right">
|
|
248
|
+
{config.showClearAll && (
|
|
249
|
+
<button type="button" className="mdt-clear-all" onClick={onClearAll}>
|
|
250
|
+
{config.clearAllLabel}
|
|
251
|
+
</button>
|
|
252
|
+
)}
|
|
253
|
+
{showSaveAs && hasAnyFilterValue && (
|
|
254
|
+
<button type="button" className="mdt-clear-all" onClick={onSaveAs}>
|
|
255
|
+
{config.saveAsLabel}
|
|
256
|
+
</button>
|
|
257
|
+
)}
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export default MdtActiveFilterBar;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Trash2 } from "lucide-react";
|
|
3
|
+
import { renderColumnIcon } from "../../ui/tableColumnIcons";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bottom bulk action bar — shown when one or more rows are selected.
|
|
7
|
+
* bulkFields: [{ id, label, Icon?, iconName?, column? }]
|
|
8
|
+
*/
|
|
9
|
+
const MdtBulkSelectionBar = ({
|
|
10
|
+
selectedCount,
|
|
11
|
+
onClearSelection,
|
|
12
|
+
bulkFields = [],
|
|
13
|
+
onBulkFieldClick,
|
|
14
|
+
onBulkDelete,
|
|
15
|
+
bulkDeleteDisabled = false,
|
|
16
|
+
bulkDeleteDisabledReason = "None of the selected items can be deleted.",
|
|
17
|
+
rightAction = null,
|
|
18
|
+
}) => {
|
|
19
|
+
if (!selectedCount) return null;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className="mdt-bulk-bar" role="toolbar" aria-label="Bulk actions">
|
|
23
|
+
<div className="mdt-bulk-bar-inner">
|
|
24
|
+
<div className="mdt-bulk-bar-status">
|
|
25
|
+
<button
|
|
26
|
+
type="button"
|
|
27
|
+
className="mdt-bulk-bar-clear"
|
|
28
|
+
aria-label="Clear selection"
|
|
29
|
+
onClick={onClearSelection}
|
|
30
|
+
/>
|
|
31
|
+
<span className="mdt-bulk-bar-count">
|
|
32
|
+
{selectedCount} selected
|
|
33
|
+
</span>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div className="mdt-bulk-bar-divider" aria-hidden />
|
|
37
|
+
|
|
38
|
+
<div className="mdt-bulk-bar-actions">
|
|
39
|
+
{onBulkDelete && (
|
|
40
|
+
<div className="mdt-bulk-bar-icons">
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
className={[
|
|
44
|
+
"mdt-bulk-bar-icon-btn",
|
|
45
|
+
bulkDeleteDisabled ? "mdt-bulk-bar-icon-btn--disabled" : "",
|
|
46
|
+
]
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join(" ")}
|
|
49
|
+
aria-label="Delete"
|
|
50
|
+
title={bulkDeleteDisabled ? bulkDeleteDisabledReason : "Delete"}
|
|
51
|
+
disabled={bulkDeleteDisabled}
|
|
52
|
+
onClick={bulkDeleteDisabled ? undefined : onBulkDelete}
|
|
53
|
+
>
|
|
54
|
+
<Trash2 size={16} />
|
|
55
|
+
</button>
|
|
56
|
+
</div>
|
|
57
|
+
)}
|
|
58
|
+
|
|
59
|
+
{bulkFields.length > 0 && (
|
|
60
|
+
<div className="mdt-bulk-bar-fields">
|
|
61
|
+
{bulkFields.map((field) => {
|
|
62
|
+
const iconEl = renderColumnIcon(field.icon ?? field.iconName, {
|
|
63
|
+
className: "mdt-bulk-field-icon",
|
|
64
|
+
size: 14,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<button
|
|
69
|
+
key={field.id}
|
|
70
|
+
type="button"
|
|
71
|
+
className="mdt-bulk-field-btn"
|
|
72
|
+
onClick={(e) => onBulkFieldClick?.(field.id, field, e)}
|
|
73
|
+
>
|
|
74
|
+
{iconEl}
|
|
75
|
+
<span>{field.label}</span>
|
|
76
|
+
</button>
|
|
77
|
+
);
|
|
78
|
+
})}
|
|
79
|
+
</div>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
{rightAction && (
|
|
84
|
+
<div className="mdt-bulk-bar-right">{rightAction}</div>
|
|
85
|
+
)}
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default MdtBulkSelectionBar;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
3
|
+
import MdtColumnVisibilityList from "./MdtColumnVisibilityList";
|
|
4
|
+
|
|
5
|
+
const MdtColumnPickerPopup = ({
|
|
6
|
+
isOpen,
|
|
7
|
+
position,
|
|
8
|
+
columns,
|
|
9
|
+
hiddenColumns,
|
|
10
|
+
onToggleColumn,
|
|
11
|
+
onClose,
|
|
12
|
+
}) => {
|
|
13
|
+
const [search, setSearch] = useState("");
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!isOpen) {
|
|
17
|
+
setSearch("");
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const handleOutside = (e) => {
|
|
21
|
+
if (
|
|
22
|
+
!e.target.closest(".mdt-column-picker-popup") &&
|
|
23
|
+
!e.target.closest(".mdt-th-column-picker-btn")
|
|
24
|
+
) {
|
|
25
|
+
onClose();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
document.addEventListener("mousedown", handleOutside);
|
|
29
|
+
return () => document.removeEventListener("mousedown", handleOutside);
|
|
30
|
+
}, [isOpen, onClose]);
|
|
31
|
+
|
|
32
|
+
if (!isOpen || !position) return null;
|
|
33
|
+
|
|
34
|
+
return createPortal(
|
|
35
|
+
<div
|
|
36
|
+
className="mdt-column-picker-popup mdt-column-picker-popup--portal"
|
|
37
|
+
style={{
|
|
38
|
+
position: "fixed",
|
|
39
|
+
top: position.top,
|
|
40
|
+
left: position.left,
|
|
41
|
+
zIndex: 300000,
|
|
42
|
+
}}
|
|
43
|
+
onMouseDown={(e) => e.stopPropagation()}
|
|
44
|
+
onClick={(e) => e.stopPropagation()}
|
|
45
|
+
>
|
|
46
|
+
<MdtColumnVisibilityList
|
|
47
|
+
columns={columns}
|
|
48
|
+
hiddenColumns={hiddenColumns}
|
|
49
|
+
onToggleColumn={onToggleColumn}
|
|
50
|
+
search={search}
|
|
51
|
+
onSearchChange={setSearch}
|
|
52
|
+
showSearch
|
|
53
|
+
/>
|
|
54
|
+
</div>,
|
|
55
|
+
document.body,
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default MdtColumnPickerPopup;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import MdtPopupChecklist from "./MdtPopupChecklist";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Column visibility checklist — uses shared popup checklist design.
|
|
6
|
+
*/
|
|
7
|
+
const MdtColumnVisibilityList = ({
|
|
8
|
+
columns,
|
|
9
|
+
hiddenColumns,
|
|
10
|
+
onToggleColumn,
|
|
11
|
+
search = "",
|
|
12
|
+
onSearchChange,
|
|
13
|
+
showSearch = true,
|
|
14
|
+
}) => {
|
|
15
|
+
const options = useMemo(
|
|
16
|
+
() =>
|
|
17
|
+
columns.map((col) => ({
|
|
18
|
+
key: col.accessorKey,
|
|
19
|
+
label: col.header,
|
|
20
|
+
icon: col.headerIcon || col.rowIcon || "default",
|
|
21
|
+
checked: !hiddenColumns.includes(col.accessorKey),
|
|
22
|
+
})),
|
|
23
|
+
[columns, hiddenColumns],
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<MdtPopupChecklist
|
|
28
|
+
options={options}
|
|
29
|
+
onToggle={onToggleColumn}
|
|
30
|
+
search={search}
|
|
31
|
+
onSearchChange={onSearchChange}
|
|
32
|
+
showSearch={showSearch}
|
|
33
|
+
emptyText="No columns found"
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default MdtColumnVisibilityList;
|