]> BookStack Code Mirror - bookstack/blob - resources/assets/js/vues/image-manager.js
switch spaces to tabs
[bookstack] / resources / assets / js / vues / image-manager.js
1
2 import * as Dates from "../services/dates";
3
4 const dropzone = require('./components/dropzone');
5
6 let page = 0;
7 let previousClickTime = 0;
8 let previousClickImage = 0;
9 let dataLoaded = false;
10 let callback = false;
11 let baseUrl = '';
12
13 let preSearchImages = [];
14 let preSearchHasMore = false;
15
16 const data = {
17     images: [],
18
19     imageType: false,
20     uploadedTo: false,
21
22     selectedImage: false,
23     dependantPages: false,
24     showing: false,
25     view: 'all',
26     hasMore: false,
27     searching: false,
28     searchTerm: '',
29
30     imageUpdateSuccess: false,
31     imageDeleteSuccess: false,
32     deleteConfirm: false,
33 };
34
35 const methods = {
36
37     show(providedCallback, imageType = null) {
38         callback = providedCallback;
39         this.showing = true;
40         this.$el.children[0].components.overlay.show();
41
42         // Get initial images if they have not yet been loaded in.
43         if (dataLoaded && imageType === this.imageType) return;
44         if (imageType) {
45             this.imageType = imageType;
46             this.resetState();
47         }
48         this.fetchData();
49         dataLoaded = true;
50     },
51
52     hide() {
53         if (this.$refs.dropzone) {
54             this.$refs.dropzone.onClose();
55         }
56         this.showing = false;
57         this.selectedImage = false;
58         this.$el.children[0].components.overlay.hide();
59     },
60
61     fetchData() {
62         let url = baseUrl + page;
63         let query = {};
64         if (this.uploadedTo !== false) query.page_id = this.uploadedTo;
65         if (this.searching) query.term = this.searchTerm;
66
67         this.$http.get(url, {params: query}).then(response => {
68             this.images = this.images.concat(response.data.images);
69             this.hasMore = response.data.hasMore;
70             page++;
71         });
72     },
73
74     setView(viewName) {
75         this.view = viewName;
76         this.resetState();
77         this.fetchData();
78     },
79
80     resetState() {
81         this.cancelSearch();
82         this.images = [];
83         this.hasMore = false;
84         this.deleteConfirm = false;
85         page = 0;
86         baseUrl = window.baseUrl(`/images/${this.imageType}/${this.view}/`);
87     },
88
89     searchImages() {
90         if (this.searchTerm === '') return this.cancelSearch();
91
92         // Cache current settings for later
93         if (!this.searching) {
94             preSearchImages = this.images;
95             preSearchHasMore = this.hasMore;
96         }
97
98         this.searching = true;
99         this.images = [];
100         this.hasMore = false;
101         page = 0;
102         baseUrl = window.baseUrl(`/images/${this.imageType}/search/`);
103         this.fetchData();
104     },
105
106     cancelSearch() {
107         if (!this.searching) return;
108         this.searching = false;
109         this.searchTerm = '';
110         this.images = preSearchImages;
111         this.hasMore = preSearchHasMore;
112     },
113
114     imageSelect(image) {
115         let dblClickTime = 300;
116         let currentTime = Date.now();
117         let timeDiff = currentTime - previousClickTime;
118         let isDblClick = timeDiff < dblClickTime && image.id === previousClickImage;
119
120         if (isDblClick) {
121             this.callbackAndHide(image);
122         } else {
123             this.selectedImage = image;
124             this.deleteConfirm = false;
125             this.dependantPages = false;
126         }
127
128         previousClickTime = currentTime;
129         previousClickImage = image.id;
130     },
131
132     callbackAndHide(imageResult) {
133         if (callback) callback(imageResult);
134         this.hide();
135     },
136
137     saveImageDetails() {
138         let url = window.baseUrl(`/images/update/${this.selectedImage.id}`);
139         this.$http.put(url, this.selectedImage).then(response => {
140             this.$events.emit('success', trans('components.image_update_success'));
141         }).catch(error => {
142             if (error.response.status === 422) {
143                 let errors = error.response.data;
144                 let message = '';
145                 Object.keys(errors).forEach((key) => {
146                     message += errors[key].join('\n');
147                 });
148                 this.$events.emit('error', message);
149             }
150         });
151     },
152
153     deleteImage() {
154
155         if (!this.deleteConfirm) {
156             let url = window.baseUrl(`/images/usage/${this.selectedImage.id}`);
157             this.$http.get(url).then(resp => {
158                 this.dependantPages = resp.data;
159             }).catch(console.error).then(() => {
160                 this.deleteConfirm = true;
161             });
162             return;
163         }
164
165         this.$http.delete(`/images/${this.selectedImage.id}`).then(resp => {
166             this.images.splice(this.images.indexOf(this.selectedImage), 1);
167             this.selectedImage = false;
168             this.$events.emit('success', trans('components.image_delete_success'));
169             this.deleteConfirm = false;
170         });
171     },
172
173     getDate(stringDate) {
174         return Dates.formatDateTime(new Date(stringDate));
175     },
176
177     uploadSuccess(event) {
178         this.images.unshift(event.data);
179         this.$events.emit('success', trans('components.image_upload_success'));
180     },
181 };
182
183 const computed = {
184     uploadUrl() {
185         return window.baseUrl(`/images/${this.imageType}/upload`);
186     }
187 };
188
189 function mounted() {
190     window.ImageManager = this;
191     this.imageType = this.$el.getAttribute('image-type');
192     this.uploadedTo = this.$el.getAttribute('uploaded-to');
193     baseUrl = window.baseUrl('/images/' + this.imageType + '/all/')
194 }
195
196 module.exports = {
197     mounted,
198     methods,
199     data,
200     computed,
201     components: {dropzone},
202 };