@synerise/ds-table 0.60.6 → 0.60.7

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 CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.60.7](https://github.com/synerise/synerise-design/compare/@synerise/ds-table@0.60.6...@synerise/ds-table@0.60.7) (2024-12-11)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **table:** bulk selection logic ([a796815](https://github.com/synerise/synerise-design/commit/a7968157686afb989e9da096e8817913a7f27130))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [0.60.6](https://github.com/synerise/synerise-design/compare/@synerise/ds-table@0.60.5...@synerise/ds-table@0.60.6) (2024-12-04)
7
18
 
8
19
  **Note:** Version bump only for package @synerise/ds-table
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { ReactText } from 'react';
3
- import type { Props } from './TableSelection.types';
3
+ import { Props } from './TableSelection.types';
4
4
  declare const TableSelection: <T extends {
5
5
  key: ReactText;
6
6
  children?: T[] | undefined;
@@ -10,8 +10,9 @@ import Tooltip from '@synerise/ds-tooltip';
10
10
  import Icon, { OptionVerticalM } from '@synerise/ds-icon';
11
11
  import * as S from '../Table.styles';
12
12
  import { SELECTION_ALL, SELECTION_INVERT } from '../Table';
13
- import { useRowKey } from '../hooks/useRowKey';
14
13
  import { isRecordSelectable } from '../utils';
14
+ import { useRowKey } from '../hooks/useRowKey';
15
+ import { useBulkSelectionCount } from '../hooks/useBulkSelection';
15
16
  var TableSelection = function TableSelection(_ref) {
16
17
  var dataSource = _ref.dataSource,
17
18
  dataSourceFull = _ref.dataSourceFull,
@@ -57,12 +58,12 @@ var TableSelection = function TableSelection(_ref) {
57
58
  if (Array.isArray(rowChildren)) {
58
59
  keys = [].concat(keys, rowChildren.reduce(function (acc, child) {
59
60
  var key = getRowKey(child);
60
- return key && isRecordSelectable(child, checkRowSelectionStatus) ? [].concat(acc, [key]) : acc;
61
+ return key && (isRecordSelectable(child, checkRowSelectionStatus) || selectedRowKeys.includes(key)) ? [].concat(acc, [key]) : acc;
61
62
  }, []));
62
63
  }
63
64
  if (!Array.isArray(rowChildren) || selection.independentSelectionExpandedRows) {
64
65
  var key = getRowKey(record);
65
- keys = key !== undefined && isRecordSelectable(record, checkRowSelectionStatus) ? [].concat(keys, [key]) : [].concat(keys);
66
+ keys = key !== undefined && (isRecordSelectable(record, checkRowSelectionStatus) || selectedRowKeys.includes(key)) ? [].concat(keys, [key]) : [].concat(keys);
66
67
  }
67
68
  });
68
69
  var uniqueKeys = Array.from(new Set(keys));
@@ -72,45 +73,40 @@ var TableSelection = function TableSelection(_ref) {
72
73
  }, [childrenColumnName, dataSource, selection, isShowingSubset, getRowsForKeys, getRowKey]);
73
74
  var unselectAll = useCallback(function () {
74
75
  if (selection) {
75
- if (isShowingSubset) {
76
- var selectedRowKeys = selection.selectedRowKeys;
77
- var keysToUnselect = [];
78
- dataSource.forEach(function (record) {
79
- var rowChildren = record[childrenColumnName];
80
- if (Array.isArray(rowChildren)) {
81
- keysToUnselect = [].concat(keysToUnselect, rowChildren.reduce(function (acc, child) {
82
- var key = getRowKey(child);
83
- return key ? [].concat(acc, [key]) : acc;
84
- }, []));
85
- }
86
- if (!Array.isArray(rowChildren) || selection.independentSelectionExpandedRows) {
87
- var key = getRowKey(record);
88
- keysToUnselect = key !== undefined ? [].concat(keysToUnselect, [key]) : [].concat(keysToUnselect);
89
- }
90
- });
91
- var keysLeft = selectedRowKeys.filter(function (key) {
92
- return !keysToUnselect.includes(key);
93
- });
94
- var rows = getRowsForKeys(keysLeft);
95
- selection.onChange(keysLeft, rows);
96
- } else {
97
- selection.onChange([], []);
98
- }
76
+ var selectedRowKeys = selection.selectedRowKeys,
77
+ checkRowSelectionStatus = selection.checkRowSelectionStatus;
78
+ var keysToUnselect = [];
79
+ dataSource.forEach(function (record) {
80
+ var rowChildren = record[childrenColumnName];
81
+ if (Array.isArray(rowChildren)) {
82
+ keysToUnselect = [].concat(keysToUnselect, rowChildren.reduce(function (acc, child) {
83
+ var key = getRowKey(child);
84
+ return key && isRecordSelectable(child, checkRowSelectionStatus) ? [].concat(acc, [key]) : acc;
85
+ }, []));
86
+ }
87
+ if (!Array.isArray(rowChildren) || selection.independentSelectionExpandedRows) {
88
+ var key = getRowKey(record);
89
+ keysToUnselect = key !== undefined && isRecordSelectable(record, checkRowSelectionStatus) ? [].concat(keysToUnselect, [key]) : [].concat(keysToUnselect);
90
+ }
91
+ });
92
+ var keysLeft = selectedRowKeys.filter(function (key) {
93
+ return !keysToUnselect.includes(key);
94
+ });
95
+ var rows = getRowsForKeys(keysLeft);
96
+ selection.onChange(keysLeft, rows);
99
97
  }
100
- }, [dataSource, getRowKey, getRowsForKeys, isShowingSubset, selection, childrenColumnName]);
98
+ }, [dataSource, getRowKey, getRowsForKeys, selection, childrenColumnName]);
101
99
  var getSelectableChildren = useCallback(function (children) {
102
- var selectionStatusValidator = selection && 'checkRowSelectionStatus' in selection ? selection.checkRowSelectionStatus : undefined;
100
+ var selectionStatusValidator = (selection == null ? void 0 : selection.checkRowSelectionStatus) || undefined;
103
101
  return children ? children.filter(function (child) {
104
102
  return isRecordSelectable(child, selectionStatusValidator) && getRowKey(child) !== undefined;
105
103
  }) : [];
106
- },
107
- // eslint-disable-next-line react-hooks/exhaustive-deps
108
- [getRowKey, selection == null ? void 0 : selection.checkRowSelectionStatus]);
104
+ }, [getRowKey, selection == null ? void 0 : selection.checkRowSelectionStatus]);
109
105
  var selectInvert = useCallback(function () {
110
106
  if (dataSource && selection) {
111
107
  var selectedRowKeys = selection.selectedRowKeys,
112
108
  checkRowSelectionStatus = selection.checkRowSelectionStatus;
113
- var keys = isShowingSubset ? [].concat(selectedRowKeys) : [];
109
+ var keys = [].concat(selectedRowKeys);
114
110
  dataSource.forEach(function (record) {
115
111
  var rowChildren = record[childrenColumnName];
116
112
  var hasChildren = Array.isArray(rowChildren);
@@ -119,7 +115,7 @@ var TableSelection = function TableSelection(_ref) {
119
115
  selectableChildren.forEach(function (child) {
120
116
  var key = getRowKey(child);
121
117
  if (selectedRowKeys.includes(key)) {
122
- if (isShowingSubset) keys.splice(keys.indexOf(key), 1);
118
+ keys.splice(keys.indexOf(key), 1);
123
119
  } else {
124
120
  keys = [].concat(keys, [key]);
125
121
  }
@@ -127,9 +123,11 @@ var TableSelection = function TableSelection(_ref) {
127
123
  }
128
124
  if (!selectableChildren || selection.independentSelectionExpandedRows) {
129
125
  var key = getRowKey(record);
126
+ var isSelectable = isRecordSelectable(record, checkRowSelectionStatus);
127
+ if (!isSelectable) return;
130
128
  if (selectedRowKeys.includes(key)) {
131
- if (isShowingSubset) keys.splice(keys.indexOf(key), 1);
132
- } else if (isRecordSelectable(record, checkRowSelectionStatus)) {
129
+ keys.splice(keys.indexOf(key), 1);
130
+ } else {
133
131
  keys = [].concat(keys, [key]);
134
132
  }
135
133
  }
@@ -137,50 +135,29 @@ var TableSelection = function TableSelection(_ref) {
137
135
  var rows = getRowsForKeys(keys);
138
136
  selection.onChange(keys, rows);
139
137
  }
140
- }, [childrenColumnName, dataSource, selection, isShowingSubset, getRowsForKeys, getSelectableChildren, getRowKey]);
141
- var isEmpty = useMemo(function () {
142
- return dataSource.length === 0;
143
- }, [dataSource]);
144
- var allSelectableRecordsCount = useMemo(function () {
145
- if (isEmpty || !selection) return 0;
146
- var independentSelectionExpandedRows = selection.independentSelectionExpandedRows,
147
- checkRowSelectionStatus = selection.checkRowSelectionStatus;
148
- return dataSource.reduce(function (count, record) {
149
- var isSelectable = +isRecordSelectable(record, checkRowSelectionStatus);
150
- var rowChildren = record[childrenColumnName];
151
- if (independentSelectionExpandedRows) {
152
- return Array.isArray(rowChildren) ? count + getSelectableChildren(rowChildren).length + isSelectable : count + isSelectable;
153
- }
154
- return Array.isArray(rowChildren) ? count + getSelectableChildren(rowChildren).length : count + isSelectable;
155
- }, 0);
156
- }, [childrenColumnName, dataSource, getSelectableChildren, isEmpty, selection]);
157
- var allSelected = useMemo(function () {
158
- if (isEmpty || !selection) return false;
159
- var selectedRowKeys = selection.selectedRowKeys;
160
- var selectedKeysInDataSourceCount = isShowingSubset ? dataSource.reduce(function (count, record) {
161
- var rowChildren = record[childrenColumnName];
162
- if (Array.isArray(rowChildren)) {
163
- return rowChildren.reduce(function (childCount, child) {
164
- var key = getRowKey(child);
165
- return selectedRowKeys.includes(key) ? childCount + 1 : childCount;
166
- }, 0);
167
- }
168
- if (!Array.isArray(rowChildren) || selection.independentSelectionExpandedRows) {
169
- var key = getRowKey(record);
170
- return selectedRowKeys.includes(key) ? count + 1 : count;
171
- }
172
- return count;
173
- }, 0) : selectedRowKeys.length;
174
- return allSelectableRecordsCount === selectedKeysInDataSourceCount;
175
- }, [isEmpty, selection, isShowingSubset, dataSource, allSelectableRecordsCount, childrenColumnName, getRowKey]);
176
- var selectionTooltipTitle = !allSelected ? locale == null ? void 0 : locale.selectAllTooltip : locale == null ? void 0 : locale.unselectAll;
138
+ }, [childrenColumnName, dataSource, selection, getRowsForKeys, getSelectableChildren, getRowKey]);
139
+ var _useBulkSelectionCoun = useBulkSelectionCount({
140
+ dataSource: dataSource,
141
+ selection: selection,
142
+ childrenColumnName: childrenColumnName,
143
+ rowKey: rowKey
144
+ }),
145
+ allRecordsCount = _useBulkSelectionCoun.allRecordsCount,
146
+ selectableRecordsCount = _useBulkSelectionCoun.selectableRecordsCount,
147
+ selectableAndSelectedRecordsCount = _useBulkSelectionCoun.selectableAndSelectedRecordsCount,
148
+ selectedRecordsCount = _useBulkSelectionCoun.selectedRecordsCount;
149
+ var isIndeterminate = selectedRecordsCount > 0 && allRecordsCount !== selectableRecordsCount;
150
+ var disabledBulkSelection = allRecordsCount === 0 || selectableRecordsCount === 0;
151
+ var isChecked = !disabledBulkSelection && allRecordsCount === selectableRecordsCount;
152
+ var isAllSelected = selectableRecordsCount === selectableAndSelectedRecordsCount;
153
+ var selectionTooltipTitle = !isAllSelected ? locale == null ? void 0 : locale.selectAllTooltip : locale == null ? void 0 : locale.unselectAll;
177
154
  var menuDataSource = useMemo(function () {
178
155
  var _selection$selections;
179
156
  return selection == null || (_selection$selections = selection.selections) == null ? void 0 : _selection$selections.filter(Boolean).map(function (selectionMenuElement) {
180
157
  switch (selectionMenuElement) {
181
158
  case SELECTION_ALL:
182
159
  {
183
- return !allSelected ? {
160
+ return !isAllSelected ? {
184
161
  onClick: selectAll,
185
162
  text: locale == null ? void 0 : locale.selectAll
186
163
  } : {
@@ -204,25 +181,25 @@ var TableSelection = function TableSelection(_ref) {
204
181
  }
205
182
  }
206
183
  });
207
- }, [allSelected, locale == null ? void 0 : locale.selectAll, locale == null ? void 0 : locale.selectInvert, locale == null ? void 0 : locale.unselectAll, selectAll, selectInvert, selection == null ? void 0 : selection.selections, unselectAll]);
184
+ }, [isAllSelected, locale == null ? void 0 : locale.selectAll, locale == null ? void 0 : locale.selectInvert, locale == null ? void 0 : locale.unselectAll, selectAll, selectInvert, selection == null ? void 0 : selection.selections, unselectAll]);
208
185
  return selection != null && selection.selectedRowKeys ? /*#__PURE__*/React.createElement(S.Selection, {
209
186
  "data-popup-container": true
210
187
  }, /*#__PURE__*/React.createElement(Tooltip, {
211
188
  title: selectionTooltipTitle
212
189
  }, /*#__PURE__*/React.createElement(Button.Checkbox, {
213
- disabled: isEmpty || allSelectableRecordsCount === 0,
190
+ disabled: disabledBulkSelection,
214
191
  "data-testid": "ds-table-batch-selection-button",
215
- checked: allSelected && allSelectableRecordsCount > 0,
216
- onChange: function onChange(isChecked) {
217
- if (isChecked) {
192
+ checked: isChecked,
193
+ onChange: function onChange() {
194
+ if (!isAllSelected) {
218
195
  selectAll();
219
196
  } else {
220
197
  unselectAll();
221
198
  }
222
199
  },
223
- indeterminate: (selection == null ? void 0 : selection.selectedRowKeys.length) > 0 && !allSelected
200
+ indeterminate: isIndeterminate
224
201
  })), (selection == null ? void 0 : selection.selections) && /*#__PURE__*/React.createElement(Dropdown, {
225
- disabled: isEmpty || allSelectableRecordsCount === 0,
202
+ disabled: disabledBulkSelection,
226
203
  trigger: ['click'],
227
204
  overlay: /*#__PURE__*/React.createElement(S.SelectionMenu, {
228
205
  dataSource: menuDataSource
@@ -1,12 +1,12 @@
1
- import React from 'react';
1
+ import { ReactText } from 'react';
2
2
  import { RowSelection, Locale } from '../Table.types';
3
- export interface Props<T extends {
4
- key: React.ReactText;
5
- }> {
3
+ export type Props<T extends {
4
+ key: ReactText;
5
+ }> = {
6
6
  selection?: RowSelection<T>;
7
7
  dataSource: T[];
8
8
  dataSourceFull?: T[];
9
9
  locale?: Locale;
10
10
  rowKey?: Function | string;
11
11
  childrenColumnName: string;
12
- }
12
+ };
@@ -0,0 +1 @@
1
+ export * from './useBulkSelection';
@@ -0,0 +1 @@
1
+ export * from './useBulkSelection';
@@ -0,0 +1,12 @@
1
+ import { ReactText } from 'react';
2
+ import { Props as TableSelectionType } from '../../TableHeader/TableSelection.types';
3
+ type BulkSelectionType = {
4
+ allRecordsCount: number;
5
+ selectableRecordsCount: number;
6
+ selectableAndSelectedRecordsCount: number;
7
+ selectedRecordsCount: number;
8
+ };
9
+ export declare const useBulkSelectionCount: <T extends {
10
+ key: ReactText;
11
+ }>({ dataSource, selection, childrenColumnName, rowKey, }: TableSelectionType<T>) => BulkSelectionType;
12
+ export {};
@@ -0,0 +1,69 @@
1
+ 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; }
2
+ 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; }
3
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
5
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
+ import { useCallback, useMemo } from 'react';
7
+ import { useRowKey } from '../useRowKey';
8
+ import { isRecordSelectable } from '../../utils';
9
+ export var useBulkSelectionCount = function useBulkSelectionCount(_ref) {
10
+ var dataSource = _ref.dataSource,
11
+ selection = _ref.selection,
12
+ childrenColumnName = _ref.childrenColumnName,
13
+ rowKey = _ref.rowKey;
14
+ var _useRowKey = useRowKey(rowKey),
15
+ getRowKey = _useRowKey.getRowKey;
16
+ var getSelectableChildren = useCallback(function (children) {
17
+ var selectionStatusValidator = (selection == null ? void 0 : selection.checkRowSelectionStatus) || undefined;
18
+ return children ? children.filter(function (child) {
19
+ return isRecordSelectable(child, selectionStatusValidator) && getRowKey(child) !== undefined;
20
+ }) : [];
21
+ }, [getRowKey, selection == null ? void 0 : selection.checkRowSelectionStatus]);
22
+ var result = useMemo(function () {
23
+ var initialValue = {
24
+ selectableRecordsCount: 0,
25
+ selectableAndSelectedRecordsCount: 0,
26
+ selectedRecordsCount: 0
27
+ };
28
+ if (!dataSource.length || !selection) return initialValue;
29
+ var selectedRowKeys = selection.selectedRowKeys,
30
+ independentSelectionExpandedRows = selection.independentSelectionExpandedRows,
31
+ checkRowSelectionStatus = selection.checkRowSelectionStatus;
32
+ return dataSource.reduce(function (count, record) {
33
+ var isSelectable = +isRecordSelectable(record, checkRowSelectionStatus);
34
+ var rowChildren = record[childrenColumnName];
35
+ var selectableRecordsCount = count.selectableRecordsCount,
36
+ selectableAndSelectedRecordsCount = count.selectableAndSelectedRecordsCount,
37
+ selectedRecordsCount = count.selectedRecordsCount;
38
+ // selectable
39
+ if (independentSelectionExpandedRows) {
40
+ Array.isArray(rowChildren) ? selectableRecordsCount += getSelectableChildren(rowChildren).length + isSelectable : selectableRecordsCount += isSelectable;
41
+ } else {
42
+ Array.isArray(rowChildren) ? selectableRecordsCount += getSelectableChildren(rowChildren).length : selectableRecordsCount += isSelectable;
43
+ }
44
+ if (Array.isArray(rowChildren)) {
45
+ selectedRecordsCount += rowChildren.reduce(function (childCount, child) {
46
+ var key = getRowKey(child);
47
+ return selectedRowKeys.includes(key) ? childCount + 1 : childCount;
48
+ }, 0);
49
+ selectableAndSelectedRecordsCount += rowChildren.reduce(function (childCount, child) {
50
+ var key = getRowKey(child);
51
+ return selectedRowKeys.includes(key) && isRecordSelectable(child, checkRowSelectionStatus) ? childCount + 1 : childCount;
52
+ }, 0);
53
+ }
54
+ if (!Array.isArray(rowChildren) || selection.independentSelectionExpandedRows) {
55
+ var key = getRowKey(record);
56
+ selectedRecordsCount += selectedRowKeys.includes(key) ? 1 : 0;
57
+ selectableAndSelectedRecordsCount += selectedRowKeys.includes(key) && isRecordSelectable(record, checkRowSelectionStatus) ? 1 : 0;
58
+ }
59
+ return {
60
+ selectableRecordsCount: selectableRecordsCount,
61
+ selectableAndSelectedRecordsCount: selectableAndSelectedRecordsCount,
62
+ selectedRecordsCount: selectedRecordsCount
63
+ };
64
+ }, initialValue);
65
+ }, [childrenColumnName, dataSource, getRowKey, getSelectableChildren, selection]);
66
+ return _objectSpread({}, result, {
67
+ allRecordsCount: dataSource.length
68
+ });
69
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-table",
3
- "version": "0.60.6",
3
+ "version": "0.60.7",
4
4
  "description": "Table UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "synerise/synerise-design",
@@ -34,12 +34,12 @@
34
34
  ],
35
35
  "types": "dist/index.d.ts",
36
36
  "dependencies": {
37
- "@synerise/ds-alert": "^0.8.41",
37
+ "@synerise/ds-alert": "^0.8.42",
38
38
  "@synerise/ds-badge": "^0.8.22",
39
39
  "@synerise/ds-button": "^0.22.0",
40
40
  "@synerise/ds-button-group": "^0.7.26",
41
41
  "@synerise/ds-checkbox": "^0.12.20",
42
- "@synerise/ds-column-manager": "^0.13.6",
42
+ "@synerise/ds-column-manager": "^0.13.7",
43
43
  "@synerise/ds-data-format": "^0.6.1",
44
44
  "@synerise/ds-dropdown": "^0.18.27",
45
45
  "@synerise/ds-flag": "^0.5.3",
@@ -77,5 +77,5 @@
77
77
  "react-intl": ">=3.12.0 <= 6.8",
78
78
  "styled-components": "5.0.1"
79
79
  },
80
- "gitHead": "03c0625fb7b5baaa35f6633a425fb803469b6a20"
80
+ "gitHead": "05aa1b6f2038d83cc94b2270fd495c8df2c09dd5"
81
81
  }