1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 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) 2011, 2012, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 ZmActivityStreamPromptDialog = function() {
 25 	var extraButtons = new DwtDialog_ButtonDescriptor(ZmActivityStreamPromptDialog.ADD_ADVANCED_BUTTON, ZmMsg.advanced, DwtDialog.ALIGN_LEFT);
 26 	DwtDialog.call(this, {parent:appCtxt.getShell(), className:"ZmActivityStreamPromptDialog", title:"Activity Stream Rules",
 27 						  standardButtons:[DwtDialog.OK_BUTTON, DwtDialog.CANCEL_BUTTON], extraButtons: [extraButtons]});	
 28 	// set content
 29 	this.setContent(this._contentHtml());
 30 	this._initialize();
 31 	
 32 	var okButton = this.getButton(DwtDialog.OK_BUTTON);
 33 	okButton.setText(ZmMsg.save);
 34 	this.setButtonListener(DwtDialog.OK_BUTTON, new AjxListener(this, this._saveListener));
 35 	
 36 	var advancedButton = this.getButton(ZmActivityStreamPromptDialog.ADD_ADVANCED_BUTTON);
 37 	this.setButtonListener(ZmActivityStreamPromptDialog.ADD_ADVANCED_BUTTON, new AjxListener(this, this._advancedListener));
 38 };
 39 
 40 ZmActivityStreamPromptDialog.prototype = new DwtDialog;
 41 ZmActivityStreamPromptDialog.prototype.constructor = ZmActivityStreamPromptDialog;
 42 ZmActivityStreamPromptDialog.ADD_ADVANCED_BUTTON = ++DwtDialog.LAST_BUTTON;
 43 
 44 ZmActivityStreamPromptDialog.prototype._contentHtml = 
 45 function() {   
 46 	return "<div style='width: 400px' id='ACTIVITYSTREAM_PROMPT_FORM'>" + ZmMsg.activityStreamPrompt + "</div>";				
 47 };
 48 
 49 ZmActivityStreamPromptDialog.prototype._initialize = 
 50 function() {
 51 	var params = {};
 52 	params.parent = this;
 53 	params.template = "prefs.Pages#ActivityStreamPrompt";
 54 	params.form = {
 55 		items: [
 56 			{ id: "SENTTO", type: "DwtCheckbox", label: ZmMsg.to + ":", value: "to"},
 57 			{ id: "TO", type: "DwtInputField", value: "", cols: 30},
 58 			{ id: "RECEIVED", type: "DwtCheckbox", label: ZmMsg.receivedFrom, value: "received"},
 59 			{ id: "FROM", type: "DwtInputField", value: "", cols: 30},
 60 			{ id: "SUBJECT", type: "DwtCheckbox", label: ZmMsg.subjectContains, value: "subject"},
 61 			{ id: "CONTAINS", type: "DwtInputField", value: "", cols: 30}
 62 		]
 63 	};
 64 	this._activityStreamForm = new DwtForm(params);
 65 	var activityStreamForm = document.getElementById("ACTIVITYSTREAM_PROMPT_FORM");
 66 	this._activityStreamForm.appendElement(activityStreamForm);
 67 	this._activityStreamForm.getControl("SUBJECT").setSelected(false);
 68 };
 69 
 70 ZmActivityStreamPromptDialog.prototype._handleResponseLoadRules = 
 71 function() {
 72 	this._activityRule = this._rules.getRuleByName(ZmMsg.activityStreamsRule);	
 73 };
 74 
 75 /**
 76  * Checks to see if new condition is being added before popping up dialog
 77  * @param skip {Boolean} true to skip new condition check
 78  */
 79 ZmActivityStreamPromptDialog.prototype.popup = 
 80 function(skip) {
 81 	this._rules = AjxDispatcher.run("GetFilterRules");
 82 	var callback = new AjxCallback(this, this._handleResponseLoadRules);
 83 	this._rules.loadRules(true, callback); // make sure rules are loaded (for when we save)
 84 	if (skip || this._isNewCondition(this._getActivityStreamRule())) {	
 85 		DwtDialog.prototype.popup.call(this);
 86 	}
 87 };
 88 
 89 /**
 90  * sets form fields
 91  * @param item  {ZmMailMsg} mail message
 92  */
 93 ZmActivityStreamPromptDialog.prototype.setFields = 
 94 function(item) {
 95 	this._subject = item.subject;
 96 	var msg = item.type == ZmId.ITEM_CONV ? item.getFirstHotMsg() : item;
 97 	if (msg) {
 98 		this._from = msg.getMsgSender();
 99 	}
100 	else if (item.participants) {
101 		var arr = item.participants.getArray();
102 		for (var i=0; i<arr.length; i++) {
103 			if (arr[i].getType() == "FROM") {
104 				this._from = arr[i].getAddress();
105 			}
106 		}
107 	}
108 
109 
110 	var arr = msg._addrs && msg._addrs["TO"] && msg._addrs["TO"].getArray();
111     this._to = (arr.length == 1) ? arr[0].getAddress() : "";
112 
113 	if (this._subject) {
114 		var subjectField = this._activityStreamForm.getControl("CONTAINS");
115 		subjectField.setValue(this._subject);
116 	}
117 	
118 	if (this._from) {
119 		var fromField = this._activityStreamForm.getControl("FROM");
120 		fromField.setValue(this._from);
121 	}
122     var toField = this._activityStreamForm.getControl("TO");
123 	toField.setValue(this._to);
124 
125 };
126 
127 ZmActivityStreamPromptDialog.prototype._saveListener =
128 function() {
129 	var foundCondition = this._setConditions(this._activityRule);		
130 	if (foundCondition) {
131 		this._rules.saveRules(null, true);
132 	}
133 	this.popdown();
134 };
135 
136 ZmActivityStreamPromptDialog.prototype._setConditions = 
137 function(rule) {
138 	var received = this._activityStreamForm.getControl("RECEIVED");
139     var sentto = this._activityStreamForm.getControl("SENTTO");
140 	var subject = this._activityStreamForm.getControl("SUBJECT");
141 	var foundCondition = false;
142 	
143 	if (received && received.isSelected() && rule) {
144 		var from = this._activityStreamForm.getControl("FROM");
145 		if (from) {
146 			rule.addCondition(ZmFilterRule.TEST_ADDRESS, ZmFilterRule.OP_CONTAINS, from.getValue(), ZmFilterRule.C_ADDRESS_VALUE[ZmFilterRule.C_FROM]);
147 			foundCondition = true;
148 		}
149 	}
150 
151     if (sentto && sentto.isSelected() && rule) {
152 		var to = this._activityStreamForm.getControl("TO");
153 		if (to) {
154 			rule.addCondition(ZmFilterRule.TEST_ADDRESS, ZmFilterRule.OP_CONTAINS, to.getValue(), ZmFilterRule.C_ADDRESS_VALUE[ZmFilterRule.C_TO]);
155 			foundCondition = true;
156 		}
157 	}
158 		
159 	if (subject && subject.isSelected() && rule) {
160 		var contains = this._activityStreamForm.getControl("CONTAINS");
161 		if (contains) {
162 			rule.addCondition(ZmFilterRule.TEST_HEADER, ZmFilterRule.OP_CONTAINS, contains.getValue(), ZmFilterRule.C_HEADER_VALUE[ZmFilterRule.C_SUBJECT]);
163 			foundCondition = true;
164 		}
165 	}
166 	
167 	return foundCondition;
168 };
169 
170 ZmActivityStreamPromptDialog.prototype._advancedListener =
171 function() {
172 	this.popdown(); //popdown existing 
173 	var filterRuleDialog = appCtxt.getFilterRuleDialog();
174 	this._setConditions(this._activityRule);
175 	filterRuleDialog.popup(this._activityRule, true);
176 };
177 
178 /**
179  * Determine if user has already created an activity stream condition with subject or email value.
180  * @param  activityRule {ZmFilterRule} the activity stream rule to determine if condition already exists
181  * @return {boolean} true this is a new condition or false condition with subject or email exists
182  */
183 ZmActivityStreamPromptDialog.prototype._isNewCondition =
184 function(activityRule) {
185 	var newCondition = activityRule ? true : false;   //if we don't have an activity rule don't prompt user
186 	var conditionData = {};
187 	var header = "";
188 	var contains = -1;
189 	if (this._subject && activityRule) {
190 		var headerTest = activityRule.conditions[ZmFilterRule.TEST_HEADER] || [];
191 		for (var i=0; i<headerTest.length && newCondition; i++) {
192 			conditionData = headerTest[i];
193 			header = conditionData.header;
194 			contains = conditionData.value ? this._subject.indexOf(conditionData.value) : -1;		
195 			newCondition = !(header == ZmFilterRule.C_HEADER_VALUE[ZmFilterRule.C_SUBJECT] && contains != -1);    
196 		}
197 	}
198 	
199 	if (this._from && activityRule && newCondition) {
200 		var addressTest = activityRule.conditions[ZmFilterRule.TEST_ADDRESS] || [];
201 		for (var i=0; i<addressTest.length && newCondition; i++) {
202 			conditionData = addressTest[i];
203 			header = conditionData.header;
204 			contains = conditionData.value ? this._from.indexOf(conditionData.value) : -1;
205 			newCondition = !(header == ZmFilterRule.C_FROM.toLowerCase() && contains != -1); 
206 		}
207 	}
208 	
209 	return newCondition;
210 };
211 
212 ZmActivityStreamPromptDialog.prototype._getActivityStreamRule = 
213 function() {
214 	return this._activityStreamRule || this._rules.getRuleByName(ZmMsg.activityStreamsRule);	
215 };