6bf6a5d3236517279537990c28d4fda1de9ec1ba
[qcg-portal.git] / qcg / templates / qcg / gridftp.html
1 {% extends 'qcg/base.html' %}
2 {% load staticfiles bootstrap3 %}
3
4 {% block extra_css %}
5     <link href="{% static 'qcg/selectize/selectize.bootstrap3.css' %}" rel="stylesheet">
6 {% endblock %}
7
8 {% block extra_js %}
9     <script src="{% static 'qcg/cookie/jquery.cookie.min.js' %}"></script>
10     <script src="{% static 'qcg/globals.js' %}"></script>
11     {% include 'filex/source.js.html' %}
12
13     <script>
14         var filex = filex || {};
15
16         $(function () {
17             'use strict';
18
19             filex.initialLoad();
20
21             var statusTimeout;
22
23             String.prototype.endsWith = function(suffix) {
24                 return this.indexOf(suffix, this.length - suffix.length) !== -1;
25             };
26
27             function status(msg) {
28                 clearTimeout(statusTimeout);
29                 statusTimeout = setTimeout(function() {
30                     $('#status').text('');
31                 }, 3000);
32
33                 $('#status').text(msg);
34             }
35
36             function failModal(msg) {
37                 return function(xhr) {
38                     var $errorModal = $('#error-modal');
39
40                     $errorModal.find('#error-modal-label').text('Błąd serwera');
41                     $errorModal.find('.modal-body').html($('<h4>', {text: msg}));
42
43                     var error = (xhr.responseJSON || {}).error || undefined;
44
45                     if (typeof error === 'string')
46                         $errorModal.find('.modal-body').append($('<pre>', {text: error}));
47
48                     filex.idle();
49                     $errorModal.modal();
50
51                     console.error(arguments);
52                 };
53             }
54
55             function conflictingName(name, modal) {
56                 if (filex.files.some(function(item) { return item.get('name') == name })) {
57                     $('<div>', {
58                         'class': 'alert alert-danger',
59                         html: '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> Plik o podanej już nazwie istnieje!'
60                     }).prependTo(modal.find('.modal-body'));
61
62                     return true;
63                 }
64
65                 return false;
66             }
67
68             filex.files.on('change:checked reset', function() {
69                 var selected = filex.selectedFiles().length;
70
71                 $('#btn-rename').toggleClass('disabled', selected != 1);
72                 $('#btn-delete').toggleClass('disabled', selected == 0);
73                 $('#btn-compress').toggleClass('disabled', filex.host != 'moss.man.poznan.pl' || selected == 0);
74
75                 if (filex.host == 'moss.man.poznan.pl' && selected == 1) {
76                     var filename = filex.selectedFiles()[0].get('name'),
77                         is_archive = _.some(['.zip', '.tar.gz', '.tgz', '.tar.bz2', 'tbz'], function(ext) {
78                             return filename.endsWith(ext);
79                         });
80
81                     $('#btn-extract').toggleClass('disabled', !is_archive);
82                 }
83                 else {
84                     $('#btn-extract').addClass('disabled');
85                 }
86             });
87
88             $('form').on('show.bs.modal', function() {
89                 $(this).find('.alert').remove();
90                 this.reset();
91             }).on('shown.bs.modal', function() {
92                 $(this).find('input[type="text"]')[0].focus();
93             });
94
95             $('#btn-upload').on('click', function() {
96                 var url = '{% url 'gridftp_upload' %}?' + $.param({host: filex.host, path: filex.path.full()});
97
98                 var win = window.open(url, url, 'height=500,width=800');
99                 win.focus();
100             });
101
102             $('#btn-delete').on('click', function() {
103                 var selected = _.groupBy(filex.selectedFiles(), function(item) { return item.get('type') }),
104                     path = filex.path.full() + '/',
105                     dirs = _.map(selected.directory || [], function (item) { return path + item.get('name') }),
106                     files = _.map(selected.file || [], function (item) { return path + item.get('name') }),
107                     data = {
108                         host: filex.host,
109                         dirs: dirs,
110                         files: files
111                     },
112                     $confirmModal = $('#confirm-modal'),
113                     $confirmList = $confirmModal.find('ul').html('');
114
115                 _.each(filex.selectedFiles(), function(item) {
116                     $('<li>', {text: item.get('name')}).appendTo($confirmList);
117                 });
118
119                 $('#btn-confirm').off().on('click', function() {
120                     filex.busy();
121
122                     $.post('{% url 'filex:delete' %}', data, function(response) {
123                         var keys = Object.keys(response.fail);
124
125                         if (keys.length) {
126                             var $errorModal = $('#error-modal'),
127                                 $errorBody = $errorModal.find('.modal-body')
128                                                         .html($('<h4>', {text: 'Wystąpiły problemy podczas usuwania:'})),
129                                 $errorList = $('<dl>', {'class': 'dl-horizontal'}).appendTo($errorBody);
130
131                             $errorModal.find('#error-modal-label').text('Błąd');
132
133                             for (var i in keys) {
134                                 if(keys.hasOwnProperty(i)) {
135                                     $('<dt>', {text: keys[i].replace(path, '')}).appendTo($errorList);
136                                     $('<dd>', {text: response.fail[keys[i]]}).appendTo($errorList);
137                                 }
138                             }
139
140                             $errorModal.modal();
141                             filex.idle();
142                         }
143                         else {
144                             status('Usuwanie zakończone pomyślnie');
145                         }
146
147                         if (response.done.length)
148                             filex.reloadFiles();
149
150                     }, 'json').fail(failModal('Nie udało się usunąć plików'));
151
152                     $confirmModal.modal('hide');
153                 });
154
155                 $confirmModal.modal();
156             });
157
158             $('#mkdir-form').on('submit', function(e) {
159                 var $this = $(this);
160
161                 e.preventDefault();
162
163                 if (conflictingName($this.find('#id_name').val(), $this))
164                     return;
165
166                 filex.busy();
167                 $this.modal('hide');
168
169                 $this.find('#id_host').val(filex.host);
170                 $this.find('#id_path').val(filex.path.full());
171
172                 $.post($this.attr('action'), $this.serialize(), function() {
173                     status('Katalog utworzono pomyślnie');
174                     filex.reloadFiles();
175                 }, 'json').fail(failModal('Nie udało się utworzyć katalogu'));
176             });
177
178             $('#rename-form').on('show.bs.modal', function() {
179                 $(this).find('#id_dst').val(filex.selectedFiles()[0].get('name'));
180             }).on('submit', function(e) {
181                 e.preventDefault();
182
183                 var $this = $(this),
184                     path = filex.path.full() + '/',
185                     newName = $this.find('#id_dst').val(),
186                     data = {
187                         host: filex.host,
188                         src: path + filex.selectedFiles()[0].get('name'),
189                         dst: path + newName
190                     };
191
192                 if (conflictingName(newName, $this))
193                     return;
194
195                 filex.busy();
196                 $this.modal('hide');
197
198                 $.post($this.attr('action'), data, function() {
199                     status('Nazwę zmieniono pomyślnie');
200                     filex.reloadFiles();
201                 }, 'json').fail(failModal('Nie udało się zmienić nazwy'));
202             });
203
204             $('#compress-form').on('submit', function(e) {
205                 e.preventDefault();
206
207                 var $this = $(this),
208                     name = $this.find('#id_archive').val(),
209                     type = $this.find('#id_type').val(),
210                     path = filex.path.full(),
211                     archive = name + (name.endsWith(type) ? '' : type),
212                     data = {
213                         host: filex.host,
214                         path: path,
215                         files: _.map(filex.selectedFiles(), function (item) { return item.get('name') }),
216                         archive: path  + '/' + archive
217                     };
218
219                 if (conflictingName(archive, $this))
220                     return;
221
222                 filex.busy();
223                 $this.modal('hide');
224
225                 $.post($this.attr('action'), data, function() {
226                     status('Archiwum utworzono pomyślnie');
227                     filex.reloadFiles();
228                 }, 'json').fail(failModal('Nie udało się utworzyć archiwum'));
229             });
230
231             $('#btn-extract').on('click', function() {
232                 filex.busy();
233
234                 var data = {
235                     host: filex.host,
236                     path: filex.path.full() + '/' + filex.selectedFiles()[0].get('name'),
237                     dst: filex.path.full()
238                 };
239
240                 $.post('{% url 'filex:extract' %}', data, function() {
241                     status('Archiwum rozpakowano pomyślnie');
242                     filex.reloadFiles();
243                 }, 'json').fail(failModal('Nie udało się rozpakować archiwum'));
244             });
245         })
246     </script>
247 {% endblock extra_js %}
248
249 {% block title %}Zarządzanie plikami GridFTP{% endblock %}
250
251 {% block container %}
252     {% include 'filex/source.html' %}
253
254     <div id="confirm-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-label" aria-hidden="true">
255         <div class="modal-dialog">
256             <div class="modal-content">
257                 <div class="modal-header">
258                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
259                         <span aria-hidden="true">&times;</span>
260                     </button>
261                     <h4 class="modal-title" id="confirm-modal-label">Usuwanie plików</h4>
262                 </div>
263                 <div class="modal-body">
264                     <h4>Czy na pewno usunąć następujące elementy?</h4>
265                     <ul></ul>
266                 </div>
267                 <div class="modal-footer">
268                     <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
269                     <button id="btn-confirm" type="button" class="btn btn-primary">OK</button>
270                 </div>
271             </div>
272         </div>
273     </div>
274
275     <div id="error-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="error-modal-label" aria-hidden="true">
276         <div class="modal-dialog">
277             <div class="modal-content">
278                 <div class="modal-header">
279                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
280                         <span aria-hidden="true">&times;</span>
281                     </button>
282                     <h4 class="modal-title" id="error-modal-label"></h4>
283                 </div>
284                 <div class="modal-body">
285                 </div>
286                 <div class="modal-footer">
287                     <button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>
288                 </div>
289             </div>
290         </div>
291     </div>
292
293     <form id="mkdir-form" action="{% url 'filex:mkdir' %}" class="modal fade form-horizontal" tabindex="-1" role="dialog" aria-labelledby="mkdir-modal-label" aria-hidden="true">
294         <div class="modal-dialog">
295             <div class="modal-content">
296                 <div class="modal-header">
297                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
298                         <span aria-hidden="true">&times;</span>
299                     </button>
300                     <h4 class="modal-title" id="mkdir-modal-label">Nowy katalog</h4>
301                 </div>
302                 <div class="modal-body">
303                     {% csrf_token %}
304                     {% bootstrap_form new_dir_form layout='horizontal' %}
305                 </div>
306                 <div class="modal-footer">
307                     <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
308                     <button type="submit" class="btn btn-primary">OK</button>
309                 </div>
310             </div>
311         </div>
312     </form>
313
314     <form id="rename-form" action="{% url 'filex:move' %}" class="modal fade form-horizontal" tabindex="-1" role="dialog" aria-labelledby="rename-modal-label" aria-hidden="true">
315         <div class="modal-dialog">
316             <div class="modal-content">
317                 <div class="modal-header">
318                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
319                         <span aria-hidden="true">&times;</span>
320                     </button>
321                     <h4 class="modal-title" id="rename-modal-label">Zmień nazwę</h4>
322                 </div>
323                 <div class="modal-body">
324                     {% csrf_token %}
325                     {% bootstrap_form rename_form layout='horizontal' %}
326                 </div>
327                 <div class="modal-footer">
328                     <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
329                     <button type="submit" class="btn btn-primary">OK</button>
330                 </div>
331             </div>
332         </div>
333     </form>
334
335     <form id="compress-form" action="{% url 'filex:compress' %}" class="modal fade form-horizontal" tabindex="-1" role="dialog" aria-labelledby="compress-modal-label" aria-hidden="true">
336         <div class="modal-dialog">
337             <div class="modal-content">
338                 <div class="modal-header">
339                     <button type="button" class="close" data-dismiss="modal" aria-label="Close">
340                         <span aria-hidden="true">&times;</span>
341                     </button>
342                     <h4 class="modal-title" id="compress-modal-label">Podaj nazwę archiwum</h4>
343                 </div>
344                 <div class="modal-body">
345                     {% csrf_token %}
346                     {% bootstrap_form archive_form layout='horizontal' %}
347                 </div>
348                 <div class="modal-footer">
349                     <button type="button" class="btn btn-default" data-dismiss="modal">Anuluj</button>
350                     <button type="submit" class="btn btn-primary">OK</button>
351                 </div>
352             </div>
353         </div>
354     </form>
355 {% endblock container %}
356
357 {% block footer %}
358     <footer class="navbar navbar-default navbar-fixed-bottom" style="position:fixed">
359         <div class="container">
360             <div class="btn-toolbar" role="toolbar" style="float: left">
361                 <div class="btn-group" role="group">
362                     <button id="btn-upload" class="btn btn-default navbar-btn">Wgraj plik</button>
363                     <button class="btn btn-default navbar-btn" data-toggle="modal" data-target="#mkdir-form">Utwórz katalog</button>
364                 </div>
365                 <div class="btn-group" role="group">
366                     <button id="btn-rename" class="btn btn-default navbar-btn disabled" data-toggle="modal" data-target="#rename-form">Zmień nazwę</button>
367                     <button id="btn-delete" class="btn btn-default navbar-btn disabled">Usuń</button>
368                 </div>
369                 <div class="btn-group" role="group">
370                     <button id="btn-compress" class="btn btn-default navbar-btn disabled" data-toggle="modal" data-target="#compress-form">Spakuj</button>
371                     <button id="btn-extract" class="btn btn-default navbar-btn disabled">Rozpakuj</button>
372                 </div>
373             </div>
374             <p id="status" class="navbar-text"></p>
375         </div>
376     </footer>
377 {% endblock footer %}