UNPKG

@progress/kendo-angular-filter

Version:
290 lines (281 loc) 13.6 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { ChangeDetectorRef, Component, ElementRef, forwardRef, Input, QueryList, Renderer2, ViewChildren } from '@angular/core'; import { LocalizationService } from '@progress/kendo-angular-l10n'; import { filterAddExpressionIcon, filterAddGroupIcon, xIcon } from '@progress/kendo-svg-icons'; import { BaseFilterRowComponent } from './base-filter-row.component'; import { FilterService } from './filter.service'; import { NavigationService } from './navigation.service'; import { FilterItem, getKeyByValue, localizeOperators, logicOperators, selectors } from './util'; import { FilterExpressionComponent } from './filter-expression.component'; import { ButtonComponent } from '@progress/kendo-angular-buttons'; import { NgFor, NgClass, NgIf } from '@angular/common'; import * as i0 from "@angular/core"; import * as i1 from "./filter.service"; import * as i2 from "./navigation.service"; import * as i3 from "@progress/kendo-angular-l10n"; /** * @hidden */ export class FilterGroupComponent extends BaseFilterRowComponent { filterService; cdr; static ngAcceptInputType_currentItem; /** * @hidden */ xIcon = xIcon; /** * @hidden */ filterAddGroupIcon = filterAddGroupIcon; /** * @hidden */ filterAddExpressionIcon = filterAddExpressionIcon; _filterItems; get filterItems() { return this._filterItems.toArray(); } /** * @hidden */ handleExpressionValueChange(isRemoveOperation) { if (isRemoveOperation) { // due to tracking by index, the filters should first be set to [] so that all rerender afterwards const filtersCopy = this.currentItem.filters; this.currentItem.filters = []; this.cdr.detectChanges(); this.currentItem.filters = filtersCopy; } this.valueChange.emit(isRemoveOperation); } currentItem = { logic: 'or', filters: [] }; /** * @hidden */ trackByFunction = (index) => { return index; }; operators = []; localizationSubscription; constructor(filterService, cdr, element, navigationService, localization, renderer) { super(element, navigationService, localization, renderer); this.filterService = filterService; this.cdr = cdr; } ngOnInit() { this.operators = this.getLogicOperators(); this.localizationSubscription = this.localization.changes.subscribe(() => { this.operators = this.getLogicOperators(); this.cdr.detectChanges(); }); } ngOnDestroy() { if (this.localizationSubscription) { this.localizationSubscription.unsubscribe(); } } getLogicOperators() { return localizeOperators(logicOperators)(this.localization); } getOperator(operatorValue) { return this.messageFor(getKeyByValue(logicOperators, operatorValue)); } selectedChange(logicOperator) { if (this.currentItem.logic !== logicOperator) { this.currentItem.logic = logicOperator; this.valueChange.emit(); } } addFilterExpression() { this.filterService.addFilterExpression(this.currentItem); this.valueChange.emit(); } addFilterGroup() { this.filterService.addFilterGroup(this.currentItem); this.valueChange.emit(); } removeFilterGroup() { this.filterService.remove(this.currentItem, this.index); this.cdr.detectChanges(); this.valueChange.emit(true); } onMouseDown(event) { const toolbarItemElement = Array.from(event.target.closest(selectors.kendoToolbar).children).indexOf(event.target.closest(selectors.kendoFilterToolbarItem)); const buttonElement = Array.from(event.target.closest(selectors.kendoToolbar).children).indexOf(event.target.closest(selectors.kendoFilterToolbarButton)); let index = (toolbarItemElement > -1 ? toolbarItemElement : buttonElement) + 1; if (event.target.closest(selectors.andButton)) { index = 0; } if (event.target.closest(selectors.orButton)) { index = 1; } this.navigationService.currentToolbarItemChildrenIndex = index; this.navigationService.isFilterNavigationActivated = true; const elementToFocus = this.navigationService.flattenFilterItems[this.itemNumber].focusableChildren[index]; this.navigationService.isFilterExpressionComponentFocused = false; this.navigationService.currentToolbarItemIndex = this.itemNumber; this.navigationService.focusCurrentElement(elementToFocus, true); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterGroupComponent, deps: [{ token: i1.FilterService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i2.NavigationService }, { token: i3.LocalizationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterGroupComponent, isStandalone: true, selector: "kendo-filter-group", inputs: { currentItem: "currentItem" }, providers: [{ provide: FilterItem, useExisting: forwardRef(() => FilterGroupComponent) }], viewQueries: [{ propertyName: "_filterItems", predicate: FilterItem, descendants: true }], usesInheritance: true, ngImport: i0, template: ` <div class="k-filter-toolbar"> <div class="k-toolbar k-toolbar-md k-toolbar-solid" role="toolbar" [attr.aria-label]="messageFor('filterToolbarAriaLabel')" (mousedown)="onMouseDown($event)"> <div class="k-toolbar-button-group k-button-group k-button-group-solid" role="group"> <button tabindex="-1" *ngFor="let operator of operators" kendoButton class="k-toolbar-button" [ngClass]="{'k-group-start': operator.value === 'and', 'k-group-end': operator.value === 'or'}" [selected]="currentItem.logic === operator.value" [attr.aria-pressed]="currentItem.logic === operator.value" [title]="operator.text" (click)="selectedChange(operator.value)" > {{getOperator(operator.value)}} </button> </div> <button kendoButton class="k-toolbar-button" tabindex="-1" [title]="messageFor('addFilter')" icon="filter-add-expression" [svgIcon]="filterAddExpressionIcon" (click)="addFilterExpression()"> {{messageFor('addFilter')}} </button> <button kendoButton class="k-toolbar-button" tabindex="-1" [title]="messageFor('addGroup')" icon="filter-add-group" [svgIcon]="filterAddGroupIcon" (click)="addFilterGroup()"> {{messageFor('addGroup')}} </button> <button kendoButton class="k-toolbar-button" tabindex="-1" icon="x" [svgIcon]="xIcon" fillMode="flat" [title]="messageFor('remove')" (click)="removeFilterGroup()"> </button> </div> </div> <ul class="k-filter-lines" role="group" *ngIf="currentItem.filters"> <ng-container *ngFor="let item of currentItem.filters; let i = index; trackBy: trackByFunction"> <li class="k-filter-item" role="treeitem" *ngIf="!item['filters']"> <kendo-filter-expression (valueChange)="handleExpressionValueChange($event)" [currentItem]="item" [index]="i"> </kendo-filter-expression> </li> <li class="k-filter-item" role="treeitem" *ngIf="item['filters']"> <kendo-filter-group (valueChange)="valueChange.emit($event)" [currentItem]="item" [index]="i" > </kendo-filter-group> </li> </ng-container> </ul> `, isInline: true, dependencies: [{ kind: "component", type: FilterGroupComponent, selector: "kendo-filter-group", inputs: ["currentItem"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FilterExpressionComponent, selector: "kendo-filter-expression", inputs: ["currentItem"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterGroupComponent, decorators: [{ type: Component, args: [{ providers: [{ provide: FilterItem, useExisting: forwardRef(() => FilterGroupComponent) }], selector: 'kendo-filter-group', template: ` <div class="k-filter-toolbar"> <div class="k-toolbar k-toolbar-md k-toolbar-solid" role="toolbar" [attr.aria-label]="messageFor('filterToolbarAriaLabel')" (mousedown)="onMouseDown($event)"> <div class="k-toolbar-button-group k-button-group k-button-group-solid" role="group"> <button tabindex="-1" *ngFor="let operator of operators" kendoButton class="k-toolbar-button" [ngClass]="{'k-group-start': operator.value === 'and', 'k-group-end': operator.value === 'or'}" [selected]="currentItem.logic === operator.value" [attr.aria-pressed]="currentItem.logic === operator.value" [title]="operator.text" (click)="selectedChange(operator.value)" > {{getOperator(operator.value)}} </button> </div> <button kendoButton class="k-toolbar-button" tabindex="-1" [title]="messageFor('addFilter')" icon="filter-add-expression" [svgIcon]="filterAddExpressionIcon" (click)="addFilterExpression()"> {{messageFor('addFilter')}} </button> <button kendoButton class="k-toolbar-button" tabindex="-1" [title]="messageFor('addGroup')" icon="filter-add-group" [svgIcon]="filterAddGroupIcon" (click)="addFilterGroup()"> {{messageFor('addGroup')}} </button> <button kendoButton class="k-toolbar-button" tabindex="-1" icon="x" [svgIcon]="xIcon" fillMode="flat" [title]="messageFor('remove')" (click)="removeFilterGroup()"> </button> </div> </div> <ul class="k-filter-lines" role="group" *ngIf="currentItem.filters"> <ng-container *ngFor="let item of currentItem.filters; let i = index; trackBy: trackByFunction"> <li class="k-filter-item" role="treeitem" *ngIf="!item['filters']"> <kendo-filter-expression (valueChange)="handleExpressionValueChange($event)" [currentItem]="item" [index]="i"> </kendo-filter-expression> </li> <li class="k-filter-item" role="treeitem" *ngIf="item['filters']"> <kendo-filter-group (valueChange)="valueChange.emit($event)" [currentItem]="item" [index]="i" > </kendo-filter-group> </li> </ng-container> </ul> `, standalone: true, imports: [NgFor, ButtonComponent, NgClass, NgIf, FilterExpressionComponent] }] }], ctorParameters: function () { return [{ type: i1.FilterService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i2.NavigationService }, { type: i3.LocalizationService }, { type: i0.Renderer2 }]; }, propDecorators: { _filterItems: [{ type: ViewChildren, args: [FilterItem] }], currentItem: [{ type: Input }] } });