pragma-views2
Version:
305 lines (254 loc) • 9.26 kB
JavaScript
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);
}
}