1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2012, 2013, 2014, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2012, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 /**
 25  * View that displays the location conflicts and possible alternate locations
 26  * @constructor
 27  * @class
 28  *
 29  *  @author Vince Bellows
 30  *
 31  * @param parent        [ZmResolveLocationConflictDialog]   parent dialog
 32  * @param controller	[ZmApptComposeController]	        compose controller
 33  * @param apptEditView	[ZmApptEditView]	                the appt edit view
 34  * @param id		    [string]	                        id for the view
 35  *
 36  */
 37 ZmResolveLocationView = function(parent, controller, apptEditView, id ) {
 38     if (arguments.length == 0) { return; }
 39 
 40 
 41     var headerList = [{_field:"date",     _width:150, _label:ZmMsg.date},
 42                       {_field:"location", _width:200, _label:ZmMsg.location}];
 43 
 44     var params = {parent: parent, posStyle: DwtControl.RELATIVE_STYLE, view: id,
 45                   className:"ZmResolveConflictList DwtListView"};
 46 	DwtListView.call(this, params);
 47 
 48 	this._controller = controller;
 49 	this._editView = apptEditView;
 50 
 51 	this._rendered = false;
 52     this._normalClass = DwtListView.ROW_CLASS;
 53     this.setMultiSelect(false);
 54 
 55 };
 56 
 57 ZmResolveLocationView.prototype = new DwtListView;
 58 ZmResolveLocationView.prototype.constructor = ZmResolveLocationView;
 59 
 60 ZmResolveLocationView.NO_SELECTION = "NONE";
 61 
 62 ZmResolveLocationView.prototype.toString =
 63 function() {
 64 	return "ZmResolveLocationView";
 65 }
 66 
 67 ZmResolveLocationView.prototype.set =
 68 function(params) {
 69     DwtListView.prototype.set.call(this, params.list);
 70 };
 71 
 72 ZmResolveLocationView.prototype._setNoResultsHtml =
 73 function() {
 74     var	div = document.createElement("div");
 75     var elText = document.createTextNode(ZmMsg.noConflicts);
 76     div.appendChild(elText);
 77     this._addRow(div);
 78 };
 79 
 80 ZmResolveLocationView.prototype.setLoadingHtml =
 81 function() {
 82     this.removeAll();
 83     var	div = document.createElement("div");
 84     div.innerHTML = AjxTemplate.expand("calendar.Appointment#AlternateLocation-Loading");
 85     this._addRow(div);
 86 };
 87 
 88 ZmResolveLocationView.prototype._renderList =
 89 function(list, noResultsOk, doAdd) {
 90     var params = {};
 91     var htmlArr = [];
 92     // Add the header
 93     htmlArr.push(AjxTemplate.expand("calendar.Appointment#ResolveLocationConflictHeader", params));
 94     var item;
 95 
 96     // Add the list items, consisting of the date of the conflict, and a select dropdown
 97     // showing the alternate location suggestions
 98     this._selectLocation = [];
 99 	if (list instanceof AjxVector && list.size()) {
100 		var size = list.size();
101         var ids = [];
102         var even = true;
103         // Add the rows, one per conflict date
104 		for (var i = 0; i < size; i++) {
105 			item = list.get(i);
106 
107             var id = this.associateItemWithElement(item, null, null, null);
108             ids.push(id);
109 
110             var dateStr = AjxDateUtil.simpleComputeDateStr(new Date(item.inst.s));
111             params = {
112                 id:        id,
113                 date:      dateStr,
114                 className: even ? "ZmResolveLocationConflictEven" : "ZmResolveLocationConflictOdd"
115             };
116             even = !even;
117             htmlArr.push(AjxTemplate.expand("calendar.Appointment#ResolveLocationConflict", params));
118 		}
119 		if (htmlArr.length) {
120 			this._parentEl.innerHTML = htmlArr.join("");
121 		}
122 
123         // Create the pulldowns that provide the possible valid alternate locations
124         for (var i = 0; i < ids.length; i++) {
125             item = list.get(i);
126             var el = document.getElementById(ids[i] + "_alternatives");
127             if (item.enabled) {
128                 var select = this._createSelectionDropdown(el, item);
129                 this._selectLocation.push(select);
130             } else {
131                 // Multiple locations already specified - not supported for now, just display
132                 el.innerHTML = AjxStringUtil.htmlEncode(item.originalLocation);
133             }
134         }
135 
136 	} else if (!noResultsOk) {
137 		this._setNoResultsHtml();
138 	}
139 };
140 
141 ZmResolveLocationView.prototype._createSelectionDropdown =
142 function(el, listItem) {
143     var select = new DwtSelect({parent:this, congruent:true,
144         posStyle:DwtControl.RELATIVE_STYLE});
145     select.reparentHtmlElement(el);
146     var options = listItem.alternateLocationInfo;
147     select.addOption(ZmMsg.selectAlternateLocation, false,
148         ZmResolveLocationView.NO_SELECTION);
149     // Add each of the valid alternate locations
150     for (var i = 0; i < options.size(); i++) {
151         var locInfo = options.get(i);
152         var name = this.formatLocation(locInfo.name);
153         select.addOption(name, (listItem.originalLocation == locInfo.email), locInfo.email);
154     }
155     // Add <HR> and 'No Location'
156     select.addHR();
157     select.addOption(ZmMsg.noLocation, (listItem.originalLocation == ZmMsg.noLocation),
158         null, null, "ZmResolveNoLocationSelect ZWidgetTitle");
159     return select;
160 }
161 
162 ZmResolveLocationView.prototype.formatLocation =
163 function(name) {
164     // Limit the alternate location text to 40 characters
165     if(name && name.length > 40) {
166         name = name.substring(0, 40) + '...';
167     }
168     return name;
169 };
170 
171 ZmResolveLocationView.prototype.getAlternateLocation =
172 function(index) {
173     var location = null;
174     var select = this._selectLocation[index];
175     if (select) {
176         location = select.getValue();
177     }
178     return location;
179 }
180 
181 ZmResolveLocationView.prototype._itemSelected =
182 function(itemDiv, ev) {
183 }