2018-05-27 23:37:03 +01:00
|
|
|
<template>
|
2018-08-26 22:05:10 +01:00
|
|
|
<div class="content-box animate fadein">
|
2018-08-14 06:58:58 +01:00
|
|
|
<div class="filemanager-breadcrumbs">
|
|
|
|
/<span class="px-1">home</span><!--
|
|
|
|
-->/<router-link :to="{ name: 'server-files' }" class="px-1">container</router-link><!--
|
|
|
|
--><span v-for="crumb in breadcrumbs" class="inline-block">
|
|
|
|
<span v-if="crumb.path">
|
|
|
|
/<router-link :to="{ name: 'server-files', params: { path: crumb.path } }" class="px-1">{{crumb.directoryName}}</router-link>
|
|
|
|
</span>
|
|
|
|
<span v-else>
|
|
|
|
/<span class="px-1 font-semibold">{{crumb.directoryName}}</span>
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
</div>
|
2018-08-04 06:32:01 +01:00
|
|
|
<div v-if="loading">
|
|
|
|
<div class="spinner spinner-xl blue"></div>
|
|
|
|
</div>
|
2018-08-14 05:06:11 +01:00
|
|
|
<div v-else-if="!loading && errorMessage">
|
|
|
|
<div class="alert error" v-text="errorMessage"></div>
|
|
|
|
</div>
|
2018-08-04 06:32:01 +01:00
|
|
|
<div class="filemanager" v-else>
|
|
|
|
<div class="header">
|
|
|
|
<div class="flex-none w-8"></div>
|
|
|
|
<div class="flex-1">Name</div>
|
|
|
|
<div class="flex-1 text-right">Size</div>
|
|
|
|
<div class="flex-1 text-right">Modified</div>
|
|
|
|
<div class="flex-none w-1/6">Actions</div>
|
|
|
|
</div>
|
2018-08-14 06:58:58 +01:00
|
|
|
<div v-if="!directories.length && !files.length">
|
|
|
|
<p class="text-grey text-sm text-center p-6 pb-4">This directory is empty.</p>
|
2018-08-04 06:32:01 +01:00
|
|
|
</div>
|
2018-08-14 06:58:58 +01:00
|
|
|
<div v-else>
|
2018-08-15 05:17:10 +01:00
|
|
|
<div v-for="directory in directories">
|
|
|
|
<file-manager-folder-row :directory="directory"/>
|
|
|
|
</div>
|
|
|
|
<div v-for="file in files">
|
|
|
|
<file-manager-file-row :file="file" :editable="editableFiles" />
|
2018-08-04 06:32:01 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2018-05-27 23:37:03 +01:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2018-09-24 00:06:23 +01:00
|
|
|
// @flow
|
|
|
|
import map from 'lodash/map';
|
|
|
|
import { mapState } from 'vuex';
|
|
|
|
import type { Route } from 'vue-router';
|
|
|
|
import FileManagerFileRow from '../components/filemanager/FileManagerFileRow';
|
|
|
|
import FileManagerFolderRow from '../components/filemanager/FileManagerFolderRow';
|
|
|
|
import { getDirectoryContents, DirectoryContentsResponse } from '../../../api/server/getDirectoryContents';
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'file-manager-page',
|
|
|
|
components: { FileManagerFolderRow, FileManagerFileRow },
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
...mapState('server', ['server', 'credentials']),
|
|
|
|
...mapState('socket', ['connected']),
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configure the breadcrumbs that display on the filemanager based on the directory that the
|
|
|
|
* user is currently in.
|
|
|
|
*/
|
|
|
|
breadcrumbs: function (): Array<Object> {
|
|
|
|
const directories: Array<string> = this.currentDirectory.replace(/^\/|\/$/, '').split('/');
|
|
|
|
if (directories.length < 1 || !directories[0]) {
|
|
|
|
return [];
|
|
|
|
}
|
2018-08-14 06:58:58 +01:00
|
|
|
|
2018-09-24 00:06:23 +01:00
|
|
|
return map(directories, function (value: string, key: number) {
|
|
|
|
if (key === directories.length - 1) {
|
|
|
|
return { directoryName: value };
|
2018-08-14 06:58:58 +01:00
|
|
|
}
|
|
|
|
|
2018-09-24 00:06:23 +01:00
|
|
|
return {
|
|
|
|
directoryName: value,
|
|
|
|
path: directories.slice(0, key + 1).join('/'),
|
|
|
|
};
|
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
/**
|
|
|
|
* When the route changes reload the directory.
|
|
|
|
*/
|
|
|
|
'$route': function (to: Route) {
|
|
|
|
this.currentDirectory = to.params.path || '/';
|
2018-08-04 06:32:01 +01:00
|
|
|
},
|
|
|
|
|
2018-09-24 00:06:23 +01:00
|
|
|
/**
|
|
|
|
* Watch the current directory setting and when it changes update the file listing.
|
|
|
|
*/
|
|
|
|
currentDirectory: function (): void {
|
|
|
|
this.listDirectory();
|
|
|
|
},
|
2018-08-14 06:58:58 +01:00
|
|
|
|
2018-09-24 00:06:23 +01:00
|
|
|
/**
|
|
|
|
* When we reconnect to the Daemon make sure we grab a listing of all of the files
|
|
|
|
* so that the error message disappears and we then load in a fresh listing.
|
|
|
|
*/
|
|
|
|
connected: function (): void {
|
|
|
|
if (this.connected) {
|
2018-08-07 07:14:13 +01:00
|
|
|
this.listDirectory();
|
2018-08-14 05:06:11 +01:00
|
|
|
}
|
2018-08-07 07:14:13 +01:00
|
|
|
},
|
2018-09-24 00:06:23 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
data: function () {
|
|
|
|
return {
|
|
|
|
currentDirectory: this.$route.params.path || '/',
|
|
|
|
loading: true,
|
|
|
|
errorMessage: null,
|
|
|
|
|
|
|
|
directories: [],
|
|
|
|
editableFiles: [],
|
|
|
|
files: [],
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
mounted: function () {
|
|
|
|
this.listDirectory();
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
/**
|
|
|
|
* List the contents of a directory.
|
|
|
|
*/
|
|
|
|
listDirectory: function (): void {
|
|
|
|
this.loading = true;
|
|
|
|
|
|
|
|
const directory: string = encodeURI(this.currentDirectory.replace(/^\/|\/$/, ''));
|
|
|
|
getDirectoryContents(this.$route.params.id, directory)
|
|
|
|
.then((response: DirectoryContentsResponse) => {
|
|
|
|
this.files = response.files;
|
|
|
|
this.directories = response.directories;
|
|
|
|
this.editableFiles = response.editable;
|
|
|
|
this.errorMessage = null;
|
|
|
|
})
|
|
|
|
.catch((err: string|Object) => {
|
|
|
|
if (err instanceof String) {
|
|
|
|
this.errorMessage = err;
|
|
|
|
return;
|
|
|
|
}
|
2018-08-07 07:14:13 +01:00
|
|
|
|
2018-09-24 00:06:23 +01:00
|
|
|
console.error('An error was encountered while processing this request.', { err });
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
this.loading = false;
|
|
|
|
});
|
2018-08-04 06:32:01 +01:00
|
|
|
},
|
2018-09-24 00:06:23 +01:00
|
|
|
},
|
|
|
|
};
|
2018-08-04 06:32:01 +01:00
|
|
|
</script>
|