UNPKG

@progress/kendo-angular-pivotgrid

Version:
751 lines (722 loc) 41.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, EventEmitter, HostBinding, Input, NgZone, Output, ViewChild } from '@angular/core'; import { ConfiguratorNavigation } from '@progress/kendo-pivotgrid-common'; import { CheckDirective, ExpandDirective, TreeViewComponent } from '@progress/kendo-angular-treeview'; import { PivotGridDataService } from '../data-binding/pivotgrid-data.service'; import { ConfiguratorService } from './configurator.service'; import { DropCueService } from './drop-cue.service'; import { from, of, Subscription } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; import { clone, swapItems } from '../util'; import { LocalizationService } from '@progress/kendo-angular-l10n'; import { SinglePopupService } from './chip-menu/single-popup.service'; import { ButtonComponent, ChipComponent, ChipListComponent } from '@progress/kendo-angular-buttons'; import { ChipMenuComponent } from './chip-menu/chip-menu.component'; import { ChipKeyboardNavigationDirective } from './chip-kb-nav.directive'; import { DraggableChipDirective } from './draggable.directive'; import { DropTargetDirective } from './drop-target.directive'; import { NgClass, NgStyle, NgIf, NgTemplateOutlet, NgFor } from '@angular/common'; import { DraggableDirective } from '@progress/kendo-angular-common'; import * as i0 from "@angular/core"; import * as i1 from "../data-binding/pivotgrid-data.service"; import * as i2 from "@progress/kendo-angular-l10n"; import * as i3 from "./configurator.service"; /** * @hidden * Represents the Kendo UI PivotGrid Configurator component for Angular. */ export class PivotGridConfiguratorComponent { dataService; localization; configuratorService; cdr; zone; hostClass = true; hostAriaRole = 'dialog'; get headerTextId() { return `k-pivotgrid-${this.dataService.pivotGridId}-configurator-header`; } orientation = 'vertical'; sort = new Array(); filter; navigation; close = new EventEmitter(); treeView; columnsList; rowsList; originalState; state; fields; checked = []; get isHorizontal() { return this.orientation === 'horizontal'; } subs = new Subscription(); /** * A function which determines if a specific node has child nodes. */ hasChildren = (node) => !('hierarchyUniqueName' in node) && !('aggregator' in node); constructor(dataService, localization, configuratorService, cdr, zone) { this.dataService = dataService; this.localization = localization; this.configuratorService = configuratorService; this.cdr = cdr; this.zone = zone; this.configuratorService.configuratorInstance = this; } ngOnInit() { this.subs.add(this.dataService.fields .subscribe(res => { this.fields = res; })); this.subs.add(this.dataService.configuredFields .subscribe(res => { const normalizedState = clone({ ...this.dataService.state, dragItem: res.dragItem, dropTarget: res.dropTarget, dropZone: res.dropZone, dropDirection: res.dropDirection }); this.originalState = normalizedState; this.setState(normalizedState); this.setChecked(); })); this.subs.add(this.configuratorService.configuratorStateChange .subscribe(res => { this.state = res; this.dataService.state = { columnAxes: res.columnAxes, rowAxes: res.rowAxes, measureAxes: res.measureAxes, sort: res.sort, filter: res.filter }; this.cdr.detectChanges(); })); } ngAfterViewInit() { this.treeView.focus(); } ngOnDestroy() { this.subs.unsubscribe(); } ngOnChanges(changes) { if (changes['orientation']) { this.configuratorService.orientation = this.orientation; } } getName(name) { return name.toString(); } contentLabelId(section) { return `k-pivotgrid-${this.dataService.pivotGridId}-configurator-${section}`; } setState(state) { this.dataService.state = { columnAxes: state.columnAxes, rowAxes: state.rowAxes, measureAxes: state.measureAxes, sort: state.sort, filter: state.filter }; this.state = this.configuratorService.state = state; this.cdr.detectChanges(); } onReorder(ev, name, item) { const currentCollection = this.state[`${name}Axes`]; const itemIndex = currentCollection.indexOf(item); switch (ev.direction) { case 'right': if (itemIndex !== currentCollection.length - 1) { this.swapChips(currentCollection, itemIndex, ev.direction, name); } break; case 'left': if (itemIndex !== 0) { this.swapChips(currentCollection, itemIndex, ev.direction, name); ev.sender.focus(); } break; case 'up': if (name === 'row') { this.moveChip(currentCollection, item, itemIndex, name); } break; case 'down': if (name === 'column') { this.moveChip(currentCollection, item, itemIndex, name); } break; default: break; } } /** * Returns the localized message for a given token */ messageFor(localizationToken) { return this.localization.get(localizationToken); } /** * Retrieves the 'Columns' section item names */ get columnHierarchies() { return this.extractDefaultFields(this.dataService.state.columnAxes); } /** * Retrieves the 'Rows' section item names */ get rowHierarchies() { return this.extractDefaultFields(this.dataService.state.rowAxes); } /** * Retrieves the 'Value' section item names */ get measureHierarchies() { return this.extractDefaultFields(this.dataService.state.measureAxes); } /** * Updates the respective axis configuration of the current state * when a chip is deleted from the UI */ onChipRemove(ev, item, section) { const filteredItems = this.dataService.state[`${section}Axes`].filter(descriptor => descriptor !== item); this.dataService.state[`${section}Axes`] = filteredItems; const newState = { ...this.state, ...this.dataService.state }; this.checked = this.checked.filter(checkedItem => checkedItem.uniqueName !== item.name[0]); const targetIndex = this.navigation?.elements.indexOf(ev.sender.element.nativeElement); this.setState(newState); if (!this.navigation) { return; } this.zone.runOutsideAngular(() => setTimeout(() => this.navigation.focusElement(this.navigation.elements[targetIndex - 1], this.navigation.elements[targetIndex]))); } /** * Constructs an array with all selected fields. * @param fields - used for when child nodes are loaded on demand. * Child nodes are concatinated to the root level nodes. */ setChecked(fields = []) { const allFields = [...this.fields, ...fields]; const checked = this.getFieldsFlatMap(allFields).filter((f) => [ ...this.columnHierarchies, ...this.rowHierarchies, ...this.measureHierarchies ].some((h) => (h === f.uniqueName || h === f.defaultHierarchy))); this.checked = checked; } checkItemBy = (context) => { return context.dataItem; }; /** * Determines if a checkbox should be rendered. */ isSelectable(node) { const hasChildren = !('hierarchyUniqueName' in node) && !('aggregator' in node); return !((!hasChildren && !node.aggregator && !node.measure) || (node.type === 2) || node.uniqueName === '[KPIs]'); } /** * A function which provides the child nodes for a given parent node. */ children = (node) => { if (this.dataService.directive.type === 'olap') { const observable = from(this.dataService.directive.fetchChildren(node, this.fields)); return observable.pipe(mergeMap(value => of(value))); } return of(node.children); }; /** * Check if the newly loaded child nodes have checked items. * (Only for OLAP data-binding directive) */ handleChildrenLoaded(event) { if (this.dataService.directive.type === 'local') { return; } const fields = event.children.map(item => item.dataItem); this.setChecked(fields); } handleCheckedChange(event) { const itemIndex = this.checked.findIndex(checkedItem => checkedItem.uniqueName === event.item.dataItem.uniqueName); this.checked.splice(itemIndex, 1); const action = { type: 'PIVOT_CONFIGURATOR_ACTION_TOGGLE_SELECTION', payload: event.item.dataItem }; this.configuratorService.parseConfiguratorState(action); } onTreeViewSelect(ev) { const closestItem = ev.target.closest('.k-treeview-item'); if (closestItem) { closestItem.querySelector('.k-checkbox')?.click(); } } onTreeViewEscape(ev) { ev.stopImmediatePropagation(); this.close.emit(); } handleSubmit() { this.dataService.configuratorFieldChange.emit(this.dataService.state); } /** * Reset the configurator to the last saved state */ handleReset() { this.setState(clone(this.originalState)); this.setChecked(); } /** * Flattens all available fields. */ getFieldsFlatMap(nodes = []) { let result = [...nodes]; (nodes || []).forEach((child) => { result = result.concat(this.getFieldsFlatMap(child.children)); }); return result; } /** * Creates an array containing only the field names, e.g. '[Date].[Calendar]' or 'Product' */ extractDefaultFields(columns = []) { const result = new Set(); columns.forEach((column) => { result.add(String(column.name)); }); return Array.from(result); } /** * Swaps chips within the same ChipList */ swapChips(collection, itemIndex, direction, name) { const targetIndex = itemIndex + (direction === 'right' ? 1 : -1); swapItems(collection, itemIndex, targetIndex); this.dataService.state[`${name}Axes`] = collection; const newState = { ...this.state, ...this.dataService.state }; this.setState(newState); this.cdr.detectChanges(); } /** * Moves a chip from one ChipList to another */ moveChip(collection, item, itemIndex, name) { collection.splice(itemIndex, 1); const targetCollectionName = name === 'row' ? 'column' : 'row'; const axes = this.state[`${targetCollectionName}Axes`]; axes.push(item); this.dataService.state[`${name}Axes`] = collection; this.dataService.state[targetCollectionName] = axes; const newState = { ...this.state, ...this.dataService.state }; this.setState(newState); this.cdr.detectChanges(); this[`${targetCollectionName}sList`]?.chips.last.focus(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PivotGridConfiguratorComponent, deps: [{ token: i1.PivotGridDataService }, { token: i2.LocalizationService }, { token: i3.ConfiguratorService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: PivotGridConfiguratorComponent, isStandalone: true, selector: "kendo-pivotgrid-configurator", inputs: { orientation: "orientation", sort: "sort", filter: "filter", navigation: "navigation" }, outputs: { close: "close" }, host: { properties: { "class.k-pivotgrid-configurator": "this.hostClass", "attr.role": "this.hostAriaRole", "attr.aria-labelledby": "this.headerTextId" } }, providers: [ ConfiguratorService, DropCueService, SinglePopupService ], viewQueries: [{ propertyName: "treeView", first: true, predicate: TreeViewComponent, descendants: true }, { propertyName: "columnsList", first: true, predicate: ["columnsChiplist"], descendants: true }, { propertyName: "rowsList", first: true, predicate: ["rowsChiplist"], descendants: true }], usesOnChanges: true, ngImport: i0, template: ` <div class="k-pivotgrid-configurator-panel k-pivotgrid-configurator-push" [ngClass]="{ 'k-pivotgrid-configurator-horizontal': isHorizontal, 'k-pivotgrid-configurator-vertical': !isHorizontal }" > <div class="k-pivotgrid-configurator-header"> <div [id]="headerTextId" class="k-pivotgrid-configurator-header-text">{{messageFor('configuratorHeaderText')}}</div> </div> <div class="k-pivotgrid-configurator-content"> <div class="k-form k-form-md" [class.k-form-horizontal]="isHorizontal" [class.k-form-vertical]="!isHorizontal" role="form"> <div class="k-form-field-wrapper" [ngStyle]="isHorizontal ? {'padding-left': 0 } : null"> <div class="k-form-field" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('fields')" class="k-label">{{messageFor('configuratorFieldsText')}}</span> </div> <div class="k-form-field" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <div class="k-fields-list-wrapper"> <kendo-treeview #treeview [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('fields')" (focus)="treeview.focus()" [nodes]="fields" textField="caption" [children]="children" [hasChildren]="hasChildren" kendoTreeViewCheckable [hasCheckbox]="isSelectable" [(checkedKeys)]="checked" [checkBy]="checkItemBy" (checkedChange)="handleCheckedChange($event)" kendoTreeViewExpandable (childrenLoaded)="handleChildrenLoaded($event)" (keydown.space)="onTreeViewSelect($event)"> </kendo-treeview> </div> </div> </div> <div *ngIf="isHorizontal; else verticalTemplate" class="k-form-field-wrapper" [ngStyle]="isHorizontal ? {'padding-left': 0 } : null"> <ng-container *ngTemplateOutlet="verticalTemplate"></ng-container> </div> <ng-template #verticalTemplate> <div class="k-form-field" kendoDropTarget axes="columnAxes" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('columns')" class="k-label">{{messageFor('configuratorColumnsText')}}</span> </div> <kendo-chiplist *ngIf="state.columnAxes && state.columnAxes.length; else noColumnAxes" [navigable]="false" #columnsChiplist kendoDropTarget class="k-column-fields" axes="columnAxes" [style.width.%]="100" [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('columns')" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null" > <ng-container *ngFor="let item of state.columnAxes"> <kendo-chip *ngIf="item.name.length === 1" #chip kendoChipDraggable kendoDraggable kendoDropTarget kendoChipKeyboardNavigation [item]="item" [label]="getName(item.name)" axes="columnAxes" [removable]="true" [hasMenu]="true" (menuToggle)="chipMenuColumns.toggle($event)" (remove)="onChipRemove($event, item, 'column')" (reorder)="onReorder($event, 'column', item)" > <kendo-pivot-chip-menu #chipMenuColumns [chip]="item" [anchor]="chip" ></kendo-pivot-chip-menu> </kendo-chip> </ng-container> </kendo-chiplist> <ng-template #noColumnAxes> <div class="k-settings-description" kendoDropTarget axes="columnAxes">{{messageFor('configuratorEmptyColumnsText')}}</div> </ng-template> <div class="k-form-field" kendoDropTarget axes="rowAxes" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('rows')" class="k-label">{{messageFor('configuratorRowsText')}}</span> </div> <kendo-chiplist *ngIf="state.rowAxes && state.rowAxes.length; else noRowAxes" [navigable]="false" #rowsChiplist kendoDropTarget class="k-row-fields" axes="rowAxes" [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('rows')" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null" [style.width.%]="100" > <ng-container *ngFor="let item of state.rowAxes"> <kendo-chip *ngIf="item.name.length === 1" #chip kendoChipDraggable kendoDraggable kendoDropTarget kendoChipKeyboardNavigation [item]="item" [label]="getName(item.name)" axes="rowAxes" [removable]="true" [hasMenu]="true" (menuToggle)="chipMenuRows.toggle($event)" (remove)="onChipRemove($event, item, 'row')" (reorder)="onReorder($event, 'row', item)" > <kendo-pivot-chip-menu #chipMenuRows [chip]="item" [anchor]="chip" ></kendo-pivot-chip-menu> </kendo-chip> </ng-container> </kendo-chiplist> <ng-template #noRowAxes> <div class="k-settings-description" kendoDropTarget axes="rowAxes">{{messageFor('configuratorEmptyRowsText')}}</div> </ng-template> </ng-template> <div *ngIf="isHorizontal; else verticalMeasuresTemplate" class="k-form-field-wrapper" [ngStyle]="isHorizontal ? {'padding-left': 0 } : null" > <ng-container *ngTemplateOutlet="verticalMeasuresTemplate"></ng-container> </div> <ng-template #verticalMeasuresTemplate> <div class="k-form-field" kendoDropTarget axes="measureAxes" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('values')" class="k-label">{{messageFor('configuratorValuesText')}}</span> </div> <kendo-chiplist *ngIf="state.measureAxes && state.measureAxes.length; else noMeasureAxes" [navigable]="false" kendoDropTarget class="k-filter-fields" axes="measureAxes" [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('values')" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null" [style.width.%]="100" > <kendo-chip *ngFor="let item of state.measureAxes" #chip kendoChipDraggable kendoDraggable kendoDropTarget kendoChipKeyboardNavigation [item]="item" [label]="getName(item.name)" axes="measureAxes" [removable]="true" [hasMenu]="true" (menuToggle)="chipMenuValues.toggle($event)" (remove)="onChipRemove($event, item, 'measure')" (reorder)="onReorder($event, 'measure', item)" > <kendo-pivot-chip-menu #chipMenuValues [chip]="item" [anchor]="chip" ></kendo-pivot-chip-menu> </kendo-chip> </kendo-chiplist> <ng-template #noMeasureAxes> <div class="k-settings-description" kendoDropTarget axes="measureAxes">{{messageFor('configuratorEmptyMeasuresText')}}</div> </ng-template> </ng-template> </div> </div> <div class="k-pivotgrid-configurator-actions k-actions k-actions-end k-actions-horizontal"> <button kendoButton type="button" (click)="handleReset()">{{messageFor('configuratorCancelButtonText')}}</button> <button kendoButton themeColor="primary" type="button" (click)="handleSubmit()">{{messageFor('configuratorApplyButtonText')}}</button> </div> </div> `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: TreeViewComponent, selector: "kendo-treeview", inputs: ["filterInputPlaceholder", "expandDisabledNodes", "animate", "nodeTemplate", "loadMoreButtonTemplate", "trackBy", "nodes", "textField", "hasChildren", "isChecked", "isDisabled", "hasCheckbox", "isExpanded", "isSelected", "isVisible", "navigable", "children", "loadOnDemand", "filterable", "filter", "size", "disableParentNodesOnly"], outputs: ["childrenLoaded", "blur", "focus", "expand", "collapse", "nodeDragStart", "nodeDrag", "filterStateChange", "nodeDrop", "nodeDragEnd", "addItem", "removeItem", "checkedChange", "selectionChange", "filterChange", "nodeClick", "nodeDblClick"], exportAs: ["kendoTreeView"] }, { kind: "directive", type: ExpandDirective, selector: "[kendoTreeViewExpandable]", inputs: ["isExpanded", "expandBy", "expandOnFilter", "expandedKeys"], outputs: ["expandedKeysChange"] }, { kind: "directive", type: CheckDirective, selector: "[kendoTreeViewCheckable]", inputs: ["isChecked", "checkBy", "checkedKeys", "kendoTreeViewCheckable"], outputs: ["checkedKeysChange"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: DropTargetDirective, selector: "[kendoDropTarget]", inputs: ["item", "axes"] }, { kind: "component", type: ChipListComponent, selector: "kendo-chiplist, kendo-chip-list", inputs: ["selection", "size", "role", "navigable"], outputs: ["selectedChange", "remove"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ChipComponent, selector: "kendo-chip", inputs: ["label", "icon", "svgIcon", "iconClass", "avatarSettings", "selected", "removable", "removeIcon", "removeSvgIcon", "hasMenu", "menuIcon", "menuSvgIcon", "disabled", "size", "rounded", "fillMode", "themeColor"], outputs: ["remove", "menuToggle", "contentClick"] }, { kind: "directive", type: DraggableChipDirective, selector: "[kendoChipDraggable]", inputs: ["item"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: ChipKeyboardNavigationDirective, selector: "[kendoChipKeyboardNavigation]", outputs: ["reorder"] }, { kind: "component", type: ChipMenuComponent, selector: "kendo-pivot-chip-menu", inputs: ["chip", "tabIndex", "isMeasureField", "anchor"] }, { 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"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PivotGridConfiguratorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-pivotgrid-configurator', providers: [ ConfiguratorService, DropCueService, SinglePopupService ], template: ` <div class="k-pivotgrid-configurator-panel k-pivotgrid-configurator-push" [ngClass]="{ 'k-pivotgrid-configurator-horizontal': isHorizontal, 'k-pivotgrid-configurator-vertical': !isHorizontal }" > <div class="k-pivotgrid-configurator-header"> <div [id]="headerTextId" class="k-pivotgrid-configurator-header-text">{{messageFor('configuratorHeaderText')}}</div> </div> <div class="k-pivotgrid-configurator-content"> <div class="k-form k-form-md" [class.k-form-horizontal]="isHorizontal" [class.k-form-vertical]="!isHorizontal" role="form"> <div class="k-form-field-wrapper" [ngStyle]="isHorizontal ? {'padding-left': 0 } : null"> <div class="k-form-field" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('fields')" class="k-label">{{messageFor('configuratorFieldsText')}}</span> </div> <div class="k-form-field" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <div class="k-fields-list-wrapper"> <kendo-treeview #treeview [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('fields')" (focus)="treeview.focus()" [nodes]="fields" textField="caption" [children]="children" [hasChildren]="hasChildren" kendoTreeViewCheckable [hasCheckbox]="isSelectable" [(checkedKeys)]="checked" [checkBy]="checkItemBy" (checkedChange)="handleCheckedChange($event)" kendoTreeViewExpandable (childrenLoaded)="handleChildrenLoaded($event)" (keydown.space)="onTreeViewSelect($event)"> </kendo-treeview> </div> </div> </div> <div *ngIf="isHorizontal; else verticalTemplate" class="k-form-field-wrapper" [ngStyle]="isHorizontal ? {'padding-left': 0 } : null"> <ng-container *ngTemplateOutlet="verticalTemplate"></ng-container> </div> <ng-template #verticalTemplate> <div class="k-form-field" kendoDropTarget axes="columnAxes" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('columns')" class="k-label">{{messageFor('configuratorColumnsText')}}</span> </div> <kendo-chiplist *ngIf="state.columnAxes && state.columnAxes.length; else noColumnAxes" [navigable]="false" #columnsChiplist kendoDropTarget class="k-column-fields" axes="columnAxes" [style.width.%]="100" [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('columns')" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null" > <ng-container *ngFor="let item of state.columnAxes"> <kendo-chip *ngIf="item.name.length === 1" #chip kendoChipDraggable kendoDraggable kendoDropTarget kendoChipKeyboardNavigation [item]="item" [label]="getName(item.name)" axes="columnAxes" [removable]="true" [hasMenu]="true" (menuToggle)="chipMenuColumns.toggle($event)" (remove)="onChipRemove($event, item, 'column')" (reorder)="onReorder($event, 'column', item)" > <kendo-pivot-chip-menu #chipMenuColumns [chip]="item" [anchor]="chip" ></kendo-pivot-chip-menu> </kendo-chip> </ng-container> </kendo-chiplist> <ng-template #noColumnAxes> <div class="k-settings-description" kendoDropTarget axes="columnAxes">{{messageFor('configuratorEmptyColumnsText')}}</div> </ng-template> <div class="k-form-field" kendoDropTarget axes="rowAxes" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('rows')" class="k-label">{{messageFor('configuratorRowsText')}}</span> </div> <kendo-chiplist *ngIf="state.rowAxes && state.rowAxes.length; else noRowAxes" [navigable]="false" #rowsChiplist kendoDropTarget class="k-row-fields" axes="rowAxes" [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('rows')" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null" [style.width.%]="100" > <ng-container *ngFor="let item of state.rowAxes"> <kendo-chip *ngIf="item.name.length === 1" #chip kendoChipDraggable kendoDraggable kendoDropTarget kendoChipKeyboardNavigation [item]="item" [label]="getName(item.name)" axes="rowAxes" [removable]="true" [hasMenu]="true" (menuToggle)="chipMenuRows.toggle($event)" (remove)="onChipRemove($event, item, 'row')" (reorder)="onReorder($event, 'row', item)" > <kendo-pivot-chip-menu #chipMenuRows [chip]="item" [anchor]="chip" ></kendo-pivot-chip-menu> </kendo-chip> </ng-container> </kendo-chiplist> <ng-template #noRowAxes> <div class="k-settings-description" kendoDropTarget axes="rowAxes">{{messageFor('configuratorEmptyRowsText')}}</div> </ng-template> </ng-template> <div *ngIf="isHorizontal; else verticalMeasuresTemplate" class="k-form-field-wrapper" [ngStyle]="isHorizontal ? {'padding-left': 0 } : null" > <ng-container *ngTemplateOutlet="verticalMeasuresTemplate"></ng-container> </div> <ng-template #verticalMeasuresTemplate> <div class="k-form-field" kendoDropTarget axes="measureAxes" [style]="'padding-top: 1em; margin-top: 0;'" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null"> <span [id]="contentLabelId('values')" class="k-label">{{messageFor('configuratorValuesText')}}</span> </div> <kendo-chiplist *ngIf="state.measureAxes && state.measureAxes.length; else noMeasureAxes" [navigable]="false" kendoDropTarget class="k-filter-fields" axes="measureAxes" [attr.aria-labelledby]="headerTextId + ' ' + contentLabelId('values')" [ngStyle]="isHorizontal ? {'padding-top': 0, 'padding-left': '16px' } : null" [style.width.%]="100" > <kendo-chip *ngFor="let item of state.measureAxes" #chip kendoChipDraggable kendoDraggable kendoDropTarget kendoChipKeyboardNavigation [item]="item" [label]="getName(item.name)" axes="measureAxes" [removable]="true" [hasMenu]="true" (menuToggle)="chipMenuValues.toggle($event)" (remove)="onChipRemove($event, item, 'measure')" (reorder)="onReorder($event, 'measure', item)" > <kendo-pivot-chip-menu #chipMenuValues [chip]="item" [anchor]="chip" ></kendo-pivot-chip-menu> </kendo-chip> </kendo-chiplist> <ng-template #noMeasureAxes> <div class="k-settings-description" kendoDropTarget axes="measureAxes">{{messageFor('configuratorEmptyMeasuresText')}}</div> </ng-template> </ng-template> </div> </div> <div class="k-pivotgrid-configurator-actions k-actions k-actions-end k-actions-horizontal"> <button kendoButton type="button" (click)="handleReset()">{{messageFor('configuratorCancelButtonText')}}</button> <button kendoButton themeColor="primary" type="button" (click)="handleSubmit()">{{messageFor('configuratorApplyButtonText')}}</button> </div> </div> `, standalone: true, imports: [ NgClass, NgStyle, TreeViewComponent, ExpandDirective, CheckDirective, NgIf, NgTemplateOutlet, DropTargetDirective, ChipListComponent, NgFor, ChipComponent, DraggableChipDirective, DraggableDirective, ChipKeyboardNavigationDirective, ChipMenuComponent, ButtonComponent ] }] }], ctorParameters: function () { return [{ type: i1.PivotGridDataService }, { type: i2.LocalizationService }, { type: i3.ConfiguratorService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; }, propDecorators: { hostClass: [{ type: HostBinding, args: ['class.k-pivotgrid-configurator'] }], hostAriaRole: [{ type: HostBinding, args: ['attr.role'] }], headerTextId: [{ type: HostBinding, args: ['attr.aria-labelledby'] }], orientation: [{ type: Input }], sort: [{ type: Input }], filter: [{ type: Input }], navigation: [{ type: Input }], close: [{ type: Output }], treeView: [{ type: ViewChild, args: [TreeViewComponent] }], columnsList: [{ type: ViewChild, args: ['columnsChiplist'] }], rowsList: [{ type: ViewChild, args: ['rowsChiplist'] }] } });