UNPKG

@progress/kendo-angular-grid

Version:

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

239 lines (238 loc) 11.2 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, Input, Renderer2, ChangeDetectorRef } from '@angular/core'; import { PopupService } from '@progress/kendo-angular-popup'; import { RefreshService, ToolBarButtonComponent } from '@progress/kendo-angular-toolbar'; import { closest, isPresent } from '@progress/kendo-angular-common'; import { Subscription } from 'rxjs'; import { columnsIcon } from '@progress/kendo-svg-icons'; import { ContextService } from '../../../common/provider.service'; import { filter, take } from 'rxjs/operators'; import { AdaptiveGridService } from '../../../common/adaptiveness.service'; import { ColumnInfoService } from '../../../common/column-info.service'; import { ToolbarToolBase } from '../../../common/toolbar-tool-base.directive'; import { ToolbarToolName } from '../../../navigation/toolbar-tool-name'; import { ColumnChooserContentComponent } from '../../../column-menu/column-chooser-content.component'; import * as i0 from "@angular/core"; import * as i1 from "@progress/kendo-angular-popup"; import * as i2 from "@progress/kendo-angular-toolbar"; import * as i3 from "../../../common/provider.service"; import * as i4 from "../../../common/adaptiveness.service"; import * as i5 from "../../../common/column-info.service"; let incrementingId = 0; /** * Represents a column chooser toolbar tool of the Grid. * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid. * * @example * ```html-no-run * <kendo-grid> * <kendo-toolbar> * <kendo-toolbar-button kendoGridColumnChooserTool></kendo-toolbar-button> * </kendo-toolbar> * </kendo-grid> * ``` * @remarks * Applied to: {@link ToolBarButtonComponent}. */ export class ColumnChooserToolbarDirective extends ToolbarToolBase { renderer; popupSerivce; host; ctx; zone; refresh; adaptiveGridService; columnInfoService; /** * When `true`, changes to column visibility apply immediately. * * @default false */ autoSync = false; /** * When `true`, enables the hiding of all columns. * * @default true */ allowHideAll = true; /** * When `true`, enables the columns' filtering. * * @default true */ filterable = true; /** * When `true`, displays a select all checkbox. * * @default true */ showSelectAll = true; /** * @hidden */ get columns() { return this.columnInfoService.leafNamedColumns; } popupRef; subs = new Subscription(); actionSheetCloseSub; nextId = incrementingId++; constructor(renderer, popupSerivce, host, ctx, zone, refresh, adaptiveGridService, columnInfoService, cdr) { super(host, ToolbarToolName.columns, ctx, zone, cdr); this.renderer = renderer; this.popupSerivce = popupSerivce; this.host = host; this.ctx = ctx; this.zone = zone; this.refresh = refresh; this.adaptiveGridService = adaptiveGridService; this.columnInfoService = columnInfoService; } ngOnInit() { this.subs.add(this.host.click.subscribe(e => this.onClick(e))); 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 = 'columns'; } if (!hasSvgIcon) { this.host.svgIcon = columnsIcon; } } ngAfterViewInit() { super.ngAfterViewInit(); this.zone.onStable.pipe(take(1)).subscribe(() => { this.buttonElement?.setAttribute('aria-haspopup', 'dialog'); this.buttonElement?.setAttribute('aria-expanded', 'false'); this.buttonElement?.setAttribute('title', this.ctx.localization.get('columns')); }); this.subs.add(this.refresh.onRefresh.pipe(filter((tool) => tool === this.host)).subscribe((tool) => { if (tool.overflows && this.popupRef) { this.popupRef.close(); } })); } ngOnDestroy() { super.ngOnDestroy(); this.subs.unsubscribe(); if (this.actionSheetCloseSub) { this.actionSheetCloseSub.unsubscribe(); this.actionSheetCloseSub = null; } } /** * @hidden */ onClick(e) { e.preventDefault(); if (this.ctx.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') { if (!this.ctx.grid.isActionSheetExpanded) { this.adaptiveGridService.viewType = 'columnChooserToolbarTool'; this.adaptiveGridService.columns = this.columns; 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 { this.togglePopup(); } } togglePopup() { if (!this.popupRef) { const direction = this.ctx.localization.rtl ? 'right' : 'left'; this.popupRef = this.popupSerivce.open({ anchor: this.buttonElement, content: ColumnChooserContentComponent, positionMode: 'absolute', anchorAlign: { vertical: 'bottom', horizontal: direction }, popupAlign: { vertical: 'top', horizontal: direction } }); this.adaptiveGridService.popupRef = this.popupRef; const popupElement = this.popupRef.popupElement; const popupId = `k-column-chooser-tool-${this.nextId}-popup`; const popupAriaElement = popupElement.querySelector('.k-popup'); this.zone.runOutsideAngular(() => { this.renderer.listen(popupAriaElement, 'keydown', (e) => { if (e.key === 'Escape') { this.closePopup(true); } }); }); 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); this.host.selected = true; const columnChooserContent = this.popupRef.content.instance; columnChooserContent.columnInfoService = this.columnInfoService; columnChooserContent.ctx = this.ctx; columnChooserContent.showSelectAll = this.showSelectAll; columnChooserContent.filterable = this.filterable; columnChooserContent.isLast = true; columnChooserContent.autoSync = this.autoSync; columnChooserContent.allowHideAll = this.allowHideAll; columnChooserContent.applyText = this.ctx.localization.get('columnsApply'); columnChooserContent.resetText = this.ctx.localization.get('columnsReset'); columnChooserContent.columns = this.ctx.grid.columns; columnChooserContent.filteredColumns = this.columnInfoService?.leafNamedColumns.filter(column => { if (column.includeInChooser !== false) { column.initiallyChecked = column.currentlyChecked = !column.hidden; return true; } return false; }); this.subs.add(this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => { this.closePopup(true); })); this.subs.add(columnChooserContent.columnList.apply.subscribe((changed) => { if (changed.length) { this.cdr.markForCheck(); this.columnInfoService.changeVisibility(changed); } this.closePopup(); })); this.zone.runOutsideAngular(() => this.renderer.listen('document', 'click', ({ target }) => { if (this.popupRef && !closest(target, node => node === this.popupRef.popupElement || node === this.buttonElement)) { this.zone.run(() => { this.closePopup(); }); } })); } else { this.closePopup(); } } closePopup(focusAnchor = false) { this.popupRef.close(); this.popupRef = null; this.buttonElement?.setAttribute('aria-expanded', 'false'); this.buttonElement?.removeAttribute('aria-controls'); this.host.selected = false; focusAnchor && this.buttonElement?.focus({ preventScroll: true }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ColumnChooserToolbarDirective, deps: [{ token: i0.Renderer2 }, { token: i1.PopupService }, { token: i2.ToolBarButtonComponent }, { token: i3.ContextService }, { token: i0.NgZone }, { token: i2.RefreshService }, { token: i4.AdaptiveGridService }, { token: i5.ColumnInfoService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ColumnChooserToolbarDirective, isStandalone: true, selector: "[kendoGridColumnChooserTool]", inputs: { autoSync: "autoSync", allowHideAll: "allowHideAll", filterable: "filterable", showSelectAll: "showSelectAll" }, usesInheritance: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ColumnChooserToolbarDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoGridColumnChooserTool]', standalone: true }] }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i1.PopupService }, { type: i2.ToolBarButtonComponent }, { type: i3.ContextService }, { type: i0.NgZone }, { type: i2.RefreshService }, { type: i4.AdaptiveGridService }, { type: i5.ColumnInfoService }, { type: i0.ChangeDetectorRef }], propDecorators: { autoSync: [{ type: Input }], allowHideAll: [{ type: Input }], filterable: [{ type: Input }], showSelectAll: [{ type: Input }] } });