Merge pull request #1220 from shackbarth/22390-email
authorTravis Webb <travis@traviswebb.com>
Tue, 21 Jan 2014 18:06:08 +0000 (10:06 -0800)
committerTravis Webb <travis@traviswebb.com>
Tue, 21 Jan 2014 18:06:08 +0000 (10:06 -0800)
issue #22390: email support for reports

1  2 
enyo-client/application/source/models/customer.js
lib/backbone-x/source/model.js
lib/enyo-x/source/views/list.js
lib/enyo-x/source/views/workspace.js

@@@ -95,9 -95,6 +95,9 @@@ white:true*
        if (options.effective) {
          opts.effective = options.effective;
        }
 +      if (options.site) {
 +        opts.siteId = options.site.id;
 +      }
        params = [this.id, item.id, quantity, opts];
        this.dispatch("XM.Customer", "itemPrice", params, options);
        return this;
  
    });
  
+   XM.CustomerEmailProfile = XM.Model.extend({
+     recordType: "XM.CustomerEmailProfile"
+   });
    /**
      @class
  
  
    });
  
+   XM.CustomerEmailProfileCollection = XM.Collection.extend({
+     model: XM.CustomerEmailProfile
+   });
    /**
      @class
  
        return {
          nameSpace: modelName.prefix(),
          type: modelName.suffix(),
-         prefix: this.id,
+         id: this.id,
          action: action
        };
      },
        var K = XT.Session,
          schemas = XT.session.getSchemas(),
          parse;
-      
        // A hack to undo damage done by Backbone inside
        // save function. For use with options that have
        // collections. See XT.DataSource for the other
              }
            }
          }
 +
          return obj;
        };
 -      return parse(this.recordType.prefix(), this.recordType.suffix(), resp);
 +
 +      this._lastParse = parse(this.recordType.prefix(), this.recordType.suffix(), resp);
 +      return this._lastParse;
      },
  
      relationAdded: function (model, related, options) {
        model.on(evt, replaceId);
      },
  
 +    /**
 +      Revert a model back to its original state the last time it was fetched.
 +    */
 +    revert: function () {
 +      var K = XM.Model;
 +
 +      this.clear({silent: true});
 +      this.setStatus(K.BUSY_FETCHING);
 +      this.set(this._lastParse, {silent: true});
 +      this.setStatus(K.READY_CLEAN, {cascade: true});
 +    },
 +
      /**
        Revert the model to the previous status. Useful for reseting status
        after a failed validation.
          });
          // #refactor XXX if this is a bona fide Backbone Relational relation,
          // events will propagate automatically from child to parent.
 -        parent.changed[parentRelation.reverseRelation.key] = true;
 -        parent.trigger('change', parent, options);
 +        if (parentRelation) {
 +          parent.changed[parentRelation.reverseRelation.key] = true;
 +          parent.trigger('change', parent, options);
 +        }
        }
        this.release();
  
          // Handle both `"key", value` and `{key: value}` -style arguments.
          if (_.isObject(key) || _.isEmpty(key)) { value = options; }
  
 -        // Call the super version
 -        this.setStatus(K.BUSY_COMMITTING, options);
 +        if (options.collection) {
 +          options.collection.each(function (model) {
 +            model.setStatus(K.BUSY_COMMITTING, options);
 +          });
 +        } else {
 +          this.setStatus(K.BUSY_COMMITTING, options);
 +        }
 +
          // allow the caller to pass in a different save function to call
          result = options.prototypeSave ?
          options.prototypeSave.call(this, key, value, options) :
@@@ -87,8 -87,7 +87,8 @@@ trailing:true, white:true, strict:false
        onPrintSelectList: "",
        onReportList: "",
        onSelectionChanged: "",
 -      onWorkspace: ""
 +      onWorkspace: "",
 +      onNotify: ""
      },
      handlers: {
        onActionSelected: "actionSelected",
        var actions = this.exportActions || [],
          canExport = !XM.currentUser.get("disableExport"),
          exportAction =  canExport ? _.findWhere(actions, {"name": "export"}) : true,
-         printAction = XT.session.config.biServer && this.getAllowPrint() && canExport ?
+         printAction = XT.session.config.biAvailable && this.getAllowPrint() && canExport ?
            _.findWhere(actions, {"name": "printList"}) : true;
  
        // Handle default navigator actions
@@@ -210,15 -210,6 +210,15 @@@ trailing:true, white:true, strict: fals
      using the carousel arranger and fitted to the size of the viewport.<br />
      Its components can be extended via {@link XV.ExtensionsMixin}.<br />
      Derived from <a href="http://enyojs.com/api/#enyo.FittableRows">enyo.FittableRows</a>.
 +
 +    Supported properties on the action array are:
 +      * name
 +      * label: Menu label. Defaults to name if not present.
 +      * privilege: The privilege required by the user to enable the menu. Defaults enabled if not present.
 +      * prerequisite: A function on the model that returns a boolean dictating whether to show the menu item or not.
 +      * method: The function to call. Defaults to name if not present.
 +      * isViewMethod: Boolean value dictates whether method is called on the view or the view's model. Default false.
 +
      @extends enyo.FittableRows
      @extends XV.EditorMixin
      @extends XV.ExtensionsMixin
      kind: "FittableRows",
      modelView: "EnyoView",
      published: {
 +      actions: null,
        actionButtons: null,
        title: "_none".loc(),
        headerAttrs: null,
        recordId: null,
        saveText: "_save".loc(),
        backText: "_back".loc(),
 +      hideSaveAndNew: false,
        hideApply: false,
        hideRefresh: false,
        dirtyWarn: true,
        onLockChange: "",
        onMenuChange: "",
        onNotify: "",
 -      onSaveTextChange: ""
 +      onSaveTextChange: "",
 +      onTransactionList: "",
 +      onWorkspace: ""
      },
      handlers: {
        onValueChange: "controlValueChanged"
  
        this.processExtensions();
        this.titleChanged();
-       this.setPrintAvailable(XT.session.config.printServer);
      },
      /**
       @todo Document the destroy method.
      kind: "XV.GridPanels",
      published: {
        menuItems: [],
 -      allowNew: true
 +      allowNew: true,
      },
      events: {
        onPrevious: "",
        {kind: "FittableRows", name: "navigationPanel", classes: "left", components: [
          {kind: "onyx.Toolbar", name: "menuToolbar", components: [
            {kind: "onyx.Button", name: "backButton",
 -            content: "_back".loc(), onclick: "close"}
 +            content: "_back".loc(), onclick: "close"},
 +          {kind: "onyx.MenuDecorator", style: "margin: 0;", onSelect: "actionSelected",
 +            components: [
 +            {kind: "XV.IconButton", src: "/assets/menu-icon-gear.png",
 +              content: "_actions".loc(), name: "actionButton",
 +              classes: "xv-action-icon"},
 +            {kind: "onyx.Menu", name: "actionMenu", maxHeight: 900}
 +          ]}
          ]},
          {name: "loginInfo", content: "", classes: "xv-navigator-header"},
          {name: "menu", kind: "List", fit: true, touch: true,
          ]}
        ]}
      ],
 -    allowNewChanged: function (allowNew) {
 +    actionSelected: function (inSender, inEvent) {
 +      // Could have come from an action, or a an action button
 +      var selected = inEvent.selected || inEvent.originator;
 +
 +      // If it's a view method then call call function on the workspace.
 +      if (selected.isViewMethod) {
 +        this.$.workspace[selected.method](inEvent);
 +
 +      // Otherwise call it on the workspace's model.
 +      } else {
 +        this.$.workspace.getValue()[selected.method]();
 +      }
 +    },
 +    allowNewChanged: function () {
 +      var allowNew = this.getAllowNew();
 +
        if (allowNew) {
          this.$.saveAndNewButton.show();
        } else {
          callback: callback
        });
      },
 +    buildMenus: function () {
 +      var actionMenu = this.$.actionMenu,
 +        workspace = this.$.workspace,
 +        actions = workspace.getActions(),
 +        actionButtons = workspace.getActionButtons(),
 +        model = workspace.getValue(),
 +        that = this,
 +        count = 0;
 +
 +      // Handle menu actions
 +      if (actions) {
 +
 +        // Reset the menu
 +        actionMenu.destroyClientControls();
 +
 +        // Add whatever actions are applicable to the current context.
 +        _.each(actions, function (action) {
 +          var name = action.name,
 +            prerequisite = action.prerequisite,
 +            privilege = action.privilege,
 +            isDisabled = privilege ? !XT.session.privileges.get(privilege) : false;
 +
 +          // Only create menu item if prerequisites are met.
 +          if (!prerequisite || model[prerequisite]()) {
 +            actionMenu.createComponent({
 +              name: name,
 +              kind: XV.MenuItem,
 +              content: action.label || ("_" + name).loc(),
 +              method: action.method || action.action || name,
 +              disabled: isDisabled,
 +              isViewMethod: action.isViewMethod
 +            });
 +            count++;
 +          }
 +
 +        });
 +
 +        if (actions.length && !count) {
 +          actionMenu.createComponent({
 +            name: "noActions",
 +            kind: XV.MenuItem,
 +            content: "_noEligibleActions".loc(),
 +            disabled: true
 +          });
 +        }
 +
 +        actionMenu.render();
 +        this.$.actionButton.setShowing(actions.length);
 +      }
 +
 +      // Handle button actions
 +      if (actionButtons) {
 +        _.each(actionButtons, function (action) {
 +          var privs =  XT.session.privileges,
 +            noPriv = action.privilege ? !privs.get(action.privilege): false,
 +            noCanDo = action.prerequisite ? !model[action.prerequisite]() : false;
 +
 +          that.$[action.name].setDisabled(noPriv || noCanDo);
 +        });
 +      }
 +    },
      create: function () {
        this.inherited(arguments);
        this.setLoginInfo();
  
        if (workspace.value.getStatus() === XM.Model.READY_DIRTY &&
           !workspace.getModelAmnesty()) {
 -        // Refresh because this model may be referenced elsewhere
 +        // Revert because this model may be referenced elsewhere
          _setBindings(this.$.workspace, "off");
 -        this.$.workspace.fetch({success: callback, obtainLock: false});
 +        model.revert();
 +      }
 +
 +      if (model && model.hasLockKey && model.hasLockKey()) {
 +        model.releaseLock({
 +          success: function () {
 +            that.doPrevious();
 +          },
 +          error: function () {
 +            XT.log("Error releasing lock");
 +            that.doPrevious();
 +          }
 +        });
        } else {
 -        callback();
 +        that.doPrevious();
        }
      },
      /**
        // else see if the workspace has a specific implementation
        this.$.workspace.handleHotKey(keyCode);
      },
 -    handleWorkspaceEvent: function (inSender, inEvent) {
 -      if (inEvent.originator.isViewMethod) {
 -        this.$.workspace[inEvent.originator.associatedMethod]();
 -      } else {
 -        this.$.workspace.value[inEvent.originator.associatedMethod]();
 -      }
 -    },
      /**
       @todo Document the headerChanged method.
       */
      save: function (options) {
        var workspace = this.$.workspace,
          print = workspace.printOnSaveSetting &&
-           workspace.getPrintAvailable() &&
+           XT.session.config.printAvailable &&
            XT.session.settings.get(workspace.printOnSaveSetting);
        if (!this._saveState) { this._saveState = SAVE_APPLY; }
        workspace.save(options);
          id = options.id,
          callback = options.callback,
          // if the options do not specify allowNew, default it to true
 -        allowNew = options.allowNew === false ? false : true,
 +        allowNew,
          attributes = options.attributes;
  
        if (workspace) {
            fit: true,
            callback: callback
          };
 -        this.setAllowNew(allowNew);
 +
          workspace = this.createComponent(workspace);
 +
 +        // Handle save and new button
 +        allowNew = _.isBoolean(options.allowNew) ?
 +          options.allowNew : !workspace.getHideSaveAndNew();
 +        this.setAllowNew(allowNew);
 +
          headerAttrs = workspace.getHeaderAttrs() || [];
          if (headerAttrs.length) {
            this.$.header.show();
          }
  
          // Show the print & report button if this workspace is set up to have it
-         this.$.printButton.setShowing(workspace.allowPrint && workspace.printAvailable);
-         this.$.reportButton.setShowing(workspace.allowPrint && workspace.printAvailable);
+         this.$.printButton.setShowing(workspace.allowPrint && XT.session.config.printAvailable);
+         this.$.reportButton.setShowing(workspace.allowPrint && XT.session.config.printAvailable);
  
          // Set the button texts
          this.$.saveButton.setContent(workspace.getSaveText());
            this.$.refreshButton.hide();
          }
  
 -        _.each(this.$.workspace.actionButtons, function (buttonDesc) {
 -          that.$.contentToolbar.createComponent({kind: "onyx.Button", content: buttonDesc.label,
 -            associatedMethod: buttonDesc.method, isViewMethod: buttonDesc.isViewMethod,
 -            ontap: "handleWorkspaceEvent"}, {owner: that});
 +        // Handle any extra action buttons specified
 +        _.each(this.$.workspace.actionButtons, function (action) {
 +          that.$.contentToolbar.createComponent(
 +            {kind: "onyx.Button",
 +              name: action.name,
 +              content: action.label || ("_" + action.name).loc(),
 +              method: action.method || action.name,
 +              isViewMethod: action.isViewMethod,
 +              ontap: "actionSelected"},
 +            {owner: that});
          });
  
          this.render();
        } else {
          this.spinnerHide();
        }
 +
 +      this.buildMenus();
      },
      /**
       @todo Document titleChanged method.