UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

309 lines (308 loc) • 12.4 kB
/** * DevExtreme (esm/__internal/ui/selection/selection.strategy.deferred.js) * Version: 25.2.3 * Build date: Fri Dec 12 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import dataQuery from "../../../common/data/query"; import { Deferred } from "../../../core/utils/deferred"; import { isString } from "../../../core/utils/type"; import errors from "../../../ui/widget/ui.errors"; import SelectionStrategy from "../../ui/selection/selection.strategy"; export default class DeferredStrategy extends SelectionStrategy { getSelectedItems() { return this._loadFilteredData(this.options.selectionFilter) } getSelectedItemKeys() { const d = Deferred(); const key = this.options.key(); const select = isString(key) ? [key] : key; const getKey = item => this.options.keyOf(item); this._loadFilteredData(this.options.selectionFilter, null, select).done((items => { const keys = (Array.isArray(items) ? items : []).map(getKey); d.resolve(keys) })).fail((error => { d.reject(error) })); return d.promise() } selectedItemKeys(keys, preserve, isDeselect, isSelectAll) { if (isSelectAll) { const filter = this.options.filter(); const needResetSelectionFilter = !filter || JSON.stringify(filter) === JSON.stringify(this.options.selectionFilter) && isDeselect; if (needResetSelectionFilter) { this._setOption("selectionFilter", isDeselect ? [] : null) } else { this._addSelectionFilter(isDeselect, filter, isSelectAll) } } else { if (!preserve) { this._setOption("selectionFilter", []) } keys.forEach((key => { if (isDeselect) { this.removeSelectedItem(key) } else { this.addSelectedItem(key, isSelectAll, !preserve) } })) } this.onSelectionChanged(); return Deferred().resolve() } setSelectedItems(keys) { this._setOption("selectionFilter", null); keys.forEach((key => { this.addSelectedItem(key) })) } isItemDataSelected(itemData) { return this.isItemKeySelected(itemData) } isItemKeySelected(itemData) { const { selectionFilter: selectionFilter } = this.options; if (!selectionFilter) { return true } const queryParams = this._getQueryParams(); return !!dataQuery([itemData], queryParams).filter(selectionFilter).toArray().length } _getKeyExpr() { const keyField = this.options.key(); if (Array.isArray(keyField) && 1 === keyField.length) { return keyField[0] } return keyField } _normalizeKey(key) { const keyExpr = this.options.key(); if (Array.isArray(keyExpr) && 1 === keyExpr.length) { return key[keyExpr[0]] } return key } _getFilterByKey(key) { const keyField = this._getKeyExpr(); let filter = [keyField, "=", this._normalizeKey(key)]; if (Array.isArray(keyField)) { filter = []; for (let i = 0; i < keyField.length; i += 1) { filter.push([keyField[i], "=", key[keyField[i]]]); if (i !== keyField.length - 1) { filter.push("and") } } } return filter } addSelectedItem(key, isSelectAll, skipFilter) { const filter = this._getFilterByKey(key); this._addSelectionFilter(false, filter, isSelectAll, skipFilter) } removeSelectedItem(key) { const filter = this._getFilterByKey(key); this._addSelectionFilter(true, filter) } validate() { const { key: key } = this.options; if (key && void 0 === key()) { throw errors.Error("E1042", "Deferred selection") } } _findSubFilter(selectionFilter, filter) { if (!selectionFilter) { return -1 } const filterString = JSON.stringify(filter); for (let index = 0; index < selectionFilter.length; index += 1) { const subFilter = selectionFilter[index]; if (subFilter && JSON.stringify(subFilter) === filterString) { return index } } return -1 } _isLastSubFilter(selectionFilter, filter) { if (selectionFilter && filter) { return this._findSubFilter(selectionFilter, filter) === selectionFilter.length - 1 || 0 === this._findSubFilter([selectionFilter], filter) } return false } _addFilterOperator(selectionFilter, filterOperator) { let filter = selectionFilter; if (filter.length > 1 && isString(filter[1]) && filter[1] !== filterOperator) { filter = [filter] } if (Array.isArray(filter) && filter.length) { filter.push(filterOperator) } return filter } _denormalizeFilter(filter) { let resultFilter = filter; if (resultFilter && isString(resultFilter[0])) { resultFilter = [resultFilter] } return resultFilter } _isOnlyNegativeFiltersLeft(filters) { return filters.every(((filterItem, i) => { if (i % 2 === 0) { return Array.isArray(filterItem) && "!" === filterItem[0] } return "and" === filterItem })) } _addSelectionFilter(isDeselect, filter, isSelectAll, skipFilter) { var _selectionFilter; const currentOperation = isDeselect ? "and" : "or"; let needAddFilter = true; let selectionFilter = this.options.selectionFilter || []; selectionFilter = this._denormalizeFilter(selectionFilter); if (null !== (_selectionFilter = selectionFilter) && void 0 !== _selectionFilter && _selectionFilter.length && !skipFilter) { const removedIndex = this._removeSameFilter(selectionFilter, filter, isDeselect, isSelectAll); const filterIndex = this._removeSameFilter(selectionFilter, filter, !isDeselect); const shouldCleanFilter = isDeselect && (-1 !== removedIndex || -1 !== filterIndex) && this._isOnlyNegativeFiltersLeft(selectionFilter); if (shouldCleanFilter) { selectionFilter = [] } const isKeyOperatorsAfterRemoved = this._isKeyFilter(filter) && this._hasKeyFiltersOnlyStartingFromIndex(selectionFilter, filterIndex); needAddFilter = !!(null !== filter && void 0 !== filter && filter.length) && !isKeyOperatorsAfterRemoved } if (needAddFilter) { selectionFilter = this._addFilterOperator(selectionFilter, currentOperation); if (Array.isArray(selectionFilter) && filter) { const currentFilter = isDeselect ? ["!", filter] : filter; selectionFilter.push(currentFilter) } } selectionFilter = this._normalizeFilter(selectionFilter); this._setOption("selectionFilter", !isDeselect && !selectionFilter.length ? null : selectionFilter) } _normalizeFilter(filter) { let resultFilter = filter; if (resultFilter && 1 === resultFilter.length) { [resultFilter] = resultFilter } return resultFilter } _removeFilterByIndex(filter, filterIndex, isSelectAll) { const operation = filter[1]; if (filterIndex > 0) { filter.splice(filterIndex - 1, 2) } else { filter.splice(filterIndex, 2) } if (isSelectAll && "and" === operation) { filter.splice(0, filter.length) } } _isSimpleKeyFilter(filter, key) { return 3 === (null === filter || void 0 === filter ? void 0 : filter.length) && filter[0] === key && "=" === filter[1] } _isKeyFilter(filter) { if (2 === (null === filter || void 0 === filter ? void 0 : filter.length) && "!" === (null === filter || void 0 === filter ? void 0 : filter[0])) { return this._isKeyFilter(filter[1]) } const keyField = this._getKeyExpr(); if (Array.isArray(keyField)) { if ((null === filter || void 0 === filter ? void 0 : filter.length) !== 2 * keyField.length - 1) { return false } for (let i = 0; i < keyField.length; i += 1) { if (i > 0 && "and" !== (null === filter || void 0 === filter ? void 0 : filter[2 * i - 1])) { return false } if (!this._isSimpleKeyFilter(null === filter || void 0 === filter ? void 0 : filter[2 * i], keyField[i])) { return false } } return true } return this._isSimpleKeyFilter(filter, keyField) } _hasKeyFiltersOnlyStartingFromIndex(selectionFilter, filterIndex) { if (filterIndex >= 0) { for (let i = filterIndex; i < selectionFilter.length; i += 1) { if ("string" !== typeof selectionFilter[i] && !this._isKeyFilter(selectionFilter[i])) { return false } } return true } return false } _removeSameFilter(selectionFilter, filter, inverted, isSelectAll) { const sameFilter = inverted ? ["!", filter] : filter; if (JSON.stringify(sameFilter) === JSON.stringify(selectionFilter)) { selectionFilter.splice(0, selectionFilter.length); return 0 } const filterIndex = this._findSubFilter(selectionFilter, sameFilter); if (filterIndex >= 0) { this._removeFilterByIndex(selectionFilter, filterIndex, isSelectAll); return filterIndex } for (let i = 0; i < selectionFilter.length; i += 1) { if (Array.isArray(selectionFilter[i]) && selectionFilter[i].length > 2) { const innerFilterIndex = this._removeSameFilter(selectionFilter[i], sameFilter, false, isSelectAll); if (innerFilterIndex >= 0) { if (!selectionFilter[i].length) { this._removeFilterByIndex(selectionFilter, i, isSelectAll) } else if (1 === selectionFilter[i].length) { const [firstFilter] = selectionFilter[i]; selectionFilter[i] = firstFilter } return innerFilterIndex } } } return -1 } getSelectAllState() { const filter = this.options.filter(); let { selectionFilter: selectionFilter } = this.options; if (!selectionFilter) { return true } if (!selectionFilter.length) { return false } if (!(null !== filter && void 0 !== filter && filter.length)) { return } selectionFilter = this._denormalizeFilter(selectionFilter); if (this._isLastSubFilter(selectionFilter, filter)) { return true } if (this._isLastSubFilter(selectionFilter, ["!", filter])) { return false } return } loadSelectedItemsWithFilter() { const componentFilter = this.options.filter(); const { selectionFilter: selectionFilter } = this.options; const filter = componentFilter ? [componentFilter, "and", selectionFilter] : selectionFilter; return this._loadFilteredData(filter) } _onePageSelectAll(isDeselect) { this._selectAllPlainItems(isDeselect); this.onSelectionChanged(); return Deferred().resolve() } }