UNPKG

@adaptabletools/adaptable-cjs

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

193 lines (192 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.renderSelectionSection = void 0; exports.ValueSelector = ValueSelector; const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const react_1 = require("react"); const dnd_1 = require("../../../components/dnd"); const CheckBox_1 = require("../../../components/CheckBox"); const icons_1 = require("../../../components/icons"); const Radio_1 = tslib_1.__importDefault(require("../../../components/Radio")); const AdaptableFormControlTextClear_1 = require("../Forms/AdaptableFormControlTextClear"); const ArrayExtensions_1 = tslib_1.__importDefault(require("../../../Utilities/Extensions/ArrayExtensions")); const Flex_1 = require("../../../components/Flex"); const clsx_1 = tslib_1.__importDefault(require("clsx")); function useValuesMap({ options, value, toIdentifier, selectedMap, }) { const optionsMap = (0, react_1.useMemo)(() => { if (selectedMap) { return; } const map = new Map([]); options.forEach((option) => { map.set(toIdentifier(option), option); }); return map; }, [options, selectedMap]); const result = (0, react_1.useMemo)(() => { if (selectedMap) { return selectedMap; } const map = new Map([]); value.forEach((id) => { map.set(id, optionsMap.get(id) ?? null); }); return map; }, [optionsMap, selectedMap, value]); return { selectedMap: result, optionsMap }; } const baseClassName = 'ab-ValueSelector'; function ValueSelector(props) { const { options, value, filter, onChange, allowReorder = true, singleSelect, toLabel, toListLabel, toIdentifier, showSelectedOnlyLabel, showFilterInput, onShowSelectedOnlyChange, isOptionDisabled, disabled, } = props; const [searchInputValue, setSearchInputValue] = React.useState(''); const preparedToLabel = toListLabel ?? toLabel; const [selectedOnly, doSetSelectedOnly] = (0, react_1.useState)(false); const setSelectedOnly = (0, react_1.useCallback)((selectedOnly) => { doSetSelectedOnly(selectedOnly); onShowSelectedOnlyChange?.(selectedOnly); }, [onShowSelectedOnlyChange]); const { selectedMap } = useValuesMap({ options, toIdentifier, value, }); const notifyChange = (0, react_1.useCallback)(() => { const newSelection = [...selectedMap.keys()]; if (!newSelection.length && selectedOnly) { setSelectedOnly(false); } onChange(newSelection, new Map(selectedMap)); }, [onChange, selectedOnly, selectedMap]); const renderOption = (option, index) => { const identifier = toIdentifier(option); const label = !allowReorder ? preparedToLabel(option) : null; const reorderable = typeof allowReorder === 'function' ? allowReorder(option) : allowReorder; const renderNode = (props, dragHandleProps) => { return (React.createElement(Flex_1.Flex, { alignItems: "center", key: identifier ?? index, "data-index": index, "data-id": identifier, "data-name": "option", ...props, className: (0, clsx_1.default)(`twa:bg-primary twa:text-text-on-primary twa:rounded-standard twa:p-2`, { 'twa:mt-1': index, 'twa:mt-0': !index, }, props.className, `${baseClassName}__option`) }, React.createElement(Flex_1.Flex, { flexDirection: "row", alignItems: "center", className: "twa:flex-1" }, reorderable ? (React.createElement(Flex_1.Box, { ...dragHandleProps, className: (0, clsx_1.default)('twa:mr-3', dragHandleProps?.className) }, React.createElement(icons_1.Icon, { name: "drag", style: { cursor: 'grab' } }))) : null, singleSelect ? (React.createElement(Radio_1.default, { checked: selectedMap.has(identifier), "data-name": identifier, onChange: (checked) => { if (checked) { selectedMap.clear(); selectedMap.set(identifier, option); } else { selectedMap.delete(identifier); } notifyChange(); } }, label)) : (React.createElement(CheckBox_1.CheckBox, { "data-name": identifier, disabled: disabled || (isOptionDisabled ? isOptionDisabled(option) : false), onChange: (checked) => { if (checked) { selectedMap.set(identifier, option); } else { selectedMap.delete(identifier); } notifyChange(); }, checked: selectedMap.has(identifier) }, label)), React.createElement(Flex_1.Box, { className: "twa:ml-2 twa:flex-1" }, allowReorder ? preparedToLabel(option) : null)))); }; return (React.createElement(dnd_1.Draggable, { key: identifier, index: index, draggableId: `${identifier}`, isDragDisabled: !reorderable }, (draggableProvided) => { return renderNode({ ref: draggableProvided.innerRef, ...draggableProvided.draggableProps, style: draggableProvided.draggableProps.style, }, draggableProvided.dragHandleProps); })); }; const showOnlySelectedCheckbox = (React.createElement(CheckBox_1.CheckBox, { disabled: !value.length, checked: selectedOnly, onChange: setSelectedOnly }, showSelectedOnlyLabel ?? 'Show Selected Only')); const selectionSectionProps = { ...props, showOnlySelectedCheckbox, onSelectAll: () => { options.forEach((option) => { selectedMap.set(toIdentifier(option), option); }); notifyChange(); }, onClearOption: (id) => { selectedMap.delete(id); notifyChange(); }, onClear: () => { selectedMap.clear(); notifyChange(); }, }; return (React.createElement(Flex_1.Flex, { style: props.style, className: (0, clsx_1.default)('twa:flex-1', baseClassName), flexDirection: "column" }, React.createElement(Flex_1.Flex, { className: "twa:mb-1" }, showFilterInput && filter ? (React.createElement(AdaptableFormControlTextClear_1.AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Type to search", className: "twa:flex-1 twa:border-0 twa:m-[3px]" })) : (React.createElement(Flex_1.Box, { className: "twa:flex-1" }))), (0, exports.renderSelectionSection)(selectionSectionProps), React.createElement(dnd_1.DragDropContext, { onDragEnd: (result) => { const { source, destination } = result; const selection = []; const extraKeys = []; for (let [key, value] of selectedMap) { if (value != null) { selection.push(key); } else { // null/non-existent keys have to be stored separately extraKeys.push(key); } } const clone = new Map(selectedMap); const newSelection = ArrayExtensions_1.default.reorderArray(selection, source.index, destination.index); // and then pushed back in the new order, at the end newSelection.push(...extraKeys); selectedMap.clear(); newSelection.forEach((key) => { selectedMap.set(key, clone.get(key)); }); notifyChange(); } }, React.createElement(Flex_1.Flex, { className: `${baseClassName}__body twa:flex-1 twa:overflow-auto`, flexDirection: "column" }, React.createElement(dnd_1.Droppable, { droppableId: "droppable" }, (droppableProvided) => { return (React.createElement("div", { ref: droppableProvided.innerRef, ...droppableProvided.droppableProps }, options .filter((option) => { let result = true; if (filter) { result = filter(option, searchInputValue); } result = result && (selectedOnly ? selectedMap.has(toIdentifier(option)) : true); return result; }) .map(renderOption), droppableProvided.placeholder)); }))))); } const renderSelectionSection = (props) => { const { value, options, disabled, singleSelect, toLabel, toIdentifier, } = props; const selectionBox = (React.createElement(Flex_1.Box, { className: "twa:flex twa:flex-col twa:gap-2 twa:py-2" }, React.createElement(Flex_1.Box, { className: (0, clsx_1.default)('twa:flex twa:flex-row', 'twa:border-b twa:border-primarydark/30 twa:rounded-standard') }, singleSelect ? (React.createElement(Flex_1.Box, { className: "twa:flex twa:flex-row twa:text-3 twa:font-normal" }, "(", value.length, " of ", options.length, " selected)")) : (React.createElement(CheckBox_1.CheckBox, { className: "twa:ml-0.5 twa:font-bold", checked: !value.length ? false : value.length === options.length ? true : null, onChange: (checked) => { if (checked) { props.onSelectAll(); } else { props.onClear(); } } }, React.createElement(Flex_1.Box, { className: "twa:flex twa:flex-row twa:items-center twa:gap-3" }, "Select All", React.createElement(Flex_1.Box, { className: "twa:text-2 twa:font-normal" }, "(", value.length, " of ", options.length, " selected)")))), React.createElement("div", { className: "twa:flex-1" }), React.createElement(Flex_1.Box, { className: "twa:mr-2 twa:text-2 twa:font-normal" }, props.showOnlySelectedCheckbox)))); return React.createElement(Flex_1.Box, { className: (0, clsx_1.default)(`${baseClassName}__header `) }, selectionBox); }; exports.renderSelectionSection = renderSelectionSection;