UNPKG

@progress/kendo-angular-treelist

Version:

Kendo UI TreeList for Angular - Display hierarchical data in an Angular tree grid view that supports sorting, filtering, paging, and much more.

384 lines (383 loc) 18 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Component, HostBinding, Input } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { NgTemplateOutlet } from '@angular/common'; import { caretAltDownIcon, caretAltLeftIcon, caretAltRightIcon, reorderIcon } from '@progress/kendo-svg-icons'; import { LocalizationService } from "@progress/kendo-angular-l10n"; import { DatePickerComponent } from '@progress/kendo-angular-dateinputs'; import { CheckBoxComponent, NumericTextBoxComponent, TextBoxComponent } from '@progress/kendo-angular-inputs'; import { IconWrapperComponent } from '@progress/kendo-angular-icons'; import { EditService } from '../editing/edit.service'; import { isSpanColumn, isCheckboxColumn, isRowReorderColumn } from '../columns/column-base'; import { isColumnComponent } from '../columns/column.component'; import { columnsToRender } from "../columns/column-common"; import { isNullOrEmptyString, extractFormat, isColumnEditable } from '../utils'; import { FocusGroup } from '../navigation/focus-group'; import { LevelItemsPipe } from './common/level-items.pipe'; import { FieldAccessorPipe } from './common/field-accessor.pipe'; import { FocusableDirective } from '../navigation/focusable.directive'; import * as i0 from "@angular/core"; import * as i1 from "../editing/edit.service"; import * as i2 from "@progress/kendo-angular-l10n"; import * as i3 from "../navigation/focus-group"; import * as i4 from "@angular/forms"; /** * @hidden */ export class CellComponent { editService; localization; focusGroup; get commandCellClass() { return this.column.isCommand; } get isCheckboxColumn() { return isCheckboxColumn(this.column); } get textNoWrapClass() { return this.column.expandable; } get dragHandleCellClass() { return isRowReorderColumn(this.column); } get dragRowHandleLabel() { return isRowReorderColumn(this.column) ? this.localization.get('dragRowHandleLabel') : undefined; } column; columnIndex; isNew = false; level = 0; hasChildren; isExpanded; loading; expandIcons; rowIndex; selected; dataItem; set viewItem(value) { this._viewItem = value; this.cellContext.viewItem = this.viewItem; } get viewItem() { return this._viewItem; } get formGroup() { return this.viewItem.isNew ? this.editService.newItemGroup : this.viewItem.editContext ? this.viewItem.editContext.group : null; } get isEdited() { return Boolean((this.viewItem.isNew && isColumnEditable(this.column, this.editService.newItemGroup)) || (isColumnEditable(this.column, this.formGroup) && this.viewItem.editContext && this.editService.isEditedColumn(this.column))); } get templateContext() { return this._templateContext; } get editTemplateContext() { this._editTemplateContext.$implicit = this.formGroup; this._editTemplateContext.cellContext = this.cellContext; this._editTemplateContext.column = this.column; this._editTemplateContext.dataItem = this.dataItem; this._editTemplateContext.formGroup = this.formGroup; this._editTemplateContext.isNew = this.isNew; this._editTemplateContext.rowIndex = this.isNew ? -1 : this.rowIndex; return this._editTemplateContext; } get format() { if (isColumnComponent(this.column) && !isNullOrEmptyString(this.column.format)) { return extractFormat(this.column.format); } return undefined; } get isBoundColumn() { return this.column.field && !this.column.templateRef; } get isSpanColumn() { return isSpanColumn(this.column) && !this.column.templateRef; } get childColumns() { return columnsToRender([this.column]); } caretAltDownIcon = caretAltDownIcon; caretAltRightIcon = caretAltRightIcon; caretAltLeftIcon = caretAltLeftIcon; reorderIcon = reorderIcon; noneIcon = { name: 'none', content: '', viewBox: '0 0 24 24' }; cellContext = {}; _templateContext = {}; _editTemplateContext = {}; _viewItem; constructor(editService, localization, focusGroup) { this.editService = editService; this.localization = localization; this.focusGroup = focusGroup; this.templateContext.cellContext = this.cellContext; this.cellContext.focusGroup = focusGroup; } ngDoCheck() { this.updateTemplateContext(); } ngAfterContentChecked() { this.updateTemplateContext(); } updateTemplateContext() { if (!this.column.templateRef) { return; } const context = this._templateContext; context.$implicit = this.dataItem; context.column = this.column; context.columnIndex = this.columnIndex; context.dataItem = this.dataItem; context.hasChildren = this.hasChildren; context.isExpanded = this.isExpanded; context.isNew = this.isNew; context.level = this.level; context.loading = this.loading; context.rowIndex = this.viewItem.rowIndex; } get arrowIcon() { const icon = !this.isExpanded ? !this.localization.rtl ? 'caret-alt-right' : 'caret-alt-left' : 'caret-alt-down'; return icon; } get arrowSVGIcon() { const icon = !this.isExpanded ? !this.localization.rtl ? this.caretAltRightIcon : this.caretAltLeftIcon : this.caretAltDownIcon; return icon; } messageFor(token) { return this.localization.get(token); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CellComponent, deps: [{ token: i1.EditService }, { token: i2.LocalizationService }, { token: i3.FocusGroup }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: CellComponent, isStandalone: true, selector: "[kendoTreeListCell]", inputs: { column: "column", columnIndex: "columnIndex", isNew: "isNew", level: "level", hasChildren: "hasChildren", isExpanded: "isExpanded", loading: "loading", expandIcons: "expandIcons", rowIndex: "rowIndex", selected: "selected", dataItem: "dataItem", viewItem: "viewItem" }, host: { properties: { "class.k-command-cell": "this.commandCellClass", "class.k-checkbox-cell": "this.isCheckboxColumn", "class.k-text-nowrap": "this.textNoWrapClass", "class.k-drag-cell": "this.dragHandleCellClass", "class.k-touch-action-none": "this.dragHandleCellClass", "attr.aria-label": "this.dragRowHandleLabel" } }, ngImport: i0, template: ` @switch (isEdited) { @case (false) { @if (column.expandable) { @for (item of level | levelItems : hasChildren && expandIcons; track $index) { <kendo-icon-wrapper name="none" innerCssClass="k-treelist-toggle" [svgIcon]="noneIcon"></kendo-icon-wrapper> } @if (hasChildren && expandIcons && !loading) { <kendo-icon-wrapper innerCssClass="k-treelist-toggle" aria-hidden="true" [name]="arrowIcon" [svgIcon]="arrowSVGIcon"></kendo-icon-wrapper> } @if (hasChildren && expandIcons && loading) { <span class="k-icon k-i-loading"></span> } } @if (column.templateRef) { <ng-container [ngTemplateOutlet]="column.templateRef" [ngTemplateOutletContext]="templateContext"> </ng-container> } @if (isSpanColumn) { @for (childColumn of childColumns; track $index) { {{ dataItem | valueOf: childColumn.field: childColumn.format}} } } @if (isBoundColumn) {{{ dataItem | valueOf: column.field: column.format}}} @if (column.isCheckboxColumn && !isNew) { <kendo-checkbox kendoTreeListFocusable [inputAttributes]="{'aria-label': messageFor('selectRowCheckboxLabel')}" [checkedState]="selected" ></kendo-checkbox> } @if (column.isRowReorderColumn && !isNew) { <kendo-icon-wrapper name="reorder" [svgIcon]="reorderIcon"> </kendo-icon-wrapper> } } @case (true) { @if (column.editTemplateRef) { <ng-container [ngTemplateOutlet]="column.editTemplateRef" [ngTemplateOutletContext]="editTemplateContext"> </ng-container> } @if (!column.editTemplateRef) { @switch (column.editor) { @case ('numeric') { <kendo-numerictextbox [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-numerictextbox> } @case ('date') { <kendo-datepicker [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-datepicker> } @case ('boolean') { <kendo-checkbox [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-checkbox> } @default { <kendo-textbox [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-textbox> } } } } } `, isInline: true, dependencies: [{ kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoTreeListFocusable],\n [kendoTreeListAddCommand],\n [kendoTreeListEditCommand],\n [kendoTreeListRemoveCommand],\n [kendoTreeListSaveCommand],\n [kendoTreeListCancelCommand]\n ", inputs: ["kendoTreeListFocusable", "enabled", "kendoTreeListAddCommand", "kendoTreeListEditCommand", "kendoTreeListRemoveCommand", "kendoTreeListSaveCommand", "kendoTreeListCancelCommand"] }, { kind: "component", type: NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "adaptiveTitle", "adaptiveSubtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "pipe", type: FieldAccessorPipe, name: "valueOf" }, { kind: "pipe", type: LevelItemsPipe, name: "levelItems" }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }, { kind: "component", type: TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CellComponent, decorators: [{ type: Component, args: [{ selector: '[kendoTreeListCell]', template: ` @switch (isEdited) { @case (false) { @if (column.expandable) { @for (item of level | levelItems : hasChildren && expandIcons; track $index) { <kendo-icon-wrapper name="none" innerCssClass="k-treelist-toggle" [svgIcon]="noneIcon"></kendo-icon-wrapper> } @if (hasChildren && expandIcons && !loading) { <kendo-icon-wrapper innerCssClass="k-treelist-toggle" aria-hidden="true" [name]="arrowIcon" [svgIcon]="arrowSVGIcon"></kendo-icon-wrapper> } @if (hasChildren && expandIcons && loading) { <span class="k-icon k-i-loading"></span> } } @if (column.templateRef) { <ng-container [ngTemplateOutlet]="column.templateRef" [ngTemplateOutletContext]="templateContext"> </ng-container> } @if (isSpanColumn) { @for (childColumn of childColumns; track $index) { {{ dataItem | valueOf: childColumn.field: childColumn.format}} } } @if (isBoundColumn) {{{ dataItem | valueOf: column.field: column.format}}} @if (column.isCheckboxColumn && !isNew) { <kendo-checkbox kendoTreeListFocusable [inputAttributes]="{'aria-label': messageFor('selectRowCheckboxLabel')}" [checkedState]="selected" ></kendo-checkbox> } @if (column.isRowReorderColumn && !isNew) { <kendo-icon-wrapper name="reorder" [svgIcon]="reorderIcon"> </kendo-icon-wrapper> } } @case (true) { @if (column.editTemplateRef) { <ng-container [ngTemplateOutlet]="column.editTemplateRef" [ngTemplateOutletContext]="editTemplateContext"> </ng-container> } @if (!column.editTemplateRef) { @switch (column.editor) { @case ('numeric') { <kendo-numerictextbox [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-numerictextbox> } @case ('date') { <kendo-datepicker [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-datepicker> } @case ('boolean') { <kendo-checkbox [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-checkbox> } @default { <kendo-textbox [formControl]="$any(formGroup.get(column.field))" kendoTreeListFocusable ></kendo-textbox> } } } } } `, standalone: true, imports: [IconWrapperComponent, NgTemplateOutlet, FocusableDirective, NumericTextBoxComponent, ReactiveFormsModule, DatePickerComponent, FieldAccessorPipe, LevelItemsPipe, CheckBoxComponent, TextBoxComponent] }] }], ctorParameters: () => [{ type: i1.EditService }, { type: i2.LocalizationService }, { type: i3.FocusGroup }], propDecorators: { commandCellClass: [{ type: HostBinding, args: ['class.k-command-cell'] }], isCheckboxColumn: [{ type: HostBinding, args: ['class.k-checkbox-cell'] }], textNoWrapClass: [{ type: HostBinding, args: ['class.k-text-nowrap'] }], dragHandleCellClass: [{ type: HostBinding, args: ['class.k-drag-cell'] }, { type: HostBinding, args: ['class.k-touch-action-none'] }], dragRowHandleLabel: [{ type: HostBinding, args: ['attr.aria-label'] }], column: [{ type: Input }], columnIndex: [{ type: Input }], isNew: [{ type: Input }], level: [{ type: Input }], hasChildren: [{ type: Input }], isExpanded: [{ type: Input }], loading: [{ type: Input }], expandIcons: [{ type: Input }], rowIndex: [{ type: Input }], selected: [{ type: Input }], dataItem: [{ type: Input }], viewItem: [{ type: Input }] } });