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 ZmActivityToInboxPromptDialog = function () {
 25 	var extraButtons = new DwtDialog_ButtonDescriptor(ZmActivityToInboxPromptDialog.ADD_ADVANCED_BUTTON, ZmMsg.advanced, DwtDialog.ALIGN_LEFT);
 26 	DwtDialog.call(this, {parent:appCtxt.getShell(), className:"ZmActivityToInboxPromptDialog", title:ZmMsg.activityStreamExceptionsTitle,
 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, this._saveListener.bind(this));
 35 
 36 	var advancedButton = this.getButton(ZmActivityToInboxPromptDialog.ADD_ADVANCED_BUTTON);
 37 	this.setButtonListener(ZmActivityToInboxPromptDialog.ADD_ADVANCED_BUTTON, this._advancedListener.bind(this));
 38 };
 39 
 40 ZmActivityToInboxPromptDialog.prototype = new DwtDialog;
 41 ZmActivityToInboxPromptDialog.prototype.constructor = ZmActivityToInboxPromptDialog;
 42 ZmActivityToInboxPromptDialog.ADD_ADVANCED_BUTTON = ++DwtDialog.LAST_BUTTON;
 43 
 44 ZmActivityToInboxPromptDialog.prototype._contentHtml =
 45 function () {
 46 	return "<div style='width: 400px' id='ACTIVITYTOINBOX_PROMPT_FORM'>" + ZmMsg.activityStreamToInboxPrompt + "</div>";
 47 };
 48 
 49 ZmActivityToInboxPromptDialog.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("ACTIVITYTOINBOX_PROMPT_FORM");
 66 	this._activityStreamForm.appendElement(activityStreamForm);
 67 	this._activityStreamForm.getControl("SUBJECT").setSelected(false);
 68 };
 69 
 70 ZmActivityToInboxPromptDialog.prototype._handleResponseLoadRules =
 71 function () {
 72 	this._activityExceptionsRule = this._rules.getRuleByName(ZmMsg.activityStreamExceptionsRule);
 73 	this._activityStreamRule = this._rules.getRuleByName(ZmMsg.activityStreamsRule);
 74 	if (!this._activityExceptionsRule) {
 75 		this._ruleExists = false;
 76 		this._activityExceptionsRule = new ZmFilterRule(ZmMsg.activityStreamExceptionsRule, true, {}, {});
 77 		this._activityExceptionsRule.addAction(ZmFilterRule.A_KEEP);
 78 		this._activityExceptionsRule.addAction(ZmFilterRule.A_STOP);
 79 		this._activityExceptionsRule.setGroupOp(ZmFilterRule.GROUP_ANY);
 80 	}
 81 	else {
 82 		this._ruleExists = true;
 83 	}
 84 };
 85 
 86 /**
 87  * Checks to see if new condition is being added before popping up dialog
 88  * @param skip {Boolean} true to skip new condition check
 89  */
 90 ZmActivityToInboxPromptDialog.prototype.popup =
 91 function (skip) {
 92 	this._rules = AjxDispatcher.run("GetFilterRules");
 93 	var callback = new AjxCallback(this, this._handleResponseLoadRules);
 94 	this._rules.loadRules(true, callback); // make sure rules are loaded (for when we save)
 95 	if (skip || this._isNewCondition(this._getActivityStreamExceptionRule())) {
 96 		DwtDialog.prototype.popup.call(this);
 97 	}
 98 };
 99 
