diff --git a/app/agent/components/volume-browser/volume-browser.js b/app/agent/components/volume-browser/index.js similarity index 57% rename from app/agent/components/volume-browser/volume-browser.js rename to app/agent/components/volume-browser/index.js index 5c2b2b78d..e52633a51 100644 --- a/app/agent/components/volume-browser/volume-browser.js +++ b/app/agent/components/volume-browser/index.js @@ -1,6 +1,10 @@ +import angular from 'angular'; + +import { VolumeBrowserController } from './volumeBrowserController'; + angular.module('portainer.agent').component('volumeBrowser', { templateUrl: './volumeBrowser.html', - controller: 'VolumeBrowserController', + controller: VolumeBrowserController, bindings: { volumeId: '<', nodeName: '<', diff --git a/app/agent/components/volume-browser/volumeBrowser.html b/app/agent/components/volume-browser/volumeBrowser.html index 5b85cfd94..c94a285bb 100644 --- a/app/agent/components/volume-browser/volumeBrowser.html +++ b/app/agent/components/volume-browser/volumeBrowser.html @@ -9,7 +9,7 @@ browse="$ctrl.browse(name)" rename="$ctrl.rename(name, newName)" download="$ctrl.download(name)" - delete="$ctrl.delete(name)" + delete="$ctrl.confirmDelete(name)" is-upload-allowed="$ctrl.isUploadEnabled" on-file-selected-for-upload="($ctrl.onFileSelectedForUpload)" > diff --git a/app/agent/components/volume-browser/volumeBrowserController.js b/app/agent/components/volume-browser/volumeBrowserController.js index fccde7753..faa3fc7e5 100644 --- a/app/agent/components/volume-browser/volumeBrowserController.js +++ b/app/agent/components/volume-browser/volumeBrowserController.js @@ -1,137 +1,152 @@ import _ from 'lodash-es'; -angular.module('portainer.agent').controller('VolumeBrowserController', [ - 'HttpRequestHelper', - 'VolumeBrowserService', - 'FileSaver', - 'Blob', - 'ModalService', - 'Notifications', - function (HttpRequestHelper, VolumeBrowserService, FileSaver, Blob, ModalService, Notifications) { - var ctrl = this; - +export class VolumeBrowserController { + constructor($async, HttpRequestHelper, VolumeBrowserService, FileSaver, Blob, ModalService, Notifications) { + Object.assign(this, { $async, HttpRequestHelper, VolumeBrowserService, FileSaver, Blob, ModalService, Notifications }); this.state = { path: '/', }; - this.rename = function (file, newName) { - var filePath = this.state.path === '/' ? file : this.state.path + '/' + file; - var newFilePath = this.state.path === '/' ? newName : this.state.path + '/' + newName; + this.rename = this.rename.bind(this); + this.renameAsync = this.renameAsync.bind(this); + this.confirmDelete = this.confirmDelete.bind(this); + this.download = this.download.bind(this); + this.downloadAsync = this.downloadAsync.bind(this); + this.up = this.up.bind(this); + this.browse = this.browse.bind(this); + this.deleteFile = this.deleteFile.bind(this); + this.deleteFileAsync = this.deleteFileAsync.bind(this); + this.getFilesForPath = this.getFilesForPath.bind(this); + this.getFilesForPathAsync = this.getFilesForPathAsync.bind(this); + this.onFileSelectedForUpload = this.onFileSelectedForUpload.bind(this); + this.onFileSelectedForUploadAsync = this.onFileSelectedForUploadAsync.bind(this); + this.parentPath = this.parentPath.bind(this); + this.buildPath = this.buildPath.bind(this); + this.$onInit = this.$onInit.bind(this); + this.onFileUploaded = this.onFileUploaded.bind(this); + this.refreshList = this.refreshList.bind(this); + } - VolumeBrowserService.rename(this.volumeId, filePath, newFilePath) - .then(function success() { - Notifications.success('File successfully renamed', newFilePath); - return VolumeBrowserService.ls(ctrl.volumeId, ctrl.state.path); - }) - .then(function success(data) { - ctrl.files = data; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to rename file'); - }); - }; + rename(file, newName) { + return this.$async(this.renameAsync, file, newName); + } + async renameAsync(file, newName) { + const filePath = this.state.path === '/' ? file : `${this.state.path}/${file}`; + const newFilePath = this.state.path === '/' ? newName : `${this.state.path}/${newName}`; - this.delete = function (file) { - var filePath = this.state.path === '/' ? file : this.state.path + '/' + file; - - ModalService.confirmDeletion('Are you sure that you want to delete ' + filePath + ' ?', function onConfirm(confirmed) { - if (!confirmed) { - return; - } - deleteFile(filePath); - }); - }; - - this.download = function (file) { - var filePath = this.state.path === '/' ? file : this.state.path + '/' + file; - VolumeBrowserService.get(this.volumeId, filePath) - .then(function success(data) { - var downloadData = new Blob([data.file]); - FileSaver.saveAs(downloadData, file); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to download file'); - }); - }; - - this.up = function () { - var parentFolder = parentPath(this.state.path); - browse(parentFolder); - }; - - this.browse = function (folder) { - var path = buildPath(this.state.path, folder); - browse(path); - }; - - function deleteFile(file) { - VolumeBrowserService.delete(ctrl.volumeId, file) - .then(function success() { - Notifications.success('File successfully deleted', file); - return VolumeBrowserService.ls(ctrl.volumeId, ctrl.state.path); - }) - .then(function success(data) { - ctrl.files = data; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to delete file'); - }); + try { + await this.VolumeBrowserService.rename(this.volumeId, filePath, newFilePath); + this.Notifications.success('File successfully renamed', newFilePath); + this.files = await this.VolumeBrowserService.ls(this.volumeId, this.state.path); + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to rename file'); } + } - function browse(path) { - VolumeBrowserService.ls(ctrl.volumeId, path) - .then(function success(data) { - ctrl.state.path = path; - ctrl.files = data; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to browse volume'); - }); - } + confirmDelete(file) { + const filePath = this.state.path === '/' ? file : `${this.state.path}/${file}`; - this.onFileSelectedForUpload = function onFileSelectedForUpload(file) { - VolumeBrowserService.upload(ctrl.state.path, file, ctrl.volumeId) - .then(function onFileUpload() { - onFileUploaded(); - }) - .catch(function onFileUpload(err) { - Notifications.error('Failure', err, 'Unable to upload file'); - }); - }; - - function parentPath(path) { - if (path.lastIndexOf('/') === 0) { - return '/'; + this.ModalService.confirmDeletion(`Are you sure that you want to delete ${filePath} ?`, (confirmed) => { + if (!confirmed) { + return; } + this.deleteFile(filePath); + }); + } - var split = _.split(path, '/'); - return _.join(_.slice(split, 0, split.length - 1), '/'); + download(file) { + return this.$async(this.downloadAsync, file); + } + async downloadAsync(file) { + const filePath = this.state.path === '/' ? file : `${this.state.path}/${file}`; + + try { + const data = await this.VolumeBrowserService.get(this.volumeId, filePath); + const downloadData = new Blob([data.file]); + this.FileSaver.saveAs(downloadData, file); + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to download file'); + } + } + + up() { + const parentFolder = this.parentPath(this.state.path); + this.getFilesForPath(parentFolder); + } + + browse(folder) { + const path = this.buildPath(this.state.path, folder); + this.getFilesForPath(path); + } + + deleteFile(file) { + return this.$async(this.deleteFileAsync, file); + } + async deleteFileAsync(file) { + try { + await this.VolumeBrowserService.delete(this.volumeId, file); + this.Notifications.success('File successfully deleted', file); + this.files = await this.VolumeBrowserService.ls(this.volumeId, this.state.path); + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to delete file'); + } + } + + getFilesForPath(path) { + return this.$async(this.getFilesForPathAsync, path); + } + async getFilesForPathAsync(path) { + try { + const files = await this.VolumeBrowserService.ls(this.volumeId, path); + this.state.path = path; + this.files = files; + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to browse volume'); + } + } + + onFileSelectedForUpload(file) { + return this.$async(this.onFileSelectedForUploadAsync, file); + } + async onFileSelectedForUploadAsync(file) { + try { + await this.VolumeBrowserService.upload(this.state.path, file, this.volumeId); + this.onFileUploaded(); + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to upload file'); + } + } + + parentPath(path) { + if (path.lastIndexOf('/') === 0) { + return '/'; } - function buildPath(parent, file) { - if (parent === '/') { - return parent + file; - } - return parent + '/' + file; - } + const split = _.split(path, '/'); + return _.join(_.slice(split, 0, split.length - 1), '/'); + } - this.$onInit = function () { - HttpRequestHelper.setPortainerAgentTargetHeader(this.nodeName); - VolumeBrowserService.ls(this.volumeId, this.state.path) - .then(function success(data) { - ctrl.files = data; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to browse volume'); - }); - }; - - function onFileUploaded() { - refreshList(); + buildPath(parent, file) { + if (parent === '/') { + return parent + file; } + return `${parent}/${file}`; + } - function refreshList() { - browse(ctrl.state.path); + onFileUploaded() { + this.refreshList(); + } + + refreshList() { + this.getFilesForPath(this.state.path); + } + + async $onInit() { + this.HttpRequestHelper.setPortainerAgentTargetHeader(this.nodeName); + try { + this.files = await this.VolumeBrowserService.ls(this.volumeId, this.state.path); + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to browse volume'); } - }, -]); + } +}