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.

175 lines (174 loc) 5.88 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Injectable, EventEmitter, NgZone } from '@angular/core'; import { isPresent, isColumnEditable } from '../utils'; import { CellCloseEvent } from './cell-close-event'; import { Subject } from 'rxjs'; import { switchMap, take } from 'rxjs/operators'; import * as i0 from "@angular/core"; const identity = item => item; /** * @hidden */ export class EditService { ngZone; changes = new EventEmitter(); changed; get newItemGroup() { return this.newItem ? this.newItem.group : null; } newItem; idGetter = identity; // Maps IDs to edited rows edited = new Map(); keepEditCell = false; keepCellTimeout; column; closingCell = false; changedSource = new Subject(); constructor(ngZone) { this.ngZone = ngZone; this.changed = this.changedSource.asObservable().pipe(switchMap(() => this.ngZone.onStable.asObservable().pipe(take(1)))); } editRow(dataItem, group = undefined) { this.edited.set(this.idGetter(dataItem), { group, item: dataItem }); this.onChanged(); } addRow(parent, group) { this.newItem = { parent, group, dataItem: group ? group.value : null }; this.onChanged(); } editCell(item, column, group) { if (!isColumnEditable(column, group)) { return; } this.preventCellClose(); if (!this.closeCell()) { this.editRow(item, group); this.column = column; this.onChanged(); } } isEditing() { return this.edited.size > 0; } isEdited(dataItem) { return (this.newItem && this.newItem.dataItem === dataItem) || this.edited.has(this.idGetter(dataItem)); } isEditingCell() { return isPresent(this.column); } isEditingColumn(column) { return this.column === column; } isEditedColumn(column) { return !this.column || this.column === column; } hasNew(parent) { return Boolean(this.newItem && ((!this.newItem.parent && !parent) || this.idGetter(this.newItem.parent) === this.idGetter(parent))); } get newDataItem() { if (this.newItem) { return this.newItem.group.value; } } close(item, isNew) { if (isNew) { // parent this.newItem = undefined; return; } this.edited.delete(this.idGetter(item)); delete this.column; this.onChanged(); } closeCell(originalEvent) { if (this.column && !this.closingCell) { return this.ngZone.run(() => { const { item, group } = this.first; const args = new CellCloseEvent({ column: this.column, formGroup: group, originalEvent: originalEvent, dataItem: item }); this.closingCell = true; this.changes.emit(args); this.closingCell = false; if (!args.isDefaultPrevented()) { this.cancelCell(); } return args.isDefaultPrevented(); }); } } cancelCell() { if (this.column) { this.edited.clear(); this.column = null; this.onChanged(); } } shouldCloseCell() { return this.column && !this.keepEditCell; } preventCellClose() { this.ngZone.runOutsideAngular(() => { window.clearTimeout(this.keepCellTimeout); this.keepEditCell = true; this.keepCellTimeout = window.setTimeout(() => { this.keepEditCell = false; }, 0); }); } context(dataItem) { return this.edited.get(this.idGetter(dataItem)); } beginEdit(item) { this.changes.emit({ action: 'edit', dataItem: item }); } beginAdd(parent) { this.changes.emit({ action: 'add', parent }); } endEdit(dataItem, isNew) { const formGroup = isNew ? this.newItemGroup : this.context(dataItem).group; this.changes.emit({ action: 'cancel', dataItem, formGroup, isNew }); } save(item, isNew) { const args = { action: 'save', isNew: isNew }; if (isNew) { args.parent = this.newItem.parent; args.formGroup = this.newItem.group; args.dataItem = item; } else { args.dataItem = item; args.formGroup = this.context(item).group; } this.changes.emit(args); } remove(dataItem, parent) { this.changes.emit({ action: 'remove', dataItem, parent }); } onChanged() { this.ngZone.runOutsideAngular(() => { this.changedSource.next(undefined); }); } get first() { if (this.isEditing()) { return this.edited.values().next().value; } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i0.NgZone }] });