Migrate the rename action to follow better structure

This commit is contained in:
Dane Everitt 2019-03-10 15:44:49 -07:00
parent f3159bcec3
commit 3970a24218
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
5 changed files with 83 additions and 71 deletions

View file

@ -74,12 +74,11 @@
}, },
openRenameModal: function () { openRenameModal: function () {
window.events.$emit('server:files:rename', this.object); this.$emit('action:rename');
this.$emit('close');
}, },
openDeleteModal: function () { openDeleteModal: function () {
this.$emit('action:delete', this.object); this.$emit('action:delete');
} }
} }
}); });

View file

@ -31,10 +31,12 @@
:object="file" :object="file"
v-show="contextMenuVisible" v-show="contextMenuVisible"
v-on:close="contextMenuVisible = false" v-on:close="contextMenuVisible = false"
v-on:action:delete="showDeleteFileModal" v-on:action:delete="showModal('delete')"
v-on:action:rename="showModal('rename')"
ref="contextMenu" ref="contextMenu"
/> />
<DeleteFileModal :visible.sync="deleteModalVisible" :object="file" v-on:deleted="$emit('deleted')" v-on:close="deleteModalVisible = false"/> <DeleteFileModal :visible.sync="modals.delete" :object="file" v-on:deleted="$emit('deleted')" v-on:close="modal.delete = false"/>
<RenameModal :visible.sync="modals.rename" :object="file" v-on:renamed="$emit('renamed')" v-on:close="modal.rename = false"/>
</div> </div>
</template> </template>
@ -46,10 +48,17 @@
import FileContextMenu from "./FileContextMenu.vue"; import FileContextMenu from "./FileContextMenu.vue";
import {DirectoryContentObject} from "@/api/server/types"; import {DirectoryContentObject} from "@/api/server/types";
import DeleteFileModal from "@/components/server/components/filemanager/modals/DeleteFileModal.vue"; import DeleteFileModal from "@/components/server/components/filemanager/modals/DeleteFileModal.vue";
import RenameModal from "@/components/server/components/filemanager/modals/RenameModal.vue";
type DataStructure = {
currentDirectory: string,
contextMenuVisible: boolean,
modals: { [key: string]: boolean },
};
export default Vue.extend({ export default Vue.extend({
name: 'FileRow', name: 'FileRow',
components: {DeleteFileModal, Icon, FileContextMenu}, components: {DeleteFileModal, Icon, FileContextMenu, RenameModal},
props: { props: {
file: { file: {
@ -63,11 +72,14 @@
}, },
}, },
data: function () { data: function (): DataStructure {
return { return {
currentDirectory: this.$route.params.path || '/', currentDirectory: this.$route.params.path || '/',
contextMenuVisible: false, contextMenuVisible: false,
deleteModalVisible: false, modals: {
rename: false,
delete: false,
},
}; };
}, },
@ -89,9 +101,13 @@
}, },
methods: { methods: {
showDeleteFileModal: function () { showModal: function (name: string) {
console.warn('showModal', name);
this.contextMenuVisible = false; this.contextMenuVisible = false;
this.deleteModalVisible = true;
Object.keys(this.modals).forEach(k => {
this.modals[k] = k === name;
});
}, },
/** /**

View file

@ -1,5 +1,5 @@
<template> <template>
<Modal :show="isVisible" v-on:close="isVisible = false"> <Modal :show="isVisible" v-on:close="isVisible = false" :dismissable="!isLoading">
<MessageBox <MessageBox
class="alert error mb-8" class="alert error mb-8"
title="Error" title="Error"

View file

@ -1,10 +1,5 @@
<template> <template>
<Modal <Modal :show="isVisible" v-on:close="closeModal" :showCloseIcon="false" :dismissable="!isLoading">
:show="visible"
v-on:close="closeModal"
:showCloseIcon="false"
:dismissable="!isLoading"
>
<MessageBox <MessageBox
class="alert error mb-8" class="alert error mb-8"
title="Error" title="Error"
@ -18,6 +13,7 @@
</label> </label>
<input <input
type="text" class="input" name="element_name" type="text" class="input" name="element_name"
:placeholder="object.name"
ref="elementNameField" ref="elementNameField"
v-model="newName" v-model="newName"
v-validate.disabled="'required'" v-validate.disabled="'required'"
@ -33,7 +29,7 @@
> >
<span class="spinner white" v-bind:class="{ hidden: !isLoading }">&nbsp;</span> <span class="spinner white" v-bind:class="{ hidden: !isLoading }">&nbsp;</span>
<span :class="{ hidden: isLoading }"> <span :class="{ hidden: isLoading }">
Edit Rename
</span> </span>
</button> </button>
</div> </div>
@ -53,12 +49,11 @@
import {mapState} from "vuex"; import {mapState} from "vuex";
import {renameElement} from "@/api/server/files/renameElement"; import {renameElement} from "@/api/server/files/renameElement";
import {AxiosError} from 'axios'; import {AxiosError} from 'axios';
import {ApplicationState} from "@/store/types";
type DataStructure = { type DataStructure = {
object: null | DirectoryContentObject,
error: null | string, error: null | string,
newName: string, newName: string,
visible: boolean,
isLoading: boolean, isLoading: boolean,
}; };
@ -66,72 +61,75 @@
name: 'RenameModal', name: 'RenameModal',
components: { Flash, Modal, MessageBox }, components: { Flash, Modal, MessageBox },
props: {
visible: { type: Boolean, default: false },
object: { type: Object as () => DirectoryContentObject, required: true },
},
computed: { computed: {
...mapState('server', ['fm', 'server', 'credentials']), ...mapState({
server: (state: ApplicationState) => state.server.server,
credentials: (state: ApplicationState) => state.server.credentials,
fm: (state: ApplicationState) => state.server.fm,
}),
isVisible: {
get: function (): boolean {
return this.visible;
},
set: function (value: boolean) {
this.$emit('update:visible', value);
},
},
},
watch: {
visible: function (newVal, oldVal) {
if (newVal && newVal !== oldVal) {
this.$nextTick(() => {
if (this.$refs.elementNameField) {
(this.$refs.elementNameField as HTMLInputElement).focus();
}
});
}
}
}, },
data: function (): DataStructure { data: function (): DataStructure {
return { return {
object: null,
newName: '', newName: '',
error: null, error: null,
visible: false,
isLoading: false, isLoading: false,
}; };
}, },
mounted: function () {
window.events.$on('server:files:rename', (data: DirectoryContentObject): void => {
this.visible = true;
this.object = data;
this.newName = data.name;
this.$nextTick(() => {
if (this.$refs.elementNameField) {
(this.$refs.elementNameField as HTMLInputElement).focus();
}
})
});
},
beforeDestroy: function () {
window.events.$off('server:files:rename');
},
methods: { methods: {
submit: function () { submit: function () {
if (!this.object) {
return;
}
this.isLoading = true; this.isLoading = true;
this.error = null; this.error = null;
// @ts-ignore
renameElement(this.server.uuid, this.credentials, { renameElement(this.server.uuid, this.credentials, {
// @ts-ignore
path: this.fm.currentDirectory, path: this.fm.currentDirectory,
toName: this.newName, toName: this.newName,
fromName: this.object.name fromName: this.object.name
}) })
.then(() => { .then(() => {
if (this.object) { this.$emit('renamed', this.newName);
this.object.name = this.newName;
}
this.closeModal(); this.closeModal();
}) })
.catch((error: AxiosError) => { .catch((error: AxiosError) => {
const t = this.object ? (this.object.file ? 'file' : 'folder') : 'item'; this.error = `There was an error while renaming the requested ${this.object.file ? 'file' : 'folder'}. Response: ${error.message}`;
this.error = `There was an error while renaming the requested ${t}. Response: ${error.message}`;
console.error('Error at Server::Files::Rename', { error }); console.error('Error at Server::Files::Rename', { error });
}) })
.then(() => this.isLoading = false); .then(() => this.isLoading = false);
}, },
closeModal: function () { closeModal: function () {
this.object = null;
this.newName = ''; this.newName = '';
this.visible = false;
this.error = null; this.error = null;
this.isVisible = false;
}, },
}, },
}); });

View file

@ -31,11 +31,14 @@
<div class="flex-1 text-right">Modified</div> <div class="flex-1 text-right">Modified</div>
<div class="flex-none w-1/6">Actions</div> <div class="flex-none w-1/6">Actions</div>
</div> </div>
<div v-for="directory in directories"> <div v-for="file in Array.concat(directories, files)">
<FileRow :file="directory" v-on:deleted="folderRowDeleted(directory)" :key="`dir-${directory.name}`"/> <FileRow
</div> :key="file.directory ? `dir-${file.name}` : file.name"
<div v-for="file in files"> :file="file"
<FileRow :file="file" :editable="editableFiles" v-on:deleted="fileRowDeleted(file)" :key="file.name"/> :editable="editableFiles"
v-on:deleted="fileRowDeleted(file, file.directory)"
v-on:renamed="listDirectory"
/>
</div> </div>
</div> </div>
</div> </div>
@ -49,7 +52,6 @@
</div> </div>
</div> </div>
<CreateFolderModal v-on:created="directoryCreated"/> <CreateFolderModal v-on:created="directoryCreated"/>
<RenameModal/>
</div> </div>
</template> </template>
@ -61,7 +63,6 @@
import getDirectoryContents from "@/api/server/getDirectoryContents"; import getDirectoryContents from "@/api/server/getDirectoryContents";
import FileRow from "@/components/server/components/filemanager/FileRow.vue"; import FileRow from "@/components/server/components/filemanager/FileRow.vue";
import CreateFolderModal from '../components/filemanager/modals/CreateFolderModal.vue'; import CreateFolderModal from '../components/filemanager/modals/CreateFolderModal.vue';
import RenameModal from '../components/filemanager/modals/RenameModal.vue';
import DeleteFileModal from '../components/filemanager/modals/DeleteFileModal.vue'; import DeleteFileModal from '../components/filemanager/modals/DeleteFileModal.vue';
import {DirectoryContentObject} from "@/api/server/types"; import {DirectoryContentObject} from "@/api/server/types";
@ -76,11 +77,9 @@
export default Vue.extend({ export default Vue.extend({
name: 'FileManager', name: 'FileManager',
components: {CreateFolderModal, DeleteFileModal, FileRow, RenameModal}, components: {CreateFolderModal, DeleteFileModal, FileRow},
computed: {
...mapState('server', ['server', 'credentials']),
...mapState('socket', ['connected']),
computed: {
/** /**
* Configure the breadcrumbs that display on the filemanager based on the directory that the * Configure the breadcrumbs that display on the filemanager based on the directory that the
* user is currently in. * user is currently in.
@ -180,12 +179,12 @@
window.events.$emit('server:files:open-directory-modal'); window.events.$emit('server:files:open-directory-modal');
}, },
fileRowDeleted: function (file: DirectoryContentObject) { fileRowDeleted: function (file: DirectoryContentObject, directory: boolean) {
this.files = this.files.filter(data => data !== file); if (directory) {
}, this.directories = this.directories.filter(data => data !== file);
} else {
folderRowDeleted: function (file: DirectoryContentObject) { this.files = this.files.filter(data => data !== file);
this.directories = this.directories.filter(data => data !== file); }
}, },
directoryCreated: function (directory: string) { directoryCreated: function (directory: string) {