@okta/odyssey-react-mui 1.6.20 → 1.6.21
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 +4 -0
- package/dist/Button.js +2 -2
- package/dist/Button.js.map +1 -1
- package/dist/MenuButton.js +16 -2
- package/dist/MenuButton.js.map +1 -1
- package/dist/MenuContext.js +2 -1
- package/dist/MenuContext.js.map +1 -1
- package/dist/MenuItem.js +6 -3
- package/dist/MenuItem.js.map +1 -1
- package/dist/SearchField.js.map +1 -1
- package/dist/icons.generated/ArrowBottom.js +33 -0
- package/dist/icons.generated/ArrowBottom.js.map +1 -0
- package/dist/icons.generated/ArrowTop.js +33 -0
- package/dist/icons.generated/ArrowTop.js.map +1 -0
- package/dist/icons.generated/index.js +2 -0
- package/dist/icons.generated/index.js.map +1 -1
- package/dist/labs/DataFilters.js +366 -0
- package/dist/labs/DataFilters.js.map +1 -0
- package/dist/labs/DataTable.js +366 -0
- package/dist/labs/DataTable.js.map +1 -0
- package/dist/labs/DataTablePagination.js +74 -0
- package/dist/labs/DataTablePagination.js.map +1 -0
- package/dist/labs/PaginatedTable.js +9 -6
- package/dist/labs/PaginatedTable.js.map +1 -1
- package/dist/labs/StaticTable.js +8 -5
- package/dist/labs/StaticTable.js.map +1 -1
- package/dist/labs/index.js +4 -1
- package/dist/labs/index.js.map +1 -1
- package/dist/labs/materialReactTableTypes.js.map +1 -1
- package/dist/src/MenuButton.d.ts +12 -2
- package/dist/src/MenuButton.d.ts.map +1 -1
- package/dist/src/MenuContext.d.ts +1 -0
- package/dist/src/MenuContext.d.ts.map +1 -1
- package/dist/src/MenuItem.d.ts.map +1 -1
- package/dist/src/SearchField.d.ts +16 -0
- package/dist/src/SearchField.d.ts.map +1 -1
- package/dist/src/icons.generated/ArrowBottom.d.ts +16 -0
- package/dist/src/icons.generated/ArrowBottom.d.ts.map +1 -0
- package/dist/src/icons.generated/ArrowTop.d.ts +16 -0
- package/dist/src/icons.generated/ArrowTop.d.ts.map +1 -0
- package/dist/src/icons.generated/index.d.ts +2 -0
- package/dist/src/icons.generated/index.d.ts.map +1 -1
- package/dist/src/labs/DataFilters.d.ts +85 -0
- package/dist/src/labs/DataFilters.d.ts.map +1 -0
- package/dist/src/labs/DataTable.d.ts +193 -0
- package/dist/src/labs/DataTable.d.ts.map +1 -0
- package/dist/src/labs/DataTablePagination.d.ts +25 -0
- package/dist/src/labs/DataTablePagination.d.ts.map +1 -0
- package/dist/src/labs/PaginatedTable.d.ts.map +1 -1
- package/dist/src/labs/StaticTable.d.ts.map +1 -1
- package/dist/src/labs/index.d.ts +4 -2
- package/dist/src/labs/index.d.ts.map +1 -1
- package/dist/src/labs/materialReactTableTypes.d.ts +1 -1
- package/dist/src/labs/materialReactTableTypes.d.ts.map +1 -1
- package/dist/src/theme/components.d.ts.map +1 -1
- package/dist/theme/components.js +137 -64
- package/dist/theme/components.js.map +1 -1
- package/dist/tsconfig.production.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/Button.tsx +2 -2
- package/src/MenuButton.tsx +50 -8
- package/src/MenuContext.ts +2 -0
- package/src/MenuItem.tsx +5 -3
- package/src/SearchField.tsx +8 -0
- package/src/icons.generated/ArrowBottom.tsx +43 -0
- package/src/icons.generated/ArrowTop.tsx +43 -0
- package/src/icons.generated/index.ts +2 -0
- package/src/labs/DataFilters.tsx +601 -0
- package/src/labs/DataTable.tsx +681 -0
- package/src/labs/DataTablePagination.tsx +88 -0
- package/src/labs/PaginatedTable.tsx +35 -33
- package/src/labs/StaticTable.tsx +26 -29
- package/src/labs/index.ts +6 -3
- package/src/labs/{materialReactTableTypes.ts → materialReactTableTypes.tsx} +1 -1
- package/src/theme/components.tsx +154 -62
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import _Popover from "@mui/material/Popover";
|
|
2
|
+
import _IconButton from "@mui/material/IconButton";
|
|
3
|
+
import _Menu from "@mui/material/Menu";
|
|
4
|
+
/*!
|
|
5
|
+
* Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
|
|
6
|
+
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
|
|
7
|
+
*
|
|
8
|
+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
11
|
+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
*
|
|
13
|
+
* See the License for the specific language governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
17
|
+
import { Autocomplete } from "../Autocomplete.js";
|
|
18
|
+
import { Box } from "../Box.js";
|
|
19
|
+
import { TagList } from "../TagList.js";
|
|
20
|
+
import { Tag } from "../Tag.js";
|
|
21
|
+
import { SearchField } from "../SearchField.js";
|
|
22
|
+
import { Button } from "../Button.js";
|
|
23
|
+
import { CheckIcon, ChevronRightIcon, CloseCircleFilledIcon, FilterIcon } from "../icons.generated/index.js";
|
|
24
|
+
import { MenuItem } from "../MenuItem.js";
|
|
25
|
+
import { Paragraph, Subordinate } from "../Typography.js";
|
|
26
|
+
import { TextField } from "../TextField.js";
|
|
27
|
+
import { CheckboxGroup } from "../CheckboxGroup.js";
|
|
28
|
+
import { Checkbox } from "../Checkbox.js";
|
|
29
|
+
import { RadioGroup } from "../RadioGroup.js";
|
|
30
|
+
import { Radio } from "../Radio.js";
|
|
31
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
32
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
33
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
34
|
+
const DataFilters = _ref => {
|
|
35
|
+
let {
|
|
36
|
+
onChangeSearch,
|
|
37
|
+
onChangeFilters,
|
|
38
|
+
hasSearchSubmitButton = false,
|
|
39
|
+
searchDelayTime = 200,
|
|
40
|
+
defaultSearchTerm = "",
|
|
41
|
+
additionalActions,
|
|
42
|
+
filters: filtersProp = []
|
|
43
|
+
} = _ref;
|
|
44
|
+
const [filters, setFilters] = useState(filtersProp);
|
|
45
|
+
const initialInputValues = useMemo(() => {
|
|
46
|
+
return filtersProp.reduce((accumulator, filter) => {
|
|
47
|
+
accumulator[filter.id] = filter.value;
|
|
48
|
+
return accumulator;
|
|
49
|
+
}, {});
|
|
50
|
+
}, [filtersProp]);
|
|
51
|
+
const [inputValues, setInputValues] = useState(initialInputValues);
|
|
52
|
+
const [searchValue, setSearchValue] = useState(defaultSearchTerm);
|
|
53
|
+
const activeFilters = useMemo(() => {
|
|
54
|
+
return filters.filter(filter => typeof filter.value === "string" && filter.value);
|
|
55
|
+
}, [filters]);
|
|
56
|
+
const [isFiltersMenuOpen, setIsFiltersMenuOpen] = useState(false);
|
|
57
|
+
const [filtersMenuAnchorElement, setFiltersMenuAnchorElement] = useState();
|
|
58
|
+
const [isFilterPopoverOpen, setIsFilterPopoverOpen] = useState(false);
|
|
59
|
+
const [filterPopoverAnchorElement, setFilterPopoverAnchorElement] = useState();
|
|
60
|
+
const [filterPopoverCurrentFilter, setFilterPopoverCurrentFilter] = useState();
|
|
61
|
+
const menuRef = useRef();
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
onChangeFilters?.(filters);
|
|
64
|
+
}, [filters, onChangeFilters]);
|
|
65
|
+
const debouncer = useRef(undefined);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (!hasSearchSubmitButton) {
|
|
68
|
+
if (debouncer.current) {
|
|
69
|
+
clearTimeout(debouncer.current);
|
|
70
|
+
}
|
|
71
|
+
debouncer.current = setTimeout(() => {
|
|
72
|
+
onChangeSearch?.(searchValue ?? "");
|
|
73
|
+
}, searchDelayTime);
|
|
74
|
+
}
|
|
75
|
+
}, [onChangeSearch, searchValue, searchDelayTime, hasSearchSubmitButton]);
|
|
76
|
+
const handleInputChange = useCallback(function (filterId, value) {
|
|
77
|
+
let submit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
78
|
+
setInputValues({
|
|
79
|
+
...inputValues,
|
|
80
|
+
[filterId]: value
|
|
81
|
+
});
|
|
82
|
+
if (submit) {
|
|
83
|
+
const updatedFilters = filtersProp.map(filter => ({
|
|
84
|
+
...filter,
|
|
85
|
+
value: filter.id === filterId ? value : inputValues[filter.id]
|
|
86
|
+
}));
|
|
87
|
+
setFilters(updatedFilters);
|
|
88
|
+
}
|
|
89
|
+
}, [inputValues, filtersProp]);
|
|
90
|
+
const handleMultiSelectChange = useCallback(function (filterId, value) {
|
|
91
|
+
let submit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
92
|
+
const startingValues = filtersProp.find(filter => filter.id === filterId)?.options?.map(option => option.value);
|
|
93
|
+
const currentValues = inputValues[filterId] ?? startingValues;
|
|
94
|
+
const updatedValues = currentValues.includes(value) ? currentValues.filter(item => item !== value) : [...currentValues, value];
|
|
95
|
+
const valuesToSave = updatedValues.sort().join() === startingValues?.sort().join() ? undefined : updatedValues;
|
|
96
|
+
setInputValues({
|
|
97
|
+
...inputValues,
|
|
98
|
+
[filterId]: valuesToSave
|
|
99
|
+
});
|
|
100
|
+
if (submit) {
|
|
101
|
+
const updatedFilters = filtersProp.map(filter => ({
|
|
102
|
+
...filter,
|
|
103
|
+
value: filter.id === filterId ? valuesToSave : inputValues[filter.id]
|
|
104
|
+
}));
|
|
105
|
+
setFilters(updatedFilters);
|
|
106
|
+
}
|
|
107
|
+
}, [inputValues, filtersProp]);
|
|
108
|
+
const clearAllFilters = useCallback(() => {
|
|
109
|
+
const updatedInputValues = filtersProp.reduce((accumulator, filter) => {
|
|
110
|
+
accumulator[filter.id] = undefined;
|
|
111
|
+
return accumulator;
|
|
112
|
+
}, {});
|
|
113
|
+
setInputValues(updatedInputValues);
|
|
114
|
+
const updatedFilters = filtersProp.map(filter => ({
|
|
115
|
+
...filter,
|
|
116
|
+
value: undefined
|
|
117
|
+
}));
|
|
118
|
+
setFilters(updatedFilters);
|
|
119
|
+
}, [filtersProp]);
|
|
120
|
+
const handleFilterSubmit = useCallback(() => {
|
|
121
|
+
const updatedFilters = filtersProp.map(filter => ({
|
|
122
|
+
...filter,
|
|
123
|
+
value: inputValues[filter.id]
|
|
124
|
+
}));
|
|
125
|
+
setFilters(updatedFilters);
|
|
126
|
+
}, [inputValues, filtersProp]);
|
|
127
|
+
const filterMenu = useMemo(() => _jsxs(_Fragment, {
|
|
128
|
+
children: [_jsx(Box, {
|
|
129
|
+
children: _jsx(Button, {
|
|
130
|
+
"aria-controls": isFiltersMenuOpen ? "filters-menu" : undefined,
|
|
131
|
+
"aria-expanded": isFiltersMenuOpen ? "true" : undefined,
|
|
132
|
+
"aria-haspopup": "true",
|
|
133
|
+
ariaLabel: "Filters",
|
|
134
|
+
endIcon: _jsx(FilterIcon, {}),
|
|
135
|
+
onClick: event => {
|
|
136
|
+
setFiltersMenuAnchorElement(event.currentTarget);
|
|
137
|
+
setIsFiltersMenuOpen(true);
|
|
138
|
+
},
|
|
139
|
+
variant: "secondary"
|
|
140
|
+
})
|
|
141
|
+
}), _jsx(_Menu, {
|
|
142
|
+
anchorOrigin: {
|
|
143
|
+
horizontal: "left",
|
|
144
|
+
vertical: "bottom"
|
|
145
|
+
},
|
|
146
|
+
transformOrigin: {
|
|
147
|
+
horizontal: "left",
|
|
148
|
+
vertical: "top"
|
|
149
|
+
},
|
|
150
|
+
id: "filters-menu",
|
|
151
|
+
anchorEl: filtersMenuAnchorElement,
|
|
152
|
+
onClose: () => setIsFiltersMenuOpen(false),
|
|
153
|
+
open: isFiltersMenuOpen,
|
|
154
|
+
PaperProps: {
|
|
155
|
+
ref: menuRef
|
|
156
|
+
},
|
|
157
|
+
children: filtersProp.map(filter => {
|
|
158
|
+
const latestFilterValue = filters.find(f => f.id === filter.id)?.value;
|
|
159
|
+
return _jsx(MenuItem, {
|
|
160
|
+
onClick: event => {
|
|
161
|
+
setIsFilterPopoverOpen(true);
|
|
162
|
+
setFilterPopoverAnchorElement(event.currentTarget);
|
|
163
|
+
setFilterPopoverCurrentFilter(filter);
|
|
164
|
+
},
|
|
165
|
+
children: _jsxs(Box, {
|
|
166
|
+
sx: {
|
|
167
|
+
display: "flex",
|
|
168
|
+
alignItems: "center",
|
|
169
|
+
justifyContent: "space-between",
|
|
170
|
+
width: "100%",
|
|
171
|
+
minWidth: 180
|
|
172
|
+
},
|
|
173
|
+
children: [_jsxs(Box, {
|
|
174
|
+
sx: {
|
|
175
|
+
marginRight: 2
|
|
176
|
+
},
|
|
177
|
+
children: [_jsx(Paragraph, {
|
|
178
|
+
component: "div",
|
|
179
|
+
children: filter.label
|
|
180
|
+
}), _jsx(Subordinate, {
|
|
181
|
+
component: "div",
|
|
182
|
+
children: !latestFilterValue || Array.isArray(latestFilterValue) && latestFilterValue.length === 0 ? `Any ${filter.label.toLowerCase()}` : Array.isArray(latestFilterValue) ? `${latestFilterValue.length} selected` : latestFilterValue
|
|
183
|
+
})]
|
|
184
|
+
}), _jsx(ChevronRightIcon, {})]
|
|
185
|
+
})
|
|
186
|
+
}, filter.id);
|
|
187
|
+
})
|
|
188
|
+
})]
|
|
189
|
+
}), [isFiltersMenuOpen, filtersMenuAnchorElement, filtersProp, filters]);
|
|
190
|
+
return _jsxs(Box, {
|
|
191
|
+
children: [_jsxs(Box, {
|
|
192
|
+
sx: {
|
|
193
|
+
display: "flex",
|
|
194
|
+
justifyContent: "space-between"
|
|
195
|
+
},
|
|
196
|
+
children: [_jsxs(Box, {
|
|
197
|
+
sx: {
|
|
198
|
+
display: "flex",
|
|
199
|
+
gap: 2,
|
|
200
|
+
width: "50%",
|
|
201
|
+
maxWidth: 480
|
|
202
|
+
},
|
|
203
|
+
children: [filters.length > 0 && _jsxs(_Fragment, {
|
|
204
|
+
children: [filterMenu, _jsx(_Popover, {
|
|
205
|
+
anchorEl: filterPopoverAnchorElement,
|
|
206
|
+
open: isFilterPopoverOpen,
|
|
207
|
+
anchorOrigin: {
|
|
208
|
+
vertical: "top",
|
|
209
|
+
horizontal: "right"
|
|
210
|
+
},
|
|
211
|
+
onClose: ev => {
|
|
212
|
+
if (menuRef.current) {
|
|
213
|
+
const menuRect = menuRef.current.getBoundingClientRect();
|
|
214
|
+
const clickInsideMenu = ev.clientX >= menuRect.left && ev.clientX <= menuRect.right && ev.clientY >= menuRect.top && ev.clientY <= menuRect.bottom;
|
|
215
|
+
if (!clickInsideMenu) {
|
|
216
|
+
setIsFiltersMenuOpen(false);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
setIsFilterPopoverOpen(false);
|
|
220
|
+
},
|
|
221
|
+
children: _jsx(Box, {
|
|
222
|
+
sx: {
|
|
223
|
+
padding: 4,
|
|
224
|
+
minWidth: 320
|
|
225
|
+
},
|
|
226
|
+
children: _jsxs("form", {
|
|
227
|
+
onSubmit: ev => {
|
|
228
|
+
ev.preventDefault();
|
|
229
|
+
handleFilterSubmit();
|
|
230
|
+
setIsFilterPopoverOpen(false);
|
|
231
|
+
setIsFiltersMenuOpen(false);
|
|
232
|
+
},
|
|
233
|
+
children: [filterPopoverCurrentFilter?.variant === "autocomplete" && filterPopoverCurrentFilter?.options && _jsx(Autocomplete, {
|
|
234
|
+
label: filterPopoverCurrentFilter.label,
|
|
235
|
+
value: inputValues[filterPopoverCurrentFilter.id] ?? "",
|
|
236
|
+
onBlur: function ro() {},
|
|
237
|
+
onChange: function ro() {},
|
|
238
|
+
onFocus: function ro() {},
|
|
239
|
+
onInputChange: function ro() {},
|
|
240
|
+
options: filterPopoverCurrentFilter.options.map(option => ({
|
|
241
|
+
label: option.label
|
|
242
|
+
}))
|
|
243
|
+
}), (filterPopoverCurrentFilter?.variant === "text" || filterPopoverCurrentFilter?.variant === "range") && _jsxs(Box, {
|
|
244
|
+
sx: {
|
|
245
|
+
display: "flex",
|
|
246
|
+
gap: 2,
|
|
247
|
+
alignItems: "flex-end"
|
|
248
|
+
},
|
|
249
|
+
children: [_jsx(Box, {
|
|
250
|
+
sx: {
|
|
251
|
+
width: "100%"
|
|
252
|
+
},
|
|
253
|
+
children: _jsx(TextField, {
|
|
254
|
+
hasInitialFocus: true,
|
|
255
|
+
label: filterPopoverCurrentFilter.label,
|
|
256
|
+
type: filterPopoverCurrentFilter.variant === "range" ? "number" : "text",
|
|
257
|
+
value: inputValues[filterPopoverCurrentFilter.id] ?? "",
|
|
258
|
+
onChange: ev => handleInputChange(filterPopoverCurrentFilter.id, ev.currentTarget.value),
|
|
259
|
+
endAdornment: inputValues[filterPopoverCurrentFilter.id] && _jsx(_IconButton, {
|
|
260
|
+
size: "small",
|
|
261
|
+
"aria-label": "Clear filter",
|
|
262
|
+
onClick: () => {
|
|
263
|
+
handleInputChange(filterPopoverCurrentFilter.id, undefined, true);
|
|
264
|
+
},
|
|
265
|
+
children: _jsx(CloseCircleFilledIcon, {})
|
|
266
|
+
})
|
|
267
|
+
})
|
|
268
|
+
}), _jsx(Button, {
|
|
269
|
+
variant: "primary",
|
|
270
|
+
endIcon: _jsx(CheckIcon, {}),
|
|
271
|
+
type: "submit"
|
|
272
|
+
})]
|
|
273
|
+
}), filterPopoverCurrentFilter?.variant === "multi-select" && filterPopoverCurrentFilter?.options && _jsx(CheckboxGroup, {
|
|
274
|
+
label: filterPopoverCurrentFilter.label,
|
|
275
|
+
isRequired: true,
|
|
276
|
+
children: filterPopoverCurrentFilter.options.map(option => _jsx(Checkbox, {
|
|
277
|
+
label: option.label,
|
|
278
|
+
value: option.value,
|
|
279
|
+
isDefaultChecked: inputValues[filterPopoverCurrentFilter.id]?.includes(option.value) || inputValues[filterPopoverCurrentFilter.id] === undefined,
|
|
280
|
+
onChange: () => handleMultiSelectChange(filterPopoverCurrentFilter.id, option.value, true)
|
|
281
|
+
}, option.value))
|
|
282
|
+
}), filterPopoverCurrentFilter?.variant === "select" && filterPopoverCurrentFilter?.options && _jsxs(RadioGroup, {
|
|
283
|
+
label: filterPopoverCurrentFilter.label,
|
|
284
|
+
onChange: (_, value) => handleInputChange(filterPopoverCurrentFilter.id, value, true),
|
|
285
|
+
children: [_jsx(Radio, {
|
|
286
|
+
label: "Any",
|
|
287
|
+
value: "",
|
|
288
|
+
isChecked: !inputValues[filterPopoverCurrentFilter.id]
|
|
289
|
+
}), _jsx(_Fragment, {
|
|
290
|
+
children: filterPopoverCurrentFilter.options.map(option => _jsx(Radio, {
|
|
291
|
+
label: option.label,
|
|
292
|
+
value: option.value,
|
|
293
|
+
isChecked: inputValues[filterPopoverCurrentFilter.id] === option.value
|
|
294
|
+
}, option.value))
|
|
295
|
+
})]
|
|
296
|
+
})]
|
|
297
|
+
})
|
|
298
|
+
})
|
|
299
|
+
})]
|
|
300
|
+
}), onChangeSearch && _jsx("form", {
|
|
301
|
+
style: {
|
|
302
|
+
width: "100%"
|
|
303
|
+
},
|
|
304
|
+
onSubmit: event => {
|
|
305
|
+
event.preventDefault();
|
|
306
|
+
if (hasSearchSubmitButton) {
|
|
307
|
+
onChangeSearch(searchValue);
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
children: _jsxs(Box, {
|
|
311
|
+
sx: {
|
|
312
|
+
display: "flex",
|
|
313
|
+
gap: 2,
|
|
314
|
+
width: "100%"
|
|
315
|
+
},
|
|
316
|
+
children: [_jsx(SearchField, {
|
|
317
|
+
value: searchValue,
|
|
318
|
+
label: "Search",
|
|
319
|
+
onClear: () => {
|
|
320
|
+
setSearchValue("");
|
|
321
|
+
onChangeSearch("");
|
|
322
|
+
},
|
|
323
|
+
onChange: ev => setSearchValue(ev.target.value)
|
|
324
|
+
}), hasSearchSubmitButton && _jsx(Box, {
|
|
325
|
+
children: _jsx(Button, {
|
|
326
|
+
variant: "primary",
|
|
327
|
+
label: "Search",
|
|
328
|
+
onClick: () => onChangeSearch(searchValue)
|
|
329
|
+
})
|
|
330
|
+
})]
|
|
331
|
+
})
|
|
332
|
+
})]
|
|
333
|
+
}), _jsxs(Box, {
|
|
334
|
+
sx: {
|
|
335
|
+
display: "flex",
|
|
336
|
+
gap: 2
|
|
337
|
+
},
|
|
338
|
+
children: [activeFilters.length > 0 && _jsx(Box, {
|
|
339
|
+
children: _jsx(Button, {
|
|
340
|
+
variant: "secondary",
|
|
341
|
+
label: "Clear filters",
|
|
342
|
+
onClick: () => clearAllFilters()
|
|
343
|
+
})
|
|
344
|
+
}), additionalActions]
|
|
345
|
+
})]
|
|
346
|
+
}), activeFilters.length > 0 && _jsx(Box, {
|
|
347
|
+
sx: {
|
|
348
|
+
borderTopWidth: 1,
|
|
349
|
+
borderTopColor: "#eeeeee",
|
|
350
|
+
borderTopStyle: "solid",
|
|
351
|
+
paddingTop: 4,
|
|
352
|
+
marginTop: 4
|
|
353
|
+
},
|
|
354
|
+
children: _jsx(TagList, {
|
|
355
|
+
children: activeFilters.map(filter => _jsx(Tag, {
|
|
356
|
+
label: `${filter.label}: ${filter.value}`,
|
|
357
|
+
onRemove: () => handleInputChange(filter.id, undefined, true)
|
|
358
|
+
}, filter.label))
|
|
359
|
+
})
|
|
360
|
+
})]
|
|
361
|
+
});
|
|
362
|
+
};
|
|
363
|
+
const MemoizedDataFilters = memo(DataFilters);
|
|
364
|
+
MemoizedDataFilters.displayName = "DataFilters";
|
|
365
|
+
export { MemoizedDataFilters as DataFilters };
|
|
366
|
+
//# sourceMappingURL=DataFilters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataFilters.js","names":["memo","useCallback","useEffect","useMemo","useRef","useState","Autocomplete","Box","TagList","Tag","SearchField","Button","CheckIcon","ChevronRightIcon","CloseCircleFilledIcon","FilterIcon","MenuItem","Paragraph","Subordinate","TextField","CheckboxGroup","Checkbox","RadioGroup","Radio","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","DataFilters","_ref","onChangeSearch","onChangeFilters","hasSearchSubmitButton","searchDelayTime","defaultSearchTerm","additionalActions","filters","filtersProp","setFilters","initialInputValues","reduce","accumulator","filter","id","value","inputValues","setInputValues","searchValue","setSearchValue","activeFilters","isFiltersMenuOpen","setIsFiltersMenuOpen","filtersMenuAnchorElement","setFiltersMenuAnchorElement","isFilterPopoverOpen","setIsFilterPopoverOpen","filterPopoverAnchorElement","setFilterPopoverAnchorElement","filterPopoverCurrentFilter","setFilterPopoverCurrentFilter","menuRef","debouncer","undefined","current","clearTimeout","setTimeout","handleInputChange","filterId","submit","arguments","length","updatedFilters","map","handleMultiSelectChange","startingValues","find","options","option","currentValues","updatedValues","includes","item","valuesToSave","sort","join","clearAllFilters","updatedInputValues","handleFilterSubmit","filterMenu","children","ariaLabel","endIcon","onClick","event","currentTarget","variant","_Menu","anchorOrigin","horizontal","vertical","transformOrigin","anchorEl","onClose","open","PaperProps","ref","latestFilterValue","f","sx","display","alignItems","justifyContent","width","minWidth","marginRight","component","label","Array","isArray","toLowerCase","gap","maxWidth","_Popover","ev","menuRect","getBoundingClientRect","clickInsideMenu","clientX","left","right","clientY","top","bottom","padding","onSubmit","preventDefault","onBlur","ro","onChange","onFocus","onInputChange","hasInitialFocus","type","endAdornment","_IconButton","size","isRequired","isDefaultChecked","_","isChecked","style","onClear","target","borderTopWidth","borderTopColor","borderTopStyle","paddingTop","marginTop","onRemove","MemoizedDataFilters","displayName"],"sources":["../../src/labs/DataFilters.tsx"],"sourcesContent":["/*!\n * Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.\n * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the \"License.\")\n *\n * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *\n * See the License for the specific language governing permissions and limitations under the License.\n */\n\nimport {\n MutableRefObject,\n ReactNode,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Autocomplete } from \"../Autocomplete\";\nimport { Box } from \"../Box\";\nimport { TagList } from \"../TagList\";\nimport { Tag } from \"../Tag\";\nimport { SearchField } from \"../SearchField\";\nimport { Button } from \"../Button\";\nimport {\n IconButton as MuiIconButton,\n Menu as MuiMenu,\n Popover as MuiPopover,\n} from \"@mui/material\";\nimport {\n CheckIcon,\n ChevronRightIcon,\n CloseCircleFilledIcon,\n FilterIcon,\n} from \"../icons.generated\";\nimport { MenuItem } from \"../MenuItem\";\nimport { Paragraph, Subordinate } from \"../Typography\";\nimport { TextField } from \"../TextField\";\nimport { CheckboxGroup } from \"../CheckboxGroup\";\nimport { Checkbox } from \"../Checkbox\";\nimport { RadioGroup } from \"../RadioGroup\";\nimport { Radio } from \"../Radio\";\nimport { MRT_ColumnDef, MRT_RowData } from \"material-react-table\";\n\nexport type DataFilterValue = string | string[] | undefined;\n\n// This is the shape of each individual filter\nexport type DataFilter = {\n /**\n * A unique ID for the filter, typically the same id\n * as the column it'll be applied to.\n */\n id: string;\n /**\n * The human-friendly name of the filter.\n */\n label: string;\n /**\n * The type of filter, which determines which filtering control\n * is shown.\n */\n variant?: MRT_ColumnDef<MRT_RowData>[\"filterVariant\"];\n /**\n * The current value of the filter. Typically a string, but\n * filters that allow for multiple selections (such as multi-select)\n * can accept an array.\n */\n value?: DataFilterValue;\n /**\n * If the filter control has preset options (such as a select or multi-select),\n * these are the options provided.\n */\n options?: Array<{ label: string; value: string }>;\n};\n\n// This is the type of the DataFilters component itself\nexport type DataFiltersProps = {\n /**\n * The callback that's fired when the search input changes\n * (either on change or on submit, based on the value of `hasSearchSubmitButton`).\n * If this is undefined, the search input will not be shown.\n */\n onChangeSearch?: (value: string) => void;\n /**\n * The callback that's fired when filter values change.\n */\n onChangeFilters?: (filters: Array<DataFilter>) => void;\n /**\n * If true, a Search button will be provided alongside the search input\n * and `onChangeSearch` will fire when the button is clicked, rather than\n * whenever the input value changes.\n */\n hasSearchSubmitButton?: boolean;\n /**\n * The debounce time, in milliseconds, for the search input firing\n * `onChangeSearch` when changed. If `hasSearchSubmitButton` is true,\n * this doesn't do anything.\n */\n searchDelayTime?: number;\n /**\n * The starting value of the search input\n */\n defaultSearchTerm?: string;\n /**\n * A slot for optional additional actions, like buttons, to be displayed\n * on the opposite side of the top row from the search and filter controls.\n */\n additionalActions?: ReactNode;\n /**\n * The filters available in the filter menu. If undefined,\n * the filter menu won't be shown.\n */\n filters?: Array<DataFilter>;\n};\n\nconst DataFilters = ({\n onChangeSearch,\n onChangeFilters,\n hasSearchSubmitButton = false,\n searchDelayTime = 200,\n defaultSearchTerm = \"\",\n additionalActions,\n filters: filtersProp = [],\n}: DataFiltersProps) => {\n const [filters, setFilters] = useState<DataFilter[]>(filtersProp);\n\n const initialInputValues = useMemo(() => {\n return filtersProp.reduce((accumulator, filter) => {\n accumulator[filter.id] = filter.value;\n return accumulator;\n }, {} as Record<string, DataFilterValue>);\n }, [filtersProp]);\n\n const [inputValues, setInputValues] = useState(initialInputValues);\n\n const [searchValue, setSearchValue] = useState<string>(defaultSearchTerm);\n const activeFilters = useMemo(() => {\n return filters.filter(\n (filter) => typeof filter.value === \"string\" && filter.value\n );\n }, [filters]);\n const [isFiltersMenuOpen, setIsFiltersMenuOpen] = useState<boolean>(false);\n const [filtersMenuAnchorElement, setFiltersMenuAnchorElement] = useState<\n HTMLElement | undefined\n >();\n const [isFilterPopoverOpen, setIsFilterPopoverOpen] =\n useState<boolean>(false);\n const [filterPopoverAnchorElement, setFilterPopoverAnchorElement] = useState<\n HTMLElement | undefined\n >();\n const [filterPopoverCurrentFilter, setFilterPopoverCurrentFilter] = useState<\n DataFilter | undefined\n >();\n\n const menuRef = useRef<HTMLDivElement>();\n\n useEffect(() => {\n onChangeFilters?.(filters);\n }, [filters, onChangeFilters]);\n\n const debouncer = useRef<NodeJS.Timeout | undefined>(undefined);\n useEffect(() => {\n if (!hasSearchSubmitButton) {\n if (debouncer.current) {\n clearTimeout(debouncer.current);\n }\n\n debouncer.current = setTimeout(() => {\n onChangeSearch?.(searchValue ?? \"\");\n }, searchDelayTime);\n }\n }, [onChangeSearch, searchValue, searchDelayTime, hasSearchSubmitButton]);\n\n const handleInputChange = useCallback(\n (filterId: string, value: DataFilterValue, submit: boolean = false) => {\n setInputValues({ ...inputValues, [filterId]: value });\n\n if (submit) {\n const updatedFilters = filtersProp.map((filter) => ({\n ...filter,\n value: filter.id === filterId ? value : inputValues[filter.id],\n }));\n\n setFilters(updatedFilters);\n }\n },\n [inputValues, filtersProp]\n );\n\n const handleMultiSelectChange = useCallback(\n (filterId: string, value: string, submit: boolean = false) => {\n const startingValues = filtersProp\n .find((filter) => filter.id === filterId)\n ?.options?.map((option) => option.value);\n const currentValues = (inputValues[filterId] ??\n startingValues) as string[];\n const updatedValues = currentValues.includes(value)\n ? currentValues.filter((item: string) => item !== value)\n : [...currentValues, value];\n const valuesToSave =\n updatedValues.sort().join() === startingValues?.sort().join()\n ? undefined\n : updatedValues;\n\n setInputValues({ ...inputValues, [filterId]: valuesToSave });\n\n if (submit) {\n const updatedFilters = filtersProp.map((filter) => ({\n ...filter,\n value: filter.id === filterId ? valuesToSave : inputValues[filter.id],\n }));\n\n setFilters(updatedFilters);\n }\n },\n [inputValues, filtersProp]\n );\n\n const clearAllFilters = useCallback(() => {\n const updatedInputValues = filtersProp.reduce((accumulator, filter) => {\n accumulator[filter.id] = undefined;\n return accumulator;\n }, {} as Record<string, DataFilterValue>);\n\n setInputValues(updatedInputValues);\n\n const updatedFilters = filtersProp.map((filter) => ({\n ...filter,\n value: undefined,\n }));\n\n setFilters(updatedFilters);\n }, [filtersProp]);\n\n const handleFilterSubmit = useCallback(() => {\n const updatedFilters = filtersProp.map((filter) => ({\n ...filter,\n value: inputValues[filter.id],\n }));\n\n setFilters(updatedFilters);\n }, [inputValues, filtersProp]);\n\n const filterMenu = useMemo(\n () => (\n <>\n <Box>\n <Button\n aria-controls={isFiltersMenuOpen ? \"filters-menu\" : undefined}\n aria-expanded={isFiltersMenuOpen ? \"true\" : undefined}\n aria-haspopup=\"true\"\n ariaLabel=\"Filters\"\n endIcon={<FilterIcon />}\n onClick={(event) => {\n setFiltersMenuAnchorElement(event.currentTarget);\n setIsFiltersMenuOpen(true);\n }}\n variant=\"secondary\"\n />\n </Box>\n\n <MuiMenu\n anchorOrigin={{ horizontal: \"left\", vertical: \"bottom\" }}\n transformOrigin={{ horizontal: \"left\", vertical: \"top\" }}\n id=\"filters-menu\"\n anchorEl={filtersMenuAnchorElement}\n onClose={() => setIsFiltersMenuOpen(false)}\n open={isFiltersMenuOpen}\n PaperProps={{\n ref: menuRef as MutableRefObject<HTMLDivElement>,\n }}\n >\n {filtersProp.map((filter) => {\n // Unintuitively, we can't just use filter.value to grab the filter value.\n // `filter` is the initial set of filters provided to the comoponent, so its\n // value prop may not reflect the current value of the filter.\n const latestFilterValue = filters.find(\n (f) => f.id === filter.id\n )?.value;\n\n return (\n <MenuItem\n key={filter.id}\n onClick={(event) => {\n setIsFilterPopoverOpen(true);\n setFilterPopoverAnchorElement(event.currentTarget);\n setFilterPopoverCurrentFilter(filter);\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n minWidth: 180,\n }}\n >\n <Box sx={{ marginRight: 2 }}>\n <Paragraph component=\"div\">{filter.label}</Paragraph>\n <Subordinate component=\"div\">\n {!latestFilterValue ||\n (Array.isArray(latestFilterValue) &&\n latestFilterValue.length === 0)\n ? `Any ${filter.label.toLowerCase()}`\n : Array.isArray(latestFilterValue)\n ? `${latestFilterValue.length} selected`\n : latestFilterValue}\n </Subordinate>\n </Box>\n <ChevronRightIcon />\n </Box>\n </MenuItem>\n );\n })}\n </MuiMenu>\n </>\n ),\n [isFiltersMenuOpen, filtersMenuAnchorElement, filtersProp, filters]\n );\n\n return (\n <Box>\n {/* Upper section */}\n <Box sx={{ display: \"flex\", justifyContent: \"space-between\" }}>\n {/* Upper section left (filters and search) */}\n <Box sx={{ display: \"flex\", gap: 2, width: \"50%\", maxWidth: 480 }}>\n {/* Filter menu */}\n {filters.length > 0 && (\n <>\n {filterMenu}\n {/* Filter popover */}\n <MuiPopover\n anchorEl={filterPopoverAnchorElement}\n open={isFilterPopoverOpen}\n anchorOrigin={{ vertical: \"top\", horizontal: \"right\" }}\n onClose={(ev: MouseEvent) => {\n if (menuRef.current) {\n const menuRect = menuRef.current.getBoundingClientRect();\n const clickInsideMenu =\n ev.clientX >= menuRect.left &&\n ev.clientX <= menuRect.right &&\n ev.clientY >= menuRect.top &&\n ev.clientY <= menuRect.bottom;\n\n if (!clickInsideMenu) {\n setIsFiltersMenuOpen(false);\n }\n }\n\n setIsFilterPopoverOpen(false);\n }}\n >\n <Box sx={{ padding: 4, minWidth: 320 }}>\n <form\n onSubmit={(ev) => {\n ev.preventDefault();\n handleFilterSubmit();\n setIsFilterPopoverOpen(false);\n setIsFiltersMenuOpen(false);\n }}\n >\n {/* Autocomplete */}\n {filterPopoverCurrentFilter?.variant === \"autocomplete\" &&\n filterPopoverCurrentFilter?.options && (\n <Autocomplete\n label={filterPopoverCurrentFilter.label}\n value={\n (inputValues[\n filterPopoverCurrentFilter.id\n ] as string) ?? \"\"\n }\n onBlur={function ro() {}}\n onChange={function ro() {}}\n onFocus={function ro() {}}\n onInputChange={function ro() {}}\n options={filterPopoverCurrentFilter.options.map(\n (option: { label: string }) => ({\n label: option.label,\n })\n )}\n />\n )}\n {/* Text or Number */}\n {(filterPopoverCurrentFilter?.variant === \"text\" ||\n filterPopoverCurrentFilter?.variant === \"range\") && (\n <Box\n sx={{\n display: \"flex\",\n gap: 2,\n alignItems: \"flex-end\",\n }}\n >\n <Box sx={{ width: \"100%\" }}>\n <TextField\n hasInitialFocus\n label={filterPopoverCurrentFilter.label}\n type={\n filterPopoverCurrentFilter.variant === \"range\"\n ? \"number\"\n : \"text\"\n }\n value={\n (inputValues[\n filterPopoverCurrentFilter.id\n ] as string) ?? \"\"\n }\n onChange={(ev) =>\n handleInputChange(\n filterPopoverCurrentFilter.id,\n ev.currentTarget.value\n )\n }\n endAdornment={\n inputValues[filterPopoverCurrentFilter.id] && (\n <MuiIconButton\n size=\"small\"\n aria-label=\"Clear filter\"\n onClick={() => {\n handleInputChange(\n filterPopoverCurrentFilter.id,\n undefined,\n true\n );\n }}\n >\n <CloseCircleFilledIcon />\n </MuiIconButton>\n )\n }\n />\n </Box>\n <Button\n variant=\"primary\"\n endIcon={<CheckIcon />}\n type=\"submit\"\n />\n </Box>\n )}\n\n {/* Checkbox */}\n {filterPopoverCurrentFilter?.variant === \"multi-select\" &&\n filterPopoverCurrentFilter?.options && (\n <CheckboxGroup\n label={filterPopoverCurrentFilter.label}\n isRequired\n >\n {filterPopoverCurrentFilter.options.map(\n (option: { label: string; value: string }) => (\n <Checkbox\n key={option.value}\n label={option.label}\n value={option.value}\n isDefaultChecked={\n inputValues[\n filterPopoverCurrentFilter.id\n ]?.includes(option.value) ||\n inputValues[filterPopoverCurrentFilter.id] ===\n undefined\n }\n onChange={() =>\n handleMultiSelectChange(\n filterPopoverCurrentFilter.id,\n option.value,\n true\n )\n }\n />\n )\n )}\n </CheckboxGroup>\n )}\n\n {/* Radio */}\n {filterPopoverCurrentFilter?.variant === \"select\" &&\n filterPopoverCurrentFilter?.options && (\n <RadioGroup\n label={filterPopoverCurrentFilter.label}\n onChange={(_, value) =>\n handleInputChange(\n filterPopoverCurrentFilter.id,\n value,\n true\n )\n }\n >\n <Radio\n label=\"Any\"\n value={\"\"}\n isChecked={\n !inputValues[filterPopoverCurrentFilter.id]\n }\n />\n <>\n {filterPopoverCurrentFilter.options.map(\n (option: { label: string; value: string }) => (\n <Radio\n key={option.value}\n label={option.label}\n value={option.value}\n isChecked={\n inputValues[\n filterPopoverCurrentFilter.id\n ] === option.value\n }\n />\n )\n )}\n </>\n </RadioGroup>\n )}\n </form>\n </Box>\n </MuiPopover>\n </>\n )}\n\n {/* Search */}\n {onChangeSearch && (\n <form\n style={{ width: \"100%\" }}\n onSubmit={(event) => {\n event.preventDefault();\n if (hasSearchSubmitButton) {\n onChangeSearch(searchValue);\n }\n }}\n >\n <Box sx={{ display: \"flex\", gap: 2, width: \"100%\" }}>\n <SearchField\n value={searchValue}\n label=\"Search\"\n onClear={() => {\n setSearchValue(\"\");\n onChangeSearch(\"\");\n }}\n onChange={(ev) => setSearchValue(ev.target.value)}\n />\n {hasSearchSubmitButton && (\n <Box>\n <Button\n variant=\"primary\"\n label=\"Search\"\n onClick={() => onChangeSearch(searchValue)}\n />\n </Box>\n )}\n </Box>\n </form>\n )}\n </Box>\n\n {/* Upper section right (clear filters & additional actions) */}\n <Box sx={{ display: \"flex\", gap: 2 }}>\n {activeFilters.length > 0 && (\n <Box>\n <Button\n variant=\"secondary\"\n label=\"Clear filters\"\n onClick={() => clearAllFilters()}\n />\n </Box>\n )}\n {additionalActions}\n </Box>\n </Box>\n\n {/* Lower section */}\n {activeFilters.length > 0 && (\n <Box\n sx={{\n borderTopWidth: 1,\n borderTopColor: \"#eeeeee\",\n borderTopStyle: \"solid\",\n paddingTop: 4,\n marginTop: 4,\n }}\n >\n <TagList>\n {activeFilters.map((filter) => (\n <Tag\n key={filter.label}\n label={`${filter.label}: ${filter.value}`}\n onRemove={() => handleInputChange(filter.id, undefined, true)}\n />\n ))}\n </TagList>\n </Box>\n )}\n </Box>\n );\n};\n\nconst MemoizedDataFilters = memo(DataFilters);\nMemoizedDataFilters.displayName = \"DataFilters\";\n\nexport { MemoizedDataFilters as DataFilters };\n"],"mappings":"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"}
|