UNPKG

@clr/angular

Version:

Angular components for Clarity

98 lines 12.8 kB
/* * Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ import { BehaviorSubject } from 'rxjs'; import { ClrSelectedState } from './selected-state.enum'; export class TreeNodeModel { constructor() { this.loading$ = new BehaviorSubject(false); this.selected = new BehaviorSubject(ClrSelectedState.UNSELECTED); /* * Being able to push this down to the RecursiveTreeNodeModel would require too much work on the angular components * right now for them to know which kind of model they are using. So I'm lifting the public properties to this * abstract parent class for now and we can revisit it later, when we're not facing such a close deadline. */ this._loading = false; } get loading() { return this._loading; } set loading(isLoading) { this._loading = isLoading; this.loading$.next(isLoading); } destroy() { // Just to be safe this.selected.complete(); } // Propagate by default when eager, don't propagate in the lazy-loaded tree. setSelected(state, propagateUp, propagateDown) { if (state === this.selected.value) { return; } this.selected.next(state); if (propagateDown && state !== ClrSelectedState.INDETERMINATE && this.children) { this.children.forEach(child => child.setSelected(state, false, true)); } if (propagateUp && this.parent) { this.parent._updateSelectionFromChildren(); } } toggleSelection(propagate) { // Both unselected and indeterminate toggle to selected const newState = this.selected.value === ClrSelectedState.SELECTED ? ClrSelectedState.UNSELECTED : ClrSelectedState.SELECTED; // NOTE: we always propagate selection up in this method because it is only called when the user takes an action. // It should never be called from lifecycle hooks or app-provided inputs. this.setSelected(newState, true, propagate); } /* * Internal, but needs to be called by other nodes */ _updateSelectionFromChildren() { const newState = this.computeSelectionStateFromChildren(); if (newState === this.selected.value) { return; } this.selected.next(newState); if (this.parent) { this.parent._updateSelectionFromChildren(); } } computeSelectionStateFromChildren() { let oneSelected = false; let oneUnselected = false; // Using a good old for loop to exit as soon as we can tell, for better performance on large trees. for (const child of this.children) { switch (child.selected.value) { case ClrSelectedState.INDETERMINATE: return ClrSelectedState.INDETERMINATE; case ClrSelectedState.SELECTED: oneSelected = true; if (oneUnselected) { return ClrSelectedState.INDETERMINATE; } break; case ClrSelectedState.UNSELECTED: default: // Default is the same as unselected, in case an undefined somehow made it all the way here. oneUnselected = true; if (oneSelected) { return ClrSelectedState.INDETERMINATE; } break; } } if (!oneSelected) { return ClrSelectedState.UNSELECTED; } else if (!oneUnselected) { return ClrSelectedState.SELECTED; } else { return ClrSelectedState.UNSELECTED; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1ub2RlLm1vZGVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvZGF0YS90cmVlLXZpZXcvbW9kZWxzL3RyZWUtbm9kZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUV2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUV6RCxNQUFNLE9BQWdCLGFBQWE7SUFBbkM7UUFLRSxhQUFRLEdBQUcsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEMsYUFBUSxHQUFHLElBQUksZUFBZSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTVEOzs7O1dBSUc7UUFDSyxhQUFRLEdBQUcsS0FBSyxDQUFDO0lBOEYzQixDQUFDO0lBbEZDLElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsU0FBa0I7UUFDNUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUM7UUFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELE9BQU87UUFDTCxrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLFdBQVcsQ0FBQyxLQUF1QixFQUFFLFdBQW9CLEVBQUUsYUFBc0I7UUFDL0UsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7WUFDakMsT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsSUFBSSxhQUFhLElBQUksS0FBSyxLQUFLLGdCQUFnQixDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQzlFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDdkU7UUFDRCxJQUFJLFdBQVcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztTQUM1QztJQUNILENBQUM7SUFFRCxlQUFlLENBQUMsU0FBa0I7UUFDaEMsdURBQXVEO1FBQ3ZELE1BQU0sUUFBUSxHQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxLQUFLLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7UUFDOUcsaUhBQWlIO1FBQ2pILHlFQUF5RTtRQUN6RSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsNEJBQTRCO1FBQzFCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxDQUFDO1FBQzFELElBQUksUUFBUSxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1lBQ3BDLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztTQUM1QztJQUNILENBQUM7SUFFTyxpQ0FBaUM7UUFDdkMsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQztRQUMxQixtR0FBbUc7UUFDbkcsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2pDLFFBQVEsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7Z0JBQzVCLEtBQUssZ0JBQWdCLENBQUMsYUFBYTtvQkFDakMsT0FBTyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUM7Z0JBQ3hDLEtBQUssZ0JBQWdCLENBQUMsUUFBUTtvQkFDNUIsV0FBVyxHQUFHLElBQUksQ0FBQztvQkFDbkIsSUFBSSxhQUFhLEVBQUU7d0JBQ2pCLE9BQU8sZ0JBQWdCLENBQUMsYUFBYSxDQUFDO3FCQUN2QztvQkFDRCxNQUFNO2dCQUNSLEtBQUssZ0JBQWdCLENBQUMsVUFBVSxDQUFDO2dCQUNqQztvQkFDRSw0RkFBNEY7b0JBQzVGLGFBQWEsR0FBRyxJQUFJLENBQUM7b0JBQ3JCLElBQUksV0FBVyxFQUFFO3dCQUNmLE9BQU8sZ0JBQWdCLENBQUMsYUFBYSxDQUFDO3FCQUN2QztvQkFDRCxNQUFNO2FBQ1Q7U0FDRjtRQUNELElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDaEIsT0FBTyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7U0FDcEM7YUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3pCLE9BQU8sZ0JBQWdCLENBQUMsUUFBUSxDQUFDO1NBQ2xDO2FBQU07WUFDTCxPQUFPLGdCQUFnQixDQUFDLFVBQVUsQ0FBQztTQUNwQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAyMyBWTXdhcmUsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuXG4gKiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IENsclNlbGVjdGVkU3RhdGUgfSBmcm9tICcuL3NlbGVjdGVkLXN0YXRlLmVudW0nO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVHJlZU5vZGVNb2RlbDxUPiB7XG4gIG5vZGVJZDogc3RyaW5nO1xuICBleHBhbmRlZDogYm9vbGVhbjtcbiAgbW9kZWw6IFQgfCBudWxsO1xuICB0ZXh0Q29udGVudDogc3RyaW5nO1xuICBsb2FkaW5nJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuICBzZWxlY3RlZCA9IG5ldyBCZWhhdmlvclN1YmplY3QoQ2xyU2VsZWN0ZWRTdGF0ZS5VTlNFTEVDVEVEKTtcblxuICAvKlxuICAgKiBCZWluZyBhYmxlIHRvIHB1c2ggdGhpcyBkb3duIHRvIHRoZSBSZWN1cnNpdmVUcmVlTm9kZU1vZGVsIHdvdWxkIHJlcXVpcmUgdG9vIG11Y2ggd29yayBvbiB0aGUgYW5ndWxhciBjb21wb25lbnRzXG4gICAqIHJpZ2h0IG5vdyBmb3IgdGhlbSB0byBrbm93IHdoaWNoIGtpbmQgb2YgbW9kZWwgdGhleSBhcmUgdXNpbmcuIFNvIEknbSBsaWZ0aW5nIHRoZSBwdWJsaWMgcHJvcGVydGllcyB0byB0aGlzXG4gICAqIGFic3RyYWN0IHBhcmVudCBjbGFzcyBmb3Igbm93IGFuZCB3ZSBjYW4gcmV2aXNpdCBpdCBsYXRlciwgd2hlbiB3ZSdyZSBub3QgZmFjaW5nIHN1Y2ggYSBjbG9zZSBkZWFkbGluZS5cbiAgICovXG4gIHByaXZhdGUgX2xvYWRpbmcgPSBmYWxzZTtcblxuICAvKlxuICAgKiBJZGVhbGx5LCBJIHdvdWxkIGxpa2UgdG8gdXNlIGEgcG9seW1vcnBoaWMgdGhpcyB0eXBlIGhlcmUgdG8gZW5zdXJlIGhvbW9nZW5laXR5IG9mIHRoZSB0cmVlLCBzb21ldGhpbmcgbGlrZTpcbiAgICogYWJzdHJhY3QgcGFyZW50OiB0aGlzPFQ+IHwgbnVsbDtcbiAgICogYWJzdHJhY3QgY2hpbGRyZW46IHRoaXM8VD5bXTtcbiAgICogQnV0IEknbSBoaXR0aW5nIGxpbWl0YXRpb25zIG9uIHR5cGVzY3JpcHQgbm90IGFsbG93aW5nIHRoYXQgdHlwZSBpbiBjb25zdHJ1Y3RvcnMgb3Igc3RhdGljIG1ldGhvZHMuXG4gICAqIFNvIEknbSByZXNvcnRpbmcgdG8gZm9yY2luZyBvdmVycmlkZSB3aXRoIG1vcmUgcHJlY2lzZSB0eXBlcyBieSBtYXJraW5nIHRoZXNlIGFic3RyYWN0LlxuICAgKi9cbiAgYWJzdHJhY3QgcGFyZW50OiBUcmVlTm9kZU1vZGVsPFQ+IHwgbnVsbDtcbiAgYWJzdHJhY3QgY2hpbGRyZW46IFRyZWVOb2RlTW9kZWw8VD5bXTtcblxuICBnZXQgbG9hZGluZygpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9hZGluZztcbiAgfVxuICBzZXQgbG9hZGluZyhpc0xvYWRpbmc6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9sb2FkaW5nID0gaXNMb2FkaW5nO1xuICAgIHRoaXMubG9hZGluZyQubmV4dChpc0xvYWRpbmcpO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICAvLyBKdXN0IHRvIGJlIHNhZmVcbiAgICB0aGlzLnNlbGVjdGVkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvLyBQcm9wYWdhdGUgYnkgZGVmYXVsdCB3aGVuIGVhZ2VyLCBkb24ndCBwcm9wYWdhdGUgaW4gdGhlIGxhenktbG9hZGVkIHRyZWUuXG4gIHNldFNlbGVjdGVkKHN0YXRlOiBDbHJTZWxlY3RlZFN0YXRlLCBwcm9wYWdhdGVVcDogYm9vbGVhbiwgcHJvcGFnYXRlRG93bjogYm9vbGVhbikge1xuICAgIGlmIChzdGF0ZSA9PT0gdGhpcy5zZWxlY3RlZC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGVkLm5leHQoc3RhdGUpO1xuICAgIGlmIChwcm9wYWdhdGVEb3duICYmIHN0YXRlICE9PSBDbHJTZWxlY3RlZFN0YXRlLklOREVURVJNSU5BVEUgJiYgdGhpcy5jaGlsZHJlbikge1xuICAgICAgdGhpcy5jaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IGNoaWxkLnNldFNlbGVjdGVkKHN0YXRlLCBmYWxzZSwgdHJ1ZSkpO1xuICAgIH1cbiAgICBpZiAocHJvcGFnYXRlVXAgJiYgdGhpcy5wYXJlbnQpIHtcbiAgICAgIHRoaXMucGFyZW50Ll91cGRhdGVTZWxlY3Rpb25Gcm9tQ2hpbGRyZW4oKTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVTZWxlY3Rpb24ocHJvcGFnYXRlOiBib29sZWFuKSB7XG4gICAgLy8gQm90aCB1bnNlbGVjdGVkIGFuZCBpbmRldGVybWluYXRlIHRvZ2dsZSB0byBzZWxlY3RlZFxuICAgIGNvbnN0IG5ld1N0YXRlID1cbiAgICAgIHRoaXMuc2VsZWN0ZWQudmFsdWUgPT09IENsclNlbGVjdGVkU3RhdGUuU0VMRUNURUQgPyBDbHJTZWxlY3RlZFN0YXRlLlVOU0VMRUNURUQgOiBDbHJTZWxlY3RlZFN0YXRlLlNFTEVDVEVEO1xuICAgIC8vIE5PVEU6IHdlIGFsd2F5cyBwcm9wYWdhdGUgc2VsZWN0aW9uIHVwIGluIHRoaXMgbWV0aG9kIGJlY2F1c2UgaXQgaXMgb25seSBjYWxsZWQgd2hlbiB0aGUgdXNlciB0YWtlcyBhbiBhY3Rpb24uXG4gICAgLy8gSXQgc2hvdWxkIG5ldmVyIGJlIGNhbGxlZCBmcm9tIGxpZmVjeWNsZSBob29rcyBvciBhcHAtcHJvdmlkZWQgaW5wdXRzLlxuICAgIHRoaXMuc2V0U2VsZWN0ZWQobmV3U3RhdGUsIHRydWUsIHByb3BhZ2F0ZSk7XG4gIH1cblxuICAvKlxuICAgKiBJbnRlcm5hbCwgYnV0IG5lZWRzIHRvIGJlIGNhbGxlZCBieSBvdGhlciBub2Rlc1xuICAgKi9cbiAgX3VwZGF0ZVNlbGVjdGlvbkZyb21DaGlsZHJlbigpIHtcbiAgICBjb25zdCBuZXdTdGF0ZSA9IHRoaXMuY29tcHV0ZVNlbGVjdGlvblN0YXRlRnJvbUNoaWxkcmVuKCk7XG4gICAgaWYgKG5ld1N0YXRlID09PSB0aGlzLnNlbGVjdGVkLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0ZWQubmV4dChuZXdTdGF0ZSk7XG4gICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICB0aGlzLnBhcmVudC5fdXBkYXRlU2VsZWN0aW9uRnJvbUNoaWxkcmVuKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlU2VsZWN0aW9uU3RhdGVGcm9tQ2hpbGRyZW4oKSB7XG4gICAgbGV0IG9uZVNlbGVjdGVkID0gZmFsc2U7XG4gICAgbGV0IG9uZVVuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAvLyBVc2luZyBhIGdvb2Qgb2xkIGZvciBsb29wIHRvIGV4aXQgYXMgc29vbiBhcyB3ZSBjYW4gdGVsbCwgZm9yIGJldHRlciBwZXJmb3JtYW5jZSBvbiBsYXJnZSB0cmVlcy5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHtcbiAgICAgIHN3aXRjaCAoY2hpbGQuc2VsZWN0ZWQudmFsdWUpIHtcbiAgICAgICAgY2FzZSBDbHJTZWxlY3RlZFN0YXRlLklOREVURVJNSU5BVEU6XG4gICAgICAgICAgcmV0dXJuIENsclNlbGVjdGVkU3RhdGUuSU5ERVRFUk1JTkFURTtcbiAgICAgICAgY2FzZSBDbHJTZWxlY3RlZFN0YXRlLlNFTEVDVEVEOlxuICAgICAgICAgIG9uZVNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICBpZiAob25lVW5zZWxlY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIENsclNlbGVjdGVkU3RhdGUuSU5ERVRFUk1JTkFURTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ2xyU2VsZWN0ZWRTdGF0ZS5VTlNFTEVDVEVEOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIERlZmF1bHQgaXMgdGhlIHNhbWUgYXMgdW5zZWxlY3RlZCwgaW4gY2FzZSBhbiB1bmRlZmluZWQgc29tZWhvdyBtYWRlIGl0IGFsbCB0aGUgd2F5IGhlcmUuXG4gICAgICAgICAgb25lVW5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgaWYgKG9uZVNlbGVjdGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gQ2xyU2VsZWN0ZWRTdGF0ZS5JTkRFVEVSTUlOQVRFO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFvbmVTZWxlY3RlZCkge1xuICAgICAgcmV0dXJuIENsclNlbGVjdGVkU3RhdGUuVU5TRUxFQ1RFRDtcbiAgICB9IGVsc2UgaWYgKCFvbmVVbnNlbGVjdGVkKSB7XG4gICAgICByZXR1cm4gQ2xyU2VsZWN0ZWRTdGF0ZS5TRUxFQ1RFRDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIENsclNlbGVjdGVkU3RhdGUuVU5TRUxFQ1RFRDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==