1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2008, 2009, 2010, 2011, 2013, 2014, 2015, 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) 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 /**
 25  * This class represents the export view.
 26  * 
 27  * @extends		ZmImportExportBaseView
 28  * @class
 29  * @private
 30  */
 31 ZmExportView = function(params) {
 32 	if (arguments.length == 0) { return; }
 33 	var today = AjxDateUtil.simpleComputeDateStr(new Date());
 34 	var isExportPeriodLimited = (appCtxt.get(ZmSetting.EXPORT_MAX_DAYS) > 0);
 35 	// setup form
 36 	params.form = {
 37 		items: [
 38 			// default items
 39 			{ id: "TYPE", type: "DwtRadioButtonGroup", value: ZmImportExportController.TYPE_TGZ,
 40 				items: [
 41 					{ id: "TYPE_TGZ", label: ZmMsg.importExportTypeTGZ, value: ZmImportExportController.TYPE_TGZ },
 42 					{ id: "TYPE_ICS", label: ZmMsg.importExportTypeICS, value: ZmImportExportController.TYPE_ICS },
 43 					{ id: "TYPE_CSV", label: ZmMsg.importExportTypeCSV, value: ZmImportExportController.TYPE_CSV }
 44 				],
 45 				onclick: this._type_onclick
 46 			},
 47 			{ id: "TYPE_HINT", type: "DwtText" },
 48 			{ id: "SUBTYPE", type: "DwtSelect",
 49 				visible: "get('TYPE') == ZmImportExportController.TYPE_CSV"
 50 			},
 51 			{ id: "FOLDER_BUTTON", type: "DwtButton", label: ZmMsg.browse,
 52 				onclick: this._folderButton_onclick
 53 			},
 54 			{ id: "ADVANCED", type: "DwtCheckbox", label: ZmMsg.advancedSettings,
 55 				visible: "get('TYPE') == ZmImportExportController.TYPE_TGZ",
 56 				checked: isExportPeriodLimited,
 57 				enabled: !isExportPeriodLimited
 58 			},
 59 			// advanced
 60 			{ id: "DATA_TYPES", type: "ZmImportExportDataTypes",
 61 				visible: "get('ADVANCED')"
 62 			},
 63 			{ id: "SEARCH_FILTER", type: "DwtInputField", hint: ZmMsg.searchFilterHint,
 64 				visible: "get('ADVANCED')"
 65 			},
 66 			{ id: "DATE_row", visible: "get('ADVANCED')"
 67 			},
 68 			{ id: "startDateField", type: "DwtInputField", visible: "get('ADVANCED')", onblur: AjxCallback.simpleClosure(this._dateFieldChangeListener, this, true),
 69 				value: isExportPeriodLimited ? today : null
 70 			},
 71 			{ id :"startMiniCalBtn", type: "DwtButton", visible: "get('ADVANCED')",
 72 				menu: {type: "DwtCalendar", id: "startMiniCal", onselect: new AjxListener(this, this._dateCalSelectionListener, [true])}
 73 			},
 74 			{ id: "endDateField", type: "DwtInputField", visible: "get('ADVANCED')", onblur: AjxCallback.simpleClosure(this._dateFieldChangeListener, this, false),
 75 				value: isExportPeriodLimited ? today : null
 76 			},
 77 			{ id :"endMiniCalBtn", type: "DwtButton", visible: "get('ADVANCED')",
 78 				menu: {type: "DwtCalendar", id: "endMiniCal", onselect: new AjxListener(this, this._dateCalSelectionListener, [false])}
 79 			},
 80 			{ id: "SKIP_META", type: "DwtCheckbox", label: ZmMsg.exportSkipMeta,
 81 				visible: "get('ADVANCED')"
 82 			}
 83 		]
 84 	};
 85 	params.id = "ZmExportView";
 86 	ZmImportExportBaseView.call(this, params);
 87 };
 88 ZmExportView.prototype = new ZmImportExportBaseView;
 89 ZmExportView.prototype.constructor = ZmExportView;
 90 
 91 ZmExportView.prototype.toString = function() {
 92 	return "ZmExportView";
 93 };
 94 
 95 //
 96 // Data
 97 //
 98 
 99 ZmExportView.prototype.TYPE_HINTS = {};
