pragma-views2
Version:
237 lines (195 loc) • 6.82 kB
JavaScript
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);
}
}
}