· 7 years ago · Apr 12, 2018, 04:16 PM
1import Controller from "../../lib/controller"
2import {templates as JST} from "../../templates"
3import selectizeHelper from "../../helpers/selectize_helper"
4import confirmModal from "../../components/modals/confirm_modal"
5import stringHelper from "../../helpers/string_helper"
6import uploadProgressHelper from "../../helpers/upload_progress_helper"
7import AccessUploadBlock from "../../components/access/upload_block"
8import TagsEdit from "../../components/tags/tags_edit"
9
10var $ = window.jQuery;
11var allowedMimes = {};
12var allowedExtensions = {};
13
14export default class DocumentUploadController extends Controller {
15
16 constructor() {
17 super();
18 this.name = "document/upload";
19 this.allowedMimes = {};
20 this.allowedExtensions = {};
21 }
22
23 run() {
24 allowedMimes = this.allowedMimes;
25 allowedExtensions = this.allowedExtensions;
26
27 $('input[autocomplete="off"]').attr('autocomplete', 'false');
28 $('#DocumentUploadForm_name').focus();
29
30 $('#submit_trigger').click(function (e) {
31 if ($(this).hasClass('disabled')) {
32 e.stopImmediatePropagation();
33 return false;
34 } else {
35 $('.main-wrapper').addClass('cursor-wait');
36 $(this).addClass('disbled');
37 }
38 });
39
40 // show optional description
41 $('#show_description').click(function (e) {
42 e.preventDefault();
43 $('#document_description').toggleClass('hidden');
44 });
45
46 reloadSubtypes();
47
48 uploadToS3();
49
50 (new AccessUploadBlock('DocumentUploadForm')).run();
51 (new TagsEdit()).initTags({
52 formName: 'DocumentUploadForm'
53 });
54 googleDrivePicker();
55
56 manageTypes();
57 }
58}
59
60function manageTypes() {
61 $("#choose_type li.document").on("click", function (e) {
62 e.preventDefault();
63 var active = $(this);
64 if ($('#choose_type li.active').data('type') == active.data('type')) {
65 return false;
66 }
67
68 if ($('.document-row:not(.active)').length) {
69 var confirmBody = 'Are you sure you want to delete all uploaded files?';
70 confirmModal("Change type", confirmBody, function () {
71 var container = $('#filesContainer');
72 container.html('');
73 changeType(active);
74 });
75 } else {
76 changeType(active);
77 }
78 });
79
80 changeType($("#choose_type li.active"));
81
82 function changeType(active) {
83 $("#choose_type li").removeClass("active");
84 active.addClass('active');
85 var type = active.data("type");
86 $("#DocumentUploadForm_type").val(type);
87 $("#DocumentUploadForm_type").trigger("change");
88 if (type == app.DOCUMENT.TYPE_IMAGE) {
89 $(".alert-wrapper").show();
90 } else {
91 $(".alert-wrapper").hide();
92 }
93 changeAlertTypes(type);
94 }
95}
96
97function changeAlertTypes(type) {
98 $('.alert-types .alert-type').addClass('hidden');
99 $('.alert-types .alert-type[data-type="' + type + '"]').removeClass('hidden');
100}
101
102function reloadSubtypes() {
103 var type = $("#DocumentUploadForm_type").val();
104 var $select = $("#DocumentUploadForm_subtype");
105
106 if ('undefined' == typeof type) {
107 return;
108 }
109
110 var options = $select.data('options');
111 var subtypesToTypes = $select.data('subtypes_to_types');
112 var subtypeIds = subtypesToTypes[type];
113
114 $select.empty();
115
116 $select.append(
117 $('<option/>').text('Choose a Category').val(null)
118 );
119 $.map(options, function (option) {
120 if ($.inArray(option.id, subtypeIds) !== -1) {
121 $select.append(
122 $('<option/>').text(option.name).val(option.id)
123 );
124 }
125 });
126 $select.selectpicker('refresh')
127}
128
129function uploadToS3() {
130
131 // @todo
132 // $('.file-pickers').addClass('disabled');
133
134 if ($("#filesContainer").children().length > 0) {
135 $('#submit_trigger').removeClass('disabled');
136 $('.main-wrapper').removeClass('cursor-wait');
137 }
138
139 $('.dragdrop').on('dragenter', function (e) {
140 e.preventDefault();
141 });
142 $('.dragdrop').on('dragover', function () {
143 $(this).addClass('drag-over');
144 });
145 $('.dragdrop').on('dragleave', function () {
146 $(this).removeClass('drag-over');
147 });
148
149 $('#progressBlock').hide();
150
151 var uploadedFilesCounter = 0;
152 $('#file_upload').fileupload({
153 autoUpload: false,
154 maxNumberOfFiles: 30,
155 dropZone: $(".dragdrop"),
156 dataType: 'xml',
157 }).on('fileuploadadd', function (e, data) {
158 setDocumentError(null);
159
160 var file = data.files[0];
161 var fileGuid = stringHelper.guid();
162
163 let contentType = $("#DocumentUploadForm_type").val();
164 let allowedTypeExtensions = allowedExtensions[contentType];
165
166 // we have a bug here for dock upload and pptx file. Mime application/vnd.openxmlformats-officedocument.presentationml.presentation
167 // will be work for doc extension
168 let checkTypeRegExp = new RegExp('(\.|\/)(' + allowedTypeExtensions.join('|') + ')', 'i');
169 if (!(checkTypeRegExp.test(file.type) || checkTypeRegExp.test(file.name))) {
170 setDocumentError("It appears the filetype is not supported or the file is locked. <br /> " +
171 "File extensions types that are supplied and accepted are: " + allowedTypeExtensions.join(", "));
172 return false;
173 }
174
175 addFileItem({
176 guid: fileGuid,
177 name: file.name
178 });
179
180
181 $('#submit_trigger').addClass('disabled');
182
183
184 data.fileGuid = fileGuid;
185 $.ajax({
186 url: "/document-s3/sign",
187 type: 'POST',
188 dataType: 'json',
189 data: {
190 name: file.name
191 },
192 beforeSend: function () {
193 if (uploadedFilesCounter == 0) {
194 setDocumentError(null);
195 }
196 uploadedFilesCounter++;
197 },
198 error: function () {
199 //cancelUpload(fileGuid);
200 },
201 success: function (sign) {
202 var $form = $('#file_upload_form');
203 $.each(sign, function (key, value) {
204 $form.find('input[name=' + key + ']').val(value);
205 });
206 $form.find('input[name="Content-Type"]').val(file.type);
207
208 var xhr = data.submit().success(function (result) {
209 var key = $(result).find('Key').text();
210 $.ajax({
211 url: "/document-s3/create",
212 type: 'POST',
213 dataType: 'json',
214 data: {
215 key: key
216 },
217 error: function () {
218 //cancelUpload(fileGuid);
219 },
220 success: function (s3Document) {
221 $('#submit_trigger').removeClass('disabled');
222 $('.main-wrapper').removeClass('cursor-wait');
223 var $file = $("#document_" + fileGuid);
224 $file.find(".document_s3_id").val(s3Document.id);
225 $file.next().hide();
226 }
227 });
228 });
229
230 }
231 });
232 return true;
233 }).on('fileuploadfail', function (e, data) {
234 // stop progress
235 $('#progressBlock').hide();
236 $('#submit_trigger').removeClass('disabled');
237 $('.main-wrapper').removeClass('cursor-wait');
238
239 }).on('fileuploadsend', function (e, data) {
240
241 var fileGuid = data.fileGuid;
242 var $file = $("#document_" + fileGuid);
243 var $progressBlock = $file.next();
244
245 $progressBlock.show();
246
247 $progressBlock.find('.progress')
248 .attr('aria-valuenow', 0)
249 .children().first().css('width', 0 + '%');
250
251 }).on('fileuploadprogress', function (e, data) {
252
253 var fileGuid = data.fileGuid;
254 var $file = $("#document_" + fileGuid);
255 var $progressBlock = $file.next();
256
257 var percent = Math.round((data.loaded / data.total) * 100);
258 var speed = uploadProgressHelper.humanFileSize(data.bitrate / 8) + '/s';
259 var loaded = uploadProgressHelper.humanFileSize(data.loaded);
260
261 $progressBlock.find('.speed').text(speed);
262 $progressBlock.find('.loaded').text(loaded);
263 $progressBlock.find('.percent').text(percent + '%');
264
265 $progressBlock.find('.progress')
266 .attr('aria-valuenow', percent)
267 .children().first().css('width', percent + '%');
268 }).on('fileuploadfail', function (e, data) {
269 // stop progress
270 var fileGuid = data.fileGuid;
271 var $file = $("#document_" + fileGuid);
272 $file.find('.progressBlock').hide();
273 });
274
275 $(".dragdrop").on('click', function () {
276 $("#file_upload").trigger("click");
277 });
278
279 $(document).on('click', ".document-row .remove", function (e) {
280 var $row = $(this).parent('.document-row');
281 var confirmBody = 'Are you sure you want to delete this file?';
282 confirmModal("Delete File", confirmBody, function () {
283 if ($row.next().attr('id') == 'progressBlock') {
284 $row.next().remove();
285 }
286 $row.remove();
287 });
288
289 return false;
290 });
291
292 $(document).on('click', ".document-row .change", function (e) {
293 var $row = $(this).parent('.document-row');
294 $row.find('input').select();
295 return false;
296 });
297
298 $("#DocumentUploadForm_type").on("change", function () {
299 $("#file_container .delete-file").trigger("click");
300 $("#file_container .cancel button").trigger("click");
301 $("#file_container").empty();
302 reloadSubtypes();
303 });
304}
305
306
307function googleDrivePicker() {
308
309 var pickerApiLoaded = false;
310 var authApiLoaded = false;
311 var oauthToken;
312 var picker;
313 var authBtn = $("#picker");
314
315 loadPicker();
316
317 authBtn.click(function () {
318 pickData();
319 });
320
321 function loadPicker() {
322 gapi.load('auth', {callback: onAuthApiLoad});
323 gapi.load('picker', {callback: onPickerApiLoad});
324 }
325
326 function pickData() {
327 authBtn.button('loading');
328
329 if (!oauthToken) {
330 var options = {
331 client_id: window.google_client_id,
332 scope: [
333 'https://www.googleapis.com/auth/drive.file',
334 'https://www.googleapis.com/auth/drive.readonly'
335 ],
336 immediate: false
337 };
338
339 gapi.auth.authorize(options, function (authResult) {
340 if (authResult && !authResult.error) {
341 handleAuthResult(authResult);
342 }
343 });
344 } else {
345 createPicker();
346 }
347
348 setTimeout(function () {
349 authBtn.button('reset');
350 }, 1);
351 }
352
353 function onAuthApiLoad() {
354 authApiLoaded = true;
355 }
356
357 function onPickerApiLoad() {
358 pickerApiLoaded = true;
359 }
360
361 function handleAuthResult(authResult) {
362 if (authResult && !authResult.error) {
363 oauthToken = authResult.access_token;
364 createPicker();
365 }
366 }
367
368 // Create and render a Picker object for searching images.
369 function createPicker() {
370 if (pickerApiLoaded && authApiLoaded && oauthToken) {
371 //var view = new google.picker.View(google.picker.ViewId.DOCS);
372 var view = new google.picker.DocsView();
373 view.setIncludeFolders(true);
374 view.setMimeTypes(getMimes().join(','));
375
376 picker = new google.picker.PickerBuilder()
377 .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
378 .setOrigin(window.location.protocol + '//' + window.location.host)
379 .setOAuthToken(oauthToken)
380 .setMaxItems(100)
381 .addView(view)
382 .setTitle(getPickerTitle())
383 .setCallback(onPicked)
384 .build();
385
386 showPicker();
387 }
388 }
389
390
391 function getPickerTitle() {
392 var documentType = $("#DocumentUploadForm_type").val();
393 switch (parseInt(documentType)) {
394 case app.DOCUMENT.TYPE_SIMPLE_DOCUMENT:
395 return 'Select document';
396 case app.DOCUMENT.TYPE_PRESENTATION:
397 return 'Select deck';
398 case app.DOCUMENT.TYPE_VIDEO:
399 return 'Select video';
400 case app.DOCUMENT.TYPE_IMAGE:
401 return 'Select creative';
402 }
403 }
404
405 function getMimes() {
406 var documentType = $("#DocumentUploadForm_type").val();
407 documentType = parseInt(documentType);
408 if (typeof allowedMimes[documentType] !== 'undefined') {
409 return allowedMimes[documentType];
410 } else {
411 return [];
412 }
413 }
414
415
416 function onPicked(data) {
417 if (data.action == google.picker.Action.PICKED) {
418 $.each(data.docs, function (index, file) {
419 gapi.client.load('drive', 'v2', function () {
420 var request = gapi.client.drive.files.get({
421 fileId: file.id
422 });
423
424 request.execute(function (resp) {
425 googleDrivePicked(resp, oauthToken);
426 });
427 });
428 });
429 }
430 }
431
432 function showPicker() {
433 picker.setVisible(true);
434 $("#picker").button('reset');
435 }
436
437 /**
438 * Callback for google drive picker
439 * @param data
440 */
441 function googleDrivePicked(file, oauthToken) {
442
443 setDocumentError(null);
444 $('.file-pickers').addClass('disabled');
445
446
447 var exportMimes = [];
448 if (typeof file.exportLinks !== 'undefined') {
449 exportMimes = Object.keys(file.exportLinks);
450 }
451
452 $.ajax({
453 url: "/document-s3/upload-from-gd",
454 type: 'POST',
455 dataType: 'json',
456 //async: true,
457 data: {
458 file_id: file.id,
459 access_token: oauthToken,
460 export_mimes: exportMimes
461 },
462 success: function (s3Document) {
463 $('#progressBlock').hide();
464
465 if ('undefined' !== typeof s3Document && s3Document.error) {
466 $('.file-pickers').removeClass('disabled');
467 setDocumentError(s3Document.error);
468 return;
469 } else {
470
471 addFileItem({
472 guid: stringHelper.guid(),
473 name: s3Document.name,
474 document_s3_id: s3Document.id
475 });
476 }
477 }
478 });
479 }
480}
481
482function setDocumentError(text) {
483 if (text == "File type not allowed") {
484 var allowedFileTypesString = '',
485 contentType = $("#DocumentUploadForm_type").val();
486
487 if (allowedExtensions[contentType]) {
488 allowedFileTypesString = allowedExtensions[contentType].join(', ').toUpperCase();
489 }
490
491 text = "It appears the filetype is not supported or the file is locked. <br /> Check your file properties and try again or upload as a " + allowedFileTypesString + ".";
492 }
493 $("#file_error_text").html(text);
494 if (text) {
495 $(".file-error").show();
496 } else {
497 $(".file-error").hide();
498 }
499}
500
501
502function addFileItem(data) {
503 var container = $('#filesContainer');
504
505 //data.canDeleteFile = $(".document-row").length > 0;
506 data.canDeleteFile = true;
507
508 var fileRow = JST['document/upload_file'](data);
509 container.append(fileRow);
510
511
512 var fileRow = $('.document-row.active', fcontainer);
513
514 if (fileRow.length && typeof data != 'undefined') {
515 fileRow.removeClass('active');
516 $(".name", fileRow).val(data.name);
517 $(".document_s3_id", fileRow).val(data.document_s3_id).trigger('change');
518 fileRow.find('input').focus();
519 }
520}