/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Logan Byam
*/
/**
* @module nmodule/webEditors/rc/wb/mgr/model/MgrModel
*/
define([ 'baja!',
'Promise',
'underscore',
'nmodule/webEditors/rc/wb/mgr/MgrTypeInfo',
'nmodule/webEditors/rc/wb/table/model/ComponentTableModel' ], function (
baja,
Promise,
_,
MgrTypeInfo,
ComponentTableModel) {
'use strict';
function checkNewTypes(newTypes) {
_.each(newTypes, function (typeInfo) {
if (!(typeInfo instanceof MgrTypeInfo)) {
throw new Error('new type is not a MgrTypeInfo instance');
}
});
}
/**
* If component is parented, unparent it and return its old property name.
*
* @inner
* @param {baja.Complex} comp
* @param {baja.comm.Batch} batch
* @returns {Promise}
*/
function unparentAndGetPropName(comp, batch) {
var parent = comp.getParent(),
prop = comp.getPropertyInParent();
return Promise.resolve(parent && parent.remove({ slot: prop, batch: batch }))
.then(function () {
return prop && String(prop);
});
}
/**
* API Status: **Development**
*
* A layer that adds edit/add/remove functionality on top of a
* `ComponentTableModel`.
*
* Due to the incubating status of the manager framework, it is *not
* recommended* that you extend `MgrModel` directly. Instead, extend
* `DeviceMgrModel` or `PointMgrModel`: these will provide more robust
* functionality for most use cases.
*
* @class
* @alias module:nmodule/webEditors/rc/wb/mgr/model/MgrModel
* @extends module:nmodule/webEditors/rc/wb/table/model/ComponentTableModel
* @param {Object} params
* @param {Array.<module:nmodule/webEditors/rc/wb/mgr/MgrTypeInfo>} [params.newTypes]
* array of `MgrTypeInfo` instances representing types that will be offered when creating new
* instances for this model.
* @see module:nmodule/driver/rc/wb/mgr/DeviceMgrModel
* @see module:nmodule/driver/rc/wb/mgr/PointMgrModel
*/
var MgrModel = function MgrModel(params) {
ComponentTableModel.apply(this, arguments);
var newTypes = params.newTypes || [];
checkNewTypes(newTypes);
this.$newTypes = newTypes;
};
MgrModel.prototype = Object.create(ComponentTableModel.prototype);
MgrModel.prototype.constructor = MgrModel;
/**
* Clean up the `MgrModel` when the parent `Manager` is being destroyed. This is
* an opportunity to unhook any remaining event handlers on the model or its data source.
*
* @returns Promise.<*>
*/
MgrModel.prototype.destroy = function () {
var componentSource = this.getComponentSource();
//TODO: proper way of removing column event handlers
this.removeAllListeners('columnsFlagsChanged');
if (componentSource) { componentSource.destroy(); }
return this.removeColumns(this.getColumns());
};
/**
* Get the columns contained in this `MgrModel`.
*
* @override
* @function getColumns
* @memberOf module:nmodule/webEditors/rc/wb/mgr/model/MgrModel
* @param {Number} [flags] if given, only return columns that have these
* flags.
* @returns {Array.<module:nmodule/webEditors/rc/wb/mgr/model/MgrColumn>}
*/
/**
* Get the `MgrTypeInfo` instances representing the types that are acceptable to add to
* this model.
*
* @returns {Array.<module:nmodule/webEditors/rc/wb/mgr/MgrTypeInfo>} array of MgrTypeInfos to add
*/
MgrModel.prototype.getNewTypes = function () {
return this.$newTypes;
};
/**
* Override point to customize how new instances of the selected `MgrTypeInfo`
* are instantiated. The default implementation is to simply delegate to the type
* info's #newInstance() function.
*
* @param {module:nmodule/webEditors/rc/wb/mgr/MgrTypeInfo} typeInfo
* @returns {baja.Value|Promise}
*/
MgrModel.prototype.newInstance = function (typeInfo) {
return typeInfo.newInstance();
};
/**
* Add the instances to this model, to be called when an add dialog or
* other add operation is committed. The default implementation is to add the
* given instances to the underlying `ComponentSource` container, which will
* commit these changes up to the station.
*
* Like Workbench, parented instances will be unparented and re-added to the
* container component. (Workbench does this via a Mark; here it will be
* done using BajaScript remove/add calls.)
*
* @param {Array.<baja.Component>} instances the instances to add
* @param {Array.<String>} [names] the desired slot names for the instances.
* If omitted, default names derived from the instance Types will be used.
* @returns {Promise} promise to be resolved when the instances are
* added, or rejected if the add fails.
*/
MgrModel.prototype.addInstances = function (instances, names) {
names = names || [];
var source = this.getComponentSource(),
batch = new baja.comm.Batch(),
getNames = _.map(instances, function (instance, i) {
return unparentAndGetPropName(instance, batch)
.then(function (prop) {
return names[i] || prop;
});
});
batch.commit();
return Promise.all(getNames)
.then(function (names) {
return source.addComponents(instances, names);
});
};
return (MgrModel);
});