100 /**
101  * sets form fields
102  * @param item  {ZmMailMsg} mail message
103  */
104 ZmActivityToInboxPromptDialog.prototype.setFields =
105 function (item) {
106 	this._subject = item.subject;
107 	var msg = item.type == ZmId.ITEM_CONV ? item.getFirstHotMsg() : item;
108 	if (msg) {
109 		this._from = msg.getMsgSender();
110 	}
111 	else if (item.participants) {
112 		var arr = item.participants.getArray();
113 		for (var i = 0; i < arr.length; i++) {
114 			if (arr[i].getType() == "FROM") {
115 				this._from = arr[i].getAddress();
116 			}
117 		}
118 	}
119 
120 	var arr = msg._addrs && msg._addrs["TO"] && msg._addrs["TO"].getArray();
121 	this._to = (arr.length == 1) ? arr[0].getAddress() : "";
122 
123 	if (this._subject) {
124 		var subjectField = this._activityStreamForm.getControl("CONTAINS");
125 		subjectField.setValue(this._subject);
126 	}
127 
128 	if (this._from) {
129 		var fromField = this._activityStreamForm.getControl("FROM");
130 		fromField.setValue(this._from);
131 	}
132 	var toField = this._activityStreamForm.getControl("TO");
133 	toField.setValue(this._to);
134 
135 };
136 
137 ZmActivityToInboxPromptDialog.prototype._saveListener =
138 function () {
139 	var foundCondition = this._setConditions(this._activityExceptionsRule);
140 	if (foundCondition) {
141 		if (!this._ruleExists) {
142 			var index = this._rules.getIndexOfRule(this._activityStreamRule);
143 			index = index > 0 ? index -1 : 0;
144 			this._rules.insertRule(this._activityExceptionsRule, index); //insert before activity stream rule
145 			this._ruleExists = true;
146 		}
147 		this._rules.saveRules(null, true);
148 	}
149 	this.popdown();
150 };
151 
152 ZmActivityToInboxPromptDialog.prototype._setConditions =
153 function (rule) {
154 	var received = this._activityStreamForm.getControl("RECEIVED");
155 	var sentto = this._activityStreamForm.getControl("SENTTO");
156 	var subject = this._activityStreamForm.getControl("SUBJECT");
157 	var foundCondition = false;
158 
159 	if (received && received.isSelected() && rule) {
160 		var from = this._activityStreamForm.getControl("FROM");
161 		if (from) {
162 			rule.addCondition(ZmFilterRule.TEST_ADDRESS, ZmFilterRule.OP_CONTAINS,
163 					from.getValue(), ZmFilterRule.C_ADDRESS_VALUE[ZmFilterRule.C_FROM]);
164 			foundCondition = true;
165 		}
166 	}
167 
168 	if (sentto && sentto.isSelected() && rule) {
169 		var to = this._activityStreamForm.getControl("TO");
170 		if (to) {
171 			rule.addCondition(ZmFilterRule.TEST_ADDRESS, ZmFilterRule.OP_CONTAINS,
172 					to.getValue(), ZmFilterRule.C_ADDRESS_VALUE[ZmFilterRule.C_TO]);
173 			foundCondition = true;
174 		}
175 	}
176 
177 	if (subject && subject.isSelected() && rule) {
178 		var contains = this._activityStreamForm.getControl("CONTAINS");
179 		if (contains) {
180 			rule.addCondition(ZmFilterRule.TEST_HEADER, ZmFilterRule.OP_CONTAINS,
181 					contains.getValue(), ZmFilterRule.C_HEADER_VALUE[ZmFilterRule.C_SUBJECT]);
182 			foundCondition = true;
183 		}
184 	}
185 
186 	return foundCondition;
187 };
188 
189 ZmActivityToInboxPromptDialog.prototype._advancedListener =
190 function () {
191 	this.popdown(); //popdown existing 
192 	var filterRuleDialog = appCtxt.getFilterRuleDialog();
193 	this._setConditions(this._activityExceptionsRule);
194 	filterRuleDialog.popup(this._activityExceptionsRule, this._ruleExists);
195 };
196 
197 /**
198  * Determine if user has already created an activity stream condition with subject or email value.
199  * @param  activityRule {ZmFilterRule} the activity stream rule to determine if condition already exists
200  * @return {boolean} true this is a new condition or false condition with subject or email exists
201  */
202 ZmActivityToInboxPromptDialog.prototype._isNewCondition =
203 function (activityRule) {
204 	var newCondition = activityRule ? true : false;   //if we don't have an activity rule don't prompt user
205 	var conditionData = {};
206 	var header = "";
207 	var contains = -1;
208 	if (this._subject && activityRule) {
209 		var headerTest = activityRule.conditions[ZmFilterRule.TEST_HEADER] || [];
210 		for (var i = 0; i < headerTest.length && newCondition; i++) {
211 			conditionData = headerTest[i];
212 			header = conditionData.header;
213 			contains = conditionData.value ? this._subject.indexOf(conditionData.value) : -1;
214 			newCondition = !(header == ZmFilterRule.C_HEADER_VALUE[ZmFilterRule.C_SUBJECT] && contains != -1);
215 		}
216 	}
217 
218 	if (this._from && activityRule && newCondition) {
219 		var addressTest = activityRule.conditions[ZmFilterRule.TEST_ADDRESS] || [];
220 		for (var i = 0; i < addressTest.length && newCondition; i++) {
221 			conditionData = addressTest[i];
222 			header = conditionData.header;
223 			contains = conditionData.value ? this._from.indexOf(conditionData.value) : -1;
224 			newCondition = !(header == ZmFilterRule.C_FROM.toLowerCase() && contains != -1);
225 		}
226 	}
227 
228 	return newCondition;
229 };
230 
231 ZmActivityToInboxPromptDialog.prototype._getActivityStreamExceptionRule =
232 function () {
233 	return this._activityExceptionsRule || this._rules.getRuleByName(ZmMsg.activityStreamExceptionsRule);
234 };