UNPKG

pragma-views2

Version:

305 lines (254 loc) 9.26 kB
import {Validator} from "./validation-rules.js"; import {DataSource} from "./datasource.js"; import {addTriggers, removeObserversFromCache} from "/baremetal/lib/binding/observers.js"; /** * todo: clean up the observation objects. * unobserver the object */ export class DataSet { constructor(definition, schema) { this["__definition"] = Object.create(definition); this["__schema"] = schema; } dispose() { removeObserversFromCache(this); const keys = Object.keys(this); for (let key of keys) { if (this[key] == null || this[key] == undefined) { continue; } if (this[key].dispose != undefined && this[key].dispose === "function") { this[key].dispose(); } else if (Array.isArray(this[key])) { for (let child of this[key]) { if (child.dispose != undefined) { child.dispose(); } } } delete this[key]; } this.__proto__ = null; } applyValues(item, mapping) { if (mapping != undefined) { // If mapping defined only update properties matched in mapping for (let key of Object.keys(mapping)) { const sourceField = mapping[key]; this[key] = item[sourceField]; } } else { // Set values of all properties found in item if no mapping set for (let key of Object.keys(item)) { this[key] = item[key]; } } } clear() { const keys = Object.keys(this); const ignore = ["datasetFactory", "__definition", "__schema", "observer", "__observers__", "__defaults"]; for (let key of keys) { if (ignore.indexOf(key) == -1) { if ((this[key] || {}).clear != undefined) { if (typeof this[key].clear == "function") { this[key].clear(); } } else { this[key] = null; } } } const fields = this.__definition.fields; for (let field of fields) { delete field.initialValue; } } defaultFromDefinition() { const result = {}; for (let field of this["__definition"].fields) { if (field.collection == true) { result[field.name] = []; } else { result[field.name] = field.default == undefined ? null : field.default; } } return result; } doDrillDown(fieldName) { this.sendPreviewMessage(fieldName, "drilldown-from-resource"); } doEdit() { window.eventEmitter.emit("do-edit", { model: this, callback: (editedItem) => this.applyValues(editedItem) }) } doLookup(fieldName) { const field = this["__definition"].fields.find(item => item.name == fieldName); const lookupId = field.lookup; const lookup = this["__schema"].lookups.find(item => item.id == lookupId); const perspective = this["__schema"].perspectives.find(item => item.id == lookup.perspective); const previewId = field.preview; const preview = previewId != undefined ? this["__schema"].previews.find(item => item.id == previewId) : previewId; window.eventEmitter.emit("do-lookup", { definition: lookup, perspective: perspective, preview: preview, model: this, callback: (selectedItem) => this.applyValues(selectedItem, lookup.mapping) }); } doPeek(fieldName) { this.sendPreviewMessage(fieldName, "view-from-resource"); } getDirtyArray(items) { const result = []; for (let item of items) { if (item instanceof DataSet) { result.push(item.getDirtyModel()) } } return result.length > 0 ? result : null; } getDirtyField(field, isNewObject) { const modelValue = this[field.name]; const initialValue = field.initialValue != undefined ? field.initialValue : null; if (modelValue instanceof DataSet) { return modelValue.getDirtyModel() } if (Array.isArray(modelValue)) { return this.getDirtyArray(modelValue); } //TODO GM: Temporary if (modelValue instanceof DataSource) { return null; } if (isNewObject == true) { if ((modelValue || "").length == 0) { return null; } return { oldValue: null, newValue: modelValue } } if (modelValue != initialValue) { return { oldValue: initialValue, newValue: modelValue } } } getDirtyModel() { const result = {}; const isNewObject = this["id"] == -1; for (let field of this.__definition.fields) { const dirty = this.getDirtyField(field, isNewObject); if (dirty != null) { result[field.name] = dirty; } } return Object.keys(result).length > 0 ? result : null; } listenFor(property, callback) { // JHR: if this is a path ? if (callback) { addTriggers(this, property, () => callback(this, property)); } else { const propertyCallback = this[`${property}Changed`]; if (propertyCallback) { addTriggers(this, property, propertyCallback); } } } raw() { const result = {}; for (let field of this.__definition.fields) { result[field.name] = this[field.name]; } return result; } resetToDefault() { for (let field of this.__definition.fields) { const fld = this[field.name]; if (fld instanceof DataSource) { fld.clear(); } else if (field instanceof DataSet) { fld.resetToDefault(); } else { this[field.name] = field.initialValue != undefined ? field.initialValue : null; } } } sendPreviewMessage(fieldName, messageKey) { if (fieldName == undefined) { return; } const field = this["__definition"].fields.find(item => item.name == fieldName); const previewId = field.preview; const preview = this["__schema"].previews.find(item => item.id == previewId); const datsetField = preview["dataset-field"]; const idValue = this[datsetField]; window.eventEmitter.emit(messageKey, { resourceId: idValue, resource: preview["remote"] }); } setInitialValues(model) { this.clear(); this.__isLoading = true; if (model == undefined) { model = {}; } const fields = this.__definition.fields; const collectionsToLoad = []; const datasetsToLoad = []; for (let field of fields) { if (field.collection == true) { if (this[field.name] == undefined) { const dsId = field.datasource; const dsSchema = this.__schema.datasources.find(item => item.id == dsId); const datasource = new DataSource(dsSchema, this.datasetFactory.schema, this.datasetFactory.remoteDsCallback); this[field.name] = datasource; } collectionsToLoad.push(this[field.name]); } else if (field.dataset != undefined) { datasetsToLoad.push(field); } else { this[field.name] = model[field.name] || (this.__defaults.has(field.name) ? this.__defaults.get(field.name) : undefined); field.initialValue = this[field.name]; } } for (let collection of collectionsToLoad) { if (collection != undefined) { if (collection.definition["delay-fetch"] != true) { collection.load(model); } } } for (let field of datasetsToLoad) { if (this[field.name] != undefined) { if (model[field.name] == undefined) { this[field.name].resetToDefault(); } else { this[field.name].setInitialValues(model[field.name]); } } } this.__isLoading = false; } validate() { return Validator.validateDataset(this); } }