UNPKG

@pilotlab/data

Version:

A luxurious user experience framework, developed by your friends at Pilot.

294 lines 13.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const is_1 = require("@pilotlab/is"); const signals_1 = require("@pilotlab/signals"); const ids_1 = require("@pilotlab/ids"); const result_1 = require("@pilotlab/result"); const nodes_1 = require("@pilotlab/nodes"); const attributeEnums_1 = require("./attributeEnums"); const dataTools_1 = require("../dataTools"); const attributesBase_1 = require("./attributesBase"); const attributeSetReturn_1 = require("./attributeSetReturn"); const attributeChangeOptions_1 = require("./attributeChangeOptions"); const attributeEventArgs_1 = require("./attributeEventArgs"); class AttributeBase extends nodes_1.NodeBase { constructor(factory, value, dataType, label, key = '', nodeType = nodes_1.NodeType.BASIC, isInitialize = true) { super(factory, nodeType, key, false); this.p_value = null; if (is_1.default.notEmpty(label, true)) this.p_label = label; this.p_dataType = attributeEnums_1.DataType.UNDEFINED; this.p_changed = new signals_1.Signal(false); this.p_isSignalChange = true; this.p_isAllowSave = true; this.p_isAllowAutoPropterties = true; this.p_returnValue = new attributeSetReturn_1.default(this, false); this.p_formatter = (value) => value; if (isInitialize) this.initialize(value, dataType, nodeType); } p_onInitializeStarted(result, args) { const value = args[0]; const dataType = args[1]; const nodeType = args[2]; super.p_onInitializeStarted(new result_1.Result(), [nodeType]).then(() => { /// Set the data type first, then the value if (is_1.default.notEmpty(dataType)) this.p_dataType = dataType; else { if (is_1.default.notEmpty(value, false)) this.p_dataType = dataTools_1.default.getDataType(value); else this.p_dataType = attributeEnums_1.DataType.OBJECT; } if (this.create.getBaseDataType(this.p_dataType) === attributeEnums_1.DataType.COLLECTION) { this.p_wrapAttributes(value, attributeEnums_1.AttributesWrapType.CLEAR_BASE); } else if (is_1.default.notEmpty(value, false)) this.p_value = value; result.resolve(value); }); return result; } /** * All data associated with this entity will be saved to the provided attribute collection, * and all change events will be propagated through that collection. */ p_wrapAttributes(value, wrapType = attributeEnums_1.AttributesWrapType.OVERWRITE_BASE) { let changeOptions = attributeChangeOptions_1.default.noSaveOrSignal; let attributes; /// If an Attributes instance was passed as the value, it will be directly assigned to this.p_value. if (is_1.default.notEmpty(value)) { attributes = this.create.collection.fromAny(value, this); } if (is_1.default.empty(attributes)) attributes = this.create.collection.instance(this); this.p_value = attributes; if (is_1.default.notEmpty(this.p_value)) { if (wrapType === attributeEnums_1.AttributesWrapType.CLEAR_BASE) { /// Do nothing. } else if (wrapType === attributeEnums_1.AttributesWrapType.CLEAR_WRAPPED) { attributes.clear(changeOptions); attributes.update(this.p_value, changeOptions); } else if (wrapType === attributeEnums_1.AttributesWrapType.OVERWRITE_BASE) { this.p_value.update(attributes, changeOptions); attributes.clear(attributeChangeOptions_1.default.noSaveOrSignal); attributes.update(this.p_value, changeOptions); } else if (wrapType === attributeEnums_1.AttributesWrapType.OVERWRITE_WRAPPED) { attributes.update(this.p_value, changeOptions); } } } /*====================================================================* START: Factory *====================================================================*/ get create() { return this.p_factory; } /** * A UI-friendly title for the attribute that can be presented to users. * If no label is set, the key of the node will be returned. */ get label() { return is_1.default.notEmpty(this.p_label, true) ? this.p_label : this.key; } set label(value) { this.p_label = value; } /** * A brief description of that attribute that can be used to supply info to the user * about how the attribute should be used. */ get summary() { return is_1.default.notEmpty(this.p_summary, true) ? this.p_summary : ''; } set summary(value) { this.p_summary = value; } /** * The value of the associated data. * This property cannot be set directly. You must use the set() method to change the value. * This allows attributes to be wrapped in an AttributeReader instance, which effectively * renders them immutable. */ get value() { return this.p_value; } set value(value) { this.set(value, this.isSignalChange ? attributeChangeOptions_1.default.save : attributeChangeOptions_1.default.zero); } get formatted() { let value = this.p_value; value = this.p_format(value); return value; } get isCollection() { return (this.nodeType === nodes_1.NodeType.ROOT || this.nodeType === nodes_1.NodeType.COLLECTION || this.create.getBaseDataType(this.dataType) === attributeEnums_1.DataType.COLLECTION); } /// This property will hold dynamically generated getters and setters /// for each child attribute that is added to this attribute. get attributes() { return this.p_value; } get children() { return this.isCollection ? this.p_value : this.p_children; } get valuePrevious() { return this.p_valuePrevious; } get dataType() { return this.p_dataType; } /** * Attributes will be considered empty if no key or value has been set. */ get isEmpty() { if (is_1.default.undefined(this.p_value)) return true; if (is_1.default.empty(this.p_value, false)) return true; if (is_1.default.empty(this.key, true)) return true; if (is_1.default.empty(this.dataType, true)) return true; if (this.dataType === attributeEnums_1.DataType.UNDEFINED) return true; if (this.dataType === attributeEnums_1.DataType.NULL) return true; return false; } /** * If this function returns true, the attribute will be omitted from data transfer objects * when saving data to the data store. */ get omitFromDataStore() { return this.p_omitFromDataStore; } set omitFromDataStore(fn) { this.p_omitFromDataStore = fn; } get formatter() { return this.p_formatter; } set formatter(value) { this.p_formatter = value; } p_format(value) { return this.p_formatter(value); } get copy() { return this.create.fromObject(this.toObject()); } /** * An automatically generated unique ID that is used when animating attribute values. */ get animationKey() { if (is_1.default.empty(this._animationKey)) this._animationKey = this.key + '_' + ids_1.Identifier.getSessionUniqueInteger(); return this._animationKey; } get isEditable() { return this.p_isEditable; } set isEditable(value) { this.p_isEditable = value; } get isHidden() { return this.p_isHidden; } set isHidden(value) { this.p_isHidden = value; } get isAllowSave() { return this.p_isAllowSave; } set isAllowSave(value) { if (this.isCollection) this.children.isAllowSave = value; this.p_isAllowSave = value; } /** * Should we allow accessor properties to be generated automatically when * a new child Attribute is added to our Attribute collection? */ get isAllowAutoProperties() { return this.p_isAllowAutoPropterties; } set isAllowAutoProperties(value) { this.p_isAllowAutoPropterties = value; } /*====================================================================* START: Signals *====================================================================*/ get changed() { return this.p_changed; } /*====================================================================* START: Internal *====================================================================*/ /// Overridden to take isSave into account. internalChanged(args) { if (!this.isSignalChange && !this.isAllowSave) return; if ((args.changeOptions.isSignalChange || args.changeOptions.isSave) && this.isSignalChange) this.changed.dispatch(args); if (is_1.default.notEmpty(this.parentCollection) && (is_1.default.notEmpty(this.parentCollection.internalChanged))) { this.parentCollection.internalChanged(args); } } /*====================================================================* START: Public Methods *====================================================================*/ /** * Save the value to the attribute. */ set(value, changeOptions = attributeChangeOptions_1.default.default) { let returnValue = this.p_returnValue; if (is_1.default.empty(value)) return returnValue; if (this.create.getBaseDataType(this.p_dataType) === attributeEnums_1.DataType.COLLECTION) { /// This attribute holds a collection... if (is_1.default.notEmpty(this.p_value) && (this.p_value instanceof attributesBase_1.default)) { let tracker = this.p_value.update(value, changeOptions); returnValue.updateTracker = tracker; tracker.then((tracker) => { returnValue.isChanged = tracker.isChanged; }); } } else { value = this.p_format(value); if (this.p_value === value) { if (changeOptions.action === attributeEnums_1.AttributeChangeActions.SAVE) { this.doChanged(changeOptions.action); } return returnValue; } this.p_valuePrevious = this.p_valueTarget; this.p_value = value; this.p_valueTarget = value; returnValue.isChanged = true; this.doChanged(changeOptions.action); } return returnValue; } /** * Interrupt any animated value transitions that are in effect. */ interruptAnimation() { if (is_1.default.notEmpty(this.p_animation)) this.p_animation.interrupt(); } /** * Manually trigger a dispatch on the 'changed' signal. */ doChanged(action) { if (!this.isSignalChange && !this.isAllowSave) return; else if (action === attributeEnums_1.AttributeChangeActions.SIGNAL_CHANGE && !this.isSignalChange) return; else if (action === attributeEnums_1.AttributeChangeActions.SAVE && !this.isAllowSave) return; let args = new attributeEventArgs_1.default(this, nodes_1.NodeChangeType.UPDATED, new attributeChangeOptions_1.default(action).durationZero); this.internalChanged(args); } toObject(isIncludeDataTypes = true, isIncludeLabels = true, appendToObject, isForceInclude = false) { if (!isForceInclude && (is_1.default.notEmpty(this.p_omitFromDataStore) && this.p_omitFromDataStore(this.p_value))) return appendToObject; let object = {}; if (isIncludeDataTypes || (isIncludeLabels && is_1.default.notEmpty(this.label, true) && this.label !== this.key)) { if (isIncludeDataTypes) object['dataType'] = this.dataType.toString(); if (isIncludeLabels && (is_1.default.notEmpty(this.label, true) && this.label !== this.key)) object['label'] = this.label; object['isEditable'] = this.isEditable; object['isHidden'] = this.isHidden; if (this.p_value instanceof attributesBase_1.default) { object['value'] = this.p_value.toObject(isIncludeDataTypes, isIncludeLabels, isForceInclude); } else object['value'] = this.formatted; } else { if (this.p_value instanceof attributesBase_1.default) { object = this.p_value.toObject(isIncludeDataTypes, isIncludeLabels, isForceInclude); } else object = this.formatted; } if (is_1.default.notEmpty(appendToObject)) { appendToObject[this.key] = object; return appendToObject; } else return object; } internalAttached(changeOptions) { if (is_1.default.notEmpty(this.parentCollection)) { this.isSignalChange = this.parentCollection.isSignalChange; this.isAllowSave = this.parentCollection.isAllowSave; } super.internalAttached(changeOptions); } } // End class exports.AttributeBase = AttributeBase; exports.default = AttributeBase; //# sourceMappingURL=attributeBase.js.map