0013080: Extend document preview
[tine20] / tine20 / Filemanager / js / nodeActions.js
1 /*
2  * Tine 2.0
3  *
4  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
5  * @author      Cornelius WeiƟ <c.weiss@metaways.de>
6  * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
7  */
8 Ext.ns('Tine.Filemanager.nodeActions');
9
10 /**
11  * @singleton
12  */
13 Tine.Filemanager.nodeActionsMgr = new (Ext.extend(Tine.widgets.ActionManager, {
14     actionConfigs: Tine.Filemanager.nodeActions
15 }))();
16
17 // /**
18 //  * reload
19 //  */
20 // Tine.Filemanager.nodeActions.Reload = {
21 //     app: 'Filemanager',
22 //     text: 'Reload', // _('Reload),
23 //     iconCls: 'x-tbar-loading',
24 //     handler: function() {
25 //         var record = this.initialConfig.selections[0];
26 //         // arg - does not trigger tree children reload!
27 //         Tine.Filemanager.fileRecordBackend.loadRecord(record);
28 //     }
29 // };
30
31 /**
32  * create new folder, needs a single folder selection with addGrant
33  */
34 Tine.Filemanager.nodeActions.CreateFolder = {
35     app: 'Filemanager',
36     requiredGrant: 'addGrant',
37     allowMultiple: false,
38     // actionType: 'add',
39     text: 'Create Folder', // _('Create Folder')
40     disabled: true,
41     iconCls: 'action_create_folder',
42     scope: this,
43     handler: function() {
44         var app = this.initialConfig.app,
45             currentFolderNode = this.initialConfig.selections[0],
46             nodeName = Tine.Filemanager.Model.Node.getContainerName();
47
48         Ext.MessageBox.prompt(app.i18n._('New Folder'), app.i18n._('Please enter the name of the new folder:'), function(btn, text) {
49             if(currentFolderNode && btn == 'ok') {
50                 if (! text) {
51                     Ext.Msg.alert(String.format(app.i18n._('No {0} added'), nodeName), String.format(app.i18n._('You have to supply a {0} name!'), nodeName));
52                     return;
53                 }
54
55                 var filename = currentFolderNode.get('path') + '/' + text;
56                 Tine.Filemanager.fileRecordBackend.createFolder(filename);
57             }
58         }, this);
59     },
60     actionUpdater: function(action, grants, records, isFilterSelect) {
61         var enabled = !isFilterSelect
62             && records && records.length == 1
63             && records[0].get('type') == 'folder'
64             && window.lodash.get(records, '[0].data.account_grants.addGrant', false);
65
66         action.setDisabled(!enabled);
67     }
68 };
69
70 /**
71  * show native file select, upload files, create nodes
72  * a single directory node with create grant has to be selected
73  * for this action to be active
74  */
75 // Tine.Filemanager.nodeActions.UploadFiles = {};
76
77 /**
78  * single file or directory node with readGrant
79  */
80 Tine.Filemanager.nodeActions.Edit = {
81     app: 'Filemanager',
82     requiredGrant: 'readGrant',
83     allowMultiple: false,
84     text: 'Edit Properties', // _('Edit Properties')
85     iconCls: 'action_edit_file',
86     disabled: true,
87     // actionType: 'edit',
88     scope: this,
89     handler: function () {
90         if(this.initialConfig.selections.length == 1) {
91             Tine.Filemanager.NodeEditDialog.openWindow({record: this.initialConfig.selections[0]});
92         }
93     },
94     actionUpdater: function(action, grants, records, isFilterSelect) {
95         // run default updater
96         Tine.widgets.ActionUpdater.prototype.defaultUpdater(action, grants, records, isFilterSelect);
97
98         var _ = window.lodash,
99             disabled = _.isFunction(action.isDisabled) ? action.isDisabled() : action.disabled;
100
101         // if enabled check for not accessible node and disable
102         if (! disabled) {
103             action.setDisabled(window.lodash.reduce(records, function(disabled, record) {
104                 return disabled || record.isVirtual();
105             }, false));
106         }
107     }
108 };
109
110 /**
111  * single file or directory node with editGrant
112  */
113 Tine.Filemanager.nodeActions.Rename = {
114     app: 'Filemanager',
115     requiredGrant: 'editGrant',
116     allowMultiple: false,
117     text: 'Rename', // _('Rename')
118     iconCls: 'action_rename',
119     disabled: true,
120     // actionType: 'edit',
121     scope: this,
122     handler: function () {
123         var _ = window.lodash,
124             app = this.initialConfig.app,
125             record = this.initialConfig.selections[0],
126             nodeName = record.get('type') == 'folder' ?
127                 Tine.Filemanager.Model.Node.getContainerName() :
128                 Tine.Filemanager.Model.Node.getRecordName();
129
130         Ext.MessageBox.show({
131             title: String.format(i18n._('Rename {0}'), nodeName),
132             msg: String.format(i18n._('Please enter the new name of the {0}:'), nodeName),
133             buttons: Ext.MessageBox.OKCANCEL,
134             value: record.get('name'),
135             fn: function (btn, text) {
136                 if (btn == 'ok') {
137                     if (!text) {
138                         Ext.Msg.alert(String.format(i18n._('Not renamed {0}'), nodeName), String.format(i18n._('You have to supply a {0} name!'), nodeName));
139                         return;
140                     }
141
142                     // @TODO validate filename
143                     var targetPath = record.get('path').replace(new RegExp(record.get('name') +'$'), text);
144                     Tine.Filemanager.fileRecordBackend.copyNodes([record], targetPath, true);
145
146                 }
147             },
148             scope: this,
149             prompt: true,
150             icon: Ext.MessageBox.QUESTION
151         });
152     }
153 };
154
155 /**
156  * one or multiple nodes, all need deleteGrant
157  */
158 Tine.Filemanager.nodeActions.Delete = {
159     app: 'Filemanager',
160     requiredGrant: 'deleteGrant',
161     allowMultiple: true,
162     text: 'Delete', // _('Delete')
163     disabled: true,
164     iconCls: 'action_delete',
165     scope: this,
166     handler: function (button, event) {
167         var app = this.initialConfig.app,
168             nodeName = '',
169             nodes = this.initialConfig.selections;
170
171         if (nodes && nodes.length) {
172             for (var i = 0; i < nodes.length; i++) {
173                 var currNodeData = nodes[i].data;
174
175                 if (typeof currNodeData.name == 'object') {
176                     nodeName += currNodeData.name.name + '<br />';
177                 }
178                 else {
179                     nodeName += currNodeData.name + '<br />';
180                 }
181             }
182         }
183
184         this.conflictConfirmWin = Tine.widgets.dialog.FileListDialog.openWindow({
185             modal: true,
186             allowCancel: false,
187             height: 180,
188             width: 300,
189             title: app.i18n._('Do you really want to delete the following files?'),
190             text: nodeName,
191             scope: this,
192             handler: function (button) {
193                 if (nodes && button == 'yes') {
194                     Tine.Filemanager.fileRecordBackend.deleteItems(nodes);
195                 }
196
197                 for (var i = 0; i < nodes.length; i++) {
198                     var node = nodes[i];
199
200                     if (node.fileRecord) {
201                         var upload = Tine.Tinebase.uploadManager.getUpload(node.fileRecord.get('uploadKey'));
202                         upload.setPaused(true);
203                         Tine.Tinebase.uploadManager.unregisterUpload(upload.id);
204                     }
205
206                 }
207             }
208         });
209     }
210 };
211
212 /**
213  * one node with readGrant
214  */
215 // Tine.Filemanager.nodeActions.Copy = {};
216
217 /**
218  * one or multiple nodes with read, edit AND deleteGrant
219  */
220 Tine.Filemanager.nodeActions.Move = {
221     app: 'Filemanager',
222     requiredGrant: 'editGrant',
223     allowMultiple: true,
224     text: 'Move', // _('Move')
225     disabled: true,
226     actionType: 'edit',
227     scope: this,
228     iconCls: 'action_move',
229     handler: function() {
230         var app = this.initialConfig.app,
231             i18n = app.i18n,
232             records = this.initialConfig.selections;
233
234         var filePickerDialog = new Tine.Filemanager.FilePickerDialog({
235             title: app.i18n._('Move Items'),
236             singleSelect: true,
237             constraint: 'folder'
238         });
239
240         filePickerDialog.on('selected', function(nodes) {
241             var node = nodes[0];
242             Tine.Filemanager.fileRecordBackend.copyNodes(records, node.path, true);
243         });
244
245         filePickerDialog.openWindow();
246     },
247 };
248
249 /**
250  * one file node with download grant
251  */
252 Tine.Filemanager.nodeActions.Download = {
253     app: 'Filemanager',
254     requiredGrant: 'downloadGrant',
255     allowMultiple: false,
256     actionType: 'download',
257     text: 'Save locally', // _('Save locally')
258     iconCls: 'action_filemanager_save_all',
259     disabled: true,
260     scope: this,
261     handler: function() {
262         Tine.Filemanager.downloadFile(this.initialConfig.selections[0]);
263     },
264     actionUpdater: function(action, grants, records, isFilterSelect) {
265         var enabled = !isFilterSelect
266             && records && records.length == 1
267             && records[0].get('type') != 'folder'
268             && window.lodash.get(records, '[0].data.account_grants.downloadGrant', false);
269
270         action.setDisabled(!enabled);
271     }
272 };
273
274 /**
275  * one file node with readGrant
276  */
277 Tine.Filemanager.nodeActions.Preview = {
278     app: 'Filemanager',
279     allowMultiple: false,
280     requiredGrant: 'readGrant',
281     text: 'Preview', // _('Preview')
282     disabled: true,
283     iconCls: 'previewIcon',
284     scope: this,
285     handler: function () {
286         var selections = this.initialConfig.selections;
287
288         if (selections.length > 0) {
289             var selection = selections[0];
290
291             if (selection && selection.get('type') === 'file') {
292                 Tine.Filemanager.DocumentPreview.openWindow({
293                     record: selection
294                 });
295             }
296         }
297     }
298 };
299
300 /**
301  * one node with publish grant
302  */
303 Tine.Filemanager.nodeActions.Publish = {
304     app: 'Filemanager',
305     allowMultiple: false,
306     text: 'Publish', // _('Publish')
307     disabled: true,
308     iconCls: 'action_publish',
309     scope: this,
310     handler: function() {
311         var app = this.initialConfig.app,
312             i18n = app.i18n,
313             selections = this.initialConfig.selections;
314
315         if (selections.length != 1) {
316             return;
317         }
318
319         var passwordDialog = new Tine.Tinebase.widgets.dialog.PasswordDialog({
320             allowEmptyPassword: true
321         });
322         passwordDialog.openWindow();
323
324         passwordDialog.on('passwordEntered', function (password) {
325             var date = new Date();
326             date.setDate(date.getDate() + 30);
327
328             var record = new Tine.Filemanager.Model.DownloadLink({
329                 node_id: selections[0].id,
330                 expiry_time: date,
331                 password: password
332             });
333             Tine.Filemanager.downloadLinkRecordBackend.saveRecord(record, {
334                 success: function (record) {
335                     // TODO: add mail-button
336                     Ext.MessageBox.show({
337                         title: selections[0].data.type == 'folder' ? app.i18n._('Folder has been published successfully') : app.i18n._('File has been published successfully'),
338                         msg: String.format(app.i18n._("Url: {0}") + '<br />' + app.i18n._("Valid Until: {1}"), record.get('url'), record.get('expiry_time')),
339                         minWidth: 900,
340                         buttons: Ext.Msg.OK,
341                         icon: Ext.MessageBox.INFO,
342                     });
343                 }, failure: Tine.Tinebase.ExceptionHandler.handleRequestException, scope: this
344             });
345         }, this);
346     },
347     actionUpdater: function(action, grants, records, isFilterSelect) {
348         var enabled = !isFilterSelect
349             && records && records.length == 1
350             && window.lodash.get(records, '[0].data.account_grants.publishGrant', false);
351
352         action.setDisabled(!enabled);
353     }
354 };
355
356 /**
357  * one or multiple file nodes currently uploaded
358  */
359 Tine.Filemanager.nodeActions.PauseUploadAction = {};
360
361 /**
362  * one or multiple file nodes currently upload paused
363  */
364 Tine.Filemanager.nodeActions.ResumeUploadAction = {};
365
366 /**
367  * one or multiple file nodes currently uploaded or upload paused
368  * @TODO deletes node as well?
369  */
370 Tine.Filemanager.nodeActions.CancelUploadAction = {};