100 ZmExportView.prototype.TYPE_HINTS[ZmImportExportController.TYPE_CSV] = ZmMsg.exportToCSVHint;
101 ZmExportView.prototype.TYPE_HINTS[ZmImportExportController.TYPE_ICS] = ZmMsg.exportToICSHint;
102 ZmExportView.prototype.TYPE_HINTS[ZmImportExportController.TYPE_TGZ] = ZmMsg.exportToTGZHint;
103 
104 ZmExportView.prototype.TEMPLATE = "data.ImportExport#ExportView";
105 
106 //
107 // Data
108 //
109 
110 ZmExportView.prototype._type = ZmImportExportController.TYPE_TGZ;
111 
112 //
113 // Public methods
114 //
115 
116 /**
117  * Returns a params object that can be used to directly call
118  * ZmImportExportController#exportData.
119  */
120 ZmExportView.prototype.getParams = function() {
121 	// export parameters
122 	var params = {
123 		// required
124 		type:			this.getValue("TYPE", ZmImportExportController.TYPE_TGZ),
125 		subType:		this.getValue("SUBTYPE"),
126 		// optional -- ignore if not relevant
127 		views:			this.isRelevant("DATA_TYPES") ? this.getValue("DATA_TYPES") : null,
128 		folderId:		this._folderId,
129 		searchFilter:		this.isRelevant("SEARCH_FILTER") ? this.getValue("SEARCH_FILTER") : null ,
130 		start:			this.isRelevant("startDateField") ? this.getValue("startDateField"): null,
131 		end:			this.isRelevant("endDateField") ? this.getValue("endDateField"): null,
132 		skipMeta:		this.isRelevant("SKIP_META") ? this.getValue("SKIP_META") : null
133 	};
134 
135 	// generate filename
136 	if (this._folderId != -1) {
137 		var folder = appCtxt.getById(params.folderId);
138 		var isRoot = folder && folder.nId == ZmOrganizer.ID_ROOT;
139 		params.filename = [
140 			isRoot ? ZmMsg.exportFilenamePrefixAllFolders : folder.name,
141 			"-",
142 			AjxDateFormat.format("yyyy-MM-dd-HHmmss", new Date())
143 		].join("");
144 		params.filename = params.filename;
145 	}
146 
147 	return params;
148 };
149 
150 //
151 // Protected methods
152 //
153 
154 ZmExportView.prototype.update = function() {
155 	var type = this.getValue("TYPE", ZmImportExportController.TYPE_TGZ);
156 	var isTGZ = type == ZmImportExportController.TYPE_TGZ;
157 	var advanced = this.getControl("ADVANCED");
158 	if (advanced) {
159 		advanced.setEnabled(isTGZ);
160 		if (!isTGZ) {
161 			this.setValue("ADVANCED", false);
162 		} else if(appCtxt.get(ZmSetting.EXPORT_MAX_DAYS) > 0) {
163 			this.setValue("ADVANCED", true);
164 		}
165 	}
166 	ZmImportExportBaseView.prototype.update.apply(this, arguments);
167 };
168 
169 // handlers
170 ZmExportView.prototype._folder_onclick = function() {
171 	var isAll = this.getValue("FOLDER") == "all";
172 	var type = isAll ? ZmImportExportController.TYPE_TGZ : null;
173 	type = type || this._getTypeFromFolder(appCtxt.getById(this._folderId));
174 	this.setValue("TYPE", type);
175 	this._initSubType(type);
176 	this.update();
177 };
178 
179 ZmExportView.prototype._dateFieldChangeListener = 
180 function(isStart, ev) {
181 	var field = isStart ? "startDateField" : "endDateField";
182 	var calId = isStart ? "startMiniCal" : "endMiniCal";
183 	var cal = this.getControl(calId);
184 	var calDate = AjxDateUtil.simpleParseDateStr(this.getValue(field));
185 	
186 	if (isNaN(calDate)) {
187 		calDate = cal.getDate() || new Date();
188 		this.setValue(field, AjxDateUtil.simpleComputeDateStr(calDate));
189 	} else {
190                 if (calDate)
191                         cal.setDate(calDate);
192                 else
193                         this.setValue(field, null);
194 	}
195 };
196 
197 ZmExportView.prototype._dateCalSelectionListener = 
198 function(isStart, ev) {
199 	var sd = AjxDateUtil.simpleParseDateStr(this.getValue("startDateField"));
200 	var ed = AjxDateUtil.simpleParseDateStr(this.getValue("endDateField"));
201 	var newDate = AjxDateUtil.simpleComputeDateStr(ev.detail);
202 	// change the start/end date if they mismatch
203 	if (isStart) {
204 		if (ed && (ed.valueOf() < ev.detail.valueOf())) {
205 			this.setValue("endDateField", newDate);
206 			this.getControl("endMiniCal").setDate(ev.detail);
207 		}
208 		this.setValue("startDateField", newDate);
209 	} else {
210 		if (sd && (sd.valueOf() > ev.detail.valueOf())) {
211 			this.setValue("startDateField", newDate);
212 			this.getControl("startMiniCal").setDate(ev.detail);
213 		}
214 		this.setValue("endDateField", newDate);
215 	}
216 };
217 
218