Merge pull request #1220 from shackbarth/22390-email
[xtuple] / lib / enyo-x / source / views / transaction_list_container.js
1 /*jshint bitwise:true, indent:2, curly:true, eqeqeq:true, immed:true,
2 latedef:true, newcap:true, noarg:true, regexp:true, undef:true,
3 trailing:true, white:true, strict:false*/
4 /*global XT:true, XM:true, XV:true, _:true, enyo:true */
5
6 (function () {
7
8   /**
9     Expected to a have a parameter widget that contains an order and
10     a transaction date.
11
12     @name XV.TransactionListContainer
13     @extends XV.SearchContainer
14    */
15   var transactionListContainer =  /** @lends XV.TransactionListContainer# */ {
16     name: "XV.TransactionListContainer",
17     kind: "XV.GridPanels",
18     published: {
19       prerequisite: "",
20       notifyMessage: "",
21       list: null,
22       actions: null,
23       transactionDate: null,
24       model: null,
25       callback: null
26     },
27     events: {
28       onPrevious: "",
29       onWorkspace: ""
30     },
31     handlers: {
32       onListItemMenuTap: "showListItemMenu",
33       onParameterChange: "requery",
34       onProcessingChanged: "processingChanged",
35       onSelectionChanged: "selectionChanged"
36     },
37     init: false,
38     components: [
39       {name: "parameterPanel", kind: "FittableRows", classes: "left",
40         components: [
41         {kind: "onyx.Toolbar", classes: "onyx-menu-toolbar", components: [
42           {kind: "onyx.Button", name: "backButton", content: "_back".loc(), ontap: "close"},
43           {kind: "onyx.MenuDecorator", style: "margin: 0;",
44             onSelect: "actionSelected", components: [
45             {kind: "XV.IconButton", src: "/assets/menu-icon-gear.png",
46               content: "_actions".loc(), name: "actionButton"},
47             {kind: "onyx.Menu", name: "actionMenu"}
48           ]}
49         ]},
50         {kind: "Scroller", name: "parameterScroller"}
51       ]},
52       {name: "listPanel", kind: "FittableRows", components: [
53         // the onyx-menu-toolbar class keeps the popups from being hidden
54         {kind: "onyx.MoreToolbar", name: "contentToolbar",
55           classes: "onyx-menu-toolbar", movedClass: "xv-toolbar-moved", components: [
56           {name: "rightLabel", content: "_search".loc(), classes: "xv-toolbar-label"},
57           {name: "spacer", content: "", fit: true},
58           {kind: "onyx.Button", name: "printButton", showing: false,
59             content: "_print".loc(), onclick: "print"},
60           {kind: "onyx.Button", name: "refreshButton", disabled: false,
61             content: "_refresh".loc(), onclick: "requery"},
62           {kind: "onyx.Button", name: "postButton",
63             disabled: true, classes: "save", showing: false,
64             content: "_post".loc(), onclick: "post"},
65           {name: "listItemMenu", kind: "onyx.Menu", floating: true,
66             onSelect: "listActionSelected", maxHeight: 500}
67         ]},
68         {name: "contentPanels", kind: "Panels", margin: 0, fit: true, draggable: false,
69           panelCount: 0},
70         {kind: "onyx.Popup", name: "spinnerPopup", centered: true,
71             modal: true, floating: true, scrim: true,
72             onHide: "popupHidden", components: [
73           {kind: "onyx.Spinner"},
74           {name: "spinnerMessage", content: "_processing".loc() + "..."}
75         ]}
76       ]}
77     ],
78     actionSelected: function (inSender, inEvent) {
79       var action = inEvent.originator.action,
80         method = action.method || action.name;
81       this[method](inSender, inEvent);
82     },
83     close: function () {
84       var callback = this.getCallback();
85       
86       this.doPrevious();
87       if (callback) { callback(); }
88     },
89     buildMenu: function () {
90       if (!this.getActions()) {
91         return;
92       }
93       var actionMenu = this.$.actionMenu,
94         actions = this.getActions().slice(0),
95         that = this;
96
97       // reset the menu
98       actionMenu.destroyClientControls();
99
100       // then add whatever actions are applicable
101       _.each(actions, function (action) {
102         var name = action.name,
103           prerequisite = action.prerequisite,
104           isDisabled = prerequisite ? !that[prerequisite]() : false;
105         actionMenu.createComponent({
106           name: name,
107           kind: XV.MenuItem,
108           content: action.label || ("_" + name).loc(),
109           action: action,
110           disabled: isDisabled
111         });
112
113       });
114       actionMenu.render();
115       this.$.actionButton.setShowing(actions.length);
116     },
117     create: function () {
118       this.inherited(arguments);
119       var disabled = !XT.session.privileges.get("AlterTransactionDates"),
120         parameterWidget;
121       this.setList({list: this.getList()});
122       parameterWidget = this.$.parameterWidget;
123       parameterWidget.$.transactionDate.$.input.setDisabled(disabled);
124       if (!this.getActions()) {
125         this.setActions([]);
126       }
127       this.buildMenu();
128       this.$.contentToolbar.resized();
129     },
130     fetch: function (options) {
131       if (!this.init) { return; }
132       options = options ? _.clone(options) : {};
133       var list = this.$.list,
134         query,
135         parameterWidget,
136         parameters;
137       if (!list) { return; }
138       query = list.getQuery() || {};
139       parameterWidget = this.$.parameterWidget;
140       parameters = parameterWidget && parameterWidget.getParameters ?
141         parameterWidget.getParameters() : [];
142       options.showMore = _.isBoolean(options.showMore) ?
143         options.showMore : false;
144
145       // Build conditions
146       if (parameters.length) {
147         query.parameters = parameters;
148       } else {
149         delete query.parameters;
150       }
151       list.setQuery(query);
152       list.fetch(options);
153     },
154     /**
155       Capture order changed and transaction date changed events.
156       Depends on a very specific implementation of parameter widget
157       that includes `order` and `transactionDate` parameters.
158     */
159     parameterChanged: function (inSender, inEvent) {
160       var originator = inEvent ? inEvent.originator : false,
161         name = originator ? originator.name : false,
162         that = this,
163         options,
164         value;
165
166       if (name === "transactionDate") {
167         value = originator.$.input.getValue();
168         value = XT.date.applyTimezoneOffset(value, true);
169         value = XT.date.toMidnight(value);
170         this.setTransactionDate(value);
171         this.buildMenu();
172         return;
173       } else if (name === "order") {
174         value = originator.getParameter().value;
175         this.setModel(value);
176         this.buildMenu();
177       } else if (name === "shipment") {
178         return;
179       }
180
181       options = {
182         success: function () {
183           that.selectionChanged();
184         }
185       };
186       this.fetch(options);
187     },
188     popupHidden: function (inSender, inEvent) {
189       if (!this._popupDone) {
190         inEvent.originator.show();
191       }
192     },
193     processingChanged: function (inSender, inEvent) {
194       if (inEvent.isProcessing) {
195         this.spinnerShow();
196       } else {
197         this.requery();
198         this.spinnerHide();
199       }
200     },
201     /**
202       Overload: Piggy back on existing handler for `onParameterChanged event`
203       by forwarding this requery to `parameterChanged`.
204     */
205     requery: function (inSender, inEvent) {
206       this.parameterChanged(inSender, inEvent);
207       return true;
208     },
209     /**
210       Whenever a user makes a selection, rebuild the menu
211       and set the transaction date on the selected models
212       to match what has been selected here.
213     */
214     selectionChanged: function () {
215       this.transactionDateChanged();
216       this.buildMenu();
217     },
218     /**
219       @param {Object} Options
220       @param {String} [options.list] Class name
221     */
222     setList: function (options) {
223       var component,
224       list = options.list;
225
226       component = this.createComponent({
227         name: "list",
228         container: this.$.contentPanels,
229         kind: list,
230         fit: true
231       });
232       this.$.rightLabel.setContent(component.label);
233       if (component) {
234         this.createComponent({
235           name: "parameterWidget",
236           classes: "xv-groupbox xv-parameter",
237           showSaveFilter: false,
238           showLayout: false,
239           defaultParameters: null,
240           container: this.$.parameterScroller,
241           kind: component.getParameterWidget(),
242           memoizeEnabled: false,
243           fit: true
244         });
245       }
246
247       this.init = true;
248       this.render();
249     },
250     spinnerHide: function () {
251       this._popupDone = true;
252       this.$.spinnerPopup.hide();
253     },
254     spinnerShow: function () {
255       this._popupDone = false;
256       this.$.spinnerPopup.show();
257     },
258     transactionDateChanged: function () {
259       var transDate = this.getTransactionDate(),
260         collection = this.$.list.getValue(),
261         i;
262
263       // Update the transaction dates on all models to match
264       // What has been selected
265       for (i = 0; i < collection.length; i++) {
266         collection.at(i).transactionDate = transDate;
267       }
268     }
269   };
270
271   enyo.mixin(transactionListContainer, XV.ListMenuManagerMixin);
272   enyo.kind(transactionListContainer);
273
274 }());