@carbon/ibm-products 2.0.0-rc.20 → 2.0.0-rc.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. package/README.md +17 -0
  2. package/css/index-full-carbon.css +12 -6
  3. package/css/index-full-carbon.css.map +1 -1
  4. package/css/index-full-carbon.min.css +4 -2
  5. package/css/index-full-carbon.min.css.map +1 -1
  6. package/css/index-without-carbon.css +12 -6
  7. package/css/index-without-carbon.css.map +1 -1
  8. package/css/index-without-carbon.min.css +4 -2
  9. package/css/index-without-carbon.min.css.map +1 -1
  10. package/css/index.css +12 -6
  11. package/css/index.css.map +1 -1
  12. package/css/index.min.css +4 -2
  13. package/css/index.min.css.map +1 -1
  14. package/es/components/Datagrid/Datagrid/DatagridContent.js +2 -2
  15. package/es/components/Datagrid/Datagrid/addons/Filtering/FilterFlyout.js +19 -247
  16. package/es/components/Datagrid/Datagrid/addons/Filtering/FilterPanel.js +41 -285
  17. package/es/components/Datagrid/Datagrid/addons/Filtering/FilterProvider.js +4 -4
  18. package/es/components/Datagrid/Datagrid/addons/Filtering/hooks/index.js +1 -0
  19. package/es/components/Datagrid/Datagrid/addons/Filtering/hooks/useFilters.js +310 -0
  20. package/es/components/Datagrid/Datagrid/addons/Filtering/utils.js +6 -6
  21. package/es/components/Datagrid/utils/DatagridActions.js +2 -2
  22. package/lib/components/Datagrid/Datagrid/DatagridContent.js +2 -2
  23. package/lib/components/Datagrid/Datagrid/addons/Filtering/FilterFlyout.js +22 -243
  24. package/lib/components/Datagrid/Datagrid/addons/Filtering/FilterPanel.js +47 -284
  25. package/lib/components/Datagrid/Datagrid/addons/Filtering/FilterProvider.js +4 -4
  26. package/lib/components/Datagrid/Datagrid/addons/Filtering/hooks/index.js +8 -0
  27. package/lib/components/Datagrid/Datagrid/addons/Filtering/hooks/useFilters.js +325 -0
  28. package/lib/components/Datagrid/Datagrid/addons/Filtering/utils.js +5 -5
  29. package/lib/components/Datagrid/utils/DatagridActions.js +2 -2
  30. package/package.json +2 -2
  31. package/scss/components/Datagrid/styles/_datagrid.scss +2 -4
  32. package/scss/components/OptionsTile/_options-tile.scss +10 -3
