UNPKG

@progress/kendo-angular-grid

Version:

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

209 lines (208 loc) 9.24 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 { groupIcon } from '@progress/kendo-svg-icons'; import { PopupService } from '@progress/kendo-angular-popup'; import { ContextService } from '../../../common/provider.service'; import { closest, isDocumentAvailable, isPresent } from '@progress/kendo-angular-common'; import { take } from 'rxjs/operators'; import { AdaptiveGridService } from '../../../common/adaptiveness.service'; import { GroupToolbarToolComponent } from './group-toolbar-tool.component'; 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/adaptiveness.service"; let incrementingId = 0; /** * Represents the toolbar tool for grouping 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 `group` event is triggered. * * @example * ```html * <kendo-grid> * <kendo-toolbar> * <kendo-toolbar-button text="Group" kendoGridGroupTool></kendo-toolbar-button> * </kendo-toolbar> * </kendo-grid> * ``` * @remarks * Applied to: {@link ToolBarButtonComponent}. */ export class GroupCommandToolbarDirective { host; popupService; ctx; ngZone; renderer; adaptiveGridService; popupRef; nextId = incrementingId++; toolSubs = new Subscription(); popupSubs; actionSheetCloseSub; removeClickListener; constructor(host, popupService, ctx, ngZone, renderer, adaptiveGridService) { this.host = host; this.popupService = popupService; this.ctx = ctx; this.ngZone = ngZone; this.renderer = renderer; this.adaptiveGridService = adaptiveGridService; } ngOnInit() { this.toolSubs = this.host.click.subscribe(e => this.onClick(e)); this.toolSubs.add(this.ctx.grid.groupChange.subscribe(group => { this.host.showBadge = this.isGroupingApplied(group); })); this.host.hasBadgeContainer = true; this.host.showBadge = this.isGroupingApplied(this.ctx.grid.group); 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 = 'group'; } if (!hasSvgIcon) { this.host.svgIcon = groupIcon; } } ngAfterViewInit() { if (!isPresent(this.host.text)) { this.ngZone.onStable.pipe(take(1)).subscribe(() => { this.host.text = this.ctx.localization.get(`groupToolbarToolText`); }); } this.buttonElement?.setAttribute('aria-haspopup', 'dialog'); this.buttonElement?.setAttribute('aria-expanded', 'false'); this.buttonElement?.setAttribute('title', this.ctx.localization.get('groupToolbarToolText')); } 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 = 'groupToolbarTool'; 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: GroupToolbarToolComponent, 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-group-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.ctx = this.ctx; this.popupRef.content.instance.hostButton = this.host; this.popupSubs.add(this.popupRef.content.instance.groupClear.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(); } isGroupingApplied(group) { return isPresent(group) && group.length > 0; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupCommandToolbarDirective, deps: [{ token: i1.ToolBarButtonComponent }, { token: i2.PopupService }, { token: i3.ContextService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i4.AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: GroupCommandToolbarDirective, isStandalone: true, selector: "[kendoGridGroupTool]", ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupCommandToolbarDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoGridGroupTool]', standalone: true }] }], ctorParameters: () => [{ type: i1.ToolBarButtonComponent }, { type: i2.PopupService }, { type: i3.ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i4.AdaptiveGridService }] });