1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2010, 2011, 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) 2010, 2011, 2012, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 */ 27 28 /** 29 * Creates a time/location suggestion preference dialog. 30 * @class 31 * This class represents a time/location preference dialog. 32 * 33 * @param {DwtControl} parent the parent 34 * @param {String} className the class name 35 * 36 * @extends DwtDialog 37 */ 38 ZmTimeSuggestionPrefDialog = function(parent, className) { 39 40 this._prefs = {}; 41 this._prefFields = {}; 42 this._prefLoaded = false; 43 44 className = className || "ZmTimeSuggestionPrefDialog"; 45 DwtDialog.call(this, {parent:parent, className:className, title:ZmMsg.suggestionPreferences}); 46 47 this.setButtonListener(DwtDialog.OK_BUTTON, new AjxListener(this, this._handleOkButton)); 48 this.setButtonListener(DwtDialog.CANCEL_BUTTON, new AjxListener(this, this._handleCancelButton)); 49 50 }; 51 52 ZmTimeSuggestionPrefDialog.prototype = new DwtDialog; 53 ZmTimeSuggestionPrefDialog.prototype.constructor = ZmTimeSuggestionPrefDialog; 54 55 // Constants 56 57 ZmTimeSuggestionPrefDialog.META_DATA_KEY = "MD_LOCATION_SEARCH_PREF"; 58 ZmTimeSuggestionPrefDialog.PREF_FIELDS = ["name", "site", "capacity", "building", "desc", "floor", 59 "my_working_hrs_pref", "others_working_hrs_pref", 60 "recurrenceSelect"]; 61 62 // corresponding attributes for search command 63 ZmTimeSuggestionPrefDialog.SF_ATTR = {}; 64 ZmTimeSuggestionPrefDialog.SF_ATTR["name"] = "fullName"; 65 ZmTimeSuggestionPrefDialog.SF_ATTR["capacity"] = "zimbraCalResCapacity"; 66 ZmTimeSuggestionPrefDialog.SF_ATTR["desc"] = "description"; 67 ZmTimeSuggestionPrefDialog.SF_ATTR["site"] = "zimbraCalResSite"; 68 ZmTimeSuggestionPrefDialog.SF_ATTR["building"] = "zimbraCalResBuilding"; 69 ZmTimeSuggestionPrefDialog.SF_ATTR["floor"] = "zimbraCalResFloor"; 70 71 // search field compares ops - listed here if not substring ("has") 72 ZmTimeSuggestionPrefDialog.SF_OP = {}; 73 ZmTimeSuggestionPrefDialog.SF_OP["capacity"] = "ge"; 74 ZmTimeSuggestionPrefDialog.SF_OP["floor"] = "eq"; 75 76 ZmTimeSuggestionPrefDialog.MY_WORKING_HOURS_FIELD = 'my_working_hrs_pref'; 77 ZmTimeSuggestionPrefDialog.OTHERS_WORKING_HOURS_FIELD = 'others_working_hrs_pref'; 78 ZmTimeSuggestionPrefDialog.RECURRENCE = 'recurrenceSelect'; 79 80 ZmTimeSuggestionPrefDialog.CHECKBOX_FIELDS = {}; 81 ZmTimeSuggestionPrefDialog.CHECKBOX_FIELDS[ZmTimeSuggestionPrefDialog.MY_WORKING_HOURS_FIELD] = true; 82 ZmTimeSuggestionPrefDialog.CHECKBOX_FIELDS[ZmTimeSuggestionPrefDialog.OTHERS_WORKING_HOURS_FIELD] = true; 83 84 ZmTimeSuggestionPrefDialog.DEFAULT_VAL = {}; 85 ZmTimeSuggestionPrefDialog.DEFAULT_VAL[ZmTimeSuggestionPrefDialog.MY_WORKING_HOURS_FIELD] = 'true'; 86 ZmTimeSuggestionPrefDialog.DEFAULT_VAL[ZmTimeSuggestionPrefDialog.OTHERS_WORKING_HOURS_FIELD] = 'true'; 87 ZmTimeSuggestionPrefDialog.DEFAULT_NUM_RECURRENCE = 4; 88 ZmTimeSuggestionPrefDialog.MAX_NUM_RECURRENCE = 10; 89 ZmTimeSuggestionPrefDialog.DEFAULT_VAL[ZmTimeSuggestionPrefDialog.RECURRENCE] = 90 ZmTimeSuggestionPrefDialog.DEFAULT_NUM_RECURRENCE.toString(); 91 92 93 // Public methods 94 95 ZmTimeSuggestionPrefDialog.prototype.toString = 96 function() { 97 return "ZmTimeSuggestionPrefDialog"; 98 }; 99 100 ZmTimeSuggestionPrefDialog.prototype._handleOkButton = 101 function(event) { 102 this.readPrefs(); 103 this.setSearchPreference(); 104 this.popdown(); 105 if(this._callback) this._callback.run(); 106 }; 107 108 ZmTimeSuggestionPrefDialog.prototype._handleCancelButton = 109 function(event) { 110 this.popdown(); 111 }; 112 113 114 115 /** 116 * Pops-up the properties dialog. 117 * 118 */ 119 ZmTimeSuggestionPrefDialog.prototype.popup = 120 function(account) { 121 this._account = account; 122 DwtDialog.prototype.popup.call(this); 123 this.getSearchPreference(); 124 125 var el = document.getElementById(this._htmlElId); 126 var loc = Dwt.getLocation(el); 127 if (loc.x < 0) { 128 // For Bug 94520. Japanese text is not getting formatted properly (it stays one very long string), until the 129 // dialog was dragged. Dragging runs the next line in its code (which places the left of the dialog on screen) 130 // and it triggers the reformatting. 131 // Don't try setting the location via the loc var to DwtDialog.popup - the DwtBaseDialog positioning 'corrects' 132 // it and resets it to an offscreen value. 133 el.style.left = "0px"; 134 } 135 }; 136 137 ZmTimeSuggestionPrefDialog.prototype.popdown = 138 function() { 139 DwtDialog.prototype.popdown.call(this); 140 }; 141 142 ZmTimeSuggestionPrefDialog.prototype.getPrefLoaded = 143 function() { 144 return this._prefLoaded; 145 } 146 147 ZmTimeSuggestionPrefDialog.prototype._getContentHtml = 148 function() { 149 return AjxTemplate.expand("calendar.Appointment#TimeLocationPreference", {id: this.getHTMLElId()}); 150 }; 151 152 ZmTimeSuggestionPrefDialog.prototype.setContent = 153 function(text) { 154 var d = this._getContentDiv(); 155 if (d) { 156 d.innerHTML = text || ""; 157 } 158 159 this._recurrenceSelect = new DwtSelect({id:this._htmlElId + "_recurrenceSelect", 160 parent:this, parentElement:(this._htmlElId + "_recurrence")}); 161 for (var i = 1; i <= ZmTimeSuggestionPrefDialog.MAX_NUM_RECURRENCE; i++) { 162 this._recurrenceSelect.addOption(i.toString(), (i == 1), i); 163 } 164 165 166 this._dlgId = AjxCore.assignId(this); 167 168 var element, id; 169 for(var i=0; i<ZmTimeSuggestionPrefDialog.PREF_FIELDS.length; i++) { 170 id = ZmTimeSuggestionPrefDialog.PREF_FIELDS[i]; 171 element = document.getElementById(this.getHTMLElId() + "_" + id); 172 if (element) { 173 this._prefFields[id] = element; 174 this._prefs[id] = this.getPreferenceFieldValue(id); 175 } 176 } 177 }; 178 179 ZmTimeSuggestionPrefDialog.prototype.getPreference = 180 function(id) { 181 return (this._prefs[id] != null) ? this._prefs[id] : ZmTimeSuggestionPrefDialog.DEFAULT_VAL[id]; 182 }; 183 184 ZmTimeSuggestionPrefDialog.prototype.setCallback = 185 function(callback) { 186 this._callback = callback; 187 }; 188 189 ZmTimeSuggestionPrefDialog.prototype.readPrefs = 190 function(text) { 191 var field; 192 for(var id in this._prefFields) { 193 this._prefs[id] = this.getPreferenceFieldValue(id) 194 } 195 }; 196 197 ZmTimeSuggestionPrefDialog.prototype.getPreferenceFieldValue = 198 function(id) { 199 if (id == "recurrenceSelect") { 200 return this._recurrenceSelect.getValue(); 201 } else { 202 var field = this._prefFields[id]; 203 if(!field) return; 204 205 if(ZmTimeSuggestionPrefDialog.CHECKBOX_FIELDS[id]){ 206 return field.checked ? 'true' : 'false'; 207 }else { 208 return field.value; 209 } 210 } 211 }; 212 213 ZmTimeSuggestionPrefDialog.prototype.setPreferenceFieldValue = 214 function(id, value) { 215 if (id == "recurrenceSelect") { 216 this._recurrenceSelect.setSelectedValue(value); 217 } else { 218 var field = this._prefFields[id]; 219 if(!field) return; 220 221 if(ZmTimeSuggestionPrefDialog.CHECKBOX_FIELDS[id]){ 222 field.checked = (value == 'true'); 223 }else { 224 field.value = value || ""; 225 } 226 } 227 }; 228 229 ZmTimeSuggestionPrefDialog.prototype.getSearchPreference = 230 function(account, prefSearchCallback) { 231 var md = new ZmMetaData(account || this._account); 232 var callback = new AjxCallback(this, this.processSearchPreference, [prefSearchCallback]); 233 md.get(ZmTimeSuggestionPrefDialog.META_DATA_KEY, null, callback); 234 }; 235 236 ZmTimeSuggestionPrefDialog.prototype.processSearchPreference = 237 function(prefSearchCallback, metadataResponse) { 238 this._prefs = {}; 239 240 var objPrefs = metadataResponse.getResponse().BatchResponse.GetMailboxMetadataResponse[0].meta[0]._attrs; 241 for (name in objPrefs) { 242 if(name && objPrefs[name]) { 243 this._prefs[name] = objPrefs[name]; 244 this.setPreferenceFieldValue(name, this._prefs[name]); 245 } 246 } 247 248 //set default value for the preferences 249 for(var id in ZmTimeSuggestionPrefDialog.DEFAULT_VAL) { 250 if(!this._prefs[id]) { 251 this.setPreferenceFieldValue(id, ZmTimeSuggestionPrefDialog.DEFAULT_VAL[id]); 252 } 253 } 254 255 this._prefLoaded = true; 256 if(prefSearchCallback) prefSearchCallback.run(); 257 }; 258 259 ZmTimeSuggestionPrefDialog.prototype.setSearchPreference = 260 function() { 261 var md = new ZmMetaData(this._account); 262 var newPrefs = {}; 263 for(var id in this._prefs) { 264 if(this._prefs[id] != "") newPrefs[id] = this._prefs[id]; 265 } 266 return md.set(ZmTimeSuggestionPrefDialog.META_DATA_KEY, newPrefs); 267 }; 268 269 ZmTimeSuggestionPrefDialog.isSearchCondition = 270 function(id) { 271 return Boolean(ZmTimeSuggestionPrefDialog.SF_ATTR[id]); 272 }; 273 274 ZmTimeSuggestionPrefDialog.prototype.handleRoomCheckbox = 275 function() { 276 this.enableLocationFields(true); 277 }; 278 279 ZmTimeSuggestionPrefDialog.prototype.enableLocationFields = 280 function(enable) { 281 for(var id in ZmTimeSuggestionPrefDialog.SF_ATTR) { 282 if(!this._prefFields[id]) continue; 283 this._prefFields[id].disabled = !enable; 284 } 285 }; 286 287 ZmTimeSuggestionPrefDialog._handleRoomCheckbox = 288 function(ev) { 289 var el = DwtUiEvent.getTarget(ev); 290 var dlg = AjxCore.objectWithId(el._dlgId); 291 if (!dlg) { return; } 292 dlg.handleRoomCheckbox(); 293 };