]> BookStack Code Mirror - bookstack/blob - resources/assets/js/directives.js
Improved error messages for image uploads and formatted much js
[bookstack] / resources / assets / js / directives.js
1 "use strict";
2 var DropZone = require('dropzone');
3
4 var toggleSwitchTemplate = require('./components/toggle-switch.html');
5 var imagePickerTemplate = require('./components/image-picker.html');
6 var dropZoneTemplate = require('./components/drop-zone.html');
7
8 module.exports = function (ngApp) {
9
10     /**
11      * Toggle Switches
12      * Has basic on/off functionality.
13      * Use string values of 'true' & 'false' to dictate the current state.
14      */
15     ngApp.directive('toggleSwitch', function () {
16         return {
17             restrict: 'E',
18             template: toggleSwitchTemplate,
19             scope: true,
20             link: function (scope, element, attrs) {
21                 scope.name = attrs.name;
22                 scope.value = attrs.value;
23                 scope.isActive = scope.value == true && scope.value != 'false';
24                 scope.value = (scope.value == true && scope.value != 'false') ? 'true' : 'false';
25
26                 scope.switch = function () {
27                     scope.isActive = !scope.isActive;
28                     scope.value = scope.isActive ? 'true' : 'false';
29                 }
30
31             }
32         };
33     });
34
35
36     /**
37      * Image Picker
38      * Is a simple front-end interface that connects to an ImageManager if present.
39      */
40     ngApp.directive('imagePicker', ['$http', 'imageManagerService', function ($http, imageManagerService) {
41         return {
42             restrict: 'E',
43             template: imagePickerTemplate,
44             scope: {
45                 name: '@',
46                 resizeHeight: '@',
47                 resizeWidth: '@',
48                 resizeCrop: '@',
49                 showRemove: '=',
50                 currentImage: '@',
51                 currentId: '@',
52                 defaultImage: '@',
53                 imageClass: '@'
54             },
55             link: function (scope, element, attrs) {
56                 var usingIds = typeof scope.currentId !== 'undefined' || scope.currentId === 'false';
57                 scope.image = scope.currentImage;
58                 scope.value = scope.currentImage || '';
59
60                 function setImage(imageModel, imageUrl) {
61                     scope.image = imageUrl;
62                     scope.value = usingIds ? imageModel.id : imageUrl;
63                 }
64
65                 scope.reset = function () {
66                     setImage({id: 0}, scope.defaultImage);
67                 };
68
69                 scope.remove = function () {
70                     scope.image = 'none';
71                     scope.value = 'none';
72                 };
73
74                 scope.showImageManager = function () {
75                     imageManagerService.show((image) => {
76                         scope.updateImageFromModel(image);
77                     });
78                 };
79
80                 scope.updateImageFromModel = function (model) {
81                     var isResized = scope.resizeWidth && scope.resizeHeight;
82
83                     if (!isResized) {
84                         scope.$apply(() => {
85                             setImage(model, model.url);
86                         });
87                         return;
88                     }
89
90                     var cropped = scope.resizeCrop ? 'true' : 'false';
91                     var requestString = '/images/thumb/' + model.id + '/' + scope.resizeWidth + '/' + scope.resizeHeight + '/' + cropped;
92                     $http.get(requestString).then((response) => {
93                         setImage(model, response.data.url);
94                     });
95                 };
96
97             }
98         };
99     }]);
100
101     /**
102      * DropZone
103      * Used for uploading images
104      */
105     ngApp.directive('dropZone', [function () {
106         return {
107             restrict: 'E',
108             template: dropZoneTemplate,
109             scope: {
110                 uploadUrl: '@',
111                 eventSuccess: '=',
112                 eventError: '='
113             },
114             link: function (scope, element, attrs) {
115                 var dropZone = new DropZone(element[0].querySelector('.dropzone-container'), {
116                     url: scope.uploadUrl,
117                     init: function () {
118                         var dz = this;
119                         dz.on('sending', function (file, xhr, data) {
120                             var token = window.document.querySelector('meta[name=token]').getAttribute('content');
121                             data.append('_token', token);
122                         });
123                         if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess);
124                         dz.on('success', function (file, data) {
125                             $(file.previewElement).fadeOut(400, function () {
126                                 dz.removeFile(file);
127                             });
128                         });
129                         if (typeof scope.eventError !== 'undefined') dz.on('error', scope.eventError);
130                         dz.on('error', function (file, errorMessage, xhr) {
131                             console.log(errorMessage);
132                             console.log(xhr);
133                             function setMessage(message) {
134                                 $(file.previewElement).find('[data-dz-errormessage]').text(message);
135                             }
136
137                             if (xhr.status === 413) setMessage('The server does not allow uploads of this size. Please try a smaller file.');
138                             if (errorMessage.file) setMessage(errorMessage.file[0]);
139
140                         });
141                     }
142                 });
143             }
144         };
145     }]);
146
147
148     ngApp.directive('dropdown', [function () {
149         return {
150             restrict: 'A',
151             link: function (scope, element, attrs) {
152                 var menu = element.find('ul');
153                 element.find('[dropdown-toggle]').on('click', function () {
154                     menu.show().addClass('anim menuIn');
155                     element.mouseleave(function () {
156                         menu.hide();
157                         menu.removeClass('anim menuIn');
158                     });
159                 });
160             }
161         };
162     }]);
163
164
165 };