ee786883b81fcc121e834d998efa99341b7e6e4d
[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
279 /**
280  * one node with publish grant
281  */
282 Tine.Filemanager.nodeActions.Publish = {
283     app: 'Filemanager',
284     allowMultiple: false,
285     text: 'Publish', // _('Publish')
286     disabled: true,
287     iconCls: 'action_publish',
288     scope: this,
289     handler: function() {
290         var app = this.initialConfig.app,
291             i18n = app.i18n,
292             selections = this.initialConfig.selections;
293
294         if (selections.length != 1) {
295             return;
296         }
297
298         var passwordDialog = new Tine.Tinebase.widgets.dialog.PasswordDialog({
299             allowEmptyPassword: true
300         });
301         passwordDialog.openWindow();
302
303         passwordDialog.on('passwordEntered', function (password) {
304             var date = new Date();
305             date.setDate(date.getDate() + 30);
306
307             var record = new Tine.Filemanager.Model.DownloadLink({
308                 node_id: selections[0].id,
309                 expiry_time: date,
310                 password: password
311             });
312             Tine.Filemanager.downloadLinkRecordBackend.saveRecord(record, {
313                 success: function (record) {
314                     // TODO: add mail-button
315                     Ext.MessageBox.show({
316                         title: selections[0].data.type == 'folder' ? app.i18n._('Folder has been published successfully') : app.i18n._('File has been published successfully'),
317                         msg: String.format(app.i18n._("Url: {0}") + '<br />' + app.i18n._("Valid Until: {1}"), record.get('url'), record.get('expiry_time')),
318                         minWidth: 900,
319                         buttons: Ext.Msg.OK,
320                         icon: Ext.MessageBox.INFO,
321                     });
322                 }, failure: Tine.Tinebase.ExceptionHandler.handleRequestException, scope: this
323             });
324         }, this);
325     },
326     actionUpdater: function(action, grants, records, isFilterSelect) {
327         var enabled = !isFilterSelect
328             && records && records.length == 1
329             && window.lodash.get(records, '[0].data.account_grants.publishGrant', false);
330
331         action.setDisabled(!enabled);
332     }
333 };
334
335 /**
336  * one or multiple file nodes currently uploaded
337  */
338 Tine.Filemanager.nodeActions.PauseUploadAction = {};
339
340 /**
341  * one or multiple file nodes currently upload paused
342  */
343 Tine.Filemanager.nodeActions.ResumeUploadAction = {};
344
345 /**
346  * one or multiple file nodes currently uploaded or upload paused
347  * @TODO deletes node as well?
348  */
349 Tine.Filemanager.nodeActions.CancelUploadAction = {};