wb/mgr/model/columns/NameMgrColumn.js

/**
 * @copyright 2015 Tridium, Inc. All Rights Reserved.
 * @author Logan Byam
 */

/**
 * @module nmodule/webEditors/rc/wb/mgr/model/columns/NameMgrColumn
 */
define([ 'baja!',
        'lex!webEditors',
        'Promise',
        'underscore',
        'nmodule/webEditors/rc/fe/baja/DisplayOnlyEditor',
        'nmodule/webEditors/rc/wb/mgr/mgrUtils',
        'nmodule/webEditors/rc/wb/mgr/model/MgrColumn' ], function (
         baja,
         lexs,
         Promise,
         _,
         DisplayOnlyEditor,
         mgrUtils,
         MgrColumn) {

  'use strict';

  var webEditorsLex = lexs[0],
      OBJECT_ICON = '/module/icons/x16/object.png';

  const { getProposedValue } = mgrUtils;

  function xor(a, b) { return a ? !b : b; }

  /**
   * API Status: **Development**
   *
   * `MgrColumn` subclass that allows components in a `MgrModel` to be renamed.
   *
   * @class
   * @alias module:nmodule/webEditors/rc/wb/mgr/model/columns/NameMgrColumn
   * @extends module:nmodule/webEditors/rc/wb/mgr/model/MgrColumn
   * @param {Object} params
   */
  var NameMgrColumn = function NameMgrColumn(params) {
    MgrColumn.call(this, '__name', params);
  };
  NameMgrColumn.prototype = Object.create(MgrColumn.prototype);
  NameMgrColumn.prototype.constructor = NameMgrColumn;

  /**
   * Returns `name` from webEditors lexicon.
   *
   * @returns {String}
   */
  NameMgrColumn.prototype.toDisplayName = function () {
    return webEditorsLex.get('name');
  };

  /**
   * Renames the row's `Component` subject.
   *
   * @param {String} value the new name
   * @param {module:nmodule/webEditors/rc/wb/table/model/Row} row
   * @param {Object} [params]
   * @param {baja.comm.Batch} [params.batch]
   * @returns {Promise} promise to be resolved when the component has
   * been renamed.
   */
  NameMgrColumn.prototype.commit = function (value, row, params) {
    var subject = row.getSubject(),
        name = subject.getName(),
        parent = subject.getParent(),
        batch = params && params.batch,
        progressCallback = params && params.progressCallback,
        newName = baja.SlotPath.escape(value),
        slotExists = parent.has(newName),
        prom = slotExists ? Promise.resolve() : parent.rename({
          slot: name, newName: newName, batch: batch
        });

    if (progressCallback) { progressCallback(MgrColumn.COMMIT_READY); }

    return prom;
  };

  /**
   * Returns the row's `Component` subject's slot name.
   *
   * @param {module:nmodule/webEditors/rc/wb/table/model/Row} row
   * @returns {String}
   */
  NameMgrColumn.prototype.getValueFor = function (row) {
    return row.getSubject().getName() ? baja.SlotPath.unescape(row.getSubject().getName()) : '';
  };

  /**
   * @param {Array.<module:nmodule/webEditors/rc/wb/table/model/Row>} rows
   * @returns {string} the component name when a single row is selected
   * @throws {Error} if more than one row is selected
   */
  NameMgrColumn.prototype.coalesceRows = function (rows) {
    if (rows.length > 1) { throw new Error('cannot coalesce multiple component names'); }

    const slot = rows[0].getSubject().getPropertyInParent();
    if (slot.isFrozen()) {
      throw new Error('cannot rename a frozen slot');
    }

    return MgrColumn.prototype.coalesceRows.apply(this, arguments);
  };

  /**
   * Creates the cell's contents by calling getDisplayName on the row's proposed value
   * or the current value if there is no proposal.
   * If the row's subject does not have a displayName function, buildCell defers to the superclass.
   *
   * @param {module:nmodule/webEditors/rc/wb/table/model/Row} row
   * @param {JQuery} dom
   * @returns {Promise}
   */
  NameMgrColumn.prototype.buildCell = function (row, dom) {
    const displayName = _.result(row.getSubject(), 'getDisplayName'),
      hasProposedName = getProposedValue(row, this.getName());

    if (displayName && !hasProposedName) {
      return Promise.resolve(displayName).then((str) => dom.text(str));
    }

    return MgrColumn.prototype.buildCell.apply(this, arguments);
  };

  /**
   * We can't set multiple components to the same name. So if editing more than
   * one row, we need the editor to be a DisplayOnlyEditor.
   *
   * @param {module:nmodule/webEditors/rc/fe/baja/BaseEditor} editor
   * @param {Array.<module:nmodule/webEditors/rc/wb/table/model/Row>} rows
   * @returns {boolean} true when:
   *                      there's more than one row and it's a DisplayOnlyEditor,
   *                      it's a frozen slot and it's a DisplayOnlyEditor, or
   *                      it's only one row and it's editable
   */
  NameMgrColumn.prototype.isEditorSuitable = function (editor, rows) {
     if (!editor || !editor.jq()) {
      return false;
    }

    if (rows.length === 1) {
      var subject = rows[0].getSubject(),
        slot = subject.getParent().getSlot(subject.getName());
      return xor(editor instanceof DisplayOnlyEditor, !slot.isFrozen());
    }

    // more than one row at this point ...
    return editor instanceof DisplayOnlyEditor;
  };

  /**
   * Return `object.png`.
   *
   * @returns {String}
   */
  NameMgrColumn.prototype.getColumnIcon = function () {
    return OBJECT_ICON;
  };

  return (NameMgrColumn);
});