UNPKG

igniteui-webcomponents

Version:

Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.

266 lines 10.1 kB
import { isEmpty } from '../common/util.js'; export class IgcTreeSelectionService { constructor(tree) { this.itemSelection = new Set(); this.indeterminateItems = new Set(); this.tree = tree; } selectMultipleItems(item) { if (!this.itemSelection.size) { this.selectItem(item); return; } const lastSelectedItemIndex = this.tree.items.indexOf(this.getSelectedItems()[this.itemSelection.size - 1]); const currentItemIndex = this.tree.items.indexOf(item); const items = this.tree.items.slice(Math.min(currentItemIndex, lastSelectedItemIndex), Math.max(currentItemIndex, lastSelectedItemIndex) + 1); const added = items.filter((_item) => !this.isItemSelected(_item)); const newSelection = this.getSelectedItems().concat(added); this.emitItemSelectionEvent(newSelection, added, []); } selectItem(item) { if (this.tree.selection === 'none') { return; } this.emitItemSelectionEvent([...this.getSelectedItems(), item], [item], []); } deselectItem(item) { const newSelection = this.getSelectedItems().filter((_item) => _item !== item); this.emitItemSelectionEvent(newSelection, [], [item]); } clearItemsSelection() { const oldSelection = this.getSelectedItems(); const oldIndeterminate = this.getIndeterminateItems(); this.itemSelection.clear(); this.indeterminateItems.clear(); oldSelection.forEach((i) => { i.selected = false; }); oldIndeterminate.forEach((i) => { i.indeterminate = false; }); } isItemSelected(item) { return this.itemSelection.has(item); } isItemIndeterminate(item) { return this.indeterminateItems.has(item); } ensureStateOnItemDelete(item) { this.deselectItemsWithNoEvent([item, ...item.getChildren({ flatten: true })], true); } retriggerItemState(item) { if (item.selected) { this.itemSelection.delete(item); this.selectItemsWithNoEvent([item]); } else { this.itemSelection.add(item); this.deselectItemsWithNoEvent([item]); } } emitItemSelectionEvent(newSelection, added, removed) { const currSelection = this.getSelectedItems(); if (this.areEqualCollections(currSelection, newSelection)) { return; } if (this.tree.selection === 'cascade') { this.emitCascadeItemSelectionEvent(currSelection, added, removed); return; } const args = { detail: { newSelection, }, cancelable: true, }; const allowed = this.tree.emitEvent('igcSelection', args); if (!allowed) { return; } if (this.areEqualCollections(newSelection, args.detail.newSelection)) { this.itemSelection = new Set(newSelection); this.updateItemsState(currSelection); } } selectItemsWithNoEvent(items) { const oldSelection = this.getSelectedItems(); if (this.tree && this.tree.selection === 'cascade') { this.cascadeSelectItemsWithNoEvent(items, oldSelection); return; } items.forEach((item) => this.itemSelection.add(item)); this.updateItemsState(oldSelection); } deselectItemsWithNoEvent(items, onDelete = false) { if (this.tree && this.tree.selection === 'cascade') { this.cascadeDeselectItemsWithNoEvent(items, onDelete); return; } const itemSet = new Set(items); const oldSelection = onDelete ? this.getSelectedItems().filter((i) => !itemSet.has(i)) : this.getSelectedItems(); if (!items) { this.itemSelection.clear(); } else { items.forEach((item) => this.itemSelection.delete(item)); } this.updateItemsState(oldSelection); } emitCascadeItemSelectionEvent(currSelection, added, removed) { const oldIndeterminate = this.getIndeterminateItems(); this.calculateItemsNewSelectionState(currSelection, added, removed); const args = { detail: { newSelection: Array.from(this.itemsToBeSelected), }, cancelable: true, }; const allowed = this.tree.emitEvent('igcSelection', args); if (!allowed) { return; } if (this.areEqualCollections(Array.from(this.itemsToBeSelected), args.detail.newSelection)) { this.itemSelection = new Set(this.itemsToBeSelected); this.indeterminateItems = new Set(this.itemsToBeIndeterminate); this.updateItemsState(currSelection, oldIndeterminate); } } cascadeSelectItemsWithNoEvent(items, oldSelection) { const oldIndeterminate = this.getIndeterminateItems(); const newSelection = [...oldSelection, ...items]; const newSelectionSet = new Set(newSelection); const removed = oldSelection.filter((x) => !newSelectionSet.has(x)); const added = newSelection.filter((x) => !this.itemSelection.has(x)); this.calculateItemsNewSelectionState(oldSelection, added, removed); this.itemSelection = new Set(this.itemsToBeSelected); this.indeterminateItems = new Set(this.itemsToBeIndeterminate); this.updateItemsState(oldSelection, oldIndeterminate); } cascadeDeselectItemsWithNoEvent(items, onDelete = false) { const itemSet = new Set(items); const oldSelection = onDelete ? this.getSelectedItems().filter((i) => !itemSet.has(i)) : this.getSelectedItems(); const oldIndeterminate = onDelete ? this.getIndeterminateItems().filter((i) => !itemSet.has(i)) : this.getIndeterminateItems(); if (!items) { this.itemSelection.clear(); this.indeterminateItems.clear(); } else { this.calculateItemsNewSelectionState(oldSelection, [], items); this.itemSelection = new Set(this.itemsToBeSelected); this.indeterminateItems = new Set(this.itemsToBeIndeterminate); } this.updateItemsState(oldSelection, oldIndeterminate); } calculateItemsNewSelectionState(oldSelection, added, removed) { this.itemsToBeSelected = new Set(oldSelection); this.itemsToBeIndeterminate = new Set(this.getIndeterminateItems()); this.cascadeSelectionState(removed, false); this.cascadeSelectionState(added, true); } cascadeSelectionState(items, selected) { if (!items || isEmpty(items)) { return; } const parents = new Set(); items.forEach((item) => { this.selectDeselectItem(item, selected); const itemAndAllChildren = item.getChildren({ flatten: true }) || []; itemAndAllChildren.forEach((i) => { this.selectDeselectItem(i, selected); }); if (item?.parent) { parents.add(item.parent); } }); for (const parent of parents) { this.handleParentSelectionState(parent); } } handleParentSelectionState(item) { if (!item) { return; } this.handleItemSelectionState(item); if (item.parent) { this.handleParentSelectionState(item.parent); } } handleItemSelectionState(item) { const itemsArray = item?.getChildren() ? item.getChildren() : []; if (itemsArray.length) { if (itemsArray.every((i) => this.itemsToBeSelected.has(i))) { this.selectDeselectItem(item, true); } else if (itemsArray.some((i) => this.itemsToBeSelected.has(i) || this.itemsToBeIndeterminate.has(i))) { this.selectDeselectItem(item, false, true); } else { this.selectDeselectItem(item, false); } } else if (this.isItemSelected(item)) { this.selectDeselectItem(item, true); } else { this.selectDeselectItem(item, false); } } updateItemsState(oldSelection, oldIndeterminate = []) { const selected = new Set(oldSelection); const indeterminated = new Set(oldIndeterminate); this.getSelectedItems().forEach((i) => { if (!selected.has(i)) { i.selected = true; } }); oldSelection.forEach((i) => { if (!this.itemSelection.has(i)) { i.selected = false; } }); if (this.tree.selection === 'cascade') { this.indeterminateItems.forEach((i) => { if (!indeterminated.has(i)) { i.indeterminate = true; } }); oldIndeterminate.forEach((i) => { if (!this.indeterminateItems.has(i)) { i.indeterminate = false; } }); } } getSelectedItems() { return Array.from(this.itemSelection); } getIndeterminateItems() { return Array.from(this.indeterminateItems); } areEqualCollections(first, second) { return (first.length === second.length && new Set(first.concat(second)).size === first.length); } selectDeselectItem(item, select, indeterminate = false) { if (indeterminate) { this.itemsToBeIndeterminate.add(item); this.itemsToBeSelected.delete(item); return; } if (select) { this.itemsToBeSelected.add(item); this.itemsToBeIndeterminate.delete(item); } else { this.itemsToBeSelected.delete(item); this.itemsToBeIndeterminate.delete(item); } } } //# sourceMappingURL=tree.selection.js.map