@@ -0,0 +1,310 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
+
6
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
7
+
8
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
9
+
10
+ /*
11
+ * Licensed Materials - Property of IBM
12
+ * 5724-Q36
13
+ * (c) Copyright IBM Corp. 2023
14
+ * US Government Users Restricted Rights - Use, duplication or disclosure
15
+ * restricted by GSA ADP Schedule Contract with IBM Corp.
16
+ */
17
+ import React, { useState, useRef } from 'react';
18
+ import { Checkbox, DatePicker, DatePickerInput, Dropdown, FormGroup, NumberInput, RadioButton, RadioButtonGroup, Layer } from '@carbon/react';
19
+ import { INSTANT, DATE, CHECKBOX, NUMBER, RADIO, DROPDOWN, PANEL } from '../constants';
20
+ import useInitialStateFromFilters from './useInitialStateFromFilters';
21
+ import { getInitialStateFromFilters } from '../utils';
22
+
23
+ var useFilters = function useFilters(_ref) {
24
+ var updateMethod = _ref.updateMethod,
25
+ _ref$filters = _ref.filters,
26
+ filters = _ref$filters === void 0 ? [] : _ref$filters,
27
+ setAllFilters = _ref.setAllFilters,
28
+ variation = _ref.variation;
29
+
30
+ /** State */
31
+ var _useInitialStateFromF = useInitialStateFromFilters(filters, variation),
32
+ _useInitialStateFromF2 = _slicedToArray(_useInitialStateFromF, 2),
33
+ filtersState = _useInitialStateFromF2[0],
34
+ setFiltersState = _useInitialStateFromF2[1];
35
+
36
+ var _useState = useState([]),
37
+ _useState2 = _slicedToArray(_useState, 2),
38
+ filtersObjectArray = _useState2[0],
39
+ setFiltersObjectArray = _useState2[1]; // When using batch actions we have to store the filters to then apply them later
40
+
41
+
42
+ var prevFiltersRef = useRef(JSON.stringify(filtersState));
43
+ var prevFiltersObjectArrayRef = useRef(JSON.stringify(filtersObjectArray));
44
+ /** Methods */
45
+ // If the user decides to cancel or click outside the flyout, it reverts back to the filters that were
46
+ // there when they opened the flyout
47
+
48
+ var revertToPreviousFilters = function revertToPreviousFilters() {
49
+ setFiltersState(JSON.parse(prevFiltersRef.current));
50
+ setFiltersObjectArray(JSON.parse(prevFiltersObjectArrayRef.current));
51
+ };
52
+
53
+ var reset = function reset() {
54
+ // Get the initial values for the filters
55
+ var initialFiltersState = getInitialStateFromFilters(filters, variation);
56
+ var initialFiltersObjectArray = []; // Set the state to the initial values
57
+
58
+ setFiltersState(initialFiltersState);
59
+ setFiltersObjectArray(initialFiltersObjectArray);
60
+ setAllFilters([]); // Update their respective refs so everything is in sync
61
+
62
+ prevFiltersRef.current = JSON.stringify(initialFiltersState);
63
+ prevFiltersObjectArrayRef.current = JSON.stringify(initialFiltersObjectArray);
64
+ };
65
+
66
+ var applyFilters = function applyFilters(_ref2) {
67
+ var column = _ref2.column,
68
+ value = _ref2.value,
69
+ type = _ref2.type;
70
+
71
+ // If no end date is selected return because we need the end date to do computations
72
+ if (type === DATE && value.length > 0 && !value[1]) {
73
+ return;
74
+ }
75
+
76
+ var filtersObjectArrayCopy = _toConsumableArray(filtersObjectArray); // // check if the filter already exists in the array
77
+
78
+
79
+ var filter = filtersObjectArrayCopy.find(function (item) {
80
+ return item.id === column;
81
+ }); // // if filter exists in array then update the filter's new value
82
+
83
+ if (filter) {
84
+ filter.value = value;
85
+ } else {
86
+ filtersObjectArrayCopy.push({
87
+ id: column,
88
+ value: value,
89
+ type: type
90
+ });
91
+ } // ATTENTION: this is where you would reset or remove individual filters from the filters array
92
+
93
+
94
+ if (type === CHECKBOX) {
95
+ /**
96
+ When all checkboxes of a group are all unselected the value still exists in the filtersObjectArray
97
+ This checks if all the checkboxes are selected = false and removes it from the array
98
+ */
99
+ var index = filtersObjectArrayCopy.findIndex(function (filter) {
100
+ return filter.id === column;
101
+ }); // If all the selected state is false remove from array
102
+
103
+ var shouldRemoveFromArray = filtersObjectArrayCopy[index].value.every(function (val) {
104
+ return val.selected === false;
105
+ });
106
+
107
+ if (shouldRemoveFromArray) {
108
+ filtersObjectArrayCopy.splice(index, 1);
109
+ }
110
+ } else if (type === DATE) {
111
+ if (value.length === 0) {
112
+ /**
113
+ Checks to see if the date value is an empty array, if it is that means the user wants
114
+ to reset the date filter
115
+ */
116
+ var _index = filtersObjectArrayCopy.findIndex(function (filter) {
117
+ return filter.id === column;
118
+ }); // Remove it from the filters array since there is nothing to filter
119
+
120
+
121
+ filtersObjectArrayCopy.splice(_index, 1);
122
+ }
123
+ } else if (type === DROPDOWN || type === RADIO) {
124
+ if (value === 'Any') {
125
+ /**
126
+ Checks to see if the selected value is 'Any', that means the user wants
127
+ to reset specific filter
128
+ */
129
+ var _index2 = filtersObjectArrayCopy.findIndex(function (filter) {
130
+ return filter.id === column;
131
+ }); // Remove it from the filters array
132
+
133
+
134
+ filtersObjectArrayCopy.splice(_index2, 1);
135
+ }
136
+ }
137
+
138
+ setFiltersObjectArray(filtersObjectArrayCopy); // // Automatically apply the filters if the updateMethod is instant
139
+
140
+ if (updateMethod === INSTANT) {
141
+ setAllFilters(filtersObjectArrayCopy);
142
+ }
143
+ };
144
+ /** Render the individual filter component */
145
+
146
+
147
+ var renderFilter = function renderFilter(_ref3) {
148
+ var _filtersState$column, _filtersState$column2, _filtersState$column3, _filtersState$column4;
149
+
150
+ var type = _ref3.type,
151
+ column = _ref3.column,
152
+ components = _ref3.props;
153
+ var isPanel = variation === PANEL;
154
+ var filter;
155
+
156
+ switch (type) {
157
+ case DATE:
158
+ filter = /*#__PURE__*/React.createElement(DatePicker, _extends({}, components.DatePicker, {
159
+ onChange: function onChange(value) {
160
+ var _components$DatePicke, _components$DatePicke2;
161
+
162
+ setFiltersState(_objectSpread(_objectSpread({}, filtersState), {}, _defineProperty({}, column, {
163
+ value: value,
164
+ type: type
165
+ })));
166
+ applyFilters({
167
+ column: column,
168
+ value: value,
169
+ type: type
170
+ });
171
+ (_components$DatePicke = (_components$DatePicke2 = components.DatePicker).onChange) === null || _components$DatePicke === void 0 ? void 0 : _components$DatePicke.call(_components$DatePicke2, value);
172
+ },
173
+ value: filtersState[column].value,
174
+ datePickerType: "range"
175
+ }), /*#__PURE__*/React.createElement(DatePickerInput, _extends({
176
+ placeholder: "mm/dd/yyyy",
177
+ labelText: "Start date"
178
+ }, components.DatePickerInput.start)), /*#__PURE__*/React.createElement(DatePickerInput, _extends({
179
+ placeholder: "mm/dd/yyyy",
180
+ labelText: "End date"
181
+ }, components.DatePickerInput.end)));
182
+ break;
183
+
184
+ case NUMBER:
185
+ filter = /*#__PURE__*/React.createElement(NumberInput, _extends({
186
+ step: 1,
187
+ allowEmpty: true,
188
+ hideSteppers: true
189
+ }, components.NumberInput, {
190
+ onChange: function onChange(event) {
191
+ var _components$NumberInp, _components$NumberInp2;
192
+
193
+ setFiltersState(_objectSpread(_objectSpread({}, filtersState), {}, _defineProperty({}, column, {
194
+ value: event.target.value,
195
+ type: type
196
+ })));
197
+ applyFilters({
198
+ column: column,
199
+ value: event.target.value,
200
+ type: type
201
+ });
202
+ (_components$NumberInp = (_components$NumberInp2 = components.NumberInput).onChange) === null || _components$NumberInp === void 0 ? void 0 : _components$NumberInp.call(_components$NumberInp2, event);
203
+ },
204
+ value: filtersState[column].value
205
+ }));
206
+ break;
207
+
208
+ case CHECKBOX:
209
+ filter = /*#__PURE__*/React.createElement(FormGroup, components.FormGroup, filtersState[column].value.map(function (option) {
210
+ return /*#__PURE__*/React.createElement(Checkbox, _extends({
211
+ key: option.labelText
212
+ }, option, {
213
+ onChange: function onChange(_, _ref4) {
214
+ var _option$onChange;
215
+
216
+ var isSelected = _ref4.checked;
217
+ var checkboxCopy = filtersState[column].value;
218
+ var foundCheckbox = checkboxCopy.find(function (checkbox) {
219
+ return checkbox.value === option.value;
220
+ });
221
+ foundCheckbox.selected = isSelected;
222
+ setFiltersState(_objectSpread(_objectSpread({}, filtersState), {}, _defineProperty({}, column, {
223
+ value: checkboxCopy,
224
+ type: type
225
+ })));
226
+ applyFilters({
227
+ column: column,
228
+ value: _toConsumableArray(filtersState[column].value),
229
+ type: type
230
+ });
231
+ (_option$onChange = option.onChange) === null || _option$onChange === void 0 ? void 0 : _option$onChange.call(option, isSelected);
232
+ },
233
+ checked: option.selected
234
+ }));
235
+ }));
236
+ break;
237
+
238
+ case RADIO:
239
+ filter = /*#__PURE__*/React.createElement(FormGroup, components.FormGroup, /*#__PURE__*/React.createElement(RadioButtonGroup, _extends({}, components.RadioButtonGroup, {
240
+ valueSelected: ((_filtersState$column = filtersState[column]) === null || _filtersState$column === void 0 ? void 0 : _filtersState$column.value) === '' ? 'Any' : (_filtersState$column2 = filtersState[column]) === null || _filtersState$column2 === void 0 ? void 0 : _filtersState$column2.value,
241
+ onChange: function onChange(selected) {
242
+ var _components$RadioButt, _components$RadioButt2;
243
+
244
+ setFiltersState(_objectSpread(_objectSpread({}, filtersState), {}, _defineProperty({}, column, {
245
+ value: selected,
246
+ type: type
247
+ })));
248
+ applyFilters({
249
+ column: column,
250
+ value: selected,
251
+ type: type
252
+ });
253
+ (_components$RadioButt = (_components$RadioButt2 = components.RadioButtonGroup).onChange) === null || _components$RadioButt === void 0 ? void 0 : _components$RadioButt.call(_components$RadioButt2, selected);
254
+ }
255
+ }), /*#__PURE__*/React.createElement(RadioButton, {
256
+ id: "any",
257
+ labelText: "Any",
258
+ value: "Any"
259
+ }), components.RadioButton.map(function (radio) {
260
+ var _ref5, _radio$id;
261
+
262
+ return /*#__PURE__*/React.createElement(RadioButton, _extends({
263
+ key: (_ref5 = (_radio$id = radio.id) !== null && _radio$id !== void 0 ? _radio$id : radio.labelText) !== null && _ref5 !== void 0 ? _ref5 : radio.value
264
+ }, radio));
265
+ })));
266
+ break;
267
+
268
+ case DROPDOWN:
269
+ filter = /*#__PURE__*/React.createElement(Dropdown, _extends({}, components.Dropdown, {
270
+ selectedItem: ((_filtersState$column3 = filtersState[column]) === null || _filtersState$column3 === void 0 ? void 0 : _filtersState$column3.value) === '' ? 'Any' : (_filtersState$column4 = filtersState[column]) === null || _filtersState$column4 === void 0 ? void 0 : _filtersState$column4.value,
271
+ items: ['Any'].concat(_toConsumableArray(components.Dropdown.items)),
272
+ onChange: function onChange(_ref6) {
273
+ var _components$Dropdown$, _components$Dropdown;
274
+
275
+ var selectedItem = _ref6.selectedItem;
276
+ setFiltersState(_objectSpread(_objectSpread({}, filtersState), {}, _defineProperty({}, column, {
277
+ value: selectedItem,
278
+ type: type
279
+ })));
280
+ applyFilters({
281
+ column: column,
282
+ value: selectedItem,
283
+ type: type
284
+ });
285
+ (_components$Dropdown$ = (_components$Dropdown = components.Dropdown).onChange) === null || _components$Dropdown$ === void 0 ? void 0 : _components$Dropdown$.call(_components$Dropdown, selectedItem);
286
+ }
287
+ }));
288
+ break;
289
+ }
290
+
291
+ if (isPanel) {
292
+ return /*#__PURE__*/React.createElement(Layer, null, filter);
293
+ }
294
+
295
+ return filter;
296
+ };
297
+
298
+ return {
299
+ filtersState: filtersState,
300
+ setFiltersState: setFiltersState,
301
+ prevFiltersObjectArrayRef: prevFiltersObjectArrayRef,
302
+ prevFiltersRef: prevFiltersRef,
303
+ revertToPreviousFilters: revertToPreviousFilters,
304
+ reset: reset,
305
+ renderFilter: renderFilter,
306
+ filtersObjectArray: filtersObjectArray
307
+ };
308
+ };
309
+
310
+ export default useFilters;
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { FLYOUT, PANEL } from './constants'; // This functions takes the filters passed in and makes an object to track it's state
7
+ import { CHECKBOX, DATE, DROPDOWN, FLYOUT, NUMBER, PANEL, RADIO } from './constants'; // This functions takes the filters passed in and makes an object to track it's state
8
8
 
