UNPKG

xenos

Version:

Xenos is a data grid built upon angular2 and bootstrap.

231 lines (184 loc) 6.79 kB
import { Component, ElementRef, Input, Renderer, ViewChild, AfterViewInit } from "@angular/core"; import { ViewSource, ItemsPreview } from "./view-source"; import { CellDirective } from "./cell.directive"; import { HeaderDirective } from "./header.directive"; import { CandidateDirective } from "./candidate.directive"; import { DataGridColumn } from "./data-grid-column"; import { SortDescriptor } from "./sort-descriptor"; import { ColumnSortDescriptor } from "./column-sort-descriptor"; import { FilterDescriptor } from "./filter-descriptor"; import { FtsFilterDescriptor } from "./fts-filter-descriptor"; import { I18nService } from "./i18n.service"; import { I18n } from "./i18n"; import { I18nDirective } from "./i18n.directive"; import { IdGenerator } from "./id-generator"; import { ObservableArray } from "./observable-array"; import { Observable } from "rxjs/Observable"; // Some IDE's won't recognize the module node. I'm looking at you VS2015 ... declare var module: { id: any } @Component({ moduleId: module.id, selector: "data-grid", templateUrl: "data-grid.component.html", styleUrls: ["data-grid.component.min.css"] }) export class DataGrid implements AfterViewInit { private itemsPresenter: any[] = []; private viewSource: ViewSource; private pagingRangeInternal: number[] = []; private columnsInternal: ObservableArray<DataGridColumn>; private deferRefreshInternal: boolean = false; private lastSnapShotInternal: ItemsPreview; constructor( private renderer: Renderer, private elementRef: ElementRef, private i18nService: I18nService) { this.viewSource = new ViewSource(); this.viewSource.itemsViewChanging .subscribe(x => this.lastSnapShotInternal = x); this.viewSource.itemsViewChanged .subscribe(x => this.onItemsViewChanged(x)); this.viewSource.filterDescriptors.itemsChanged.subscribe(x => { this.autoRefresh(); }); this.viewSource.sortDescriptors.itemsChanged.subscribe(x => { this.autoRefresh(); }); this.columnsInternal = new ObservableArray<DataGridColumn>(); this.columnsInternal.itemsChanged.subscribe(x => { x.itemsRemoved.forEach(x => x.dataGrid = undefined); x.itemsAdded.forEach(x => { x.dataGrid = this; if (x.initialSortDirection) { x.sortDirection = x.initialSortDirection; } }); }); } @ViewChild("table") private table: ElementRef; @Input() public set pageSize(value: number) { this.viewSource.pageSize = value; this.autoRefresh(); } public set searchPhrase(phrase: string) { let index = this.filterDescriptors.findIndex(x => x.id === FtsFilterDescriptor.id); if (~index) { this.filterDescriptors.splice(index, 1); } if (!phrase) { return; } this.filterDescriptors.push(new FtsFilterDescriptor(this.columns, phrase)); } public get itemsViewChanging(): Observable<ItemsPreview> { return this.viewSource.itemsViewChanging; } public get itemsViewChanged(): Observable<any[]> { return this.viewSource.itemsViewChanged; } public get i18n(): I18n { return this.i18nService; } public get columns(): ObservableArray<DataGridColumn> { return this.columnsInternal; } public get working(): boolean { return this.viewSource.working; } public get filterDescriptors(): FilterDescriptor[] { return this.viewSource.filterDescriptors; } public get sortDescriptors(): SortDescriptor[] { return this.viewSource.sortDescriptors; } public get pageCount(): number { return this.viewSource.pageCount; } public get pageIndex(): number { return this.viewSource.pageIndex; } public set pageIndex(value: number) { this.viewSource.pageIndex = value; this.autoRefresh(); } public get pageSize(): number { return this.viewSource.pageSize; } public set itemsSource(source: any[]) { this.viewSource.itemsSource = source; this.autoRefresh(); } public get lastSnapShot(): ItemsPreview { if (!this.lastSnapShotInternal) { return undefined; } return this.lastSnapShotInternal; } public get itemsSource(): any[] { return this.viewSource.itemsSource; } private get items(): any[] { return this.itemsPresenter; } public deferRefresh(): void { this.deferRefreshInternal = true; } public refresh(): void { this.viewSource.refresh(); this.deferRefreshInternal = false; } private autoRefresh(): void { if (this.deferRefreshInternal) return; this.viewSource.refresh(); } private onItemsViewChanged(items: any[]): void { this.itemsPresenter.splice(0); items.forEach(x => this.itemsPresenter.push(x)); } private onHeaderClicked(event: MouseEvent, column: DataGridColumn): void { event.stopPropagation(); event.preventDefault(); if (column.disableSorting) { return; } this.deferRefresh(); if (!event.ctrlKey) { this.columns.forEach(x => { if (x.id === column.id) return; x.sortDirection = undefined; }); } column.cycleSortDirections(); this.refresh(); } private onPageChanged(event: Event, i: number) { event.preventDefault(); this.viewSource.pageIndex = i; this.autoRefresh(); } private get pagingRange(): number[] { this.pagingRangeInternal.splice(0); let start: number = this.pageIndex - 4; let end: number = this.pageIndex + 5; if (start < 0) { let s = Math.abs(start); start += s; end = Math.min(end + Math.abs(s), this.pageCount); } if (end > this.pageCount) { let e = end; end = end + (this.pageCount - e); start = Math.max(start + (this.pageCount - e), 0); } for (let i = start; i < end; i++) { this.pagingRangeInternal.push(i); } return this.pagingRangeInternal; } // Implementation of AfterViewInit public ngAfterViewInit(): void { // Nada ... } }