--- /dev/null
+(function() {
+ "use strict";
+
+ angular.module("nero.app")
+ .controller("FileSelectorController", FileSelectorController);
+
+ FileSelectorController.$inject = ["$uibModalInstance", "toastr", "fileSelectorService", "parameters", "$scope"];
+
+ /**
+ File picker window
+
+ parameters :
+ - maxFileNumber : (Optionnal - default = -1) Integer that represent the max file number that can be added, -1 means no limit
+ - authorizedExtensions : (Optionnal - default = []) Array containing the list of autorized file extensions
+ - isBase64Expected : (Optionnal - default = false) Boolean set to true when expected base64 in return (images)
+ - isThumbnailPicker : (Optionnal - default = false) If true then we activate the image crop view on selection
+ */
+ function FileSelectorController($uibModalInstance, toastr, fileSelectorService, parameters, $scope) {
+
+ var vm = this;
+
+ // Methods
+ vm.onValidate = onValidate;
+ vm.onCancel = onCancel;
+ vm.add = add;
+ vm.remove = remove;
+ vm.getFilesTree = getFilesTree;
+ vm.mapFile = mapFile;
+ vm.selectNode = selectNode;
+ vm.expandNode = expandNode;
+ vm.uploadFile = uploadFile;
+ vm.addDisabled = false;
+ vm.isExtensionsLimited = isExtensionsLimited;
+ vm.authorizedExtensions = "*";
+ if (vm.isExtensionsLimited()) {
+ vm.authorizedExtensions = "." + parameters.authorizedExtensions.join(",.");
+ }
+
+ //Thumbnail picker infos
+ vm.isThumbnailPicker = parameters.isThumbnailPicker || false;
+ vm.selectedImage = {};
+ vm.croppedImg = "";
+
+ // Variables
+ vm.maxSize = 100;
+ vm.attachFiles = [];
+ vm.selectedFile = {
+ fileId: 0
+ };
+
+ vm.maxFileNumber = -1;
+ if (parameters.maxFileNumber != undefined) {
+ vm.maxFileNumber = parameters.maxFileNumber;
+ }
+
+ // Init the files tree
+ vm.fileList = [];
+ initFileSelector();
+
+ // Example of nodes
+ // vm.fileList = [
+ // {
+ // "fileName": "Espace de travail",
+ // "fileId": 123,
+ // "expanded": false,
+ // "children": []
+ // },
+ // {
+ // "fileName": "Casier",
+ // "fileId": 456,
+ // "expanded": false,
+ // "children": []
+ // }
+ // ];
+
+ /**
+ * Get the maximum size for file upload, then load the tree
+ */
+ function initFileSelector() {
+ fileSelectorService.getMaxSize()
+ .then(function(data) {
+ vm.maxSize = data.uploadMaxSize;
+ getFilesTree();
+ });
+ }
+
+ /**
+ * Get the child files and folders from a given fileId
+ * - if fileId = 0 : get dropbox and 'My documents' root folder Ids
+ * - if fileId = 0 : get the fileId or the folderId child files
+ */
+ function getFilesTree() {
+ fileSelectorService.getFilesTree(vm.selectedFile.fileId)
+ .then(function(data) {
+ var formattedFiles = [];
+ var index;
+ for (index = 0; index < data.files.length; index++) {
+ var file = data.files[index];
+
+ var fileExtension = "";
+ if (file.leaf) {
+ var fileExtension = file.text.substr(file.text.lastIndexOf('.') + 1).toLowerCase();
+ }
+
+ if (!file.leaf || !vm.isExtensionsLimited() || parameters.authorizedExtensions.indexOf(fileExtension) != -1) {
+ // Format json structure
+ var formattedFile = mapFile(file);
+ formattedFiles.push(formattedFile);
+ }
+ }
+
+ // Root tree
+ if (vm.selectedFile.fileId == 0) {
+ vm.fileList.push.apply(vm.fileList, formattedFiles);
+ } else {
+ // Add files in json tree
+ vm.selectedFile.children = formattedFiles;
+ }
+
+ })
+ ["catch"](function(message) {
+ toastr.error(message);
+ });
+ }
+
+ /**
+ * Maps a JSON file object returned from backend with the angular-treeview-format
+ */
+ function mapFile(file) {
+ var formattedFile = {
+ "fileId": file.id,
+ "fileName": file.text,
+ "isSignet": file.isSignet,
+ "leaf": file.leaf,
+ "collapsed": true,
+ "customImage": file.iconCls
+ };
+ if (file.leaf) {
+ formattedFile.children = [];
+ }
+ return formattedFile;
+ }
+
+ /**
+ * Expand the node (folder) and prints the children
+ */
+ function expandNode(folder) {
+ vm.selectedFile = folder;
+ if (!vm.selectedFile.leaf) {
+ getFilesTree();
+ }
+ }
+
+ /**
+ * Selects a node in the tree
+ * Triggered by a simple click on a file or folder
+ */
+ function selectNode(file) {
+ vm.selectedFile = file;
+ }
+
+ /**
+ Get base64 from dropbox or schoolbag image to send it to image crop
+ */
+ function getImageBase64() {
+ vm.myPromise = fileSelectorService.getFileBase64(vm.attachFiles)
+ .then(function(data) {
+ vm.selectedImage = data.fileList[0];
+ //init the array, we add the image when it's cropped
+ vm.attachFiles = [];
+ })
+ ["catch"](function(message) {
+ toastr.error(message);
+ });
+ }
+
+ /**
+ * Add a file to the list of attached files (right column)
+ * Triggered by a click on button or by a double click on a file
+ */
+ function add() {
+ if (!vm.addDisabled && vm.selectedFile.leaf) {
+ vm.attachFiles.push(vm.selectedFile);
+
+ if (vm.isThumbnailPicker) {
+ getImageBase64();
+ }
+ else {
+ checkFileNumber();
+ }
+
+ vm.selectedFile = {
+ fileId: 0
+ };
+ }
+ }
+
+ /**
+ * Remove a file from the 'to attach' list
+ */
+ function remove(fileId) {
+ vm.attachFiles.forEach(function(result, index) {
+ if (result['fileId'] === fileId) {
+ vm.attachFiles.splice(index, 1);
+ }
+ });
+ checkFileNumber();
+ }
+
+ /**
+ * Upload a file from the local desktop, to the temporary folder
+ */
+ function uploadFile(model, input) {
+ var event = input.$event;
+ if (vm.isThumbnailPicker) {
+ var file = event.currentTarget.files[0];
+ var reader = new FileReader();
+ reader.onload = function (evt) {
+ $scope.$apply(function($scope){
+ vm.selectedImage.fileBase64 = evt.target.result;
+ vm.selectedImage.fileName = file.name;
+ });
+ };
+ reader.readAsDataURL(file);
+ }
+ else {
+ var file = event.target.files[0];
+ var fd = new FormData();
+ fd.append('files', file, file.name);
+
+ saveUploadedFile(fd);
+ }
+ };
+
+ /*
+ Return true if only several extension are allowed
+ */
+ function isExtensionsLimited() {
+ return (parameters.authorizedExtensions != undefined && parameters.authorizedExtensions.length > 0);
+ }
+
+ /*
+ Check if the selection limit has been reached
+ */
+ function checkFileNumber() {
+ if (vm.maxFileNumber != undefined && vm.maxFileNumber > 0) {
+ if (vm.attachFiles.length < vm.maxFileNumber) {
+ vm.addDisabled = false;
+ } else {
+ vm.addDisabled = true;
+ }
+ }
+ }
+
+ /**
+ Save the result thumbnail after the crop action
+ */
+ function handleCroppedThumbnail() {
+ var formData = new FormData();
+ var content = vm.croppedImg.split(",");
+
+ var binary_string = window.atob(content[1]);
+ var len = binary_string.length;
+ var bytes = new Uint8Array( len );
+ for (var i = 0; i < len; i++) {
+ bytes[i] = binary_string.charCodeAt(i);
+ }
+
+ var fileName = vm.selectedImage.fileName.substr(0, vm.selectedImage.fileName.lastIndexOf(".")) + ".png";
+
+ var fileOfBlob = new Blob([bytes.buffer], {type: "image/png"});
+ //var fileOfBlob = new File([bytes.buffer], fileName, {type: "image/png"});
+ formData.append("files", fileOfBlob, fileName);
+
+ saveUploadedFile(formData, true);
+ }
+
+ /**
+ Upload new file from user computer
+ */
+ function saveUploadedFile(formData, closeModal) {
+ vm.myPromise = fileSelectorService.uploadFile(formData)
+ .then(function(data) {
+ var uploadedFile = {
+ fileId: data.id,
+ fileName: data.name,
+ expanded: false,
+ children: []
+ };
+
+ vm.attachFiles.push(uploadedFile);
+ if (closeModal) {
+ closeAndResetModal();
+ }
+ else {
+ checkFileNumber();
+ }
+ });
+ }
+
+ /**
+ * On click ok button
+ */
+ function onValidate() {
+ if (vm.isThumbnailPicker) {
+ handleCroppedThumbnail();
+ }
+ else if (parameters.isBase64Expected) {
+ fileSelectorService.getFileBase64(vm.attachFiles)
+ .then(function(data) {
+ vm.attachFiles = data.fileList;
+ closeAndResetModal();
+ })
+ ["catch"](function(message) {
+ toastr.error(message);
+ });
+ }
+ else {
+ closeAndResetModal();
+ }
+ };
+
+ /*
+ Close modal after validation
+ */
+ function closeAndResetModal() {
+ $uibModalInstance.close(vm.attachFiles);
+
+ // Reset the attach files list
+ vm.attachFiles = [];
+ }
+
+ /**
+ * Cancel button clicked
+ */
+ function onCancel() {
+ $uibModalInstance.dismiss("cancel");
+ };
+
+ }
+})();