@geotab/zenith 3.16.0-nightly.20261005.f8d767e → 3.17.0-beta.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/README.md +28 -0
- package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +3 -1
- package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.js +39 -4
- package/dist/table/children/useTableChildren.d.ts +3 -2
- package/dist/table/children/useTableChildren.js +31 -7
- package/dist/table/selectable/interfaces.d.ts +3 -8
- package/dist/table/selectable/useSelectableRows.d.ts +3 -0
- package/dist/table/selectable/useSelectableRows.js +37 -29
- package/dist/table/selectable/utils/calculateSelectionState.js +4 -7
- package/dist/table/selectable/utils/getCurrentPageSelection.js +8 -5
- package/dist/table/table.d.ts +1 -2
- package/dist/table/table.js +31 -24
- package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +3 -1
- package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.js +39 -4
- package/esm/table/children/useTableChildren.d.ts +3 -2
- package/esm/table/children/useTableChildren.js +31 -7
- package/esm/table/selectable/interfaces.d.ts +3 -8
- package/esm/table/selectable/useSelectableRows.d.ts +3 -0
- package/esm/table/selectable/useSelectableRows.js +35 -28
- package/esm/table/selectable/utils/calculateSelectionState.js +4 -7
- package/esm/table/selectable/utils/getCurrentPageSelection.js +9 -6
- package/esm/table/table.d.ts +1 -2
- package/esm/table/table.js +15 -8
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -51,6 +51,34 @@ Zenith has English and 32 non-English locale dictionaries, including Arabic (`ar
|
|
|
51
51
|
|
|
52
52
|
## Change log
|
|
53
53
|
|
|
54
|
+
### 3.17.0
|
|
55
|
+
|
|
56
|
+
- [MYG-138984](https://geotab.atlassian.net/browse/MYG-138984): Add Primary, Destructive, and TertiaryDestructive trigger variants to `Dropdown` / `FilterButton`
|
|
57
|
+
- [MYG-138985](https://geotab.atlassian.net/browse/MYG-138985): Add optional separators below single- and multi-select `Dropdown` items
|
|
58
|
+
- [MYG-138983](https://geotab.atlassian.net/browse/MYG-138983): Add destructive styling to single-select `Dropdown` items
|
|
59
|
+
- [MYG-105567](https://geotab.atlassian.net/browse/MYG-105567): Add `sortSelectedToTop` to float selected `Dropdown` options to the top when opened
|
|
60
|
+
- [MYG-147075](https://geotab.atlassian.net/browse/MYG-147075): Show full single-select `Dropdown` option labels on hover
|
|
61
|
+
- [MYG-147879](https://geotab.atlassian.net/browse/MYG-147879): Add loaded/total counts and an end-of-results message for desktop infinite-scroll tables; improve row-loading announcements
|
|
62
|
+
- [MYG-130553](https://geotab.atlassian.net/browse/MYG-130553): Add progressive loading of nested `Table` rows with a +N more control, plus the `useShowMore` hook and `DEFAULT_SHOW_MORE_CAP` export
|
|
63
|
+
- [MYG-148443](https://geotab.atlassian.net/browse/MYG-148443): Add seven sequential and seven diverging data-visualization color tokens
|
|
64
|
+
- [MYG-129023](https://geotab.atlassian.net/browse/MYG-129023): Support destructive menu items and open-in-new-page indicators, including collapsed `Header` actions
|
|
65
|
+
- [MYG-142469](https://geotab.atlassian.net/browse/MYG-142469): Export `PillBox`, `DEFAULT_MAX_PILLS`, `IPillData`, and `IPillBox` from the package entry point
|
|
66
|
+
- [MYG-139327](https://geotab.atlassian.net/browse/MYG-139327): Add mouse-drag and Shift-click range selection to `Table` and selectable `DataGrid` rows, including expanded nested rows
|
|
67
|
+
- [MYG-142234](https://geotab.atlassian.net/browse/MYG-142234): Add opt-in cross-page Select All exclusions when individual rows or the current-page header are unchecked
|
|
68
|
+
- [MYG-149449](https://geotab.atlassian.net/browse/MYG-149449): Preserve cross-page Select All and existing exclusions during drag and Shift-click range selection; correct exclusion counts, childless nested-row selection, and global selection commands; exclude loading and show-more placeholders from fully loaded selection counts
|
|
69
|
+
- [MYG-148015](https://geotab.atlassian.net/browse/MYG-148015): Make cross-page exclusions opt-in through `selectable.allowExclusions` while preserving the existing selection contract by default; correct selection feedback during reloads and empty-selection bulk actions
|
|
70
|
+
- [MYG-147924](https://geotab.atlassian.net/browse/MYG-147924): Preserve `Table` selection during append loading and refreshes
|
|
71
|
+
- [MYG-143552](https://geotab.atlassian.net/browse/MYG-143552): Keep `Waiting` overlays covering scrollable content, improve spinner positioning, and block keyboard interaction with sibling content while the overlay is visible
|
|
72
|
+
- [MYG-148751](https://geotab.atlassian.net/browse/MYG-148751): Remove special bold styling from the first `Table` / `DataGrid` column header
|
|
73
|
+
- [MYG-113389](https://geotab.atlassian.net/browse/MYG-113389): Reduce form label/control gaps and correct `Dropdown` form-field styling and width
|
|
74
|
+
- [MYG-148954](https://geotab.atlassian.net/browse/MYG-148954): Close `PillExpandable` popovers on user scrolling while ignoring browser scroll-anchoring adjustments
|
|
75
|
+
- [MYG-149705](https://geotab.atlassian.net/browse/MYG-149705): Fix RTL tab keyboard navigation, focus scrolling, and tab/pill/chip/accordion styling
|
|
76
|
+
- [MYG-145500](https://geotab.atlassian.net/browse/MYG-145500): Allow `Tabs` to associate tabs with explicitly named panels through `ariaControls`, including panels outside the default tab layout
|
|
77
|
+
- [MYG-148568](https://geotab.atlassian.net/browse/MYG-148568): Forward ARIA attributes to the appropriate input elements in `DropdownRaw` and `TextInputRaw`
|
|
78
|
+
- [MYG-150227](https://geotab.atlassian.net/browse/MYG-150227): Make `FormLayout` positioning deterministic for fractional and invalid positions
|
|
79
|
+
- [MYG-145929](https://geotab.atlassian.net/browse/MYG-145929): Keep disabled `Button` and related menu/header buttons keyboard-focusable while preventing activation
|
|
80
|
+
- [MYG-148696](https://geotab.atlassian.net/browse/MYG-148696): Improve `PillExpandable` popover focus management and accessible trigger/content relationships
|
|
81
|
+
|
|
54
82
|
### 3.16.0
|
|
55
83
|
|
|
56
84
|
- Add `Tooltip.InlineTrigger` subcomponent for inline tooltip triggers
|
|
@@ -12,6 +12,8 @@ export interface IBulkActionsProps extends IZenComponentProps {
|
|
|
12
12
|
* even when `selected` is 0 (i.e., cross-page "select all" is active).
|
|
13
13
|
*/
|
|
14
14
|
allSelected?: boolean;
|
|
15
|
+
/** Show a selection label without a count when the selected total is unknown. */
|
|
16
|
+
selectionCountUnknown?: boolean;
|
|
15
17
|
onClearSelection: () => void;
|
|
16
18
|
onSelectAll?: () => void;
|
|
17
19
|
gridType?: DeviceType;
|
|
@@ -23,7 +25,7 @@ export interface IBulkActions extends IBulkActionsProps {
|
|
|
23
25
|
ActionButton: (props: IBulkActionButton) => ReactNode;
|
|
24
26
|
}
|
|
25
27
|
export declare const BulkActions: {
|
|
26
|
-
({ selected, allSelected, className, onClearSelection, onSelectAll, gridType, children, turnOffSelectAll }: IBulkActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
({ selected, allSelected, selectionCountUnknown, className, onClearSelection, onSelectAll, gridType, children, turnOffSelectAll }: IBulkActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
27
29
|
ActionLink: ({ title, icon, link, disabled, type, ref }: IBulkActionLink) => import("react/jsx-runtime").JSX.Element;
|
|
28
30
|
ActionButton: ({ title, icon, clickHandler, onClick, disabled, type, ref }: IBulkActionButton) => import("react/jsx-runtime").JSX.Element;
|
|
29
31
|
translations: string[];
|
|
@@ -8,6 +8,39 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
});
|
|
9
9
|
exports.BulkActions = void 0;
|
|
10
10
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
11
|
+
injectString("cs", "Selected", "Vybr\xE1no");
|
|
12
|
+
injectString("da-DK", "Selected", "Valgt");
|
|
13
|
+
injectString("de", "Selected", "Ausgew\xE4hlt");
|
|
14
|
+
injectString("en", "Selected", "Selected");
|
|
15
|
+
injectString("es", "Selected", "Seleccionado");
|
|
16
|
+
injectString("fi-FI", "Selected", "Valittu");
|
|
17
|
+
injectString("fr", "Selected", "S\xE9lectionn\xE9");
|
|
18
|
+
injectString("fr-FR", "Selected", "S\xE9lectionn\xE9");
|
|
19
|
+
injectString("hu-HU", "Selected", "Kiv\xE1lasztott");
|
|
20
|
+
injectString("id", "Selected", "Dipilih");
|
|
21
|
+
injectString("it", "Selected", "Selezionato");
|
|
22
|
+
injectString("ja", "Selected", "\u9078\u629E\u8ECA\u4E21");
|
|
23
|
+
injectString("ko-KR", "Selected", "\uC120\uD0DD\uB428");
|
|
24
|
+
injectString("ms", "Selected", "Dipilih");
|
|
25
|
+
injectString("nb-NO", "Selected", "Valgt");
|
|
26
|
+
injectString("nl", "Selected", "Geselecteerd");
|
|
27
|
+
injectString("pl", "Selected", "Wybrano");
|
|
28
|
+
injectString("pt-BR", "Selected", "Selecionado");
|
|
29
|
+
injectString("pt-PT", "Selected", "Selecionado");
|
|
30
|
+
injectString("sk-SK", "Selected", "Vybran\xE9");
|
|
31
|
+
injectString("sv", "Selected", "Valda");
|
|
32
|
+
injectString("th", "Selected", "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27");
|
|
33
|
+
injectString("tr", "Selected", "Se\xE7ildi");
|
|
34
|
+
injectString("zh-Hans", "Selected", "\u9009\u4E2D\u7684");
|
|
35
|
+
injectString("zh-TW", "Selected", "\u5DF2\u9078\u53D6");
|
|
36
|
+
injectString("ro-RO", "Selected", "Selec\u021Bie");
|
|
37
|
+
injectString("ar-001", "Selected", "\u0627\u0644\u0645\u062D\u062F\u062F");
|
|
38
|
+
injectString("lt-LT", "Selected", "Pasirinkta");
|
|
39
|
+
injectString("lv-LV", "Selected", "Atlas\u012Bts");
|
|
40
|
+
injectString("ka-GE", "Selected", "\u10D0\u10E0\u10E9\u10D4\u10E3\u10DA\u10D8");
|
|
41
|
+
injectString("el-GR", "Selected", "\u0395\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03B1");
|
|
42
|
+
injectString("et-EE", "Selected", "Valitud");
|
|
43
|
+
injectString("bg-BG", "Selected", "\u0418\u0437\u0431\u0440\u0430\u043D\u0438");
|
|
11
44
|
injectString("cs", "{1} selected", "{1} vybran\xFD/vybran\xE9");
|
|
12
45
|
injectString("da-DK", "{1} selected", "{1} valgt");
|
|
13
46
|
injectString("de", "{1} selected", "{1} ausgew\xE4hlt");
|
|
@@ -189,6 +222,7 @@ const button_1 = require("../../../../button/button");
|
|
|
189
222
|
const BulkActions = ({
|
|
190
223
|
selected,
|
|
191
224
|
allSelected,
|
|
225
|
+
selectionCountUnknown,
|
|
192
226
|
className,
|
|
193
227
|
onClearSelection,
|
|
194
228
|
onSelectAll,
|
|
@@ -222,7 +256,8 @@ const BulkActions = ({
|
|
|
222
256
|
widthDelta
|
|
223
257
|
});
|
|
224
258
|
const isMobile = gridType === deviceType_1.DeviceType.Mobile;
|
|
225
|
-
const
|
|
259
|
+
const hasSelection = selected > 0 || allSelected || selectionCountUnknown;
|
|
260
|
+
const text = selectionCountUnknown ? translate("Selected") : translate("{1} selected").replace("{1}", allSelected ? translate("All") : selected.toFixed());
|
|
226
261
|
return (0, jsx_runtime_1.jsxs)("div", {
|
|
227
262
|
className: (0, classNames_1.classNames)(["zen-bulk-actions", className || "", isMobile ? "zen-bulk-actions--condensed" : ""]),
|
|
228
263
|
ref: bulkActionsElement,
|
|
@@ -248,7 +283,7 @@ const BulkActions = ({
|
|
|
248
283
|
className: "zen-bulk-actions__action-button-holder",
|
|
249
284
|
ref: buttonHolder,
|
|
250
285
|
children: [react_1.Children.map(visibleElements, element => (0, react_1.cloneElement)(element, {
|
|
251
|
-
disabled:
|
|
286
|
+
disabled: hasSelection ? element.props.disabled : true
|
|
252
287
|
})), nonFittingElements.length > 0 ? (0, jsx_runtime_1.jsx)(menu_1.Menu, {
|
|
253
288
|
title: translate("More"),
|
|
254
289
|
trigger: (0, jsx_runtime_1.jsx)(textIconButton_1.TextIconButton, {
|
|
@@ -269,7 +304,7 @@ const BulkActions = ({
|
|
|
269
304
|
id: props.id || "",
|
|
270
305
|
name: props.title,
|
|
271
306
|
icon: props.icon,
|
|
272
|
-
disabled: props.disabled,
|
|
307
|
+
disabled: hasSelection ? props.disabled : true,
|
|
273
308
|
onClick: clickHandler,
|
|
274
309
|
link: link
|
|
275
310
|
}, props.id);
|
|
@@ -285,4 +320,4 @@ const BulkActions = ({
|
|
|
285
320
|
exports.BulkActions = BulkActions;
|
|
286
321
|
exports.BulkActions.ActionLink = bulkActionLink_1.BulkActionLink;
|
|
287
322
|
exports.BulkActions.ActionButton = bulkActionButton_1.BulkActionButton;
|
|
288
|
-
exports.BulkActions.translations = ["Clear selection", "More options", "{1} selected", "Selecting..."];
|
|
323
|
+
exports.BulkActions.translations = ["Clear selection", "More options", "{1} selected", "Selecting...", "Selected"];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactElement, ReactNode, RefObject } from "react";
|
|
2
|
-
export declare const useTableChildren: (children: ReactNode, isMobile: boolean, selected: number, allSelected: boolean, clearSelection: () => void, activeId?: string, gridRef?: RefObject<HTMLElement | null>, onCloseDetailPanel?: () => void, isInfinite?: boolean, loadedCount?: number) => {
|
|
3
|
-
bulkActions:
|
|
2
|
+
export declare const useTableChildren: (children: ReactNode, isMobile: boolean, selected: number, allSelected: boolean, clearSelection: () => void, activeId?: string, gridRef?: RefObject<HTMLElement | null>, onCloseDetailPanel?: () => void, isInfinite?: boolean, loadedCount?: number, excludedCount?: number, canUsePaginationTotal?: boolean, hasMoreRows?: boolean) => {
|
|
3
|
+
bulkActions: import("react/jsx-runtime").JSX.Element | undefined;
|
|
4
|
+
hasSelection: boolean;
|
|
4
5
|
pagination: ReactElement | undefined;
|
|
5
6
|
paginationTotal: number | undefined;
|
|
6
7
|
activePage: undefined;
|
|
@@ -31,8 +31,8 @@ const useTableChildren = (children, isMobile, selected, allSelected, clearSelect
|
|
|
31
31
|
// Desktop infinite scroll (Table's `onScrollEnd`): when true, a `Table.Pagination` child is
|
|
32
32
|
// rendered as the chevron-less "loaded" variant (see `pagination.tsx`) instead of the normal
|
|
33
33
|
// paged controls, driven by `loadedCount` (the number of rows currently rendered).
|
|
34
|
-
isInfinite = false, loadedCount = 0) => (0, react_1.useMemo)(() => {
|
|
35
|
-
let
|
|
34
|
+
isInfinite = false, loadedCount = 0, excludedCount = 0, canUsePaginationTotal = true, hasMoreRows = false) => (0, react_1.useMemo)(() => {
|
|
35
|
+
let bulkActionButtons;
|
|
36
36
|
let tablePagination = undefined;
|
|
37
37
|
let activePage = undefined;
|
|
38
38
|
// A plain `let` reassigned only inside the `Children.forEach` callback below would be seen
|
|
@@ -52,11 +52,11 @@ isInfinite = false, loadedCount = 0) => (0, react_1.useMemo)(() => {
|
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
if (isChildElement(child, tableBulkActions_1.TableBulkActions.displayName)) {
|
|
55
|
-
|
|
56
|
-
bulkActions = ((0, jsx_runtime_1.jsx)(bulkActions_1.BulkActions, { gridType: isMobile ? deviceType_1.DeviceType.Mobile : deviceType_1.DeviceType.Desktop, selected: selected, allSelected: allSelected, onClearSelection: clearSelection, children: bulkActionButtons }));
|
|
55
|
+
bulkActionButtons = child.props.children || [];
|
|
57
56
|
return;
|
|
58
57
|
}
|
|
59
58
|
if (isChildElement(child, tablePagination_1.TablePagination.displayName)) {
|
|
59
|
+
paginationMeta.present = true;
|
|
60
60
|
const total = child.props.total || 0;
|
|
61
61
|
tablePagination = isInfinite
|
|
62
62
|
? (0, react_1.createElement)(pagination_1.Pagination, {
|
|
@@ -78,7 +78,7 @@ isInfinite = false, loadedCount = 0) => (0, react_1.useMemo)(() => {
|
|
|
78
78
|
gridRef: gridRef,
|
|
79
79
|
disabled: child.props.disabled
|
|
80
80
|
});
|
|
81
|
-
paginationMeta.total = total;
|
|
81
|
+
paginationMeta.total = child.props.total;
|
|
82
82
|
activePage = child.props.activePage;
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
@@ -116,8 +116,18 @@ isInfinite = false, loadedCount = 0) => (0, react_1.useMemo)(() => {
|
|
|
116
116
|
}
|
|
117
117
|
other.push(child);
|
|
118
118
|
});
|
|
119
|
+
const allRowsLoaded = (!paginationMeta.present && !hasMoreRows) || (paginationMeta.total !== undefined && loadedCount >= paginationMeta.total);
|
|
120
|
+
const hasExclusions = allSelected && excludedCount > 0;
|
|
121
|
+
const selectedCount = allSelected && !allRowsLoaded
|
|
122
|
+
? canUsePaginationTotal && paginationMeta.total !== undefined
|
|
123
|
+
? Math.max(0, paginationMeta.total - excludedCount)
|
|
124
|
+
: undefined
|
|
125
|
+
: selected;
|
|
126
|
+
const hasSelection = selectedCount === undefined || selectedCount > 0;
|
|
127
|
+
const bulkActions = bulkActionButtons !== undefined ? ((0, jsx_runtime_1.jsx)(bulkActions_1.BulkActions, { gridType: isMobile ? deviceType_1.DeviceType.Mobile : deviceType_1.DeviceType.Desktop, selected: selectedCount !== null && selectedCount !== void 0 ? selectedCount : selected, allSelected: allSelected && !hasExclusions && hasSelection, selectionCountUnknown: hasExclusions && selectedCount === undefined, onClearSelection: clearSelection, children: bulkActionButtons })) : undefined;
|
|
119
128
|
return {
|
|
120
|
-
bulkActions
|
|
129
|
+
bulkActions,
|
|
130
|
+
hasSelection,
|
|
121
131
|
pagination: tablePagination,
|
|
122
132
|
paginationTotal: paginationMeta.total,
|
|
123
133
|
activePage: activePage,
|
|
@@ -127,5 +137,19 @@ isInfinite = false, loadedCount = 0) => (0, react_1.useMemo)(() => {
|
|
|
127
137
|
detailPanel: detailPanel,
|
|
128
138
|
other: other
|
|
129
139
|
};
|
|
130
|
-
}, [
|
|
140
|
+
}, [
|
|
141
|
+
children,
|
|
142
|
+
clearSelection,
|
|
143
|
+
isMobile,
|
|
144
|
+
selected,
|
|
145
|
+
gridRef,
|
|
146
|
+
allSelected,
|
|
147
|
+
activeId,
|
|
148
|
+
onCloseDetailPanel,
|
|
149
|
+
isInfinite,
|
|
150
|
+
loadedCount,
|
|
151
|
+
excludedCount,
|
|
152
|
+
canUsePaginationTotal,
|
|
153
|
+
hasMoreRows
|
|
154
|
+
]);
|
|
131
155
|
exports.useTableChildren = useTableChildren;
|
|
@@ -10,14 +10,9 @@ export interface ISelectionValue {
|
|
|
10
10
|
*/
|
|
11
11
|
all: boolean;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* fully-selected set (e.g. rows unchecked after a "select all" across paginated data).
|
|
17
|
-
*
|
|
18
|
-
* This lets `all: true` represent "all except these ids" without needing to know the
|
|
19
|
-
* full id universe (MYG-142234) - unchecking a row while `all` is true only ever adds
|
|
20
|
-
* to this exclusion list; it must never be rebuilt from the currently rendered page.
|
|
13
|
+
* Included IDs by default. With `ISelectableRowsOptions.allowExclusions: true`,
|
|
14
|
+
* these are excluded IDs while `all` is true, and included IDs while `all` is false.
|
|
15
|
+
* Consumers opting in must resolve the effective selection before running bulk actions.
|
|
21
16
|
*/
|
|
22
17
|
selected: string[];
|
|
23
18
|
}
|
|
@@ -8,6 +8,8 @@ export type TSelectionStrategy = "main" | "nested";
|
|
|
8
8
|
export interface ISelectableRowsOptions<T extends IRowEntity<N>, N extends IEntityWithId> {
|
|
9
9
|
selection: ISelectionValue | undefined;
|
|
10
10
|
onSelect: (selection: ISelectionValue) => void;
|
|
11
|
+
/** Preserve cross-page Select All using excluded IDs. Consumers must resolve exclusions before running bulk actions. Defaults to false. */
|
|
12
|
+
allowExclusions?: boolean;
|
|
11
13
|
checkboxDisabled?: (entity: T | N, isNested?: boolean) => boolean;
|
|
12
14
|
checkboxVisible?: (entity: T | N, isNested?: boolean) => boolean;
|
|
13
15
|
checkboxInHeader?: boolean;
|
|
@@ -32,6 +34,7 @@ export declare const getEmptySelection: () => {
|
|
|
32
34
|
all: boolean;
|
|
33
35
|
selected: string[];
|
|
34
36
|
};
|
|
37
|
+
export declare const isAllSelection: (all: boolean | undefined, selectedCount: number | undefined, allowExclusions?: boolean) => boolean;
|
|
35
38
|
export declare const SelectableWrapperName = "Selectable";
|
|
36
39
|
export declare const useSelectableRows: <T extends IRowEntity<N>, N extends IEntityWithId>(columns: IListColumn<T, N>[], entities: T[], isMobile: boolean, selectMode: boolean, setSelectMode: (value: boolean) => void, selectable?: ISelectableRowsOptions<T, N>, isInfinite?: boolean, gridRef?: RefObject<HTMLElement | null>, expandedRows?: string[]) => {
|
|
37
40
|
selectableColumns: IListColumn<T, N>[];
|
|
@@ -6,8 +6,9 @@ const {
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", {
|
|
7
7
|
value: true
|
|
8
8
|
});
|
|
9
|
-
exports.TRANSLATIONS = exports.useSelectableRows = exports.SelectableWrapperName = exports.getEmptySelection = void 0;
|
|
9
|
+
exports.TRANSLATIONS = exports.useSelectableRows = exports.SelectableWrapperName = exports.isAllSelection = exports.getEmptySelection = void 0;
|
|
10
10
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
11
|
+
/* eslint-disable complexity */
|
|
11
12
|
const react_1 = require("react");
|
|
12
13
|
const interfaces_1 = require("./interfaces");
|
|
13
14
|
const checkboxCell_1 = require("../../dataGrid/columns/checkboxColumn/checkboxCell");
|
|
@@ -92,9 +93,12 @@ const getEmptySelection = () => ({
|
|
|
92
93
|
selected: []
|
|
93
94
|
});
|
|
94
95
|
exports.getEmptySelection = getEmptySelection;
|
|
96
|
+
const isAllSelection = (all, selectedCount, allowExclusions) => !!all && (!!allowExclusions || selectedCount === 0);
|
|
97
|
+
exports.isAllSelection = isAllSelection;
|
|
95
98
|
exports.SelectableWrapperName = "Selectable";
|
|
96
99
|
// Infinite scroll has no pages, so the header checkbox always means "select all" (never current page).
|
|
97
100
|
const resolveCheckboxEmitsCurrentPage = (isInfinite, checkboxSelectsCurrentPage, turnOffSelectAll) => isInfinite ? false : checkboxSelectsCurrentPage !== null && checkboxSelectsCurrentPage !== void 0 ? checkboxSelectsCurrentPage : turnOffSelectAll;
|
|
101
|
+
const getSelectionMenuState = (allSelected, selections, pageState) => allSelected ? selections.size === 0 ? interfaces_1.SelectionState.All : interfaces_1.SelectionState.Partial : pageState;
|
|
98
102
|
const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMode, selectable, isInfinite = false, gridRef, expandedRows) => {
|
|
99
103
|
var _a;
|
|
100
104
|
const {
|
|
@@ -138,20 +142,25 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
138
142
|
}, [selectable === null || selectable === void 0 ? void 0 : selectable.checkboxPlaceholder, selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
139
143
|
const isAllSelected = (0, react_1.useMemo)(() => {
|
|
140
144
|
var _a;
|
|
141
|
-
return ((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all
|
|
142
|
-
}, [(_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all]);
|
|
145
|
+
return (0, exports.isAllSelection)((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, selections.size, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions);
|
|
146
|
+
}, [(_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, selections.size]);
|
|
143
147
|
const selectableState = (0, react_1.useMemo)(() => (0, calculateSelectionState_1.calculateSelectionState)(entities, selections, isAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy), [checkboxDisabled, checkboxVisible, entities, isAllSelected, selections, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
148
|
+
const selectionMenuState = getSelectionMenuState(isAllSelected, selections, selectableState);
|
|
144
149
|
const firstColumnId = (0, react_1.useMemo)(() => columns.length > 0 ? columns[0].id : null, [columns]);
|
|
145
150
|
(0, react_1.useEffect)(() => {
|
|
146
151
|
if (selectable && selectable.selection) {
|
|
147
152
|
const newSelections = new Set(selectable.selection.selected);
|
|
148
|
-
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, newSelections,
|
|
153
|
+
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, newSelections, isAllSelected, checkboxVisible, checkboxDisabled, selectable.strategy);
|
|
149
154
|
setState(newState);
|
|
150
155
|
}
|
|
151
|
-
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
156
|
+
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, selectable === null || selectable === void 0 ? void 0 : selectable.strategy, isAllSelected]);
|
|
152
157
|
const getNewSelection = (0, react_1.useCallback)((id, checked) => {
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
if (isAllSelected && !(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions)) {
|
|
159
|
+
const included = (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable);
|
|
160
|
+
(0, checkRow_1.checkRow)(included, wrappedSelectable, entities, id, checked);
|
|
161
|
+
return included;
|
|
162
|
+
}
|
|
163
|
+
if (isAllSelected) {
|
|
155
164
|
// MYG-142234: `selections` holds the ids excluded from the "all" selection.
|
|
156
165
|
// Toggling a row here must only ever add/remove that single id from the
|
|
157
166
|
// exclusion set - it must never be rebuilt from `entities` (the current page),
|
|
@@ -162,10 +171,9 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
162
171
|
}
|
|
163
172
|
(0, checkRow_1.checkRow)(selections, wrappedSelectable, entities, id, checked);
|
|
164
173
|
return selections;
|
|
165
|
-
}, [entities, selectable, wrappedSelectable, selections]);
|
|
174
|
+
}, [entities, selectable, wrappedSelectable, selections, isAllSelected]);
|
|
166
175
|
const onSelectListener = (0, react_1.useCallback)((id, checked) => {
|
|
167
|
-
|
|
168
|
-
const wasAllSelected = ((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all) || false;
|
|
176
|
+
const wasAllSelected = !!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && isAllSelected;
|
|
169
177
|
const newSelection = getNewSelection(id, checked);
|
|
170
178
|
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, newSelection, wasAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy);
|
|
171
179
|
// MYG-142234: once selection spans "all" pages, unchecking a row must keep `all: true`
|
|
@@ -180,26 +188,26 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
180
188
|
setState(newState);
|
|
181
189
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
182
190
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
183
|
-
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, setState, getNewSelection]);
|
|
191
|
+
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, setState, getNewSelection, isAllSelected]);
|
|
184
192
|
const onBatchSelect = (0, react_1.useCallback)((rangeIds, select, base) => {
|
|
185
|
-
var _a;
|
|
186
193
|
const result = new Set(base);
|
|
187
194
|
const limit = selectable === null || selectable === void 0 ? void 0 : selectable.selectionLimit;
|
|
195
|
+
const wasAllSelected = !!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && isAllSelected;
|
|
188
196
|
for (const id of rangeIds) {
|
|
189
|
-
if (select && limit !== undefined && result.size >= limit) {
|
|
197
|
+
if (!wasAllSelected && select && limit !== undefined && result.size >= limit) {
|
|
190
198
|
break;
|
|
191
199
|
}
|
|
192
|
-
(0, checkRow_1.checkRow)(result, wrappedSelectable, entities, id, select);
|
|
200
|
+
(0, checkRow_1.checkRow)(result, wrappedSelectable, entities, id, wasAllSelected ? !select : select);
|
|
193
201
|
}
|
|
194
|
-
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, result,
|
|
202
|
+
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, result, wasAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy);
|
|
195
203
|
const newValue = {
|
|
196
204
|
selected: [...result],
|
|
197
|
-
all: newState === interfaces_1.SelectionState.All
|
|
205
|
+
all: wasAllSelected || newState === interfaces_1.SelectionState.All
|
|
198
206
|
};
|
|
199
207
|
setState(newState);
|
|
200
208
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
201
209
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
202
|
-
}, [entities, selectable, wrappedSelectable, checkboxVisible, checkboxDisabled, setSelectMode]);
|
|
210
|
+
}, [entities, selectable, wrappedSelectable, checkboxVisible, checkboxDisabled, setSelectMode, isAllSelected]);
|
|
203
211
|
// Deliberately independent of the current selection, so the drag anchor survives the
|
|
204
212
|
// selection changes a drag itself produces.
|
|
205
213
|
const {
|
|
@@ -210,7 +218,7 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
210
218
|
const entity = entityById.get(row.id);
|
|
211
219
|
return !!entity && checkboxVisible(entity, row.isNested) && !checkboxDisabled(entity, row.isNested);
|
|
212
220
|
}, [entityById, checkboxVisible, checkboxDisabled]);
|
|
213
|
-
const getBaseSelection = (0, react_1.useCallback)(() =>
|
|
221
|
+
const getBaseSelection = (0, react_1.useCallback)(() => isAllSelected && !(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) ? (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable) : new Set(selections), [isAllSelected, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, entities, wrappedSelectable, selections]);
|
|
214
222
|
const {
|
|
215
223
|
onCheckboxMouseDown,
|
|
216
224
|
suppressNextChangeRef
|
|
@@ -242,14 +250,12 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
242
250
|
}
|
|
243
251
|
const newSelections = (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable);
|
|
244
252
|
setState(newState);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const newValue = {
|
|
252
|
-
selected: [...mergedSelections],
|
|
253
|
+
const previousSelections = (_b = (_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.selected) !== null && _b !== void 0 ? _b : [];
|
|
254
|
+
const newValue = (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_c = selectable.selection) === null || _c === void 0 ? void 0 : _c.all) ? {
|
|
255
|
+
selected: previousSelections.filter(id => !newSelections.has(id)),
|
|
256
|
+
all: true
|
|
257
|
+
} : {
|
|
258
|
+
selected: [...new Set([...previousSelections, ...newSelections])],
|
|
253
259
|
all: false
|
|
254
260
|
};
|
|
255
261
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
@@ -328,7 +334,9 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
328
334
|
const newState = checkboxEmitsCurrentPage ? interfaces_1.SelectionState.CurrentPage : interfaces_1.SelectionState.All;
|
|
329
335
|
setState(newState);
|
|
330
336
|
onChangeSelectionState(newState);
|
|
331
|
-
} else if (
|
|
337
|
+
} else if (isInfinite) {
|
|
338
|
+
onChangeSelectionState(interfaces_1.SelectionState.None);
|
|
339
|
+
} else if (selectable.allowExclusions && ((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.all)) {
|
|
332
340
|
// MYG-142234: in exclusion mode, `selected` holds excluded ids. Unchecking
|
|
333
341
|
// the header must add the current page's ids to that exclusion set and
|
|
334
342
|
// keep `all: true` - it must never be treated as an inclusion list, or
|
|
@@ -356,7 +364,7 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
356
364
|
setSelectMode(remaining.length > 0);
|
|
357
365
|
}
|
|
358
366
|
},
|
|
359
|
-
calculateSelectionState: () =>
|
|
367
|
+
calculateSelectionState: () => selectionMenuState,
|
|
360
368
|
checkboxInHeader: checkboxInHeaderValue,
|
|
361
369
|
header: selectableHeader,
|
|
362
370
|
onSelect: newState => {
|
|
@@ -369,7 +377,7 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
369
377
|
return cell;
|
|
370
378
|
}
|
|
371
379
|
};
|
|
372
|
-
}, [checkboxDisabled, checkboxTitle, checkboxVisible, headerTitle, onChangeSelectionState, onCheckboxChange, onCheckboxMouseDown, hasSelectable, checkboxEmitsCurrentPage, checkboxInHeaderValue, selectableHeader, selectableTurnOffSelectAll, isInfinite, selectable, wrappedSelectable,
|
|
380
|
+
}, [checkboxDisabled, checkboxTitle, checkboxVisible, headerTitle, onChangeSelectionState, onCheckboxChange, onCheckboxMouseDown, hasSelectable, checkboxEmitsCurrentPage, checkboxInHeaderValue, selectableHeader, selectableTurnOffSelectAll, isInfinite, selectable, wrappedSelectable, selectionMenuState, state, isMobile, checkboxPlaceholder, isEntityChecked, entities, setSelectMode]);
|
|
373
381
|
const selectableFeedWrapper = (0, react_1.useCallback)((primaryData, secondaryData, entity, isNested) => {
|
|
374
382
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
375
383
|
if (!entity) {
|
|
@@ -12,10 +12,7 @@ const calculateSelectionState = (entities, selections, all, checkboxVisible, che
|
|
|
12
12
|
// otherwise-fully-selected set (see ISelectionValue), rather than included ids.
|
|
13
13
|
const isExcluded = (entity) => {
|
|
14
14
|
const children = strategy === "nested" ? (0, showMoreRow_1.getChildrenForSelection)(entity) : undefined;
|
|
15
|
-
if (children) {
|
|
16
|
-
if (children.length === 0) {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
15
|
+
if (children && children.length > 0) {
|
|
19
16
|
return children.every(child => {
|
|
20
17
|
if (!checkboxVisible(child, true)) {
|
|
21
18
|
return true;
|
|
@@ -30,7 +27,7 @@ const calculateSelectionState = (entities, selections, all, checkboxVisible, che
|
|
|
30
27
|
};
|
|
31
28
|
const isPartiallyExcluded = (entity) => {
|
|
32
29
|
const children = strategy === "nested" ? (0, showMoreRow_1.getChildrenForSelection)(entity) : undefined;
|
|
33
|
-
if (children) {
|
|
30
|
+
if (children && children.length > 0) {
|
|
34
31
|
return children.some(child => selections.has(child.id));
|
|
35
32
|
}
|
|
36
33
|
return selections.has(entity.id);
|
|
@@ -53,7 +50,7 @@ const calculateSelectionState = (entities, selections, all, checkboxVisible, che
|
|
|
53
50
|
}
|
|
54
51
|
if (strategy === "nested") {
|
|
55
52
|
const children = (0, showMoreRow_1.getChildrenForSelection)(entity);
|
|
56
|
-
if (children) {
|
|
53
|
+
if (children && children.length > 0) {
|
|
57
54
|
return children.every(child => {
|
|
58
55
|
if (!checkboxVisible(child, true)) {
|
|
59
56
|
return true;
|
|
@@ -64,7 +61,7 @@ const calculateSelectionState = (entities, selections, all, checkboxVisible, che
|
|
|
64
61
|
return selections.has(child.id);
|
|
65
62
|
});
|
|
66
63
|
}
|
|
67
|
-
return
|
|
64
|
+
return selections.has(entity.id);
|
|
68
65
|
}
|
|
69
66
|
return selections.has(entity.id);
|
|
70
67
|
})
|
|
@@ -5,12 +5,15 @@ const showMoreRow_1 = require("../../../commonHelpers/showMoreRow");
|
|
|
5
5
|
const getCurrentPageSelection = (entities, selectable) => {
|
|
6
6
|
const newSelections = new Set();
|
|
7
7
|
entities.forEach(entity => {
|
|
8
|
-
const isVisible = (selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(entity) : true;
|
|
8
|
+
const isVisible = !entity.isLoading && !(0, showMoreRow_1.isShowMoreRow)(entity) && ((selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(entity) : true);
|
|
9
9
|
const isEnabled = !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) || !selectable.checkboxDisabled(entity);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
10
|
+
const children = (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) === "nested" ? (0, showMoreRow_1.getChildrenForSelection)(entity) : undefined;
|
|
11
|
+
if (children && children.length > 0) {
|
|
12
|
+
children.forEach(child => {
|
|
13
|
+
const isChildVisible = !child.isLoading &&
|
|
14
|
+
!(0, showMoreRow_1.isShowMoreRow)(child) &&
|
|
15
|
+
((selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(child, true) : true);
|
|
16
|
+
const isChildEnabled = !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) || !selectable.checkboxDisabled(child, true);
|
|
14
17
|
if (isChildVisible && isChildEnabled) {
|
|
15
18
|
newSelections.add(child.id);
|
|
16
19
|
}
|
package/dist/table/table.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IZenComponentProps, IZenGridItem } from "../commonHelpers/zenComponent";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
-
import { ISelectableRowsOptions } from "./selectable/useSelectableRows";
|
|
3
|
+
import { getEmptySelection, ISelectableRowsOptions } from "./selectable/useSelectableRows";
|
|
4
4
|
import { ISortableOptions } from "./sortable/useSortableColumns";
|
|
5
5
|
import { IFlexibleColumnsOptions } from "./flexible/useFlexibleColumns";
|
|
6
6
|
import { IColumnComponent, IListColumnWrapper } from "../dataGrid/listColumn";
|
|
@@ -11,7 +11,6 @@ import { ITablePagination, TablePagination } from "./children/tablePagination";
|
|
|
11
11
|
import { ITableEmpty, TableEmpty } from "./children/tableEmpty";
|
|
12
12
|
import { ITableFooter, TableFooter } from "./children/tableFooter";
|
|
13
13
|
import "./table.less";
|
|
14
|
-
import { getEmptySelection } from "./selectable/useSelectableRows";
|
|
15
14
|
import { ColumnSortDirection } from "./sortable/interfaces";
|
|
16
15
|
import { getSortableValue } from "./sortable/useSortableColumns";
|
|
17
16
|
import { ActionsColumn } from "../dataGrid/columns/actionsColumn/actionsColumn";
|
package/dist/table/table.js
CHANGED
|
@@ -13,22 +13,6 @@ const dataFeed_1 = require("../dataFeed/dataFeed");
|
|
|
13
13
|
const dataGrid_1 = require("../dataGrid/dataGrid");
|
|
14
14
|
const lazyLoadingEnd_1 = require("../dataGrid/lazyLoadingEnd/lazyLoadingEnd");
|
|
15
15
|
const useSelectableRows_1 = require("./selectable/useSelectableRows");
|
|
16
|
-
const useSortableColumns_1 = require("./sortable/useSortableColumns");
|
|
17
|
-
const useFlexibleColumns_1 = require("./flexible/useFlexibleColumns");
|
|
18
|
-
const useActions_1 = require("./actions/useActions");
|
|
19
|
-
const useLoading_1 = require("./loading/useLoading");
|
|
20
|
-
const emptySearchList_1 = require("../dataGrid/emptySearchList/emptySearchList");
|
|
21
|
-
const entitiesListActions_1 = require("../dataGrid/entitiesListActions/entitiesListActions");
|
|
22
|
-
const dataFeedSelectPanel_1 = require("../dataFeed/dataFeedSelectPanel/dataFeedSelectPanel");
|
|
23
|
-
const columnsListButton_1 = require("../dataGrid/entitiesListActions/actions/columnsListButton");
|
|
24
|
-
const useTableChildren_1 = require("./children/useTableChildren");
|
|
25
|
-
const deviceType_1 = require("../commonHelpers/hooks/deviceType");
|
|
26
|
-
const useMobile_1 = require("../commonHelpers/hooks/useMobile");
|
|
27
|
-
const tableFullscreen_1 = require("./children/tableFullscreen");
|
|
28
|
-
const tableBulkActions_1 = require("./children/tableBulkActions");
|
|
29
|
-
const tablePagination_1 = require("./children/tablePagination");
|
|
30
|
-
const tableEmpty_1 = require("./children/tableEmpty");
|
|
31
|
-
const tableFooter_1 = require("./children/tableFooter");
|
|
32
16
|
injectString("da-DK", "Loading more rows", "Indl\xE6ser flere r\xE6kker");
|
|
33
17
|
injectString("en", "Loading more rows", "Loading more rows");
|
|
34
18
|
injectString("fi-FI", "Loading more rows", "Ladataan lis\xE4\xE4 rivej\xE4");
|
|
@@ -146,13 +130,29 @@ injectString("ka-GE", "Bulk select", "\u10DB\u10D0\u10E1\u10D8\u10E3\u10E0\u10D8
|
|
|
146
130
|
injectString("el-GR", "Bulk select", "\u039C\u03B1\u03B6\u03B9\u03BA\u03AE \u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE");
|
|
147
131
|
injectString("et-EE", "Bulk select", "Massvalimine");
|
|
148
132
|
injectString("bg-BG", "Bulk select", "\u041C\u0430\u0441\u043E\u0432 \u0438\u0437\u0431\u043E\u0440");
|
|
149
|
-
const useSelectableRows_2 = require("./selectable/useSelectableRows");
|
|
150
133
|
Object.defineProperty(exports, "getEmptySelection", {
|
|
151
134
|
enumerable: true,
|
|
152
135
|
get: function () {
|
|
153
|
-
return
|
|
136
|
+
return useSelectableRows_1.getEmptySelection;
|
|
154
137
|
}
|
|
155
138
|
});
|
|
139
|
+
const useSortableColumns_1 = require("./sortable/useSortableColumns");
|
|
140
|
+
const useFlexibleColumns_1 = require("./flexible/useFlexibleColumns");
|
|
141
|
+
const useActions_1 = require("./actions/useActions");
|
|
142
|
+
const useLoading_1 = require("./loading/useLoading");
|
|
143
|
+
const emptySearchList_1 = require("../dataGrid/emptySearchList/emptySearchList");
|
|
144
|
+
const entitiesListActions_1 = require("../dataGrid/entitiesListActions/entitiesListActions");
|
|
145
|
+
const dataFeedSelectPanel_1 = require("../dataFeed/dataFeedSelectPanel/dataFeedSelectPanel");
|
|
146
|
+
const columnsListButton_1 = require("../dataGrid/entitiesListActions/actions/columnsListButton");
|
|
147
|
+
const useTableChildren_1 = require("./children/useTableChildren");
|
|
148
|
+
const deviceType_1 = require("../commonHelpers/hooks/deviceType");
|
|
149
|
+
const useMobile_1 = require("../commonHelpers/hooks/useMobile");
|
|
150
|
+
const getCurrentPageSelection_1 = require("./selectable/utils/getCurrentPageSelection");
|
|
151
|
+
const tableFullscreen_1 = require("./children/tableFullscreen");
|
|
152
|
+
const tableBulkActions_1 = require("./children/tableBulkActions");
|
|
153
|
+
const tablePagination_1 = require("./children/tablePagination");
|
|
154
|
+
const tableEmpty_1 = require("./children/tableEmpty");
|
|
155
|
+
const tableFooter_1 = require("./children/tableFooter");
|
|
156
156
|
const interfaces_1 = require("./sortable/interfaces");
|
|
157
157
|
Object.defineProperty(exports, "ColumnSortDirection", {
|
|
158
158
|
enumerable: true,
|
|
@@ -235,7 +235,7 @@ const TableInner = ({
|
|
|
235
235
|
active,
|
|
236
236
|
onClick
|
|
237
237
|
}) => {
|
|
238
|
-
var _a, _b, _c;
|
|
238
|
+
var _a, _b, _c, _d, _e;
|
|
239
239
|
const isMobile = (0, useMobile_1.useMobile)();
|
|
240
240
|
const {
|
|
241
241
|
translate
|
|
@@ -325,13 +325,19 @@ const TableInner = ({
|
|
|
325
325
|
} = (0, useFeedExpandable_1.useFeedExpandable)(isMobile, feedExpandable);
|
|
326
326
|
// Keep bulk-action state available during initial/replacement loading for backward compatibility.
|
|
327
327
|
// The row controls themselves still use selectableForRender and remain hidden until real rows can render.
|
|
328
|
-
const
|
|
328
|
+
const allSelected = (0, react_1.useMemo)(() => {
|
|
329
329
|
var _a, _b;
|
|
330
|
+
return (0, useSelectableRows_1.isAllSelection)((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, (_b = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _b === void 0 ? void 0 : _b.selected.length, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions);
|
|
331
|
+
}, [(_c = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _c === void 0 ? void 0 : _c.all, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, (_d = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _d === void 0 ? void 0 : _d.selected.length]);
|
|
332
|
+
const selectionQty = (0, react_1.useMemo)(() => {
|
|
333
|
+
var _a;
|
|
330
334
|
if (!selectable) {
|
|
331
335
|
return 0;
|
|
332
336
|
}
|
|
333
|
-
|
|
334
|
-
|
|
337
|
+
const ids = new Set((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.selected);
|
|
338
|
+
const base = entities.length > 0 ? entities : loadingEntities;
|
|
339
|
+
return allSelected ? [...(0, getCurrentPageSelection_1.getCurrentPageSelection)(base, selectable)].filter(id => !selectable.allowExclusions || !ids.has(id)).length : ids.size;
|
|
340
|
+
}, [selectable, entities, loadingEntities, allSelected]);
|
|
335
341
|
const clearSelection = (0, react_1.useCallback)(() => {
|
|
336
342
|
setSelectMode(false);
|
|
337
343
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect({
|
|
@@ -348,6 +354,7 @@ const TableInner = ({
|
|
|
348
354
|
}, [onClickRow]);
|
|
349
355
|
const {
|
|
350
356
|
bulkActions,
|
|
357
|
+
hasSelection,
|
|
351
358
|
pagination,
|
|
352
359
|
paginationTotal,
|
|
353
360
|
activePage,
|
|
@@ -356,7 +363,7 @@ const TableInner = ({
|
|
|
356
363
|
detailPanel,
|
|
357
364
|
footer,
|
|
358
365
|
other
|
|
359
|
-
} = (0, useTableChildren_1.useTableChildren)(children, isMobile, selectionQty, ((
|
|
366
|
+
} = (0, useTableChildren_1.useTableChildren)(children, isMobile, selectionQty, allSelected, clearSelection, activeId, gridRef, onCloseDetailPanel, isInfinite, entities.length, (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_e = selectable.selection) === null || _e === void 0 ? void 0 : _e.all) ? new Set(selectable.selection.selected).size : 0, (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) !== "nested" && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible), !!feedEndCallback || !!isLoading);
|
|
360
367
|
const hasDetailPanel = !!detailPanel;
|
|
361
368
|
const shouldEnableRowClick = hasDetailPanel || !!onClick;
|
|
362
369
|
const activeIdForRow = shouldEnableRowClick ? activeId : undefined;
|
|
@@ -391,7 +398,7 @@ const TableInner = ({
|
|
|
391
398
|
children: [hasToolbar ? (0, jsx_runtime_1.jsxs)(entitiesListActions_1.EntitiesListActions, {
|
|
392
399
|
gridType: isMobile ? deviceType_1.DeviceType.Mobile : deviceType_1.DeviceType.Desktop,
|
|
393
400
|
children: [(0, jsx_runtime_1.jsxs)(entitiesListActions_1.EntitiesListActions.Actions, {
|
|
394
|
-
children: [!isMobile &&
|
|
401
|
+
children: [!isMobile && hasSelection ? bulkActions : null, feedSortControl]
|
|
395
402
|
}), showPagination || other.length > 0 ? (0, jsx_runtime_1.jsxs)(entitiesListActions_1.EntitiesListActions.Pagination, {
|
|
396
403
|
children: [(0, jsx_runtime_1.jsx)(entitiesListActions_1.EntitiesListActions.CustomElements, {
|
|
397
404
|
children: other
|
|
@@ -12,6 +12,8 @@ export interface IBulkActionsProps extends IZenComponentProps {
|
|
|
12
12
|
* even when `selected` is 0 (i.e., cross-page "select all" is active).
|
|
13
13
|
*/
|
|
14
14
|
allSelected?: boolean;
|
|
15
|
+
/** Show a selection label without a count when the selected total is unknown. */
|
|
16
|
+
selectionCountUnknown?: boolean;
|
|
15
17
|
onClearSelection: () => void;
|
|
16
18
|
onSelectAll?: () => void;
|
|
17
19
|
gridType?: DeviceType;
|
|
@@ -23,7 +25,7 @@ export interface IBulkActions extends IBulkActionsProps {
|
|
|
23
25
|
ActionButton: (props: IBulkActionButton) => ReactNode;
|
|
24
26
|
}
|
|
25
27
|
export declare const BulkActions: {
|
|
26
|
-
({ selected, allSelected, className, onClearSelection, onSelectAll, gridType, children, turnOffSelectAll }: IBulkActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
({ selected, allSelected, selectionCountUnknown, className, onClearSelection, onSelectAll, gridType, children, turnOffSelectAll }: IBulkActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
27
29
|
ActionLink: ({ title, icon, link, disabled, type, ref }: IBulkActionLink) => import("react/jsx-runtime").JSX.Element;
|
|
28
30
|
ActionButton: ({ title, icon, clickHandler, onClick, disabled, type, ref }: IBulkActionButton) => import("react/jsx-runtime").JSX.Element;
|
|
29
31
|
translations: string[];
|
|
@@ -13,6 +13,39 @@ import { useResizeObserver } from "../../../../commonHelpers/hooks/useResizeObse
|
|
|
13
13
|
import { Menu } from "../../../../menu/menu";
|
|
14
14
|
import { IconDotVertical } from "../../../../icons/iconDotVertical";
|
|
15
15
|
import { Button } from "../../../../button/button";
|
|
16
|
+
injectString("cs", "Selected", "Vybr\xE1no");
|
|
17
|
+
injectString("da-DK", "Selected", "Valgt");
|
|
18
|
+
injectString("de", "Selected", "Ausgew\xE4hlt");
|
|
19
|
+
injectString("en", "Selected", "Selected");
|
|
20
|
+
injectString("es", "Selected", "Seleccionado");
|
|
21
|
+
injectString("fi-FI", "Selected", "Valittu");
|
|
22
|
+
injectString("fr", "Selected", "S\xE9lectionn\xE9");
|
|
23
|
+
injectString("fr-FR", "Selected", "S\xE9lectionn\xE9");
|
|
24
|
+
injectString("hu-HU", "Selected", "Kiv\xE1lasztott");
|
|
25
|
+
injectString("id", "Selected", "Dipilih");
|
|
26
|
+
injectString("it", "Selected", "Selezionato");
|
|
27
|
+
injectString("ja", "Selected", "\u9078\u629E\u8ECA\u4E21");
|
|
28
|
+
injectString("ko-KR", "Selected", "\uC120\uD0DD\uB428");
|
|
29
|
+
injectString("ms", "Selected", "Dipilih");
|
|
30
|
+
injectString("nb-NO", "Selected", "Valgt");
|
|
31
|
+
injectString("nl", "Selected", "Geselecteerd");
|
|
32
|
+
injectString("pl", "Selected", "Wybrano");
|
|
33
|
+
injectString("pt-BR", "Selected", "Selecionado");
|
|
34
|
+
injectString("pt-PT", "Selected", "Selecionado");
|
|
35
|
+
injectString("sk-SK", "Selected", "Vybran\xE9");
|
|
36
|
+
injectString("sv", "Selected", "Valda");
|
|
37
|
+
injectString("th", "Selected", "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27");
|
|
38
|
+
injectString("tr", "Selected", "Se\xE7ildi");
|
|
39
|
+
injectString("zh-Hans", "Selected", "\u9009\u4E2D\u7684");
|
|
40
|
+
injectString("zh-TW", "Selected", "\u5DF2\u9078\u53D6");
|
|
41
|
+
injectString("ro-RO", "Selected", "Selec\u021Bie");
|
|
42
|
+
injectString("ar-001", "Selected", "\u0627\u0644\u0645\u062D\u062F\u062F");
|
|
43
|
+
injectString("lt-LT", "Selected", "Pasirinkta");
|
|
44
|
+
injectString("lv-LV", "Selected", "Atlas\u012Bts");
|
|
45
|
+
injectString("ka-GE", "Selected", "\u10D0\u10E0\u10E9\u10D4\u10E3\u10DA\u10D8");
|
|
46
|
+
injectString("el-GR", "Selected", "\u0395\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03B1");
|
|
47
|
+
injectString("et-EE", "Selected", "Valitud");
|
|
48
|
+
injectString("bg-BG", "Selected", "\u0418\u0437\u0431\u0440\u0430\u043D\u0438");
|
|
16
49
|
injectString("cs", "{1} selected", "{1} vybran\xFD/vybran\xE9");
|
|
17
50
|
injectString("da-DK", "{1} selected", "{1} valgt");
|
|
18
51
|
injectString("de", "{1} selected", "{1} ausgew\xE4hlt");
|
|
@@ -181,6 +214,7 @@ injectString("bg-BG", "More", "\u041F\u043E\u0432\u0435\u0447\u0435");
|
|
|
181
214
|
export const BulkActions = ({
|
|
182
215
|
selected,
|
|
183
216
|
allSelected,
|
|
217
|
+
selectionCountUnknown,
|
|
184
218
|
className,
|
|
185
219
|
onClearSelection,
|
|
186
220
|
onSelectAll,
|
|
@@ -214,7 +248,8 @@ export const BulkActions = ({
|
|
|
214
248
|
widthDelta
|
|
215
249
|
});
|
|
216
250
|
const isMobile = gridType === DeviceType.Mobile;
|
|
217
|
-
const
|
|
251
|
+
const hasSelection = selected > 0 || allSelected || selectionCountUnknown;
|
|
252
|
+
const text = selectionCountUnknown ? translate("Selected") : translate("{1} selected").replace("{1}", allSelected ? translate("All") : selected.toFixed());
|
|
218
253
|
return _jsxs("div", {
|
|
219
254
|
className: classNames(["zen-bulk-actions", className || "", isMobile ? "zen-bulk-actions--condensed" : ""]),
|
|
220
255
|
ref: bulkActionsElement,
|
|
@@ -240,7 +275,7 @@ export const BulkActions = ({
|
|
|
240
275
|
className: "zen-bulk-actions__action-button-holder",
|
|
241
276
|
ref: buttonHolder,
|
|
242
277
|
children: [Children.map(visibleElements, element => cloneElement(element, {
|
|
243
|
-
disabled:
|
|
278
|
+
disabled: hasSelection ? element.props.disabled : true
|
|
244
279
|
})), nonFittingElements.length > 0 ? _jsx(Menu, {
|
|
245
280
|
title: translate("More"),
|
|
246
281
|
trigger: _jsx(TextIconButton, {
|
|
@@ -261,7 +296,7 @@ export const BulkActions = ({
|
|
|
261
296
|
id: props.id || "",
|
|
262
297
|
name: props.title,
|
|
263
298
|
icon: props.icon,
|
|
264
|
-
disabled: props.disabled,
|
|
299
|
+
disabled: hasSelection ? props.disabled : true,
|
|
265
300
|
onClick: clickHandler,
|
|
266
301
|
link: link
|
|
267
302
|
}, props.id);
|
|
@@ -276,4 +311,4 @@ export const BulkActions = ({
|
|
|
276
311
|
};
|
|
277
312
|
BulkActions.ActionLink = BulkActionLink;
|
|
278
313
|
BulkActions.ActionButton = BulkActionButton;
|
|
279
|
-
BulkActions.translations = ["Clear selection", "More options", "{1} selected", "Selecting..."];
|
|
314
|
+
BulkActions.translations = ["Clear selection", "More options", "{1} selected", "Selecting...", "Selected"];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactElement, ReactNode, RefObject } from "react";
|
|
2
|
-
export declare const useTableChildren: (children: ReactNode, isMobile: boolean, selected: number, allSelected: boolean, clearSelection: () => void, activeId?: string, gridRef?: RefObject<HTMLElement | null>, onCloseDetailPanel?: () => void, isInfinite?: boolean, loadedCount?: number) => {
|
|
3
|
-
bulkActions:
|
|
2
|
+
export declare const useTableChildren: (children: ReactNode, isMobile: boolean, selected: number, allSelected: boolean, clearSelection: () => void, activeId?: string, gridRef?: RefObject<HTMLElement | null>, onCloseDetailPanel?: () => void, isInfinite?: boolean, loadedCount?: number, excludedCount?: number, canUsePaginationTotal?: boolean, hasMoreRows?: boolean) => {
|
|
3
|
+
bulkActions: import("react/jsx-runtime").JSX.Element | undefined;
|
|
4
|
+
hasSelection: boolean;
|
|
4
5
|
pagination: ReactElement | undefined;
|
|
5
6
|
paginationTotal: number | undefined;
|
|
6
7
|
activePage: undefined;
|
|
@@ -28,8 +28,8 @@ export const useTableChildren = (children, isMobile, selected, allSelected, clea
|
|
|
28
28
|
// Desktop infinite scroll (Table's `onScrollEnd`): when true, a `Table.Pagination` child is
|
|
29
29
|
// rendered as the chevron-less "loaded" variant (see `pagination.tsx`) instead of the normal
|
|
30
30
|
// paged controls, driven by `loadedCount` (the number of rows currently rendered).
|
|
31
|
-
isInfinite = false, loadedCount = 0) => useMemo(() => {
|
|
32
|
-
let
|
|
31
|
+
isInfinite = false, loadedCount = 0, excludedCount = 0, canUsePaginationTotal = true, hasMoreRows = false) => useMemo(() => {
|
|
32
|
+
let bulkActionButtons;
|
|
33
33
|
let tablePagination = undefined;
|
|
34
34
|
let activePage = undefined;
|
|
35
35
|
// A plain `let` reassigned only inside the `Children.forEach` callback below would be seen
|
|
@@ -49,11 +49,11 @@ isInfinite = false, loadedCount = 0) => useMemo(() => {
|
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
if (isChildElement(child, TableBulkActions.displayName)) {
|
|
52
|
-
|
|
53
|
-
bulkActions = (_jsx(BulkActions, { gridType: isMobile ? DeviceType.Mobile : DeviceType.Desktop, selected: selected, allSelected: allSelected, onClearSelection: clearSelection, children: bulkActionButtons }));
|
|
52
|
+
bulkActionButtons = child.props.children || [];
|
|
54
53
|
return;
|
|
55
54
|
}
|
|
56
55
|
if (isChildElement(child, TablePagination.displayName)) {
|
|
56
|
+
paginationMeta.present = true;
|
|
57
57
|
const total = child.props.total || 0;
|
|
58
58
|
tablePagination = isInfinite
|
|
59
59
|
? createElement(Pagination, {
|
|
@@ -75,7 +75,7 @@ isInfinite = false, loadedCount = 0) => useMemo(() => {
|
|
|
75
75
|
gridRef: gridRef,
|
|
76
76
|
disabled: child.props.disabled
|
|
77
77
|
});
|
|
78
|
-
paginationMeta.total = total;
|
|
78
|
+
paginationMeta.total = child.props.total;
|
|
79
79
|
activePage = child.props.activePage;
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
@@ -113,8 +113,18 @@ isInfinite = false, loadedCount = 0) => useMemo(() => {
|
|
|
113
113
|
}
|
|
114
114
|
other.push(child);
|
|
115
115
|
});
|
|
116
|
+
const allRowsLoaded = (!paginationMeta.present && !hasMoreRows) || (paginationMeta.total !== undefined && loadedCount >= paginationMeta.total);
|
|
117
|
+
const hasExclusions = allSelected && excludedCount > 0;
|
|
118
|
+
const selectedCount = allSelected && !allRowsLoaded
|
|
119
|
+
? canUsePaginationTotal && paginationMeta.total !== undefined
|
|
120
|
+
? Math.max(0, paginationMeta.total - excludedCount)
|
|
121
|
+
: undefined
|
|
122
|
+
: selected;
|
|
123
|
+
const hasSelection = selectedCount === undefined || selectedCount > 0;
|
|
124
|
+
const bulkActions = bulkActionButtons !== undefined ? (_jsx(BulkActions, { gridType: isMobile ? DeviceType.Mobile : DeviceType.Desktop, selected: selectedCount !== null && selectedCount !== void 0 ? selectedCount : selected, allSelected: allSelected && !hasExclusions && hasSelection, selectionCountUnknown: hasExclusions && selectedCount === undefined, onClearSelection: clearSelection, children: bulkActionButtons })) : undefined;
|
|
116
125
|
return {
|
|
117
|
-
bulkActions
|
|
126
|
+
bulkActions,
|
|
127
|
+
hasSelection,
|
|
118
128
|
pagination: tablePagination,
|
|
119
129
|
paginationTotal: paginationMeta.total,
|
|
120
130
|
activePage: activePage,
|
|
@@ -124,4 +134,18 @@ isInfinite = false, loadedCount = 0) => useMemo(() => {
|
|
|
124
134
|
detailPanel: detailPanel,
|
|
125
135
|
other: other
|
|
126
136
|
};
|
|
127
|
-
}, [
|
|
137
|
+
}, [
|
|
138
|
+
children,
|
|
139
|
+
clearSelection,
|
|
140
|
+
isMobile,
|
|
141
|
+
selected,
|
|
142
|
+
gridRef,
|
|
143
|
+
allSelected,
|
|
144
|
+
activeId,
|
|
145
|
+
onCloseDetailPanel,
|
|
146
|
+
isInfinite,
|
|
147
|
+
loadedCount,
|
|
148
|
+
excludedCount,
|
|
149
|
+
canUsePaginationTotal,
|
|
150
|
+
hasMoreRows
|
|
151
|
+
]);
|
|
@@ -10,14 +10,9 @@ export interface ISelectionValue {
|
|
|
10
10
|
*/
|
|
11
11
|
all: boolean;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* fully-selected set (e.g. rows unchecked after a "select all" across paginated data).
|
|
17
|
-
*
|
|
18
|
-
* This lets `all: true` represent "all except these ids" without needing to know the
|
|
19
|
-
* full id universe (MYG-142234) - unchecking a row while `all` is true only ever adds
|
|
20
|
-
* to this exclusion list; it must never be rebuilt from the currently rendered page.
|
|
13
|
+
* Included IDs by default. With `ISelectableRowsOptions.allowExclusions: true`,
|
|
14
|
+
* these are excluded IDs while `all` is true, and included IDs while `all` is false.
|
|
15
|
+
* Consumers opting in must resolve the effective selection before running bulk actions.
|
|
21
16
|
*/
|
|
22
17
|
selected: string[];
|
|
23
18
|
}
|
|
@@ -8,6 +8,8 @@ export type TSelectionStrategy = "main" | "nested";
|
|
|
8
8
|
export interface ISelectableRowsOptions<T extends IRowEntity<N>, N extends IEntityWithId> {
|
|
9
9
|
selection: ISelectionValue | undefined;
|
|
10
10
|
onSelect: (selection: ISelectionValue) => void;
|
|
11
|
+
/** Preserve cross-page Select All using excluded IDs. Consumers must resolve exclusions before running bulk actions. Defaults to false. */
|
|
12
|
+
allowExclusions?: boolean;
|
|
11
13
|
checkboxDisabled?: (entity: T | N, isNested?: boolean) => boolean;
|
|
12
14
|
checkboxVisible?: (entity: T | N, isNested?: boolean) => boolean;
|
|
13
15
|
checkboxInHeader?: boolean;
|
|
@@ -32,6 +34,7 @@ export declare const getEmptySelection: () => {
|
|
|
32
34
|
all: boolean;
|
|
33
35
|
selected: string[];
|
|
34
36
|
};
|
|
37
|
+
export declare const isAllSelection: (all: boolean | undefined, selectedCount: number | undefined, allowExclusions?: boolean) => boolean;
|
|
35
38
|
export declare const SelectableWrapperName = "Selectable";
|
|
36
39
|
export declare const useSelectableRows: <T extends IRowEntity<N>, N extends IEntityWithId>(columns: IListColumn<T, N>[], entities: T[], isMobile: boolean, selectMode: boolean, setSelectMode: (value: boolean) => void, selectable?: ISelectableRowsOptions<T, N>, isInfinite?: boolean, gridRef?: RefObject<HTMLElement | null>, expandedRows?: string[]) => {
|
|
37
40
|
selectableColumns: IListColumn<T, N>[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { injectString } from "../../utils/localization/translationsDictionary";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/* eslint-disable complexity */
|
|
3
4
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
5
|
import { SelectionState } from "./interfaces";
|
|
5
6
|
import { CheckboxCell } from "../../dataGrid/columns/checkboxColumn/checkboxCell";
|
|
@@ -83,9 +84,11 @@ export const getEmptySelection = () => ({
|
|
|
83
84
|
all: false,
|
|
84
85
|
selected: []
|
|
85
86
|
});
|
|
87
|
+
export const isAllSelection = (all, selectedCount, allowExclusions) => !!all && (!!allowExclusions || selectedCount === 0);
|
|
86
88
|
export const SelectableWrapperName = "Selectable";
|
|
87
89
|
// Infinite scroll has no pages, so the header checkbox always means "select all" (never current page).
|
|
88
90
|
const resolveCheckboxEmitsCurrentPage = (isInfinite, checkboxSelectsCurrentPage, turnOffSelectAll) => isInfinite ? false : checkboxSelectsCurrentPage !== null && checkboxSelectsCurrentPage !== void 0 ? checkboxSelectsCurrentPage : turnOffSelectAll;
|
|
91
|
+
const getSelectionMenuState = (allSelected, selections, pageState) => allSelected ? selections.size === 0 ? SelectionState.All : SelectionState.Partial : pageState;
|
|
89
92
|
export const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMode, selectable, isInfinite = false, gridRef, expandedRows) => {
|
|
90
93
|
var _a;
|
|
91
94
|
const {
|
|
@@ -129,20 +132,25 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
129
132
|
}, [selectable === null || selectable === void 0 ? void 0 : selectable.checkboxPlaceholder, selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
130
133
|
const isAllSelected = useMemo(() => {
|
|
131
134
|
var _a;
|
|
132
|
-
return ((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all
|
|
133
|
-
}, [(_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all]);
|
|
135
|
+
return isAllSelection((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, selections.size, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions);
|
|
136
|
+
}, [(_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, selections.size]);
|
|
134
137
|
const selectableState = useMemo(() => calculateSelectionState(entities, selections, isAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy), [checkboxDisabled, checkboxVisible, entities, isAllSelected, selections, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
138
|
+
const selectionMenuState = getSelectionMenuState(isAllSelected, selections, selectableState);
|
|
135
139
|
const firstColumnId = useMemo(() => columns.length > 0 ? columns[0].id : null, [columns]);
|
|
136
140
|
useEffect(() => {
|
|
137
141
|
if (selectable && selectable.selection) {
|
|
138
142
|
const newSelections = new Set(selectable.selection.selected);
|
|
139
|
-
const newState = calculateSelectionState(entities, newSelections,
|
|
143
|
+
const newState = calculateSelectionState(entities, newSelections, isAllSelected, checkboxVisible, checkboxDisabled, selectable.strategy);
|
|
140
144
|
setState(newState);
|
|
141
145
|
}
|
|
142
|
-
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
146
|
+
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, selectable === null || selectable === void 0 ? void 0 : selectable.strategy, isAllSelected]);
|
|
143
147
|
const getNewSelection = useCallback((id, checked) => {
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
if (isAllSelected && !(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions)) {
|
|
149
|
+
const included = getCurrentPageSelection(entities, wrappedSelectable);
|
|
150
|
+
checkRow(included, wrappedSelectable, entities, id, checked);
|
|
151
|
+
return included;
|
|
152
|
+
}
|
|
153
|
+
if (isAllSelected) {
|
|
146
154
|
// MYG-142234: `selections` holds the ids excluded from the "all" selection.
|
|
147
155
|
// Toggling a row here must only ever add/remove that single id from the
|
|
148
156
|
// exclusion set - it must never be rebuilt from `entities` (the current page),
|
|
@@ -153,10 +161,9 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
153
161
|
}
|
|
154
162
|
checkRow(selections, wrappedSelectable, entities, id, checked);
|
|
155
163
|
return selections;
|
|
156
|
-
}, [entities, selectable, wrappedSelectable, selections]);
|
|
164
|
+
}, [entities, selectable, wrappedSelectable, selections, isAllSelected]);
|
|
157
165
|
const onSelectListener = useCallback((id, checked) => {
|
|
158
|
-
|
|
159
|
-
const wasAllSelected = ((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all) || false;
|
|
166
|
+
const wasAllSelected = !!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && isAllSelected;
|
|
160
167
|
const newSelection = getNewSelection(id, checked);
|
|
161
168
|
const newState = calculateSelectionState(entities, newSelection, wasAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy);
|
|
162
169
|
// MYG-142234: once selection spans "all" pages, unchecking a row must keep `all: true`
|
|
@@ -171,26 +178,26 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
171
178
|
setState(newState);
|
|
172
179
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
173
180
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
174
|
-
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, setState, getNewSelection]);
|
|
181
|
+
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, setState, getNewSelection, isAllSelected]);
|
|
175
182
|
const onBatchSelect = useCallback((rangeIds, select, base) => {
|
|
176
|
-
var _a;
|
|
177
183
|
const result = new Set(base);
|
|
178
184
|
const limit = selectable === null || selectable === void 0 ? void 0 : selectable.selectionLimit;
|
|
185
|
+
const wasAllSelected = !!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && isAllSelected;
|
|
179
186
|
for (const id of rangeIds) {
|
|
180
|
-
if (select && limit !== undefined && result.size >= limit) {
|
|
187
|
+
if (!wasAllSelected && select && limit !== undefined && result.size >= limit) {
|
|
181
188
|
break;
|
|
182
189
|
}
|
|
183
|
-
checkRow(result, wrappedSelectable, entities, id, select);
|
|
190
|
+
checkRow(result, wrappedSelectable, entities, id, wasAllSelected ? !select : select);
|
|
184
191
|
}
|
|
185
|
-
const newState = calculateSelectionState(entities, result,
|
|
192
|
+
const newState = calculateSelectionState(entities, result, wasAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy);
|
|
186
193
|
const newValue = {
|
|
187
194
|
selected: [...result],
|
|
188
|
-
all: newState === SelectionState.All
|
|
195
|
+
all: wasAllSelected || newState === SelectionState.All
|
|
189
196
|
};
|
|
190
197
|
setState(newState);
|
|
191
198
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
192
199
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
193
|
-
}, [entities, selectable, wrappedSelectable, checkboxVisible, checkboxDisabled, setSelectMode]);
|
|
200
|
+
}, [entities, selectable, wrappedSelectable, checkboxVisible, checkboxDisabled, setSelectMode, isAllSelected]);
|
|
194
201
|
// Deliberately independent of the current selection, so the drag anchor survives the
|
|
195
202
|
// selection changes a drag itself produces.
|
|
196
203
|
const {
|
|
@@ -201,7 +208,7 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
201
208
|
const entity = entityById.get(row.id);
|
|
202
209
|
return !!entity && checkboxVisible(entity, row.isNested) && !checkboxDisabled(entity, row.isNested);
|
|
203
210
|
}, [entityById, checkboxVisible, checkboxDisabled]);
|
|
204
|
-
const getBaseSelection = useCallback(() =>
|
|
211
|
+
const getBaseSelection = useCallback(() => isAllSelected && !(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) ? getCurrentPageSelection(entities, wrappedSelectable) : new Set(selections), [isAllSelected, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, entities, wrappedSelectable, selections]);
|
|
205
212
|
const {
|
|
206
213
|
onCheckboxMouseDown,
|
|
207
214
|
suppressNextChangeRef
|
|
@@ -233,14 +240,12 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
233
240
|
}
|
|
234
241
|
const newSelections = getCurrentPageSelection(entities, wrappedSelectable);
|
|
235
242
|
setState(newState);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const newValue = {
|
|
243
|
-
selected: [...mergedSelections],
|
|
243
|
+
const previousSelections = (_b = (_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.selected) !== null && _b !== void 0 ? _b : [];
|
|
244
|
+
const newValue = (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_c = selectable.selection) === null || _c === void 0 ? void 0 : _c.all) ? {
|
|
245
|
+
selected: previousSelections.filter(id => !newSelections.has(id)),
|
|
246
|
+
all: true
|
|
247
|
+
} : {
|
|
248
|
+
selected: [...new Set([...previousSelections, ...newSelections])],
|
|
244
249
|
all: false
|
|
245
250
|
};
|
|
246
251
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
@@ -319,7 +324,9 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
319
324
|
const newState = checkboxEmitsCurrentPage ? SelectionState.CurrentPage : SelectionState.All;
|
|
320
325
|
setState(newState);
|
|
321
326
|
onChangeSelectionState(newState);
|
|
322
|
-
} else if (
|
|
327
|
+
} else if (isInfinite) {
|
|
328
|
+
onChangeSelectionState(SelectionState.None);
|
|
329
|
+
} else if (selectable.allowExclusions && ((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.all)) {
|
|
323
330
|
// MYG-142234: in exclusion mode, `selected` holds excluded ids. Unchecking
|
|
324
331
|
// the header must add the current page's ids to that exclusion set and
|
|
325
332
|
// keep `all: true` - it must never be treated as an inclusion list, or
|
|
@@ -347,7 +354,7 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
347
354
|
setSelectMode(remaining.length > 0);
|
|
348
355
|
}
|
|
349
356
|
},
|
|
350
|
-
calculateSelectionState: () =>
|
|
357
|
+
calculateSelectionState: () => selectionMenuState,
|
|
351
358
|
checkboxInHeader: checkboxInHeaderValue,
|
|
352
359
|
header: selectableHeader,
|
|
353
360
|
onSelect: newState => {
|
|
@@ -360,7 +367,7 @@ export const useSelectableRows = (columns, entities, isMobile, selectMode, setSe
|
|
|
360
367
|
return cell;
|
|
361
368
|
}
|
|
362
369
|
};
|
|
363
|
-
}, [checkboxDisabled, checkboxTitle, checkboxVisible, headerTitle, onChangeSelectionState, onCheckboxChange, onCheckboxMouseDown, hasSelectable, checkboxEmitsCurrentPage, checkboxInHeaderValue, selectableHeader, selectableTurnOffSelectAll, isInfinite, selectable, wrappedSelectable,
|
|
370
|
+
}, [checkboxDisabled, checkboxTitle, checkboxVisible, headerTitle, onChangeSelectionState, onCheckboxChange, onCheckboxMouseDown, hasSelectable, checkboxEmitsCurrentPage, checkboxInHeaderValue, selectableHeader, selectableTurnOffSelectAll, isInfinite, selectable, wrappedSelectable, selectionMenuState, state, isMobile, checkboxPlaceholder, isEntityChecked, entities, setSelectMode]);
|
|
364
371
|
const selectableFeedWrapper = useCallback((primaryData, secondaryData, entity, isNested) => {
|
|
365
372
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
366
373
|
if (!entity) {
|
|
@@ -9,10 +9,7 @@ export const calculateSelectionState = (entities, selections, all, checkboxVisib
|
|
|
9
9
|
// otherwise-fully-selected set (see ISelectionValue), rather than included ids.
|
|
10
10
|
const isExcluded = (entity) => {
|
|
11
11
|
const children = strategy === "nested" ? getChildrenForSelection(entity) : undefined;
|
|
12
|
-
if (children) {
|
|
13
|
-
if (children.length === 0) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
12
|
+
if (children && children.length > 0) {
|
|
16
13
|
return children.every(child => {
|
|
17
14
|
if (!checkboxVisible(child, true)) {
|
|
18
15
|
return true;
|
|
@@ -27,7 +24,7 @@ export const calculateSelectionState = (entities, selections, all, checkboxVisib
|
|
|
27
24
|
};
|
|
28
25
|
const isPartiallyExcluded = (entity) => {
|
|
29
26
|
const children = strategy === "nested" ? getChildrenForSelection(entity) : undefined;
|
|
30
|
-
if (children) {
|
|
27
|
+
if (children && children.length > 0) {
|
|
31
28
|
return children.some(child => selections.has(child.id));
|
|
32
29
|
}
|
|
33
30
|
return selections.has(entity.id);
|
|
@@ -50,7 +47,7 @@ export const calculateSelectionState = (entities, selections, all, checkboxVisib
|
|
|
50
47
|
}
|
|
51
48
|
if (strategy === "nested") {
|
|
52
49
|
const children = getChildrenForSelection(entity);
|
|
53
|
-
if (children) {
|
|
50
|
+
if (children && children.length > 0) {
|
|
54
51
|
return children.every(child => {
|
|
55
52
|
if (!checkboxVisible(child, true)) {
|
|
56
53
|
return true;
|
|
@@ -61,7 +58,7 @@ export const calculateSelectionState = (entities, selections, all, checkboxVisib
|
|
|
61
58
|
return selections.has(child.id);
|
|
62
59
|
});
|
|
63
60
|
}
|
|
64
|
-
return
|
|
61
|
+
return selections.has(entity.id);
|
|
65
62
|
}
|
|
66
63
|
return selections.has(entity.id);
|
|
67
64
|
})
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { getChildrenForSelection } from "../../../commonHelpers/showMoreRow";
|
|
1
|
+
import { getChildrenForSelection, isShowMoreRow } from "../../../commonHelpers/showMoreRow";
|
|
2
2
|
export const getCurrentPageSelection = (entities, selectable) => {
|
|
3
3
|
const newSelections = new Set();
|
|
4
4
|
entities.forEach(entity => {
|
|
5
|
-
const isVisible = (selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(entity) : true;
|
|
5
|
+
const isVisible = !entity.isLoading && !isShowMoreRow(entity) && ((selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(entity) : true);
|
|
6
6
|
const isEnabled = !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) || !selectable.checkboxDisabled(entity);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
7
|
+
const children = (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) === "nested" ? getChildrenForSelection(entity) : undefined;
|
|
8
|
+
if (children && children.length > 0) {
|
|
9
|
+
children.forEach(child => {
|
|
10
|
+
const isChildVisible = !child.isLoading &&
|
|
11
|
+
!isShowMoreRow(child) &&
|
|
12
|
+
((selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(child, true) : true);
|
|
13
|
+
const isChildEnabled = !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) || !selectable.checkboxDisabled(child, true);
|
|
11
14
|
if (isChildVisible && isChildEnabled) {
|
|
12
15
|
newSelections.add(child.id);
|
|
13
16
|
}
|
package/esm/table/table.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IZenComponentProps, IZenGridItem } from "../commonHelpers/zenComponent";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
-
import { ISelectableRowsOptions } from "./selectable/useSelectableRows";
|
|
3
|
+
import { getEmptySelection, ISelectableRowsOptions } from "./selectable/useSelectableRows";
|
|
4
4
|
import { ISortableOptions } from "./sortable/useSortableColumns";
|
|
5
5
|
import { IFlexibleColumnsOptions } from "./flexible/useFlexibleColumns";
|
|
6
6
|
import { IColumnComponent, IListColumnWrapper } from "../dataGrid/listColumn";
|
|
@@ -11,7 +11,6 @@ import { ITablePagination, TablePagination } from "./children/tablePagination";
|
|
|
11
11
|
import { ITableEmpty, TableEmpty } from "./children/tableEmpty";
|
|
12
12
|
import { ITableFooter, TableFooter } from "./children/tableFooter";
|
|
13
13
|
import "./table.less";
|
|
14
|
-
import { getEmptySelection } from "./selectable/useSelectableRows";
|
|
15
14
|
import { ColumnSortDirection } from "./sortable/interfaces";
|
|
16
15
|
import { getSortableValue } from "./sortable/useSortableColumns";
|
|
17
16
|
import { ActionsColumn } from "../dataGrid/columns/actionsColumn/actionsColumn";
|
package/esm/table/table.js
CHANGED
|
@@ -4,7 +4,7 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
4
4
|
import { DataFeed } from "../dataFeed/dataFeed";
|
|
5
5
|
import { DataGrid as DataGridInternal, EndOfList as DataGridEndOfList } from "../dataGrid/dataGrid";
|
|
6
6
|
import { LazyLoadingEnd } from "../dataGrid/lazyLoadingEnd/lazyLoadingEnd";
|
|
7
|
-
import { useSelectableRows } from "./selectable/useSelectableRows";
|
|
7
|
+
import { getEmptySelection, isAllSelection, useSelectableRows } from "./selectable/useSelectableRows";
|
|
8
8
|
import { useSortableColumns } from "./sortable/useSortableColumns";
|
|
9
9
|
import { useFlexibleColumns } from "./flexible/useFlexibleColumns";
|
|
10
10
|
import { useActions } from "./actions/useActions";
|
|
@@ -16,12 +16,12 @@ import { ColumnsListButton } from "../dataGrid/entitiesListActions/actions/colum
|
|
|
16
16
|
import { useTableChildren } from "./children/useTableChildren";
|
|
17
17
|
import { DeviceType } from "../commonHelpers/hooks/deviceType";
|
|
18
18
|
import { useMobile } from "../commonHelpers/hooks/useMobile";
|
|
19
|
+
import { getCurrentPageSelection } from "./selectable/utils/getCurrentPageSelection";
|
|
19
20
|
import { TableFullscreen } from "./children/tableFullscreen";
|
|
20
21
|
import { TableBulkActions } from "./children/tableBulkActions";
|
|
21
22
|
import { TablePagination } from "./children/tablePagination";
|
|
22
23
|
import { TableEmpty } from "./children/tableEmpty";
|
|
23
24
|
import { TableFooter } from "./children/tableFooter";
|
|
24
|
-
import { getEmptySelection } from "./selectable/useSelectableRows";
|
|
25
25
|
import { ColumnSortDirection } from "./sortable/interfaces";
|
|
26
26
|
import { getSortableValue } from "./sortable/useSortableColumns";
|
|
27
27
|
import { ActionsColumn } from "../dataGrid/columns/actionsColumn/actionsColumn";
|
|
@@ -185,7 +185,7 @@ const TableInner = ({
|
|
|
185
185
|
active,
|
|
186
186
|
onClick
|
|
187
187
|
}) => {
|
|
188
|
-
var _a, _b, _c;
|
|
188
|
+
var _a, _b, _c, _d, _e;
|
|
189
189
|
const isMobile = useMobile();
|
|
190
190
|
const {
|
|
191
191
|
translate
|
|
@@ -275,13 +275,19 @@ const TableInner = ({
|
|
|
275
275
|
} = useFeedExpandable(isMobile, feedExpandable);
|
|
276
276
|
// Keep bulk-action state available during initial/replacement loading for backward compatibility.
|
|
277
277
|
// The row controls themselves still use selectableForRender and remain hidden until real rows can render.
|
|
278
|
-
const
|
|
278
|
+
const allSelected = useMemo(() => {
|
|
279
279
|
var _a, _b;
|
|
280
|
+
return isAllSelection((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, (_b = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _b === void 0 ? void 0 : _b.selected.length, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions);
|
|
281
|
+
}, [(_c = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _c === void 0 ? void 0 : _c.all, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, (_d = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _d === void 0 ? void 0 : _d.selected.length]);
|
|
282
|
+
const selectionQty = useMemo(() => {
|
|
283
|
+
var _a;
|
|
280
284
|
if (!selectable) {
|
|
281
285
|
return 0;
|
|
282
286
|
}
|
|
283
|
-
|
|
284
|
-
|
|
287
|
+
const ids = new Set((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.selected);
|
|
288
|
+
const base = entities.length > 0 ? entities : loadingEntities;
|
|
289
|
+
return allSelected ? [...getCurrentPageSelection(base, selectable)].filter(id => !selectable.allowExclusions || !ids.has(id)).length : ids.size;
|
|
290
|
+
}, [selectable, entities, loadingEntities, allSelected]);
|
|
285
291
|
const clearSelection = useCallback(() => {
|
|
286
292
|
setSelectMode(false);
|
|
287
293
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect({
|
|
@@ -298,6 +304,7 @@ const TableInner = ({
|
|
|
298
304
|
}, [onClickRow]);
|
|
299
305
|
const {
|
|
300
306
|
bulkActions,
|
|
307
|
+
hasSelection,
|
|
301
308
|
pagination,
|
|
302
309
|
paginationTotal,
|
|
303
310
|
activePage,
|
|
@@ -306,7 +313,7 @@ const TableInner = ({
|
|
|
306
313
|
detailPanel,
|
|
307
314
|
footer,
|
|
308
315
|
other
|
|
309
|
-
} = useTableChildren(children, isMobile, selectionQty, ((
|
|
316
|
+
} = useTableChildren(children, isMobile, selectionQty, allSelected, clearSelection, activeId, gridRef, onCloseDetailPanel, isInfinite, entities.length, (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_e = selectable.selection) === null || _e === void 0 ? void 0 : _e.all) ? new Set(selectable.selection.selected).size : 0, (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) !== "nested" && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible), !!feedEndCallback || !!isLoading);
|
|
310
317
|
const hasDetailPanel = !!detailPanel;
|
|
311
318
|
const shouldEnableRowClick = hasDetailPanel || !!onClick;
|
|
312
319
|
const activeIdForRow = shouldEnableRowClick ? activeId : undefined;
|
|
@@ -341,7 +348,7 @@ const TableInner = ({
|
|
|
341
348
|
children: [hasToolbar ? _jsxs(EntitiesListActions, {
|
|
342
349
|
gridType: isMobile ? DeviceType.Mobile : DeviceType.Desktop,
|
|
343
350
|
children: [_jsxs(EntitiesListActions.Actions, {
|
|
344
|
-
children: [!isMobile &&
|
|
351
|
+
children: [!isMobile && hasSelection ? bulkActions : null, feedSortControl]
|
|
345
352
|
}), showPagination || other.length > 0 ? _jsxs(EntitiesListActions.Pagination, {
|
|
346
353
|
children: [_jsx(EntitiesListActions.CustomElements, {
|
|
347
354
|
children: other
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geotab/zenith",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.17.0-beta.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
4
7
|
"description": "Zenith components library on React",
|
|
5
8
|
"main": "dist/index.js",
|
|
6
9
|
"types": "esm/index.d.ts",
|
|
@@ -156,8 +159,5 @@
|
|
|
156
159
|
"minimatch@<9": {
|
|
157
160
|
"brace-expansion": "^1.1.18"
|
|
158
161
|
}
|
|
159
|
-
},
|
|
160
|
-
"publishConfig": {
|
|
161
|
-
"access": "public"
|
|
162
162
|
}
|
|
163
163
|
}
|