Translated using Weblate (Korean)
[phpmyadmin.git] / js / drag_drop_import.js
blob8b35e24152adbe66d4a8cf14e0c77f1bd6c63c17
2 /* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
4 /**
5  * Class to handle PMA Drag and Drop Import
6  *      feature
7  */
8 var DragDropImport = {
9     /**
10      * @var int, count of total uploads in this view
11      */
12     uploadCount: 0,
13     /**
14      * @var int, count of live uploads
15      */
16     liveUploadCount: 0,
17     /**
18      * @var string array, allowed extensions
19      */
20     allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'],
21     /**
22      * @var string array, allowed extensions for compressed files
23      */
24     allowedCompressedExtensions: ['gz', 'bz2', 'zip'],
25     /**
26      * @var obj array to store message returned by /import-status
27      */
28     importStatus: [],
29     /**
30      * Checks if any dropped file has valid extension or not
31      *
32      * @param file filename
33      *
34      * @return string, extension for valid extension, '' otherwise
35      */
36     getExtension: function (file) {
37         var arr = file.split('.');
38         var ext = arr[arr.length - 1];
40         // check if compressed
41         if (jQuery.inArray(ext.toLowerCase(),
42             DragDropImport.allowedCompressedExtensions) !== -1) {
43             ext = arr[arr.length - 2];
44         }
46         // Now check for extension
47         if (jQuery.inArray(ext.toLowerCase(),
48             DragDropImport.allowedExtensions) !== -1) {
49             return ext;
50         }
51         return '';
52     },
53     /**
54      * Shows upload progress for different sql uploads
55      *
56      * @param: hash (string), hash for specific file upload
57      * @param: percent (float), file upload percentage
58      *
59      * @return void
60      */
61     setProgress: function (hash, percent) {
62         $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
63             .children('progress').val(percent);
64     },
65     /**
66      * Function to upload the file asynchronously
67      *
68      * @param formData FormData object for a specific file
69      * @param hash hash of the current file upload
70      *
71      * @return void
72      */
73     sendFileToServer: function (formData, hash) {
74         var jqXHR = $.ajax({
75             xhr: function () {
76                 var xhrobj = $.ajaxSettings.xhr();
77                 if (xhrobj.upload) {
78                     xhrobj.upload.addEventListener('progress', function (event) {
79                         var percent = 0;
80                         var position = event.loaded || event.position;
81                         var total = event.total;
82                         if (event.lengthComputable) {
83                             percent = Math.ceil(position / total * 100);
84                         }
85                         // Set progress
86                         DragDropImport.setProgress(hash, percent);
87                     }, false);
88                 }
89                 return xhrobj;
90             },
91             url: 'index.php?route=/import',
92             type: 'POST',
93             contentType:false,
94             processData: false,
95             cache: false,
96             data: formData,
97             success: function (data) {
98                 DragDropImport.importFinished(hash, false, data.success);
99                 if (!data.success) {
100                     DragDropImport.importStatus[DragDropImport.importStatus.length] = {
101                         hash: hash,
102                         message: data.error
103                     };
104                 }
105             }
106         });
108         // -- provide link to cancel the upload
109         $('.pma_sql_import_status div li[data-hash="' + hash +
110             '"] span.filesize').html('<span hash="' +
111             hash + '" class="pma_drop_file_status" task="cancel">' +
112             Messages.dropImportMessageCancel + '</span>');
114         // -- add event listener to this link to abort upload operation
115         $('.pma_sql_import_status div li[data-hash="' + hash +
116             '"] span.filesize span.pma_drop_file_status')
117             .on('click', function () {
118                 if ($(this).attr('task') === 'cancel') {
119                     jqXHR.abort();
120                     $(this).html('<span>' + Messages.dropImportMessageAborted + '</span>');
121                     DragDropImport.importFinished(hash, true, false);
122                 } else if ($(this).children('span').html() ===
123                     Messages.dropImportMessageFailed) {
124                     // -- view information
125                     var $this = $(this);
126                     $.each(DragDropImport.importStatus,
127                         function (key, value) {
128                             if (value.hash === hash) {
129                                 $('.pma_drop_result:visible').remove();
130                                 var filename = $this.parent('span').attr('data-filename');
131                                 $('body').append('<div class="pma_drop_result"><h2>' +
132                                 Messages.dropImportImportResultHeader + ' - ' +
133                                 filename + '<span class="close">x</span></h2>' + value.message + '</div>');
134                                 $('.pma_drop_result').draggable();  // to make this dialog draggable
135                             }
136                         });
137                 }
138             });
139     },
140     /**
141      * Triggered when an object is dragged into the PMA UI
142      *
143      * @param event obj
144      *
145      * @return void
146      */
147     dragEnter : function (event) {
148         // We don't want to prevent users from using
149         // browser's default drag-drop feature on some page(s)
150         if ($('.noDragDrop').length !== 0) {
151             return;
152         }
154         event.stopPropagation();
155         event.preventDefault();
156         if (!DragDropImport.hasFiles(event)) {
157             return;
158         }
159         if (CommonParams.get('db') === '') {
160             $('.pma_drop_handler').html(Messages.dropImportSelectDB);
161         } else {
162             $('.pma_drop_handler').html(Messages.dropImportDropFiles);
163         }
164         $('.pma_drop_handler').fadeIn();
165     },
166     /**
167      * Check if dragged element contains Files
168      *
169      * @param event the event object
170      *
171      * @return bool
172      */
173     hasFiles: function (event) {
174         return !(typeof event.originalEvent.dataTransfer.types === 'undefined' ||
175             $.inArray('Files', event.originalEvent.dataTransfer.types) < 0 ||
176             $.inArray(
177                 'application/x-moz-nativeimage',
178                 event.originalEvent.dataTransfer.types
179             ) >= 0);
180     },
181     /**
182      * Triggered when dragged file is being dragged over PMA UI
183      *
184      * @param event obj
185      *
186      * @return void
187      */
188     dragOver: function (event) {
189         // We don't want to prevent users from using
190         // browser's default drag-drop feature on some page(s)
191         if ($('.noDragDrop').length !== 0) {
192             return;
193         }
195         event.stopPropagation();
196         event.preventDefault();
197         if (!DragDropImport.hasFiles(event)) {
198             return;
199         }
200         $('.pma_drop_handler').fadeIn();
201     },
202     /**
203      * Triggered when dragged objects are left
204      *
205      * @param event obj
206      *
207      * @return void
208      */
209     dragLeave: function (event) {
210         // We don't want to prevent users from using
211         // browser's default drag-drop feature on some page(s)
212         if ($('.noDragDrop').length !== 0) {
213             return;
214         }
215         event.stopPropagation();
216         event.preventDefault();
217         var $dropHandler = $('.pma_drop_handler');
218         $dropHandler.clearQueue().stop();
219         $dropHandler.fadeOut();
220         $dropHandler.html(Messages.dropImportDropFiles);
221     },
222     /**
223      * Called when upload has finished
224      *
225      * @param string, unique hash for a certain upload
226      * @param bool, true if upload was aborted
227      * @param bool, status of sql upload, as sent by server
228      *
229      * @return void
230      */
231     importFinished: function (hash, aborted, status) {
232         $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
233             .children('progress').hide();
234         var icon = 'icon ic_s_success';
235         // -- provide link to view upload status
236         if (!aborted) {
237             if (status) {
238                 $('.pma_sql_import_status div li[data-hash="' + hash +
239                    '"] span.filesize span.pma_drop_file_status')
240                     .html('<span>' + Messages.dropImportMessageSuccess + '</a>');
241             } else {
242                 $('.pma_sql_import_status div li[data-hash="' + hash +
243                    '"] span.filesize span.pma_drop_file_status')
244                     .html('<span class="underline">' + Messages.dropImportMessageFailed +
245                    '</a>');
246                 icon = 'icon ic_s_error';
247             }
248         } else {
249             icon = 'icon ic_s_notice';
250         }
251         $('.pma_sql_import_status div li[data-hash="' + hash +
252             '"] span.filesize span.pma_drop_file_status')
253             .attr('task', 'info');
255         // Set icon
256         $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
257             .prepend('<img src="./themes/dot.gif" title="finished" class="' +
258             icon + '"> ');
260         // Decrease liveUploadCount by one
261         $('.pma_import_count').html(--DragDropImport.liveUploadCount);
262         if (!DragDropImport.liveUploadCount) {
263             $('.pma_sql_import_status h2 .close').fadeIn();
264         }
265     },
266     /**
267      * Triggered when dragged objects are dropped to UI
268      * From this function, the AJAX Upload operation is initiated
269      *
270      * @param event object
271      *
272      * @return void
273      */
274     drop: function (event) {
275         // We don't want to prevent users from using
276         // browser's default drag-drop feature on some page(s)
277         if ($('.noDragDrop').length !== 0) {
278             return;
279         }
281         var dbname = CommonParams.get('db');
282         var server = CommonParams.get('server');
284         // if no database is selected -- no
285         if (dbname !== '') {
286             var files = event.originalEvent.dataTransfer.files;
287             if (!files || files.length === 0) {
288                 // No files actually transferred
289                 $('.pma_drop_handler').fadeOut();
290                 event.stopPropagation();
291                 event.preventDefault();
292                 return;
293             }
294             $('.pma_sql_import_status').slideDown();
295             for (var i = 0; i < files.length; i++) {
296                 var ext  = (DragDropImport.getExtension(files[i].name));
297                 var hash = AJAX.hash(++DragDropImport.uploadCount);
299                 var $sqlImportStatusDiv = $('.pma_sql_import_status div');
300                 $sqlImportStatusDiv.append('<li data-hash="' + hash + '">' +
301                     ((ext !== '') ? '' : '<img src="./themes/dot.gif" title="invalid format" class="icon ic_s_notice"> ') +
302                     Functions.escapeHtml(files[i].name) + '<span class="filesize" data-filename="' +
303                     Functions.escapeHtml(files[i].name) + '">' + (files[i].size / 1024).toFixed(2) +
304                     ' kb</span></li>');
306                 // scroll the UI to bottom
307                 $sqlImportStatusDiv.scrollTop(
308                     $sqlImportStatusDiv.scrollTop() + 50
309                 );  // 50 hardcoded for now
311                 if (ext !== '') {
312                     // Increment liveUploadCount by one
313                     $('.pma_import_count').html(++DragDropImport.liveUploadCount);
314                     $('.pma_sql_import_status h2 .close').fadeOut();
316                     $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
317                         .append('<br><progress max="100" value="2"></progress>');
319                     // uploading
320                     var fd = new FormData();
321                     fd.append('import_file', files[i]);
322                     fd.append('noplugin', Math.random().toString(36).substring(2, 12));
323                     fd.append('db', dbname);
324                     fd.append('server', server);
325                     fd.append('token', CommonParams.get('token'));
326                     fd.append('import_type', 'database');
327                     // todo: method to find the value below
328                     fd.append('MAX_FILE_SIZE', '4194304');
329                     // todo: method to find the value below
330                     fd.append('charset_of_file','utf-8');
331                     // todo: method to find the value below
332                     fd.append('allow_interrupt', 'yes');
333                     fd.append('skip_queries', '0');
334                     fd.append('format',ext);
335                     fd.append('sql_compatibility','NONE');
336                     fd.append('sql_no_auto_value_on_zero','something');
337                     fd.append('ajax_request','true');
338                     fd.append('hash', hash);
340                     // init uploading
341                     DragDropImport.sendFileToServer(fd, hash);
342                 } else if (!DragDropImport.liveUploadCount) {
343                     $('.pma_sql_import_status h2 .close').fadeIn();
344                 }
345             }
346         }
347         $('.pma_drop_handler').fadeOut();
348         event.stopPropagation();
349         event.preventDefault();
350     }
354  * Called when some user drags, dragover, leave
355  *       a file to the PMA UI
356  * @param object Event data
357  * @return void
358  */
359 $(document).on('dragenter', DragDropImport.dragEnter);
360 $(document).on('dragover', DragDropImport.dragOver);
361 $(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave);
363 // when file is dropped to PMA UI
364 $(document).on('drop', 'body', DragDropImport.drop);
366 // minimizing-maximising the sql ajax upload status
367 $(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
368     if ($(this).attr('toggle') === 'off') {
369         $('.pma_sql_import_status div').css('height','270px');
370         $(this).attr('toggle','on');
371         $(this).html('-');  // to minimize
372     } else {
373         $('.pma_sql_import_status div').css('height','0px');
374         $(this).attr('toggle','off');
375         $(this).html('+');  // to maximise
376     }
379 // closing sql ajax upload status
380 $(document).on('click', '.pma_sql_import_status h2 .close', function () {
381     $('.pma_sql_import_status').fadeOut(function () {
382         $('.pma_sql_import_status div').html('');
383         DragDropImport.importStatus = [];  // clear the message array
384     });
387 // Closing the import result box
388 $(document).on('click', '.pma_drop_result h2 .close', function () {
389     $(this).parent('h2').parent('div').remove();