9
9
  export var getInitialStateFromFilters = function getInitialStateFromFilters(filters) {
10
10
  var variation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : FLYOUT;
@@ -15,7 +15,7 @@ export var getInitialStateFromFilters = function getInitialStateFromFilters(filt
15
15
  column = _ref.column,
16
16
  props = _ref.props;
17
17
 
18
- if (type === 'checkbox') {
18
+ if (type === CHECKBOX) {
19
19
  initialFilterState[column] = {
20
20
  value: props.Checkbox.map(function (_ref2) {
21
21
  var id = _ref2.id,
@@ -30,22 +30,22 @@ export var getInitialStateFromFilters = function getInitialStateFromFilters(filt
30
30
  }),
31
31
  type: type
32
32
  };
33
- } else if (type === 'date') {
33
+ } else if (type === DATE) {
34
34
  initialFilterState[column] = {
35
35
  value: [null, null],
36
36
  type: type
37
37
  };
38
- } else if (type === 'number') {
38
+ } else if (type === NUMBER) {
39
39
  initialFilterState[column] = {
40
40
  value: '',
41
41
  type: type
42
42
  };
43
- } else if (type === 'radio') {
43
+ } else if (type === RADIO) {
44
44
  initialFilterState[column] = {
45
45
  value: '',
46
46
  type: type
47
47
  };
48
- } else if (type === 'dropdown') {
48
+ } else if (type === DROPDOWN) {
49
49
  initialFilterState[column] = {
50
50
  value: '',
51
51
  type: type
@@ -17,7 +17,7 @@ import { FilterContext } from '../Datagrid/addons/Filtering';
17
17
  var blockClass = "".concat(pkg.prefix, "--datagrid");
18
18
  export var DatagridActions = function DatagridActions(datagridState) {
19
19
  var _useContext = useContext(FilterContext),
20
- setLeftPanelOpen = _useContext.setLeftPanelOpen;
20
+ setPanelOpen = _useContext.setPanelOpen;
21
21
 
22
22
  var selectedFlatRows = datagridState.selectedFlatRows,
23
23
  setGlobalFilter = datagridState.setGlobalFilter,
@@ -63,7 +63,7 @@ export var DatagridActions = function DatagridActions(datagridState) {
63
63
  iconDescription: filterProps.panelIconDescription,
64
64
  className: "".concat(blockClass, "-filter-panel-open-button"),
65
65
  onClick: function onClick() {
66
- return setLeftPanelOpen(function (open) {
66
+ return setPanelOpen(function (open) {
67
67
  return !open;
68
68
  });
69
69
  },
@@ -71,7 +71,7 @@ var DatagridContent = function DatagridContent(_ref) {
71
71
  var _useContext2 = (0, _react.useContext)(_Filtering.FilterContext),
72
72
  filterTags = _useContext2.filterTags,
73
73
  EventEmitter = _useContext2.EventEmitter,
74
- leftPanelOpen = _useContext2.leftPanelOpen;
74
+ panelOpen = _useContext2.panelOpen;
75
75
 
76
76
  var activeCellId = inlineEditState.activeCellId,
77
77
  gridActive = inlineEditState.gridActive,
@@ -181,7 +181,7 @@ var DatagridContent = function DatagridContent(_ref) {
181
181
  title: gridTitle,
182
182
  description: gridDescription
183
183
  }, /*#__PURE__*/_react.default.createElement(_DatagridToolbar.default, datagridState), /*#__PURE__*/_react.default.createElement("div", {
184
- className: (0, _classnames.default)("".concat(blockClass, "__table-container"), (0, _defineProperty2.default)({}, "".concat(blockClass, "__table-container--filter-open"), leftPanelOpen)),
184
+ className: (0, _classnames.default)("".concat(blockClass, "__table-container"), (0, _defineProperty2.default)({}, "".concat(blockClass, "__table-container--filter-open"), panelOpen)),
185
185
  ref: gridAreaRef
186
186
  }, (filterProps === null || filterProps === void 0 ? void 0 : filterProps.variation) === 'panel' && /*#__PURE__*/_react.default.createElement(_Filtering.FilterPanel, (0, _extends2.default)({
187
187
  updateMethod: "batch"