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 () {
|
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 }"> </span>
|
<span class="spinner white" v-bind:class="{ hidden: !isLoading }"> </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;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue