5d22a0a3fbf2ae20321774747c48d96cc1eef56b
[kivitendo-erp.git] / js / kivi.ImageUpload.js
1 namespace("kivi.ImageUpload", function(ns) {
2   "use strict";
3
4   const MAXSIZE = 15*1024*1024; // 5MB size limit
5   const M = kivi.Materialize;
6
7   let num_images = 0;
8
9   ns.add_files = function(target) {
10     let files = [];
11     for (var i = 0; i < target.files.length; i++) {
12       files.push(target.files.item(i));
13     }
14
15     kivi.FileDB.store_image(files[0], files[0].name, () => {
16       ns.reload_images();
17       target.value = null;
18     });
19   };
20
21   ns.reload_images = function() {
22     kivi.FileDB.retrieve_all((data) => {
23       $('#stored-images').empty();
24       num_images = data.length;
25
26       data.forEach(ns.create_thumb_row);
27       ns.set_image_button_enabled();
28     });
29   };
30
31   ns.create_thumb_row = function(file)  {
32     let URL = window.URL || window.webkitURL;
33     let file_url = URL.createObjectURL(file);
34
35     let $row = $("<div>").addClass("row image-upload-row");
36     let $button = $("<a>")
37       .addClass("btn-floating btn-large waves-effect waves-light red")
38       .click((event) => ns.remove_image(event, file.name))
39       .append($("<i>delete</i>").addClass("material-icons"));
40     $row.append($("<div>").addClass("col s3").append($button));
41
42     let $image = $('<img>').attr("src", file_url).addClass("materialboxed responsive-img");
43     $row.append($("<div>").addClass("col s9").append($image));
44
45     $("#stored-images").append($row);
46   };
47
48   ns.remove_image = function(event, key) {
49     let $row = $(event.target).closest(".image-upload-row");
50     kivi.FileDB.delete_key(key, () => {
51       $row.remove();
52       num_images--;
53       ns.set_image_button_enabled();
54     });
55   };
56
57   ns.set_image_button_enabled = function() {
58     $('#upload_images_submit').attr("disabled", num_images == 0 || !$('#object_id').val());
59   };
60
61
62   ns.upload_files = function() {
63     let id = $('#object_id').val();
64     let type = $('#object_type').val();
65
66     ns.upload_selected_files(id, type, MAXSIZE);
67   };
68
69   ns.upload_selected_files = function(id, type, maxsize) {
70     $("#upload_modal").modal("open");
71
72     kivi.FileDB.retrieve_all((myfiles) => {
73       let filesize  = 0;
74       myfiles.forEach(file => {
75         filesize  += file.size;
76         if (filesize > maxsize) {
77           M.flash(kivi.t8("filesize too big: ") + ns.format_si(filesize) + kivi.t8(" > ") + ns.format_si(maxsize));
78           $("#upload_modal").modal("close");
79           return;
80         }
81
82         let data = new FormData();
83         data.append("uploadfiles[]", file);
84         data.append("action", "File/ajax_files_uploaded");
85         data.append("json", "1");
86         data.append("object_type", type);
87         data.append("object_id", id);
88         data.append("file_type", "attachment");
89
90         $("#upload_result").html(kivi.t8("start upload"));
91
92         let xhr = new XMLHttpRequest;
93         xhr.open('POST', 'controller.pl', true);
94         xhr.onload = ns.attSuccess;
95         xhr.upload.onprogress = ns.attProgress;
96         xhr.upload.onerror = ns.attFailed;
97         xhr.upload.onabort = ns.attCanceled;
98         xhr.send(data);
99       });
100     });
101   };
102
103   ns.attProgress = function(event) {
104     if (event.lengthComputable) {
105       var percent_complete = (event.loaded / event.total) * 100;
106       $("#upload_progress div").removeClass("indeterminate").addClass("determinate").attr("style", "width: " + percent_complete + "%");
107     }
108   };
109
110   ns.attFailed = function() {
111     $('#upload_modal').modal('close');
112     M.flash(kivi.t8("An error occurred while transferring the file."));
113   };
114
115   ns.attCanceled = function() {
116     $('#upload_modal').modal('close');
117     M.flash(kivi.t8("The transfer has been canceled by the user."));
118   };
119
120   ns.attSuccess = function() {
121     $('#upload_modal').modal('close');
122     M.flash(kivi.t8("Files have been uploaded successfully."));
123     kivi.FileDB.delete_all(ns.reload_images);
124   };
125
126   ns.resolve_object = function(event) {
127     let obj_type = $('#object_type').val();
128     let number   = event.target.value;
129
130     $.ajax({
131       url: "controller.pl",
132       data: {
133         action: "ImageUpload/resolve_object_by_number",
134         object_type: obj_type,
135         object_number: number
136       },
137       type: "json",
138       success: (json) => {
139         if (json.error) {
140           $("#object_description").html("");
141           $("#object_id").val("");
142         } else {
143           $("#object_description").html(json.description);
144           $("#object_id").val(json.id);
145         }
146         ns.set_image_button_enabled();
147       },
148       error: () => {
149         $("#object_description").html("");
150         $("#object_id").val("");
151         ns.set_image_button_enabled();
152       }
153     });
154   };
155
156   /* this tries to format the number human readable. 3 significant digits, si suffix, */
157   ns.format_si = function(n) {
158     const prefixes = ["", "K" , "M", "G", "T", "P"];
159     let i = 0;
160     while (n >= 1024) {
161       n /= 1024;
162       i++;
163     }
164
165     return kivi.format_amount(n, 3 - (n|0).toString().length) + prefixes[i] + "B";
166   };
167
168   ns.init = function() {
169     ns.reload_images();
170   };
171 });
172
173 $(kivi.ImageUpload.init);