UNPKG

@anglr/grid

Version:
417 lines 21 kB
import { Component, ChangeDetectionStrategy, Inject, Optional, Type, Input, ContentChild, forwardRef, inject, ViewChild, ViewContainerRef, resolveForwardRef } from '@angular/core'; import { extend } from '@jscrpt/common/extend'; import { lastValueFrom } from '@jscrpt/common/rxjs'; import { BehaviorSubject, map, combineLatest, distinctUntilChanged, take } from 'rxjs'; import { CONTENT_RENDERER_TYPE, DATA_LOADER_TYPE, DEFAULT_OPTIONS, GRID_INITIALIZER_TYPE, GRID_INSTANCE, GRID_OPTIONS, GRID_PLUGIN_INSTANCES, METADATA_GATHERER, METADATA_SELECTOR_TYPE, NO_DATA_RENDERER_TYPE, ORDERING_TYPE, PAGING_TYPE, ROW_SELECTOR_TYPE } from '../../misc/tokens'; import { AsyncDataLoaderComponent, BasicPagingComponent, NoRowSelectorComponent, NoGridInitializerComponent, NoMetadataSelectorComponent, SimpleNoDataRendererComponent, SingleOrderingComponent, TableContentRendererComponent } from '../../plugins'; import { GridPluginType } from '../../misc/enums'; import { GridPluginInstancesDef } from '../../misc/gridPluginInstancesDef'; import * as i0 from "@angular/core"; /** * Default 'GridOptions' */ const defaultOptions = { autoInitialize: true, plugins: { contentRenderer: { type: forwardRef(() => TableContentRendererComponent), instance: null, instanceCallback: null, options: null, }, dataLoader: { type: forwardRef(() => AsyncDataLoaderComponent), instance: null, instanceCallback: null, options: null, }, gridInitializer: { type: forwardRef(() => NoGridInitializerComponent), instance: null, instanceCallback: null, options: null, }, metadataSelector: { type: forwardRef(() => NoMetadataSelectorComponent), instance: null, instanceCallback: null, options: null, }, noDataRenderer: { type: forwardRef(() => SimpleNoDataRendererComponent), instance: null, instanceCallback: null, options: null, }, ordering: { type: forwardRef(() => SingleOrderingComponent), instance: null, instanceCallback: null, options: null, }, paging: { type: forwardRef(() => BasicPagingComponent), instance: null, instanceCallback: null, options: null, }, rowSelector: { type: forwardRef(() => NoRowSelectorComponent), instance: null, instanceCallback: null, options: null, }, } }; /** * Grid component used for rendering grid */ export class GridComponent { /** * Metadata gatherer instance */ get metadataGatherer() { return this.metadataGathererChild; } //######################### public properties - inputs ######################### /** * @inheritdoc */ get gridOptions() { return this.ɵgridOptions; } set gridOptions(options) { this.ɵgridOptions = extend(true, this.ɵgridOptions, options); } //######################### public properties - implementation of Grid ######################### /** * @inheritdoc */ get initialized() { return this.initializedSubject.asObservable().pipe(distinctUntilChanged()); } //######################### constructors ######################### constructor(options, pagingType, orderingType, gridInitializerType, dataLoaderType, contentRendererType, metadataSelectorType, noDataRendererType, rowSelectorType) { //######################### protected fields ######################### /** * Object storing current used plugin type */ this.pluginTypes = { ContentRenderer: null, DataLoader: null, GridInitializer: null, MetadataSelector: null, NoDataRenderer: null, Ordering: null, Paging: null, RowSelector: null, }; /** * Grid plugin instances available for grid */ this.pluginInstances = inject(GRID_PLUGIN_INSTANCES); /** * Instance that allows changing state of initialized plugins */ this.pluginsOptionsInitialization = { contentRenderer: new BehaviorSubject(false), dataLoader: new BehaviorSubject(false), gridInitializer: new BehaviorSubject(false), metadataSelector: new BehaviorSubject(false), noDataRenderer: new BehaviorSubject(false), ordering: new BehaviorSubject(false), paging: new BehaviorSubject(false), rowSelector: new BehaviorSubject(false), }; /** * Subject used for indication that grid was initialized */ this.initializedSubject = new BehaviorSubject(false); /** * @inheritdoc */ this.pluginsOptionsInitialized = combineLatest([ this.pluginsOptionsInitialization.contentRenderer, this.pluginsOptionsInitialization.dataLoader, this.pluginsOptionsInitialization.gridInitializer, this.pluginsOptionsInitialization.metadataSelector, this.pluginsOptionsInitialization.noDataRenderer, this.pluginsOptionsInitialization.ordering, this.pluginsOptionsInitialization.paging, this.pluginsOptionsInitialization.rowSelector, ]).pipe(map(initFlags => { const [contentRenderer, dataLoader, gridInitializer, metadataSelector, noDataRenderer, ordering, paging, rowSelector] = initFlags; return contentRenderer && dataLoader && gridInitializer && metadataSelector && noDataRenderer && ordering && paging && rowSelector; }), distinctUntilChanged()); this.pluginsOptionsInitialized.subscribe(async (initialized) => { if (initialized && this.ɵgridOptions.autoInitialize && !(await lastValueFrom(this.initialized.pipe(take(1))))) { this.initialize(false); } }); const opts = extend({}, options); if (!opts.plugins) { opts.plugins = {}; } if (pagingType) { opts.plugins.paging ??= {}; opts.plugins.paging.type = pagingType; } if (orderingType) { opts.plugins.ordering ??= {}; opts.plugins.ordering.type = orderingType; } if (gridInitializerType) { opts.plugins.gridInitializer ??= {}; opts.plugins.gridInitializer.type = gridInitializerType; } if (dataLoaderType) { opts.plugins.dataLoader ??= {}; opts.plugins.dataLoader.type = dataLoaderType; } if (contentRendererType) { opts.plugins.contentRenderer ??= {}; opts.plugins.contentRenderer.type = contentRendererType; } if (metadataSelectorType) { opts.plugins.metadataSelector ??= {}; opts.plugins.metadataSelector.type = metadataSelectorType; } if (noDataRendererType) { opts.plugins.noDataRenderer ??= {}; opts.plugins.noDataRenderer.type = noDataRendererType; } if (rowSelectorType) { opts.plugins.rowSelector ??= {}; opts.plugins.rowSelector.type = rowSelectorType; } this.ɵgridOptions = extend(true, {}, inject(DEFAULT_OPTIONS), opts); } //######################### public methods - implementation of OnInit ######################### /** * Initialize component */ ngOnInit() { if (this.gridOptions.autoInitialize) { this.initOptions(); } } //######################### public methods - implementation of Grid ######################### /** * @inheritdoc */ async initialize(force) { this.initializedSubject.next(false); await this.pluginInstances[GridPluginType.RowSelector].initialize(force); await this.pluginInstances[GridPluginType.MetadataSelector].initialize(force); await this.pluginInstances[GridPluginType.GridInitializer].initialize(force); await this.pluginInstances[GridPluginType.Ordering].initialize(force); await this.pluginInstances[GridPluginType.Paging].initialize(force); await this.pluginInstances[GridPluginType.ContentRenderer].initialize(force); await this.pluginInstances[GridPluginType.NoDataRenderer].initialize(force); await this.pluginInstances[GridPluginType.DataLoader].initialize(force); this.initializedSubject.next(true); } /** * @inheritdoc */ async initOptions() { const initOptionsFn = async (pluginType, pluginDescription, initOptionsSubject, pluginViewContainer, beforeOptionsSet) => { if ((pluginDescription.instance && pluginDescription.type) || (!pluginDescription.instance && !pluginDescription.type)) { throw new Error(`GridComponent: provide only instance or type for plugin ${pluginType}, cant provide both of these properties at the same time!`); } let newInstance = false; initOptionsSubject.next(false); //only for existing instances of plugins if (pluginDescription.instance) { this.pluginTypes[pluginType] = null; pluginViewContainer.clear(); //plugin is different from current plugin if (pluginDescription.instance != this.pluginInstances[pluginType]) { this.pluginInstances[pluginType] = pluginDescription.instance; pluginDescription.instance.gridPlugins = this.pluginInstances; newInstance = true; } } //only if plugin type is provided else if (pluginDescription.type) { const type = resolveForwardRef(pluginDescription.type); //new type provided if (type != this.pluginTypes[pluginType]) { this.pluginTypes[pluginType] = type; pluginViewContainer.clear(); const component = pluginViewContainer.createComponent(type); component.changeDetectorRef.detectChanges(); this.pluginInstances[pluginType] = component.instance; newInstance = true; } } //only call when new instance of plugin was created if (newInstance) { await beforeOptionsSet?.(this.pluginInstances[pluginType]); pluginDescription.instanceCallback?.(this.pluginInstances[pluginType]); } //options are available, set them if (pluginDescription.options) { this.pluginInstances[pluginType].options = pluginDescription.options; } await this.pluginInstances[pluginType].initOptions(); initOptionsSubject.next(true); }; //init options paging await initOptionsFn(GridPluginType.Paging, this.ɵgridOptions.plugins.paging, this.pluginsOptionsInitialization.paging, this.pagingContainer); //init options ordering await initOptionsFn(GridPluginType.Ordering, this.ɵgridOptions.plugins.ordering, this.pluginsOptionsInitialization.ordering, this.orderingContainer); //init options grid initializer await initOptionsFn(GridPluginType.GridInitializer, this.ɵgridOptions.plugins.gridInitializer, this.pluginsOptionsInitialization.gridInitializer, this.gridInitializerContainer); //init options data loader await initOptionsFn(GridPluginType.DataLoader, this.ɵgridOptions.plugins.dataLoader, this.pluginsOptionsInitialization.dataLoader, this.dataLoaderContainer); //init options content renderer await initOptionsFn(GridPluginType.ContentRenderer, this.ɵgridOptions.plugins.contentRenderer, this.pluginsOptionsInitialization.contentRenderer, this.contentRendererContainer); //init options metadata selector await initOptionsFn(GridPluginType.MetadataSelector, this.ɵgridOptions.plugins.metadataSelector, this.pluginsOptionsInitialization.metadataSelector, this.metadataSelectorContainer, metadataSelector => { if (this.metadataGatherer) { metadataSelector.setMetadataGatherer(this.metadataGatherer); } }); //init options no data renderer await initOptionsFn(GridPluginType.NoDataRenderer, this.ɵgridOptions.plugins.noDataRenderer, this.pluginsOptionsInitialization.noDataRenderer, this.noDataRendererContainer); //init options row selector await initOptionsFn(GridPluginType.RowSelector, this.ɵgridOptions.plugins.rowSelector, this.pluginsOptionsInitialization.rowSelector, this.rowSelectorContainer); } /** * @inheritdoc */ getPlugin(pluginId) { return this.pluginInstances[pluginId]; } /** * @inheritdoc */ setGridPluginInstances(plugin) { plugin.gridPlugins = this.pluginInstances; } /** * @inheritdoc */ async execute(...actions) { if (!actions) { return; } for (const action of actions) { await action(this); } } /** * @inheritdoc */ executeAndReturn(func) { return func(this); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0", ngImport: i0, type: GridComponent, deps: [{ token: GRID_OPTIONS, optional: true }, { token: PAGING_TYPE, optional: true }, { token: ORDERING_TYPE, optional: true }, { token: GRID_INITIALIZER_TYPE, optional: true }, { token: DATA_LOADER_TYPE, optional: true }, { token: CONTENT_RENDERER_TYPE, optional: true }, { token: METADATA_SELECTOR_TYPE, optional: true }, { token: NO_DATA_RENDERER_TYPE, optional: true }, { token: ROW_SELECTOR_TYPE, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.0", type: GridComponent, isStandalone: true, selector: "ng-grid", inputs: { gridOptions: "gridOptions" }, providers: [ { provide: GRID_INSTANCE, useExisting: forwardRef(() => GridComponent), }, { provide: GRID_PLUGIN_INSTANCES, useFactory: () => { return new GridPluginInstancesDef(); }, }, { provide: DEFAULT_OPTIONS, useValue: defaultOptions, }, ], queries: [{ propertyName: "metadataGathererChild", first: true, predicate: METADATA_GATHERER, descendants: true }], viewQueries: [{ propertyName: "metadataSelectorContainer", first: true, predicate: ["metadataSelectorContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "dataLoaderContainer", first: true, predicate: ["dataLoaderContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "rowSelectorContainer", first: true, predicate: ["rowSelectorContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "gridInitializerContainer", first: true, predicate: ["gridInitializerContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "orderingContainer", first: true, predicate: ["orderingContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "contentRendererContainer", first: true, predicate: ["contentRendererContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "noDataRendererContainer", first: true, predicate: ["noDataRendererContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "pagingContainer", first: true, predicate: ["pagingContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<ng-container #metadataSelectorContainer/>\r\n<ng-container #dataLoaderContainer/>\r\n<ng-container #rowSelectorContainer/>\r\n<ng-container #gridInitializerContainer/>\r\n<ng-container #orderingContainer/>\r\n<ng-container #contentRendererContainer/>\r\n<ng-container #noDataRendererContainer/>\r\n<ng-container #pagingContainer/>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0", ngImport: i0, type: GridComponent, decorators: [{ type: Component, args: [{ selector: 'ng-grid', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: GRID_INSTANCE, useExisting: forwardRef(() => GridComponent), }, { provide: GRID_PLUGIN_INSTANCES, useFactory: () => { return new GridPluginInstancesDef(); }, }, { provide: DEFAULT_OPTIONS, useValue: defaultOptions, }, ], template: "<ng-container #metadataSelectorContainer/>\r\n<ng-container #dataLoaderContainer/>\r\n<ng-container #rowSelectorContainer/>\r\n<ng-container #gridInitializerContainer/>\r\n<ng-container #orderingContainer/>\r\n<ng-container #contentRendererContainer/>\r\n<ng-container #noDataRendererContainer/>\r\n<ng-container #pagingContainer/>" }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [GRID_OPTIONS] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [PAGING_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [ORDERING_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [GRID_INITIALIZER_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [DATA_LOADER_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [CONTENT_RENDERER_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [METADATA_SELECTOR_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [NO_DATA_RENDERER_TYPE] }, { type: Optional }] }, { type: i0.Type, decorators: [{ type: Inject, args: [ROW_SELECTOR_TYPE] }, { type: Optional }] }], propDecorators: { gridOptions: [{ type: Input }], metadataSelectorContainer: [{ type: ViewChild, args: ['metadataSelectorContainer', { read: ViewContainerRef, static: true }] }], dataLoaderContainer: [{ type: ViewChild, args: ['dataLoaderContainer', { read: ViewContainerRef, static: true }] }], rowSelectorContainer: [{ type: ViewChild, args: ['rowSelectorContainer', { read: ViewContainerRef, static: true }] }], gridInitializerContainer: [{ type: ViewChild, args: ['gridInitializerContainer', { read: ViewContainerRef, static: true }] }], orderingContainer: [{ type: ViewChild, args: ['orderingContainer', { read: ViewContainerRef, static: true }] }], contentRendererContainer: [{ type: ViewChild, args: ['contentRendererContainer', { read: ViewContainerRef, static: true }] }], noDataRendererContainer: [{ type: ViewChild, args: ['noDataRendererContainer', { read: ViewContainerRef, static: true }] }], pagingContainer: [{ type: ViewChild, args: ['pagingContainer', { read: ViewContainerRef, static: true }] }], metadataGathererChild: [{ type: ContentChild, args: [METADATA_GATHERER] }] } }); //# sourceMappingURL=grid.component.js.map