UNPKG

pragma-views2

Version:

237 lines (195 loc) 6.82 kB
import {HierarchicalItem} from './hierarchical-item.js'; export class DataSource { constructor(definition, schema, remoteCallback) { this.ready = false; this.definition = definition; this.schema = schema; this.remoteCallback = remoteCallback; // Set this value if you want to be notified that the root items has been loaded. this.rootItemsLoaded = []; this.itemsUpdateCallbacks = []; } dispose() { if (this.definition.perspective != undefined) { if (this.definition.perspective.cache != undefined) { window.groupWorker.disposeCache(this.definition.cache); } } this._data = null; this.rootItemsLoaded = null; this.definition = null; this.schema = null; window.groupWorker = null; this.remoteCallback = null; this.itemsUpdateCallbacks = null; } /** * We don't know how to fetch this item so performa remote callback to fetch that data * @param model * @param parentId * @returns {Promise<*>} * @private */ async _loadItemsFromRemoteSource(model, parentItem) { return await this.remoteCallback(this.definition, model, parentItem); } /** * Load this array from resource property defined in the schema definition * @returns {Promise<*>} * @private */ async _loadItemsFromResource() { return this.definition.resource.slice(0); } _notifyChanges() { for (let fn of this.itemsUpdateCallbacks) { fn(); } } /** * The items feched are flat list items so process them as such * @param items * @private */ async _processPerspectiveCache(items) { return new Promise(resolve => { let perspectives = []; for (let id of this.definition.perspective.perspectives) { const perspective = this.schema.perspectives.find(item => item.id == id); perspectives.push(perspective); } const eventName = `records_${this.definition.perspective.cache}`; const fn = (data) => { window.eventEmitter.remove(eventName, fn); resolve(); } window.eventEmitter.on(eventName, fn); window.groupWorker.createCache(this.definition.perspective.cache, items, perspectives); }); } addRootItemsLoadedCallback(fn) { if (this.rootItemsLoaded.indexOf(fn) == -1) { this.rootItemsLoaded.push(fn); } } removeRootItemsLoadedCallback(fn) { const index = this.rootItemsLoaded.indexOf(fn); if (index != -1) { this.rootItemsLoaded.slice(index, 1); } } clear() { if (this._data == null) { return; } while (this._data.length > 0) { const item = this._data.pop(); if (item.dispose != undefined) { item.dispose(); } } } /** * Get the data required * @returns {Promise<void>} */ async data(options) { if (this._data != undefined) { return this._data; } if (options != undefined && options.perspective != undefined) { return this.getPerspectiveData(options.perspective); } } getPerspeciveData(id) { return new Promise((resolve, reject) => { // get the perspective data from the group worker resolve(); }) } async getPerspectiveData(pid) { return new Promise(resolve => { const eventName = `${this.definition.perspective.cache}_${pid}`; const fn = (data) => { window.eventEmitter.remove(eventName, fn); let result = data; const p = this.schema.perspectives.find(item => item.id == pid); if (p.data.grouping != undefined) { result = this.itemsToHierarchyItems([result]); } resolve(result); }; window.eventEmitter.on(eventName, fn); window.groupWorker.getGroupPerspective(this.definition.perspective.cache, pid); }) } itemsToHierarchyItems(items, depth) { const result = []; for (let item of items) { const h = new HierarchicalItem(item, false, (item.items || []).length > 0, depth); if (item.items != undefined) { h.items = this.itemsToHierarchyItems(item.items, h.depth); delete item.items; } result.push(h); } return result; } /** * The load method is the primary way to load information in the datasource * @param model - context model that may give insights on what data to fetch * @param options - what parent item is this for on a hierarchical data source * { * perspective: 0 * } or * { * parent: parentObject * } * @returns {Promise<void>} */ async load(model, parentItem) { if (parentItem == undefined) { await this.loadRootItems(model); } else { await this.loadParentedItems(model, parentItem); } } async loadParentedItems(model, parentItem) { let items = await this._loadItemsFromRemoteSource(model, parentItem); items = this.itemsToHierarchyItems(items, parentItem.depth); parentItem.items = items; } /** * Get items from a remote source that the application needs to resolve * @param model * @param parentItem * @returns {Promise<*>} */ async loadRootItems(model) { this.clear(); let items; if ((this.definition.remote || "").length > 0) { items = await this._loadItemsFromRemoteSource(model, null); } else { items = await this._loadItemsFromResource(); } if (this.definition.hierarchical == true) { items = this.itemsToHierarchyItems(items); } if (this.definition.perspective == undefined) { this._data = items; } else { await this._processPerspectiveCache(items); } this.ready = true; if (this.rootItemsLoaded == undefined) { debugger; } for (let callback of this.rootItemsLoaded) { callback(this); } } }