Migrate the rename action to follow better structure
This commit is contained in:
parent
f3159bcec3
commit
3970a24218
5 changed files with 83 additions and 71 deletions
|
@ -74,12 +74,11 @@
|
|||
},
|
||||
|
||||
openRenameModal: function () {
|
||||
window.events.$emit('server:files:rename', this.object);
|
||||
this.$emit('close');
|
||||
this.$emit('action:rename');
|
||||
},
|
||||
|
||||
openDeleteModal: function () {
|
||||
this.$emit('action:delete', this.object);
|
||||
this.$emit('action:delete');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -31,10 +31,12 @@
|
|||
:object="file"
|
||||
v-show="contextMenuVisible"
|
||||
v-on:close="contextMenuVisible = false"
|
||||
v-on:action:delete="showDeleteFileModal"
|
||||
v-on:action:delete="showModal('delete')"
|
||||
v-on:action:rename="showModal('rename')"
|
||||
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>
|
||||
</template>
|
||||
|
||||
|
@ -46,10 +48,17 @@
|
|||
import FileContextMenu from "./FileContextMenu.vue";
|
||||
import {DirectoryContentObject} from "@/api/server/types";
|
||||
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({
|
||||
name: 'FileRow',
|
||||
components: {DeleteFileModal, Icon, FileContextMenu},
|
||||
components: {DeleteFileModal, Icon, FileContextMenu, RenameModal},
|
||||
|
||||
props: {
|
||||
file: {
|
||||
|
@ -63,11 +72,14 @@
|
|||
},
|
||||
},
|
||||
|
||||
data: function () {
|
||||
data: function (): DataStructure {
|
||||
return {
|
||||
currentDirectory: this.$route.params.path || '/',
|
||||
contextMenuVisible: false,
|
||||
deleteModalVisible: false,
|
||||
modals: {
|
||||
rename: false,
|
||||
delete: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -89,9 +101,13 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
showDeleteFileModal: function () {
|
||||
showModal: function (name: string) {
|
||||
console.warn('showModal', name);
|
||||
this.contextMenuVisible = false;
|
||||
this.deleteModalVisible = true;
|
||||
|
||||
Object.keys(this.modals).forEach(k => {
|
||||
this.modals[k] = k === name;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Modal :show="isVisible" v-on:close="isVisible = false">
|
||||
<Modal :show="isVisible" v-on:close="isVisible = false" :dismissable="!isLoading">
|
||||
<MessageBox
|
||||
class="alert error mb-8"
|
||||
title="Error"
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<template>
|
||||
<Modal
|
||||
:show="visible"
|
||||
v-on:close="closeModal"
|
||||
:showCloseIcon="false"
|
||||
:dismissable="!isLoading"
|
||||
>
|
||||
<Modal :show="isVisible" v-on:close="closeModal" :showCloseIcon="false" :dismissable="!isLoading">
|
||||
<MessageBox
|
||||
class="alert error mb-8"
|
||||
title="Error"
|
||||
|
@ -18,6 +13,7 @@
|
|||
</label>
|
||||
<input
|
||||
type="text" class="input" name="element_name"
|
||||
:placeholder="object.name"
|
||||
ref="elementNameField"
|
||||
v-model="newName"
|
||||
v-validate.disabled="'required'"
|
||||
|
@ -33,7 +29,7 @@
|
|||
>
|
||||
<span class="spinner white" v-bind:class="{ hidden: !isLoading }"> </span>
|
||||
<span :class="{ hidden: isLoading }">
|
||||
Edit
|
||||
Rename
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -53,12 +49,11 @@
|
|||
import {mapState} from "vuex";
|
||||
import {renameElement} from "@/api/server/files/renameElement";
|
||||
import {AxiosError} from 'axios';
|
||||
import {ApplicationState} from "@/store/types";
|
||||
|
||||
type DataStructure = {
|
||||
object: null | DirectoryContentObject,
|
||||
error: null | string,
|
||||
newName: string,
|
||||
visible: boolean,
|
||||
isLoading: boolean,
|
||||
};
|
||||
|
||||
|
@ -66,72 +61,75 @@
|
|||
name: 'RenameModal',
|
||||
components: { Flash, Modal, MessageBox },
|
||||
|
||||
props: {
|
||||
visible: { type: Boolean, default: false },
|
||||
object: { type: Object as () => DirectoryContentObject, required: true },
|
||||
},
|
||||
|
||||
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 {
|
||||
return {
|
||||
object: null,
|
||||
newName: '',
|
||||
error: null,
|
||||
visible: 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: {
|
||||
submit: function () {
|
||||
if (!this.object) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
this.error = null;
|
||||
|
||||
// @ts-ignore
|
||||
renameElement(this.server.uuid, this.credentials, {
|
||||
// @ts-ignore
|
||||
path: this.fm.currentDirectory,
|
||||
toName: this.newName,
|
||||
fromName: this.object.name
|
||||
})
|
||||
.then(() => {
|
||||
if (this.object) {
|
||||
this.object.name = this.newName;
|
||||
}
|
||||
|
||||
this.$emit('renamed', this.newName);
|
||||
this.closeModal();
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
const t = this.object ? (this.object.file ? 'file' : 'folder') : 'item';
|
||||
|
||||
this.error = `There was an error while renaming the requested ${t}. Response: ${error.message}`;
|
||||
this.error = `There was an error while renaming the requested ${this.object.file ? 'file' : 'folder'}. Response: ${error.message}`;
|
||||
console.error('Error at Server::Files::Rename', { error });
|
||||
})
|
||||
.then(() => this.isLoading = false);
|
||||
},
|
||||
|
||||
closeModal: function () {
|
||||
this.object = null;
|
||||
this.newName = '';
|
||||
this.visible = false;
|
||||
this.error = null;
|
||||
this.isVisible = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -31,11 +31,14 @@
|
|||
<div class="flex-1 text-right">Modified</div>
|
||||
<div class="flex-none w-1/6">Actions</div>
|
||||
</div>
|
||||
<div v-for="directory in directories">
|
||||
<FileRow :file="directory" v-on:deleted="folderRowDeleted(directory)" :key="`dir-${directory.name}`"/>
|
||||
</div>
|
||||
<div v-for="file in files">
|
||||
<FileRow :file="file" :editable="editableFiles" v-on:deleted="fileRowDeleted(file)" :key="file.name"/>
|
||||
<div v-for="file in Array.concat(directories, files)">
|
||||
<FileRow
|
||||
:key="file.directory ? `dir-${file.name}` : file.name"
|
||||
:file="file"
|
||||
:editable="editableFiles"
|
||||
v-on:deleted="fileRowDeleted(file, file.directory)"
|
||||
v-on:renamed="listDirectory"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -49,7 +52,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<CreateFolderModal v-on:created="directoryCreated"/>
|
||||
<RenameModal/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -61,7 +63,6 @@
|
|||
import getDirectoryContents from "@/api/server/getDirectoryContents";
|
||||
import FileRow from "@/components/server/components/filemanager/FileRow.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 {DirectoryContentObject} from "@/api/server/types";
|
||||
|
||||
|
@ -76,11 +77,9 @@
|
|||
|
||||
export default Vue.extend({
|
||||
name: 'FileManager',
|
||||
components: {CreateFolderModal, DeleteFileModal, FileRow, RenameModal},
|
||||
computed: {
|
||||
...mapState('server', ['server', 'credentials']),
|
||||
...mapState('socket', ['connected']),
|
||||
components: {CreateFolderModal, DeleteFileModal, FileRow},
|
||||
|
||||
computed: {
|
||||
/**
|
||||
* Configure the breadcrumbs that display on the filemanager based on the directory that the
|
||||
* user is currently in.
|
||||
|
@ -180,12 +179,12 @@
|
|||
window.events.$emit('server:files:open-directory-modal');
|
||||
},
|
||||
|
||||
fileRowDeleted: function (file: DirectoryContentObject) {
|
||||
this.files = this.files.filter(data => data !== file);
|
||||
},
|
||||
|
||||
folderRowDeleted: function (file: DirectoryContentObject) {
|
||||
this.directories = this.directories.filter(data => data !== file);
|
||||
fileRowDeleted: function (file: DirectoryContentObject, directory: boolean) {
|
||||
if (directory) {
|
||||
this.directories = this.directories.filter(data => data !== file);
|
||||
} else {
|
||||
this.files = this.files.filter(data => data !== file);
|
||||
}
|
||||
},
|
||||
|
||||
directoryCreated: function (directory: string) {
|
||||
|
|
Loading…
Reference in a new issue