@geotab/zenith 3.17.0-beta.1 → 3.17.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 +26 -29
- package/dist/button/button.d.ts +1 -2
- package/dist/button/button.js +5 -22
- package/dist/button/buttonDisabledProps.d.ts +35 -0
- package/dist/button/buttonDisabledProps.js +33 -0
- package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +1 -1
- package/dist/dropdownRaw/dropdownHelper.d.ts +20 -3
- package/dist/dropdownRaw/dropdownHelper.js +29 -6
- package/dist/dropdownRaw/dropdownRaw.js +22 -6
- package/dist/header/components/collapsedItemsControl/collapsedItemsControl.js +1 -1
- package/dist/header/headerButton.d.ts +15 -2
- package/dist/header/headerButton.js +11 -6
- package/dist/index.css +4 -8
- package/dist/menu/components/menuButton.js +40 -58
- package/dist/pageHeader/pageHeaderButton.d.ts +15 -1
- package/dist/pageHeader/pageHeaderButton.js +8 -6
- package/dist/pillExpandable/pillExpandable.js +3 -1
- package/dist/pillExpandable/pillExpandableSimple.d.ts +2 -1
- package/dist/pillExpandable/pillExpandableSimple.js +2 -2
- package/dist/table/selectable/interfaces.d.ts +6 -0
- package/dist/table/selectable/useDragSelection.d.ts +1 -1
- package/dist/table/selectable/useDragSelection.js +4 -4
- package/dist/table/selectable/useSelectableRows.d.ts +2 -0
- package/dist/table/selectable/useSelectableRows.js +88 -41
- package/dist/table/selectable/utils/calculateSelectionState.js +3 -2
- package/dist/table/selectable/utils/getCurrentPageSelection.js +9 -4
- package/dist/table/selectable/utils/groupExclusions.d.ts +7 -0
- package/dist/table/selectable/utils/groupExclusions.js +61 -0
- package/dist/table/selectable/utils/isRowChecked.js +1 -1
- package/dist/table/table.js +6 -5
- package/dist/tooltip/tooltip.d.ts +5 -3
- package/dist/tooltip/tooltip.js +11 -9
- package/esm/button/button.d.ts +1 -2
- package/esm/button/button.js +5 -22
- package/esm/button/buttonDisabledProps.d.ts +35 -0
- package/esm/button/buttonDisabledProps.js +29 -0
- package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +1 -1
- package/esm/dropdownRaw/dropdownHelper.d.ts +20 -3
- package/esm/dropdownRaw/dropdownHelper.js +27 -5
- package/esm/dropdownRaw/dropdownRaw.js +23 -7
- package/esm/header/components/collapsedItemsControl/collapsedItemsControl.js +1 -1
- package/esm/header/headerButton.d.ts +15 -2
- package/esm/header/headerButton.js +11 -6
- package/esm/menu/components/menuButton.js +40 -58
- package/esm/pageHeader/pageHeaderButton.d.ts +15 -1
- package/esm/pageHeader/pageHeaderButton.js +8 -6
- package/esm/pillExpandable/pillExpandable.js +3 -1
- package/esm/pillExpandable/pillExpandableSimple.d.ts +2 -1
- package/esm/pillExpandable/pillExpandableSimple.js +2 -2
- package/esm/table/selectable/interfaces.d.ts +6 -0
- package/esm/table/selectable/useDragSelection.d.ts +1 -1
- package/esm/table/selectable/useDragSelection.js +4 -4
- package/esm/table/selectable/useSelectableRows.d.ts +2 -0
- package/esm/table/selectable/useSelectableRows.js +90 -43
- package/esm/table/selectable/utils/calculateSelectionState.js +3 -2
- package/esm/table/selectable/utils/getCurrentPageSelection.js +9 -4
- package/esm/table/selectable/utils/groupExclusions.d.ts +7 -0
- package/esm/table/selectable/utils/groupExclusions.js +55 -0
- package/esm/table/selectable/utils/isRowChecked.js +1 -1
- package/esm/table/table.js +6 -5
- package/esm/tooltip/tooltip.d.ts +5 -3
- package/esm/tooltip/tooltip.js +11 -9
- package/package.json +1 -1
- package/README.md.baseline +0 -1
|
@@ -2,6 +2,7 @@ import { IButton } from "../button/button";
|
|
|
2
2
|
import { TButtonIconPosition } from "../textIconButton/textIconButton";
|
|
3
3
|
import { TSvgIconSize } from "../svgIcon/svgIconSize";
|
|
4
4
|
import { IIcon } from "../icons/icon";
|
|
5
|
+
import { TAlignment } from "../absolute/absolute";
|
|
5
6
|
export interface IPageHeaderButton extends Omit<IButton, "onClick" | "icon" | "title"> {
|
|
6
7
|
id: string;
|
|
7
8
|
icon: React.FC<IIcon>;
|
|
@@ -9,10 +10,23 @@ export interface IPageHeaderButton extends Omit<IButton, "onClick" | "icon" | "t
|
|
|
9
10
|
iconPosition?: TButtonIconPosition;
|
|
10
11
|
iconClasses?: string;
|
|
11
12
|
iconSize?: TSvgIconSize;
|
|
13
|
+
/**
|
|
14
|
+
* Tooltip content shown only while the button is `disabled`.
|
|
15
|
+
*
|
|
16
|
+
* When `disabled` and `disabledTooltip` are both set, the button uses `aria-disabled` instead of the native
|
|
17
|
+
* `disabled` attribute, so it stays focusable and hoverable and the tooltip can explain why it is unavailable.
|
|
18
|
+
* In every other case the standard `disabled` attribute is used, and `disabledTooltip` is ignored while the
|
|
19
|
+
* button is enabled.
|
|
20
|
+
*/
|
|
21
|
+
disabledTooltip?: React.ReactNode;
|
|
12
22
|
onClick?: (id: string, event: React.MouseEvent) => void;
|
|
13
23
|
}
|
|
24
|
+
interface IPageHeaderButtonInternal {
|
|
25
|
+
tooltipAlignment?: TAlignment;
|
|
26
|
+
}
|
|
14
27
|
export declare const PageHeaderButtonDisplayName = "PageHeaderButton";
|
|
15
28
|
export declare const PageHeaderButton: {
|
|
16
|
-
({ id, children, icon, iconPosition, className, onClick, title, disabled,
|
|
29
|
+
({ id, children, icon, iconPosition, className, onClick, title, disabledTooltip, tooltipAlignment, disabled, link, ...restProps }: IPageHeaderButton & IPageHeaderButtonInternal): import("react/jsx-runtime").JSX.Element;
|
|
17
30
|
displayName: string;
|
|
18
31
|
};
|
|
32
|
+
export {};
|
|
@@ -15,14 +15,16 @@ exports.PageHeaderButton = exports.PageHeaderButtonDisplayName = void 0;
|
|
|
15
15
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
16
|
const textIconButton_1 = require("../textIconButton/textIconButton");
|
|
17
17
|
const classNames_1 = require("../commonHelpers/classNames/classNames");
|
|
18
|
+
const tooltip_1 = require("../tooltip/tooltip");
|
|
19
|
+
const buttonDisabledProps_1 = require("../button/buttonDisabledProps");
|
|
18
20
|
exports.PageHeaderButtonDisplayName = "PageHeaderButton";
|
|
19
21
|
const PageHeaderButton = (_a) => {
|
|
20
|
-
var { id, children, icon, iconPosition = textIconButton_1.ButtonIconPosition.Start, className = "", onClick, title, disabled,
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
22
|
+
var { id, children, icon, iconPosition = textIconButton_1.ButtonIconPosition.Start, className = "", onClick, title, disabledTooltip, tooltipAlignment = "bottom", disabled, link } = _a, restProps = __rest(_a, ["id", "children", "icon", "iconPosition", "className", "onClick", "title", "disabledTooltip", "tooltipAlignment", "disabled", "link"]);
|
|
23
|
+
const tooltip = disabled ? disabledTooltip : undefined;
|
|
24
|
+
const _b = (0, buttonDisabledProps_1.getButtonDisabledProps)({ disabled, focusable: Boolean(tooltip), link }), { className: disabledClassName } = _b, disabledProps = __rest(_b, ["className"]);
|
|
25
|
+
const fullClassName = (0, classNames_1.classNames)(["zen-page-header-button", className || "", disabledClassName !== null && disabledClassName !== void 0 ? disabledClassName : ""]);
|
|
26
|
+
const button = ((0, jsx_runtime_1.jsx)(textIconButton_1.TextIconButton, Object.assign({ id: id, icon: icon, title: title, iconPosition: iconPosition, className: fullClassName, onClick: onClick ? e => onClick(id, e) : undefined, link: link }, restProps, disabledProps, { children: children })));
|
|
27
|
+
return tooltip ? ((0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { trigger: button, alignment: tooltipAlignment, children: tooltip })) : (button);
|
|
26
28
|
};
|
|
27
29
|
exports.PageHeaderButton = PageHeaderButton;
|
|
28
30
|
exports.PageHeaderButton.displayName = exports.PageHeaderButtonDisplayName;
|
|
@@ -428,6 +428,7 @@ const PillExpandableBase = ({
|
|
|
428
428
|
}) => {
|
|
429
429
|
const popupId = (0, react_1.useId)();
|
|
430
430
|
const descriptionId = (0, react_1.useId)();
|
|
431
|
+
const counterId = (0, react_1.useId)();
|
|
431
432
|
const [descriptionElement, setDescriptionElement] = (0, react_1.useState)(null);
|
|
432
433
|
const isDrive = (0, useDrive_1.useDrive)();
|
|
433
434
|
const [isMobile, setIsMobile] = (0, react_1.useState)(false);
|
|
@@ -596,10 +597,11 @@ const PillExpandableBase = ({
|
|
|
596
597
|
errorHandler: errorHandler,
|
|
597
598
|
isBeta: isBeta,
|
|
598
599
|
isMobile: isMobile,
|
|
599
|
-
descriptionId: isPopupOpen && descriptionElement ? descriptionId : undefined,
|
|
600
|
+
descriptionId: [uniqueChildren && !hideCounterNumber ? counterId : undefined, isPopupOpen && descriptionElement ? descriptionId : undefined].filter(Boolean).join(" ") || undefined,
|
|
600
601
|
ariaHasPopup: "dialog",
|
|
601
602
|
dataAnalyticsId: dataAnalyticsId
|
|
602
603
|
}), uniqueChildren && (0, jsx_runtime_1.jsx)(pillExpandableSimple_1.PillExpandableSimple, {
|
|
604
|
+
id: counterId,
|
|
603
605
|
icon: secondaryIcon || effectiveIcon,
|
|
604
606
|
text: hideCounterNumber ? "" : counterText,
|
|
605
607
|
includeExpandIcon: false,
|
|
@@ -2,6 +2,7 @@ import { FC, RefObject } from "react";
|
|
|
2
2
|
import { IPillExpandableBase, TPillType } from "./pillExpandable";
|
|
3
3
|
import { IIcon } from "../icons/icon";
|
|
4
4
|
interface IPillExpandableSimple extends IPillExpandableBase {
|
|
5
|
+
id?: string;
|
|
5
6
|
includeExpandIcon?: boolean;
|
|
6
7
|
expanded?: boolean;
|
|
7
8
|
onExpand?: () => void;
|
|
@@ -15,7 +16,7 @@ interface IPillExpandableSimple extends IPillExpandableBase {
|
|
|
15
16
|
type?: TPillType;
|
|
16
17
|
}
|
|
17
18
|
export declare const PillExpandableSimple: {
|
|
18
|
-
({ onExpand, text, expanded, includeExpandIcon, type, icon, isBeta, isMobile, ref, className, descriptionId, ariaHasPopup, isDecorative, dataAnalyticsId }: IPillExpandableSimple): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
({ id, onExpand, text, expanded, includeExpandIcon, type, icon, isBeta, isMobile, ref, className, descriptionId, ariaHasPopup, isDecorative, dataAnalyticsId }: IPillExpandableSimple): import("react/jsx-runtime").JSX.Element;
|
|
19
20
|
displayName: string;
|
|
20
21
|
};
|
|
21
22
|
export {};
|
|
@@ -8,7 +8,7 @@ const iconChevronTop_1 = require("../icons/iconChevronTop");
|
|
|
8
8
|
const iconChevronBottom_1 = require("../icons/iconChevronBottom");
|
|
9
9
|
const iconException_1 = require("../icons/iconException");
|
|
10
10
|
const classNames_1 = require("../commonHelpers/classNames/classNames");
|
|
11
|
-
const PillExpandableSimple = ({ onExpand, text, expanded, includeExpandIcon = true, type = "warning", icon = iconException_1.IconException, isBeta, isMobile, ref, className, descriptionId, ariaHasPopup, isDecorative, dataAnalyticsId
|
|
11
|
+
const PillExpandableSimple = ({ id, onExpand, text, expanded, includeExpandIcon = true, type = "warning", icon = iconException_1.IconException, isBeta, isMobile, ref, className, descriptionId, ariaHasPopup, isDecorative, dataAnalyticsId
|
|
12
12
|
// eslint-disable-next-line complexity
|
|
13
13
|
}) => {
|
|
14
14
|
const iconDriveClassName = (0, useDriveClassName_1.useDriveClassName)("icon");
|
|
@@ -37,7 +37,7 @@ const PillExpandableSimple = ({ onExpand, text, expanded, includeExpandIcon = tr
|
|
|
37
37
|
size: iconSize
|
|
38
38
|
}) }) }))] }));
|
|
39
39
|
if (isDecorative) {
|
|
40
|
-
return ((0, jsx_runtime_1.jsx)("span", { className: (0, classNames_1.classNames)([
|
|
40
|
+
return ((0, jsx_runtime_1.jsx)("span", { id: id, className: (0, classNames_1.classNames)([
|
|
41
41
|
"zen-status-pill__container",
|
|
42
42
|
`zen-status-pill__container--${type}`,
|
|
43
43
|
containerDriveClassName || "",
|
|
@@ -15,6 +15,12 @@ export interface ISelectionValue {
|
|
|
15
15
|
* Consumers opting in must resolve the effective selection before running bulk actions.
|
|
16
16
|
*/
|
|
17
17
|
selected: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Excluded nested groups, including children that have not loaded yet. Only used with
|
|
20
|
+
* allowExclusions and all: true. Preserve this field when saving controlled selection;
|
|
21
|
+
* resolve these groups as well as selected before running a bulk action.
|
|
22
|
+
*/
|
|
23
|
+
excludedGroupIds?: string[];
|
|
18
24
|
}
|
|
19
25
|
/**
|
|
20
26
|
* One checkbox row in the order it is rendered. Expanded nested rows are part of this list,
|
|
@@ -4,7 +4,7 @@ import { IDragSelectionRow } from "./interfaces";
|
|
|
4
4
|
* @param rows every checkbox row in render order, expanded nested rows included, so ranges can
|
|
5
5
|
* span nesting levels.
|
|
6
6
|
*/
|
|
7
|
-
export declare const useDragSelection: (rows: IDragSelectionRow[], gridRef: RefObject<HTMLElement | null> | undefined, onBatchSelect: (rangeIds: string[], select: boolean, base:
|
|
7
|
+
export declare const useDragSelection: <TSelection = Set<string>>(rows: IDragSelectionRow[], gridRef: RefObject<HTMLElement | null> | undefined, onBatchSelect: (rangeIds: string[], select: boolean, base: TSelection) => void, getBaseSelection: () => TSelection, isSelectable: (row: IDragSelectionRow) => boolean, isEnabled: boolean) => {
|
|
8
8
|
onCheckboxMouseDown: (id: string, checked: boolean, e: ReactMouseEvent) => void;
|
|
9
9
|
suppressNextChangeRef: RefObject<boolean>;
|
|
10
10
|
};
|
|
@@ -22,7 +22,7 @@ const useDragSelection = (rows, gridRef, onBatchSelect, getBaseSelection, isSele
|
|
|
22
22
|
isEnabledRef.current = isEnabled;
|
|
23
23
|
const anchorIdRef = (0, react_1.useRef)(null);
|
|
24
24
|
const anchorSelectRef = (0, react_1.useRef)(true);
|
|
25
|
-
const baseSelectedRef = (0, react_1.useRef)(
|
|
25
|
+
const baseSelectedRef = (0, react_1.useRef)(null);
|
|
26
26
|
const isDraggingRef = (0, react_1.useRef)(false);
|
|
27
27
|
const movedRef = (0, react_1.useRef)(false);
|
|
28
28
|
const lastResultKeyRef = (0, react_1.useRef)("");
|
|
@@ -31,7 +31,7 @@ const useDragSelection = (rows, gridRef, onBatchSelect, getBaseSelection, isSele
|
|
|
31
31
|
const attachedGridElementRef = (0, react_1.useRef)(null);
|
|
32
32
|
const emitRange = (0, react_1.useCallback)((currentId) => {
|
|
33
33
|
const anchorId = anchorIdRef.current;
|
|
34
|
-
if (anchorId === null) {
|
|
34
|
+
if (anchorId === null || baseSelectedRef.current === null) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
const range = (0, getRangeIds_1.getRangeIds)(rowsRef.current, anchorId, currentId, isSelectableRef.current);
|
|
@@ -85,7 +85,7 @@ const useDragSelection = (rows, gridRef, onBatchSelect, getBaseSelection, isSele
|
|
|
85
85
|
(_c = attachedGridElementRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener("scroll", onScroll);
|
|
86
86
|
(_d = attachedGridElementRef.current) === null || _d === void 0 ? void 0 : _d.classList.remove(DRAG_CLASS);
|
|
87
87
|
attachedGridElementRef.current = null;
|
|
88
|
-
}, [onMouseMove, onScroll]);
|
|
88
|
+
}, [onMouseMove, onScroll]);
|
|
89
89
|
const onCheckboxMouseDown = (0, react_1.useCallback)((id, checked, e) => {
|
|
90
90
|
var _a, _b, _c, _d, _e;
|
|
91
91
|
// Right-click between drag-end and the trailing click must not clear suppression.
|
|
@@ -95,7 +95,7 @@ const useDragSelection = (rows, gridRef, onBatchSelect, getBaseSelection, isSele
|
|
|
95
95
|
if (!isEnabledRef.current || e.button !== 0) {
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
|
-
if (e.shiftKey && anchorIdRef.current !== null) {
|
|
98
|
+
if (e.shiftKey && anchorIdRef.current !== null && baseSelectedRef.current !== null) {
|
|
99
99
|
e.preventDefault();
|
|
100
100
|
const anchorId = anchorIdRef.current;
|
|
101
101
|
const anchorInList = rowsRef.current.some(row => row.id === anchorId);
|
|
@@ -10,6 +10,8 @@ export interface ISelectableRowsOptions<T extends IRowEntity<N>, N extends IEnti
|
|
|
10
10
|
onSelect: (selection: ISelectionValue) => void;
|
|
11
11
|
/** Preserve cross-page Select All using excluded IDs. Consumers must resolve exclusions before running bulk actions. Defaults to false. */
|
|
12
12
|
allowExclusions?: boolean;
|
|
13
|
+
/** Changes when the dataset represented by the selection is replaced, rather than paged. */
|
|
14
|
+
selectionDatasetId?: string | number;
|
|
13
15
|
checkboxDisabled?: (entity: T | N, isNested?: boolean) => boolean;
|
|
14
16
|
checkboxVisible?: (entity: T | N, isNested?: boolean) => boolean;
|
|
15
17
|
checkboxInHeader?: boolean;
|
|
@@ -88,6 +88,7 @@ const getCurrentPageSelection_1 = require("./utils/getCurrentPageSelection");
|
|
|
88
88
|
const useDragSelection_1 = require("./useDragSelection");
|
|
89
89
|
const getDragSelectionRows_1 = require("./utils/getDragSelectionRows");
|
|
90
90
|
const showMoreRow_1 = require("../../commonHelpers/showMoreRow");
|
|
91
|
+
const groupExclusions_1 = require("./utils/groupExclusions");
|
|
91
92
|
const getEmptySelection = () => ({
|
|
92
93
|
all: false,
|
|
93
94
|
selected: []
|
|
@@ -98,13 +99,14 @@ exports.isAllSelection = isAllSelection;
|
|
|
98
99
|
exports.SelectableWrapperName = "Selectable";
|
|
99
100
|
// Infinite scroll has no pages, so the header checkbox always means "select all" (never current page).
|
|
100
101
|
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;
|
|
102
102
|
const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMode, selectable, isInfinite = false, gridRef, expandedRows) => {
|
|
103
103
|
var _a;
|
|
104
104
|
const {
|
|
105
105
|
translate
|
|
106
106
|
} = (0, useLanguage_1.useLanguage)();
|
|
107
|
-
const
|
|
107
|
+
const previousDatasetId = (0, react_1.useRef)(selectable === null || selectable === void 0 ? void 0 : selectable.selectionDatasetId);
|
|
108
|
+
const datasetWasReplaced = (selectable === null || selectable === void 0 ? void 0 : selectable.selectionDatasetId) !== undefined && previousDatasetId.current !== undefined && selectable.selectionDatasetId !== previousDatasetId.current;
|
|
109
|
+
const appliedSelections = (0, react_1.useMemo)(() => (0, getSelection_1.getSelections)(selectable === null || selectable === void 0 ? void 0 : selectable.selection), [selectable === null || selectable === void 0 ? void 0 : selectable.selection]);
|
|
108
110
|
const [state, setState] = (0, react_1.useState)(interfaces_1.SelectionState.None);
|
|
109
111
|
const checkboxVisible = (0, react_1.useMemo)(() => {
|
|
110
112
|
const base = (selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible : (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) !== "nested" ? (_, isNested) => !isNested : () => true;
|
|
@@ -120,16 +122,19 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
120
122
|
}
|
|
121
123
|
if (selectable === null || selectable === void 0 ? void 0 : selectable.selectionLimit) {
|
|
122
124
|
const limit = selectable.selectionLimit;
|
|
123
|
-
return entity =>
|
|
125
|
+
return entity => appliedSelections.size >= limit && !appliedSelections.has(entity.id);
|
|
124
126
|
}
|
|
125
127
|
return () => false;
|
|
126
|
-
}, [selectable,
|
|
128
|
+
}, [selectable, appliedSelections]);
|
|
127
129
|
// `checkRow` and `getCurrentPageSelection` read callbacks off `selectable`, so hand them the
|
|
128
130
|
// wrapped ones to apply the same exclusions.
|
|
129
131
|
const wrappedSelectable = (0, react_1.useMemo)(() => selectable ? Object.assign(Object.assign({}, selectable), {
|
|
130
132
|
checkboxVisible,
|
|
131
133
|
checkboxDisabled
|
|
132
134
|
}) : undefined, [selectable, checkboxVisible, checkboxDisabled]);
|
|
135
|
+
const resolvedSelection = (0, react_1.useMemo)(() => (0, groupExclusions_1.resolveGroupExclusions)(entities, wrappedSelectable, datasetWasReplaced), [datasetWasReplaced, entities, wrappedSelectable]);
|
|
136
|
+
const selections = (0, react_1.useMemo)(() => (0, getSelection_1.getSelections)(resolvedSelection), [resolvedSelection]);
|
|
137
|
+
const excludedGroupIds = (0, react_1.useMemo)(() => new Set((selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && selectable.strategy === "nested" && (resolvedSelection === null || resolvedSelection === void 0 ? void 0 : resolvedSelection.all) ? resolvedSelection.excludedGroupIds : []), [selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, selectable === null || selectable === void 0 ? void 0 : selectable.strategy, resolvedSelection === null || resolvedSelection === void 0 ? void 0 : resolvedSelection.all, resolvedSelection === null || resolvedSelection === void 0 ? void 0 : resolvedSelection.excludedGroupIds]);
|
|
133
138
|
const checkboxPlaceholder = (0, react_1.useMemo)(() => {
|
|
134
139
|
if ((selectable === null || selectable === void 0 ? void 0 : selectable.checkboxPlaceholder) !== undefined) {
|
|
135
140
|
return selectable.checkboxPlaceholder;
|
|
@@ -144,21 +149,21 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
144
149
|
var _a;
|
|
145
150
|
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
151
|
}, [(_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]);
|
|
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);
|
|
152
|
+
const selectableState = (0, react_1.useMemo)(() => (0, calculateSelectionState_1.calculateSelectionState)(entities, new Set([...selections, ...excludedGroupIds]), isAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy), [checkboxDisabled, checkboxVisible, entities, isAllSelected, selections, excludedGroupIds, selectable === null || selectable === void 0 ? void 0 : selectable.strategy]);
|
|
149
153
|
const firstColumnId = (0, react_1.useMemo)(() => columns.length > 0 ? columns[0].id : null, [columns]);
|
|
150
154
|
(0, react_1.useEffect)(() => {
|
|
151
155
|
if (selectable && selectable.selection) {
|
|
152
|
-
|
|
153
|
-
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, newSelections, isAllSelected, checkboxVisible, checkboxDisabled, selectable.strategy);
|
|
154
|
-
setState(newState);
|
|
156
|
+
setState(selectableState);
|
|
155
157
|
}
|
|
156
|
-
}, [
|
|
158
|
+
}, [selectable, selectableState]);
|
|
157
159
|
const getNewSelection = (0, react_1.useCallback)((id, checked) => {
|
|
158
160
|
if (isAllSelected && !(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions)) {
|
|
159
161
|
const included = (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable);
|
|
160
162
|
(0, checkRow_1.checkRow)(included, wrappedSelectable, entities, id, checked);
|
|
161
|
-
return
|
|
163
|
+
return {
|
|
164
|
+
selected: included,
|
|
165
|
+
groups: new Set()
|
|
166
|
+
};
|
|
162
167
|
}
|
|
163
168
|
if (isAllSelected) {
|
|
164
169
|
// MYG-142234: `selections` holds the ids excluded from the "all" selection.
|
|
@@ -166,22 +171,29 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
166
171
|
// exclusion set - it must never be rebuilt from `entities` (the current page),
|
|
167
172
|
// otherwise every other page's rows would silently fall out of the selection.
|
|
168
173
|
const excluded = new Set(selections);
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
const groups = new Set(excludedGroupIds);
|
|
175
|
+
(0, groupExclusions_1.checkExcludedRow)(excluded, groups, wrappedSelectable, entities, id, checked);
|
|
176
|
+
return {
|
|
177
|
+
selected: excluded,
|
|
178
|
+
groups
|
|
179
|
+
};
|
|
171
180
|
}
|
|
172
181
|
(0, checkRow_1.checkRow)(selections, wrappedSelectable, entities, id, checked);
|
|
173
|
-
return
|
|
174
|
-
|
|
182
|
+
return {
|
|
183
|
+
selected: selections,
|
|
184
|
+
groups: new Set()
|
|
185
|
+
};
|
|
186
|
+
}, [entities, selectable, wrappedSelectable, selections, excludedGroupIds, isAllSelected]);
|
|
175
187
|
const onSelectListener = (0, react_1.useCallback)((id, checked) => {
|
|
176
188
|
const wasAllSelected = !!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && isAllSelected;
|
|
177
|
-
const
|
|
189
|
+
const {
|
|
190
|
+
selected: newSelection,
|
|
191
|
+
groups
|
|
192
|
+
} = getNewSelection(id, checked);
|
|
178
193
|
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, newSelection, wasAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy);
|
|
179
194
|
// MYG-142234: once selection spans "all" pages, unchecking a row must keep `all: true`
|
|
180
195
|
// and only record the exclusion - it must not collapse to the current page's ids.
|
|
181
|
-
const newValue = wasAllSelected ? {
|
|
182
|
-
selected: [...newSelection],
|
|
183
|
-
all: true
|
|
184
|
-
} : {
|
|
196
|
+
const newValue = wasAllSelected ? (0, groupExclusions_1.createExcludedSelection)(newSelection, groups) : {
|
|
185
197
|
selected: [...newSelection],
|
|
186
198
|
all: newState === interfaces_1.SelectionState.All
|
|
187
199
|
};
|
|
@@ -190,24 +202,43 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
190
202
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
191
203
|
}, [checkboxDisabled, checkboxVisible, entities, selectable, setSelectMode, setState, getNewSelection, isAllSelected]);
|
|
192
204
|
const onBatchSelect = (0, react_1.useCallback)((rangeIds, select, base) => {
|
|
193
|
-
const result = new Set(base);
|
|
205
|
+
const result = new Set(base.selected);
|
|
206
|
+
const groups = new Set(base.excludedGroupIds);
|
|
194
207
|
const limit = selectable === null || selectable === void 0 ? void 0 : selectable.selectionLimit;
|
|
195
208
|
const wasAllSelected = !!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && isAllSelected;
|
|
196
209
|
for (const id of rangeIds) {
|
|
197
210
|
if (!wasAllSelected && select && limit !== undefined && result.size >= limit) {
|
|
198
211
|
break;
|
|
199
212
|
}
|
|
200
|
-
|
|
213
|
+
if (wasAllSelected) {
|
|
214
|
+
(0, groupExclusions_1.checkExcludedRow)(result, groups, wrappedSelectable, entities, id, select);
|
|
215
|
+
} else {
|
|
216
|
+
(0, checkRow_1.checkRow)(result, wrappedSelectable, entities, id, select);
|
|
217
|
+
}
|
|
201
218
|
}
|
|
202
219
|
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, result, wasAllSelected, checkboxVisible, checkboxDisabled, selectable === null || selectable === void 0 ? void 0 : selectable.strategy);
|
|
203
|
-
const newValue = {
|
|
220
|
+
const newValue = wasAllSelected ? (0, groupExclusions_1.createExcludedSelection)(result, groups) : {
|
|
204
221
|
selected: [...result],
|
|
205
|
-
all:
|
|
222
|
+
all: newState === interfaces_1.SelectionState.All
|
|
206
223
|
};
|
|
207
224
|
setState(newState);
|
|
208
225
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
209
226
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
210
227
|
}, [entities, selectable, wrappedSelectable, checkboxVisible, checkboxDisabled, setSelectMode, isAllSelected]);
|
|
228
|
+
// Persist group intent separately from concrete IDs so remounts and incremental batches agree.
|
|
229
|
+
(0, react_1.useEffect)(() => {
|
|
230
|
+
previousDatasetId.current = selectable === null || selectable === void 0 ? void 0 : selectable.selectionDatasetId;
|
|
231
|
+
}, [selectable === null || selectable === void 0 ? void 0 : selectable.selectionDatasetId]);
|
|
232
|
+
(0, react_1.useEffect)(() => {
|
|
233
|
+
const applied = selectable === null || selectable === void 0 ? void 0 : selectable.selection;
|
|
234
|
+
if (!applied || !resolvedSelection || !selectable.allowExclusions || !applied.all || selectable.strategy !== "nested") {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const sameIds = (left = [], right = []) => left.length === right.length && left.every((id, index) => id === right[index]);
|
|
238
|
+
if (!sameIds(applied.selected, resolvedSelection.selected) || !sameIds(applied.excludedGroupIds, resolvedSelection.excludedGroupIds)) {
|
|
239
|
+
selectable.onSelect(resolvedSelection);
|
|
240
|
+
}
|
|
241
|
+
}, [selectable, resolvedSelection]);
|
|
211
242
|
// Deliberately independent of the current selection, so the drag anchor survives the
|
|
212
243
|
// selection changes a drag itself produces.
|
|
213
244
|
const {
|
|
@@ -218,7 +249,12 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
218
249
|
const entity = entityById.get(row.id);
|
|
219
250
|
return !!entity && checkboxVisible(entity, row.isNested) && !checkboxDisabled(entity, row.isNested);
|
|
220
251
|
}, [entityById, checkboxVisible, checkboxDisabled]);
|
|
221
|
-
const getBaseSelection = (0, react_1.useCallback)(() =>
|
|
252
|
+
const getBaseSelection = (0, react_1.useCallback)(() => Object.assign({
|
|
253
|
+
all: isAllSelected,
|
|
254
|
+
selected: [...(isAllSelected && !(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) ? (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable) : selections)]
|
|
255
|
+
}, excludedGroupIds.size > 0 ? {
|
|
256
|
+
excludedGroupIds: [...excludedGroupIds]
|
|
257
|
+
} : {}), [isAllSelected, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, entities, wrappedSelectable, selections, excludedGroupIds]);
|
|
222
258
|
const {
|
|
223
259
|
onCheckboxMouseDown,
|
|
224
260
|
suppressNextChangeRef
|
|
@@ -231,7 +267,7 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
231
267
|
onSelectListener(id, checked);
|
|
232
268
|
}, [onSelectListener, suppressNextChangeRef]);
|
|
233
269
|
const onChangeSelectionState = (0, react_1.useCallback)(newState => {
|
|
234
|
-
var _a
|
|
270
|
+
var _a;
|
|
235
271
|
if (newState === interfaces_1.SelectionState.All) {
|
|
236
272
|
(selectable === null || selectable === void 0 ? void 0 : selectable.onSelect) && selectable.onSelect({
|
|
237
273
|
selected: [],
|
|
@@ -250,17 +286,16 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
250
286
|
}
|
|
251
287
|
const newSelections = (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable);
|
|
252
288
|
setState(newState);
|
|
253
|
-
const previousSelections =
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
} : {
|
|
289
|
+
const previousSelections = [...selections];
|
|
290
|
+
const groups = new Set(excludedGroupIds);
|
|
291
|
+
entities.forEach(entity => groups.delete(entity.id));
|
|
292
|
+
const newValue = (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.all) ? (0, groupExclusions_1.createExcludedSelection)(new Set(previousSelections.filter(id => !newSelections.has(id))), groups) : {
|
|
258
293
|
selected: [...new Set([...previousSelections, ...newSelections])],
|
|
259
294
|
all: false
|
|
260
295
|
};
|
|
261
296
|
selectable === null || selectable === void 0 ? void 0 : selectable.onSelect(newValue);
|
|
262
297
|
setSelectMode(newValue.all || newValue.selected.length > 0);
|
|
263
|
-
}, [selectable, wrappedSelectable, entities, setSelectMode]);
|
|
298
|
+
}, [selectable, wrappedSelectable, entities, setSelectMode, selections, excludedGroupIds]);
|
|
264
299
|
const checkboxTitle = (0, react_1.useCallback)(entity => (selectable === null || selectable === void 0 ? void 0 : selectable.checkboxTitle) ? selectable.checkboxTitle(entity) : firstColumnId ? entity[firstColumnId] || entity.id : entity.id, [firstColumnId, selectable]);
|
|
265
300
|
const headerTitle = (0, react_1.useCallback)(() => {
|
|
266
301
|
if (selectable === null || selectable === void 0 ? void 0 : selectable.headerTitle) {
|
|
@@ -276,7 +311,15 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
276
311
|
// row must be evaluated through the SelectionState.All (exclusion-aware) branch of
|
|
277
312
|
// isRowChecked - not the per-page `state`, which can be Partial/None for a page that
|
|
278
313
|
// contains some of those exclusions.
|
|
279
|
-
(entity, isNested) =>
|
|
314
|
+
(entity, isNested) => {
|
|
315
|
+
if (!isNested && isAllSelected && excludedGroupIds.has(entity.id)) {
|
|
316
|
+
return {
|
|
317
|
+
indeterminate: false,
|
|
318
|
+
checked: false
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
return (0, isRowChecked_1.isRowChecked)(selections, isAllSelected ? interfaces_1.SelectionState.All : state, selectable === null || selectable === void 0 ? void 0 : selectable.strategy, entity, isNested, checkboxVisible, checkboxDisabled);
|
|
322
|
+
}, [selections, excludedGroupIds, isAllSelected, state, selectable === null || selectable === void 0 ? void 0 : selectable.strategy, checkboxVisible, checkboxDisabled]);
|
|
280
323
|
const hasSelectable = !!selectable;
|
|
281
324
|
const selectableCheckboxSelectsCurrentPage = selectable === null || selectable === void 0 ? void 0 : selectable.checkboxSelectsCurrentPage;
|
|
282
325
|
const selectableTurnOffSelectAll = selectable === null || selectable === void 0 ? void 0 : selectable.turnOffSelectAll;
|
|
@@ -342,13 +385,17 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
342
385
|
// keep `all: true` - it must never be treated as an inclusion list, or
|
|
343
386
|
// every other page's selection would be silently wiped out.
|
|
344
387
|
const currentPageIds = (0, getCurrentPageSelection_1.getCurrentPageSelection)(entities, wrappedSelectable);
|
|
345
|
-
const newExcluded = new Set([...
|
|
346
|
-
const
|
|
388
|
+
const newExcluded = new Set([...selections, ...currentPageIds]);
|
|
389
|
+
const groups = new Set(excludedGroupIds);
|
|
390
|
+
if (selectable.strategy === "nested") {
|
|
391
|
+
entities.forEach(entity => {
|
|
392
|
+
var _a;
|
|
393
|
+
if ((_a = (0, showMoreRow_1.getChildrenForSelection)(entity)) === null || _a === void 0 ? void 0 : _a.length) groups.add(entity.id);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
const newState = (0, calculateSelectionState_1.calculateSelectionState)(entities, new Set([...newExcluded, ...groups]), true, checkboxVisible, checkboxDisabled, selectable.strategy);
|
|
347
397
|
setState(newState);
|
|
348
|
-
selectable.onSelect(
|
|
349
|
-
selected: [...newExcluded],
|
|
350
|
-
all: true
|
|
351
|
-
});
|
|
398
|
+
selectable.onSelect((0, groupExclusions_1.createExcludedSelection)(newExcluded, groups));
|
|
352
399
|
setSelectMode(true);
|
|
353
400
|
} else {
|
|
354
401
|
// Intentionally different from onSelect(None) ("Deselect all" menu item, which clears everything).
|
|
@@ -364,7 +411,7 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
364
411
|
setSelectMode(remaining.length > 0);
|
|
365
412
|
}
|
|
366
413
|
},
|
|
367
|
-
calculateSelectionState: () =>
|
|
414
|
+
calculateSelectionState: () => isAllSelected ? selections.size === 0 && excludedGroupIds.size === 0 ? interfaces_1.SelectionState.All : interfaces_1.SelectionState.Partial : selections.size === 0 ? interfaces_1.SelectionState.None : selectableState === interfaces_1.SelectionState.CurrentPage ? interfaces_1.SelectionState.CurrentPage : interfaces_1.SelectionState.Partial,
|
|
368
415
|
checkboxInHeader: checkboxInHeaderValue,
|
|
369
416
|
header: selectableHeader,
|
|
370
417
|
onSelect: newState => {
|
|
@@ -377,7 +424,7 @@ const useSelectableRows = (columns, entities, isMobile, selectMode, setSelectMod
|
|
|
377
424
|
return cell;
|
|
378
425
|
}
|
|
379
426
|
};
|
|
380
|
-
}, [checkboxDisabled, checkboxTitle, checkboxVisible, headerTitle, onChangeSelectionState, onCheckboxChange, onCheckboxMouseDown, hasSelectable, checkboxEmitsCurrentPage, checkboxInHeaderValue, selectableHeader, selectableTurnOffSelectAll, isInfinite, selectable, wrappedSelectable,
|
|
427
|
+
}, [checkboxDisabled, checkboxTitle, checkboxVisible, headerTitle, onChangeSelectionState, onCheckboxChange, onCheckboxMouseDown, hasSelectable, checkboxEmitsCurrentPage, checkboxInHeaderValue, selectableHeader, selectableTurnOffSelectAll, isInfinite, selectable, wrappedSelectable, selectableState, isAllSelected, selections, excludedGroupIds, state, isMobile, checkboxPlaceholder, isEntityChecked, entities, setSelectMode]);
|
|
381
428
|
const selectableFeedWrapper = (0, react_1.useCallback)((primaryData, secondaryData, entity, isNested) => {
|
|
382
429
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
383
430
|
if (!entity) {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.calculateSelectionState = void 0;
|
|
4
4
|
const showMoreRow_1 = require("../../../commonHelpers/showMoreRow");
|
|
5
5
|
const interfaces_1 = require("../interfaces");
|
|
6
|
+
const areAllLoading = (children) => children.every(child => child.isLoading);
|
|
6
7
|
const calculateSelectionState = (entities, selections, all, checkboxVisible, checkboxDisabled, strategy) => {
|
|
7
8
|
if (selections.size === 0) {
|
|
8
9
|
return all ? interfaces_1.SelectionState.All : interfaces_1.SelectionState.None;
|
|
@@ -12,7 +13,7 @@ const calculateSelectionState = (entities, selections, all, checkboxVisible, che
|
|
|
12
13
|
// otherwise-fully-selected set (see ISelectionValue), rather than included ids.
|
|
13
14
|
const isExcluded = (entity) => {
|
|
14
15
|
const children = strategy === "nested" ? (0, showMoreRow_1.getChildrenForSelection)(entity) : undefined;
|
|
15
|
-
if (children && children.length > 0) {
|
|
16
|
+
if (children && children.length > 0 && !areAllLoading(children)) {
|
|
16
17
|
return children.every(child => {
|
|
17
18
|
if (!checkboxVisible(child, true)) {
|
|
18
19
|
return true;
|
|
@@ -27,7 +28,7 @@ const calculateSelectionState = (entities, selections, all, checkboxVisible, che
|
|
|
27
28
|
};
|
|
28
29
|
const isPartiallyExcluded = (entity) => {
|
|
29
30
|
const children = strategy === "nested" ? (0, showMoreRow_1.getChildrenForSelection)(entity) : undefined;
|
|
30
|
-
if (children && children.length > 0) {
|
|
31
|
+
if (children && children.length > 0 && !areAllLoading(children)) {
|
|
31
32
|
return children.some(child => selections.has(child.id));
|
|
32
33
|
}
|
|
33
34
|
return selections.has(entity.id);
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCurrentPageSelection = void 0;
|
|
4
4
|
const showMoreRow_1 = require("../../../commonHelpers/showMoreRow");
|
|
5
|
+
const isLoadingRow = (entity) => !!entity.isLoading;
|
|
5
6
|
const getCurrentPageSelection = (entities, selectable) => {
|
|
6
7
|
const newSelections = new Set();
|
|
7
8
|
entities.forEach(entity => {
|
|
8
|
-
|
|
9
|
+
if (isLoadingRow(entity) || (0, showMoreRow_1.isShowMoreRow)(entity)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const isVisible = (selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(entity) : true;
|
|
9
13
|
const isEnabled = !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) || !selectable.checkboxDisabled(entity);
|
|
10
14
|
const children = (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) === "nested" ? (0, showMoreRow_1.getChildrenForSelection)(entity) : undefined;
|
|
11
15
|
if (children && children.length > 0) {
|
|
12
16
|
children.forEach(child => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
if (isLoadingRow(child) || (0, showMoreRow_1.isShowMoreRow)(child)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const isChildVisible = (selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible) ? selectable.checkboxVisible(child, true) : true;
|
|
16
21
|
const isChildEnabled = !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) || !selectable.checkboxDisabled(child, true);
|
|
17
22
|
if (isChildVisible && isChildEnabled) {
|
|
18
23
|
newSelections.add(child.id);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IEntityWithId } from "../../../commonHelpers/entity";
|
|
2
|
+
import { IRowEntity } from "../../../dataGrid/row/row";
|
|
3
|
+
import { ISelectionValue } from "../interfaces";
|
|
4
|
+
import { ISelectableRowsOptions } from "../useSelectableRows";
|
|
5
|
+
export declare const createExcludedSelection: (selected: Set<string>, groups: Set<string>) => ISelectionValue;
|
|
6
|
+
export declare const resolveGroupExclusions: <T extends IRowEntity<N>, N extends IEntityWithId>(entities: T[], selectable: ISelectableRowsOptions<T, N> | undefined, pruneMissingGroups?: boolean) => ISelectionValue | undefined;
|
|
7
|
+
export declare const checkExcludedRow: <T extends IRowEntity<N>, N extends IEntityWithId>(selected: Set<string>, groups: Set<string>, selectable: ISelectableRowsOptions<T, N> | undefined, entities: T[], id: string, checked: boolean) => void;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkExcludedRow = exports.resolveGroupExclusions = exports.createExcludedSelection = void 0;
|
|
4
|
+
const showMoreRow_1 = require("../../../commonHelpers/showMoreRow");
|
|
5
|
+
const checkRow_1 = require("./checkRow");
|
|
6
|
+
const getCurrentPageSelection_1 = require("./getCurrentPageSelection");
|
|
7
|
+
const createExcludedSelection = (selected, groups) => (Object.assign({ all: true, selected: [...selected] }, (groups.size > 0 ? { excludedGroupIds: [...groups] } : {})));
|
|
8
|
+
exports.createExcludedSelection = createExcludedSelection;
|
|
9
|
+
const resolveGroupExclusions = (entities, selectable, pruneMissingGroups = false) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const selection = selectable === null || selectable === void 0 ? void 0 : selectable.selection;
|
|
12
|
+
if (!(selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) || !(selection === null || selection === void 0 ? void 0 : selection.all) || selectable.strategy !== "nested") {
|
|
13
|
+
return selection;
|
|
14
|
+
}
|
|
15
|
+
const selected = new Set(selection.selected);
|
|
16
|
+
const groups = new Set(selection.excludedGroupIds);
|
|
17
|
+
for (const entity of entities) {
|
|
18
|
+
if (selected.has(entity.id) && ((_a = (0, showMoreRow_1.getChildrenForSelection)(entity)) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
19
|
+
groups.add(entity.id);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
for (const id of groups) {
|
|
23
|
+
const entity = entities.find(item => item.id === id);
|
|
24
|
+
if (!entity && pruneMissingGroups) {
|
|
25
|
+
selected.delete(id);
|
|
26
|
+
groups.delete(id);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (!entity)
|
|
30
|
+
continue;
|
|
31
|
+
if ((_b = (0, showMoreRow_1.getChildrenForSelection)(entity)) === null || _b === void 0 ? void 0 : _b.length) {
|
|
32
|
+
selected.delete(id);
|
|
33
|
+
}
|
|
34
|
+
for (const childId of (0, getCurrentPageSelection_1.getCurrentPageSelection)([entity], selectable)) {
|
|
35
|
+
selected.add(childId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return (0, exports.createExcludedSelection)(selected, groups);
|
|
39
|
+
};
|
|
40
|
+
exports.resolveGroupExclusions = resolveGroupExclusions;
|
|
41
|
+
const checkExcludedRow = (selected, groups, selectable, entities, id, checked) => {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
if ((selectable === null || selectable === void 0 ? void 0 : selectable.strategy) === "nested") {
|
|
44
|
+
const entity = entities.find(item => item.id === id);
|
|
45
|
+
if (checked) {
|
|
46
|
+
groups.delete(id);
|
|
47
|
+
selected.delete(id);
|
|
48
|
+
// Selecting a child overrides the whole-group intent, retaining the other concrete exclusions.
|
|
49
|
+
for (const parent of entities) {
|
|
50
|
+
if ((_a = (0, showMoreRow_1.getChildrenForSelection)(parent)) === null || _a === void 0 ? void 0 : _a.some(child => child.id === id)) {
|
|
51
|
+
groups.delete(parent.id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (entity && ((_b = (0, showMoreRow_1.getChildrenForSelection)(entity)) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
56
|
+
groups.add(id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
(0, checkRow_1.checkRow)(selected, selectable, entities, id, !checked);
|
|
60
|
+
};
|
|
61
|
+
exports.checkExcludedRow = checkExcludedRow;
|
|
@@ -27,7 +27,7 @@ const isRowChecked = (selections, state, strategy, entity, isNested, checkboxVis
|
|
|
27
27
|
if (children && children.length > 0) {
|
|
28
28
|
const selectableChildren = filterSelectable(children, checkboxVisible, checkboxDisabled);
|
|
29
29
|
if (selectableChildren.length === 0) {
|
|
30
|
-
return { indeterminate: false, checked:
|
|
30
|
+
return { indeterminate: false, checked: !selections.has(entity.id) };
|
|
31
31
|
}
|
|
32
32
|
const allChildrenChecked = selectableChildren.every(child => !selections.has(child.id));
|
|
33
33
|
const someChildrenChecked = selectableChildren.some(child => !selections.has(child.id));
|