UNPKG

@progress/kendo-angular-grid

Version:

Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.

223 lines (222 loc) 10 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Directive, NgZone, Renderer2 } from '@angular/core'; import { ToolBarButtonComponent } from '@progress/kendo-angular-toolbar'; import { Subscription } from 'rxjs'; import { arrowsSwapIcon } from '@progress/kendo-svg-icons'; import { SortToolbarToolComponent } from './sort-toolbar-tool.component'; import { PopupService } from '@progress/kendo-angular-popup'; import { ContextService } from '../../../common/provider.service'; import { SortService } from '../../../common/sort.service'; import { closest, isDocumentAvailable, isPresent } from '@progress/kendo-angular-common'; import { ColumnInfoService } from '../../../common/column-info.service'; import { take } from 'rxjs/operators'; import { AdaptiveGridService } from '../../../common/adaptiveness.service'; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-toolbar"; import * as i2 from "@progress/kendo-angular-popup"; import * as i3 from "../../../common/provider.service"; import * as i4 from "../../../common/sort.service"; import * as i5 from "../../../common/column-info.service"; import * as i6 from "../../../common/adaptiveness.service"; let incrementingId = 0; /** * Represents the toolbar tool for sorting columns of the Grid. * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid. * * When you click the toolbar button with this directive, the `sort` event is triggered. * * @example * ```html-no-run * <kendo-grid> * <kendo-toolbar> * <kendo-toolbar-button text="Sort" kendoGridSortTool></kendo-toolbar-button> * </kendo-toolbar> * </kendo-grid> * ``` * @remarks * Applied to: {@link ToolBarButtonComponent}. */ export class SortCommandToolbarDirective { host; popupService; ctx; sortService; columnInfoService; ngZone; renderer; adaptiveGridService; popupRef; nextId = incrementingId++; toolSubs = new Subscription(); popupSubs; actionSheetCloseSub; removeClickListener; /** * @hidden */ isSortingApplied(sort) { return isPresent(sort) && sort.length > 0 && sort.filter(item => item.dir !== undefined).length > 0; } constructor(host, popupService, ctx, sortService, columnInfoService, ngZone, renderer, adaptiveGridService) { this.host = host; this.popupService = popupService; this.ctx = ctx; this.sortService = sortService; this.columnInfoService = columnInfoService; this.ngZone = ngZone; this.renderer = renderer; this.adaptiveGridService = adaptiveGridService; } ngOnInit() { this.toolSubs = this.host.click.subscribe(e => this.onClick(e)); this.toolSubs.add(this.sortService.changes.subscribe(sort => { this.host.showBadge = this.isSortingApplied(sort); })); this.host.hasBadgeContainer = true; this.host.showBadge = this.isSortingApplied(this.ctx.grid.sort); const hasToolbarIcon = isPresent(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== ''; const hasOverflowIcon = isPresent(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== ''; const hasIcon = hasToolbarIcon && hasOverflowIcon; const hasSvgIcon = isPresent(this.host.toolbarOptions.svgIcon) && isPresent(this.host.overflowOptions.svgIcon); if (!hasIcon) { this.host.icon = 'arrows-swap'; } if (!hasSvgIcon) { this.host.svgIcon = arrowsSwapIcon; } } ngAfterViewInit() { if (!isPresent(this.host.text)) { this.ngZone.onStable.pipe(take(1)).subscribe(() => { this.host.text = this.ctx.localization.get(`sortToolbarToolText`); }); } this.buttonElement?.setAttribute('aria-haspopup', 'dialog'); this.buttonElement?.setAttribute('aria-expanded', 'false'); this.buttonElement?.setAttribute('title', this.ctx.localization.get('sortToolbarToolText')); } ngOnDestroy() { if (this.toolSubs) { this.toolSubs.unsubscribe(); } if (this.popupSubs) { this.popupSubs.unsubscribe(); } if (this.popupRef) { this.popupRef.close(); this.popupRef = null; } if (this.actionSheetCloseSub) { this.actionSheetCloseSub.unsubscribe(); this.actionSheetCloseSub = null; } if (this.removeClickListener) { this.removeClickListener(); this.removeClickListener = null; } } onClick(e) { e.preventDefault(); if (this.ctx.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') { if (!this.ctx.grid.isActionSheetExpanded) { this.adaptiveGridService.viewType = 'sortToolbarTool'; this.ctx.grid.adaptiveRenderer.actionSheet.toggle(true); this.host.selected = true; this.actionSheetCloseSub = this.ctx.grid.adaptiveRenderer.actionSheet.collapse.subscribe(() => this.host.selected = false); } } else { if (this.popupRef) { this.closePopup(); return; } this.openPopup(); } } openPopup() { const direction = this.ctx.localization.rtl ? 'right' : 'left'; this.popupRef = this.popupService.open({ anchor: this.buttonElement, content: SortToolbarToolComponent, popupClass: 'k-grid-columnmenu-popup', positionMode: 'absolute', anchorAlign: { vertical: 'bottom', horizontal: direction }, popupAlign: { vertical: 'top', horizontal: direction } }); this.adaptiveGridService.popupRef = this.popupRef; this.setPopupAttributes(); this.host.selected = true; this.ngZone.runOutsideAngular(() => { if (!isDocumentAvailable()) { return; } this.removeClickListener = this.renderer.listen('document', 'click', (e) => { if (this.popupRef && !closest(e.target, node => node === this.popupRef.popupElement || node === this.buttonElement)) { this.ngZone.run(() => { this.closePopup(); }); } }); }); this.popupSubs = this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => { this.popupSubs?.unsubscribe(); this.popupSubs = null; this.closePopup(); }); this.initPopupProperties(); } setPopupAttributes() { const popupElement = this.popupRef.popupElement; const popupId = `k-sort-tool-${this.nextId}-popup`; const popupAriaElement = popupElement.querySelector('.k-popup'); this.renderer.setAttribute(popupElement, 'dir', this.ctx.localization.rtl ? 'rtl' : 'ltr'); this.renderer.setAttribute(popupAriaElement, 'id', popupId); this.renderer.setAttribute(popupAriaElement, 'role', 'dialog'); this.buttonElement?.setAttribute('aria-expanded', 'true'); this.buttonElement?.setAttribute('aria-controls', popupId); } initPopupProperties() { this.popupRef.content.instance.columnInfoService = this.columnInfoService; this.popupRef.content.instance.ctx = this.ctx; this.popupRef.content.instance.sortService = this.sortService; this.popupRef.content.instance.hostButton = this.host; this.popupSubs.add(this.popupRef.content.instance.sortClear.subscribe(() => { this.closePopup(); })); this.popupSubs.add(this.popupRef.content.instance.close.subscribe(() => { this.closePopup(); })); } closePopup() { this.buttonElement?.setAttribute('aria-expanded', 'false'); this.buttonElement?.removeAttribute('aria-controls'); this.host.selected = false; if (this.popupRef) { this.popupRef.close(); this.popupRef = null; } if (this.popupSubs) { this.popupSubs.unsubscribe(); this.popupSubs = null; } if (this.removeClickListener) { this.removeClickListener(); this.removeClickListener = null; } } get buttonElement() { return this.host.getButton(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortCommandToolbarDirective, deps: [{ token: i1.ToolBarButtonComponent }, { token: i2.PopupService }, { token: i3.ContextService }, { token: i4.SortService }, { token: i5.ColumnInfoService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i6.AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: SortCommandToolbarDirective, isStandalone: true, selector: "[kendoGridSortTool]", ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortCommandToolbarDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoGridSortTool]', standalone: true }] }], ctorParameters: () => [{ type: i1.ToolBarButtonComponent }, { type: i2.PopupService }, { type: i3.ContextService }, { type: i4.SortService }, { type: i5.ColumnInfoService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i6.AdaptiveGridService }] });