UNPKG

d2

Version:

Javascript library for DHIS2

127 lines (113 loc) 5.15 kB
import { checkType, hasKeys } from '../lib/check' import { pickOr } from '../lib/utils' import ModelBase, { DIRTY_PROPERTY_LIST } from './ModelBase' import createPropertyDefinitionsForAttributes from './helpers/attibutes' const pickAttributeValues = pickOr('attributeValues', []) // TODO: Perhaps we can generate model classes dynamically based on the schemas and inherit from this. /** * @extends ModelBase * * @description * A Model represents an object from the DHIS2 Api. A model is created based of a ModelDefinition. The ModelDefinition * has the properties that the model should have. * * @memberof module:model */ class Model extends ModelBase { /** * @constructor * * @param {ModelDefinition} modelDefinition The model definition that corresponds with the model. * This is essential defining what type the model is representing. * * @description * Will create a new model instanced based on the model definition. When creating a new instance the model * definition needs to have both the modelValidations and modelProperties. * * The model properties will depend on the ModelDefinition. A model definition is based on a DHIS2 Schema. */ constructor(modelDefinition) { super() checkType(modelDefinition, 'object', 'modelDefinition') checkType(modelDefinition.modelProperties, 'object', 'modelProperties') /** * @property {ModelDefinition} modelDefinition Stores reference to the modelDefinition that was used when * creating the model. This property is not enumerable or writable and will therefore not show up when looping * over the object properties. */ Object.defineProperty(this, 'modelDefinition', { value: modelDefinition, }) /** * @property {Boolean} dirty Represents the state of the model. When the model is concidered `dirty` * there are pending changes. * This property is not enumerable or writable and will therefore not show up when looping * over the object properties. */ Object.defineProperty(this, 'dirty', { writable: true, value: false }) /** * @private * @property {Object} dataValues Values object used to store the actual model values. Normally access to the * Model data will be done through accessor properties that are generated from the modelDefinition. * * @note {warning} This should not be accessed directly. */ Object.defineProperty(this, 'dataValues', { configurable: true, writable: true, value: {}, }) /** * Attach the modelDefinition modelProperties (the properties from the schema) onto the Model. * * For a data element model the modelProperties would be the following * https://play.dhis2.org/demo/api/schemas/dataElement.json?fields=properties */ Object.defineProperties(this, modelDefinition.modelProperties) const attributes = {} const { attributeProperties } = modelDefinition if (hasKeys(attributeProperties)) { /** * @property {Object} attributes The attributes objects contains references to custom attributes defined * on the metadata object. * * @description * These properties are generated based of the attributes that are created for the the specific schema. * As these properties are not defined on the schemas they're put on a separate attributes object. * When there are no attributes defined for the object type, the attributes property will not be attached * to the model. * * @see https://docs.dhis2.org/2.27/en/user/html/dhis2_user_manual_en_full.html#manage_attribute */ Object.defineProperty(this, 'attributes', { value: attributes }) const getAttributeValues = () => pickAttributeValues(this) const setAttributeValues = attributeValues => (this.attributeValues = attributeValues) const setDirty = () => (this.dirty = true) const attributeDefinitions = createPropertyDefinitionsForAttributes( attributeProperties, getAttributeValues, setAttributeValues, setDirty ) Object.defineProperties(attributes, attributeDefinitions) } this[DIRTY_PROPERTY_LIST] = new Set([]) } /** * @static * * @param {ModelDefinition} modelDefinition ModelDefinition from which the model should be created * @returns {Model} Returns an instance of the model. * * @description The static method is a factory method to create Model objects. It calls `new Model()` with the passed `ModelDefinition`. * * ```js * let myModel = Model.create(modelDefinition); * ``` */ static create(modelDefinition) { return new Model(modelDefinition) } } export default Model