UNPKG

novo-elements

Version:

Bullhorn's NOVO Element Repository for Angular 2

393 lines (351 loc) 10.2 kB
// Ng import { EventEmitter } from '@angular/core'; // App import { Collection } from './Collection'; import { CollectionEvent } from './CollectionEvent'; import { Helpers } from '../../utils/Helpers'; /** * Base Class for all Collection based data providers * * @export * @class DataProvider * @example * var dp:DataProvider = new DataProvider(); * dp.addItem({label:"Item 1"}); * dp.addItem({label:"Item 2"}); * dp.addItem({label:"Item 3"}); * dp.addItem({label:"Item 4"}); * var myList:List = new List(); * myList.dataProvider = dp; */ export class ArrayCollection<T> implements Collection<T> { dataChange: EventEmitter<CollectionEvent> = new EventEmitter<CollectionEvent>(); source: Array<T> = []; editData: Array<T> = []; isEditing: boolean = false; filterData: Array<T> = []; _filter: any = {}; _sort: Array<any> = []; constructor(source: Array<T> = []) { this.source = source; this.editData = this.copy(this.source); this.filterData = this.source.slice(); } get length() { return this.filterData.length; } get total(): number { return this.filterData.length; } get list(): Array<T> { return this.filterData; } isEmpty(): boolean { return this.length <= 0 && !this.isLoading() && !this.hasErrors(); } hasErrors(): boolean { return false; } isLoading(): boolean { return false; } isFiltered(): boolean { return (Object.keys(this._filter).length > 0); } /** * Method to switch the isEditingflag for the data source */ edit() { this.isEditing = true; this.editData = this.copy(this.source); } /** * Method to leave edit mode and reset source */ undo() { this.isEditing = false; this.source = this.copy(this.editData); this.refresh(); } /** * Method to leave edit mode and save editData */ commit() { this.isEditing = false; this.source = this.filterData.slice(); this.refresh(); } /** * Appends an item to the end of the data provider. * * @param {any} item * * @memberOf ArrayCollection */ addItem(item: T): void { this.isEditing ? this.editData.push(item) : this.source.push(item); this.onDataChange(new CollectionEvent(CollectionEvent.ADD, [item])); this.refresh(); } /** * Adds a new item to the data provider at the specified index. * * @param {any} item * @param {number} index * * @memberOf ArrayCollection */ addItemAt(item: T, index: number): void { this.isEditing ? this.editData.splice(index, 0, item) : this.source.splice(index, 0, item); this.onDataChange(new CollectionEvent(CollectionEvent.ADD, [item])); this.refresh(); } /** * Appends multiple items to the end of the DataProvider and dispatches a CollectionEvent.ADD event. * * @param {any} items * * @memberOf ArrayCollection */ addItems(items: Array<T>): void { this.isEditing ? this.editData.push(...items) : this.source.push(...items); this.onDataChange(new CollectionEvent(CollectionEvent.ADD, items)); this.refresh(); } /** * Adds several items to the data provider at the specified index and dispatches a CollectionEvent.ADD event. * * @param {any} items * @param {number} index * * @memberOf ArrayCollection */ addItemsAt(items: Array<T>, index: number): void { this.isEditing ? this.editData.splice(index, 0, ...items) : this.source.splice(index, 0, ...items); } /** * Creates a copy of the current ArrayCollection any. * * @returns {ArrayCollection} * * @memberOf ArrayCollection */ clone(): ArrayCollection<T> { return new ArrayCollection(this.isEditing ? this.copy(this.editData) : this.copy(this.source)); } /** * Creates a copy of the current ArrayCollection any. * * @returns {Array} * * @memberOf ArrayCollection */ copy(array: any[]): any[] { return Helpers.deepClone(array); } /** * Concatenates the specified items to the end of the current data provider. * * @param {any} items * * @memberOf ArrayCollection */ concat(items: Array<T>): void { this.addItems(items); } /** * Returns the item at the specified index. * * @param {number} index * @returns {any} * * @memberOf ArrayCollection */ getItemAt(index: number): any { return this.isEditing ? this.editData[index] : this.source[index]; } /** * Returns the index of the specified item. * * @param {any} item * @returns {number} * * @memberOf ArrayCollection */ getItemIndex(item: T): number { return this.isEditing ? this.editData.indexOf(item) : this.source.indexOf(item); } /** * Invalidates all the data items that the DataProvider contains and dispatches a CollectionEvent.INVALIDATE_ALL event. * * @memberOf ArrayCollection */ invalidate(): void { this.onDataChange(new CollectionEvent(CollectionEvent.INVALIDATE_ALL)); } /** * Invalidates the specified item. * * @param {any} item * * @memberOf ArrayCollection */ //invalidateItem(item:any):void {} /** * Invalidates the item at the specified index. * * @param {int} index * * @memberOf ArrayCollection */ //invalidateItemAt(index:number):void {} /** * Appends the specified data into the data that the data provider contains and removes any duplicate items. * * @param {Array} newData * * @memberOf ArrayCollection */ merge(newData: Array<T>): void { for (let obj of newData) { let existing = ~this.getItemIndex(obj); if (existing) { this.replaceItem(obj, existing); } else { this.addItem(obj); } } } /** * Removes all items from the data provider and dispatches a CollectionEvent.REMOVE_ALL event. * * @memberOf ArrayCollection */ removeAll(): void { this.source = []; this.editData = []; this.filterData = []; this.onDataChange(new CollectionEvent(CollectionEvent.REMOVE_ALL, [])); this.refresh(); } /** * Removes the specified item from the data provider and dispatches a CollectionEvent.REMOVE event. * * @param {any} item * @returns {any} * * @memberOf ArrayCollection */ removeItem(item: T): boolean { let index = this.getItemIndex(item); return this.removeItemAt(index); } /** * Removes the item at the specified index and dispatches a CollectionEvent.REMOVE event. * * @param {number} index * @returns {any} * * @memberOf ArrayCollection */ removeItemAt(index: number): boolean { let success = !!(this.source.splice(index, 1)); this.refresh(); return success; } /** * Replaces an existing item with a new item and dispatches a CollectionEvent.REPLACE event. * * @param {any} newItem * @param {any} oldItem * @returns {any} * * @memberOf ArrayCollection */ replaceItem(newItem: any, oldItem: any): any { let index = this.getItemIndex(oldItem); if (index >= 0) { this.replaceItemAt(newItem, index); } } /** * Replaces the item at the specified index and dispatches a CollectionEvent.REPLACE event. * * @param {any} newItem * @param {number} index * @returns {any} * * @memberOf ArrayCollection */ replaceItemAt(newItem: any, index: number): any { this.filterData.splice(index, 1, newItem); } /** * Sorts the items that the data provider contains and dispatches a CollectionEvent.SORT event. * * @param {any} sortArgs * @returns null * * @memberOf ArrayCollection */ get sort(): Array<any> { return this._sort; } set sort(value: Array<any>) { this._sort = value; this.refresh(); } /** * Sorts the items that the data provider contains by the specified field and dispatches a CollectionEvent.SORT event. * * @param {any} fieldName * @param {any} [options=null] * @returns null * * @memberOf ArrayCollection */ sortOn(fieldName: any, reverse = false): Array<T> { this.filterData = this.filterData.sort(Helpers.sortByField(fieldName, reverse)); this.onDataChange(new CollectionEvent(CollectionEvent.SORT)); return this.filterData; } get filter(): any { return this._filter; } set filter(value: any) { this._filter = value; this.refresh(); } filterOn(fieldName: any, value: any = null): Array<T> { this.filterData = this.filterData.filter(Helpers.filterByField(fieldName, value)); return this.filterData; } onDataChange(event: CollectionEvent): void { this.dataChange.emit(event); } refresh(): void { this.filterData = this.isEditing ? this.editData.slice() : this.source.slice(); for (let item of this._sort.reverse()) { this.sortOn(item.field, item.reverse); } for (let key in this._filter) { if (key) { this.filterOn(key, this._filter[key]); } } this.onDataChange(new CollectionEvent(CollectionEvent.CHANGE, this.filterData)); } /** * Creates an Array any representation of the data that the data provider contains. * * @returns {Array} * * @memberOf ArrayCollection */ toArray(): Array<T> { return this.isEditing ? this.editData : this.source; } toJSON() { return this.isEditing ? this.editData : this.source; } }