mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-24 11:09:16 +08:00
feat: 文件列表组件新增创建文件夹以及文件功能 (#5680)
This commit is contained in:
parent
9e103baf94
commit
966b10fbb5
@ -51,6 +51,14 @@
|
|||||||
</template>
|
</template>
|
||||||
</BreadCrumbs>
|
</BreadCrumbs>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<el-button link @click="onAddItem(true)" type="primary" size="small">
|
||||||
|
{{ $t('commons.button.createNewFolder') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button link @click="onAddItem(false)" type="primary" size="small">
|
||||||
|
{{ $t('commons.button.createNewFile') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-table :data="data" highlight-current-row height="40vh">
|
<el-table :data="data" highlight-current-row height="40vh">
|
||||||
<el-table-column width="40" fix>
|
<el-table-column width="40" fix>
|
||||||
@ -65,21 +73,34 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column show-overflow-tooltip fix>
|
<el-table-column show-overflow-tooltip fix>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon>
|
<div>
|
||||||
<svg-icon v-else className="table-icon" iconName="p-file-normal"></svg-icon>
|
<svg-icon
|
||||||
<el-link v-if="!row.isCreate" :underline="false" @click="open(row)">{{ row.name }}</el-link>
|
:class="'table-icon'"
|
||||||
<el-input
|
:iconName="row.isDir ? 'p-file-folder' : 'p-file-normal'"
|
||||||
v-else
|
></svg-icon>
|
||||||
ref="rowRefs"
|
|
||||||
v-model="newFlower"
|
<template v-if="!row.isCreate">
|
||||||
style="width: 240px"
|
<el-link :underline="false" @click="open(row)">
|
||||||
placeholder="new flower"
|
{{ row.name }}
|
||||||
@input="handleChange(newFlower, row)"
|
</el-link>
|
||||||
>
|
|
||||||
<template #append>
|
|
||||||
<el-button :icon="Check" @click="createFlower(row)" />
|
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
|
||||||
|
<template v-else>
|
||||||
|
<el-input
|
||||||
|
ref="rowRefs"
|
||||||
|
v-model="newFolder"
|
||||||
|
style="width: 200px"
|
||||||
|
placeholder="new folder"
|
||||||
|
@input="handleChange(newFolder, row)"
|
||||||
|
></el-input>
|
||||||
|
<el-button link @click="createFolder(row)" type="primary" size="small" class="ml-2">
|
||||||
|
{{ $t('commons.button.save') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button link @click="cancelFolder(row)" type="primary" size="small" class="!ml-2">
|
||||||
|
{{ $t('commons.button.cancel') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -95,10 +116,6 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<el-button link @click="onAddRow" type="primary">
|
|
||||||
{{ $t('commons.button.create') }}
|
|
||||||
</el-button>
|
|
||||||
<div class="button">
|
<div class="button">
|
||||||
<el-button @click="closePage">{{ $t('commons.button.cancel') }}</el-button>
|
<el-button @click="closePage">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="selectFile" :disabled="disBtn">
|
<el-button type="primary" @click="selectFile" :disabled="disBtn">
|
||||||
@ -106,14 +123,13 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { File } from '@/api/interface/file';
|
import { File } from '@/api/interface/file';
|
||||||
import { CreateFile, GetFilesList } from '@/api/modules/files';
|
import { CreateFile, GetFilesList } from '@/api/modules/files';
|
||||||
import { Folder, Check, HomeFilled, Close } from '@element-plus/icons-vue';
|
import { Folder, HomeFilled, Close } from '@element-plus/icons-vue';
|
||||||
import BreadCrumbs from '@/components/bread-crumbs/index.vue';
|
import BreadCrumbs from '@/components/bread-crumbs/index.vue';
|
||||||
import BreadCrumbItem from '@/components/bread-crumbs/bread-crumbs-item.vue';
|
import BreadCrumbItem from '@/components/bread-crumbs/bread-crumbs-item.vue';
|
||||||
import { onMounted, onUpdated, reactive, ref, nextTick } from 'vue';
|
import { onMounted, onUpdated, reactive, ref, nextTick } from 'vue';
|
||||||
@ -128,7 +144,7 @@ const req = reactive({ path: '/', expand: true, page: 1, pageSize: 300, showHidd
|
|||||||
const selectRow = ref();
|
const selectRow = ref();
|
||||||
const rowRefs = ref();
|
const rowRefs = ref();
|
||||||
const popoverVisible = ref(false);
|
const popoverVisible = ref(false);
|
||||||
const newFlower = ref();
|
const newFolder = ref();
|
||||||
const disBtn = ref(false);
|
const disBtn = ref(false);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -180,6 +196,9 @@ const disabledDir = (row: File.File) => {
|
|||||||
if (props.isAll) {
|
if (props.isAll) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (props.dir !== row.isDir) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!props.dir) {
|
if (!props.dir) {
|
||||||
return row.isDir;
|
return row.isDir;
|
||||||
}
|
}
|
||||||
@ -239,28 +258,39 @@ const search = async (req: File.ReqFile) => {
|
|||||||
|
|
||||||
let addForm = reactive({ path: '', name: '', isDir: true, mode: 0o755, isLink: false, isSymlink: true, linkPath: '' });
|
let addForm = reactive({ path: '', name: '', isDir: true, mode: 0o755, isLink: false, isSymlink: true, linkPath: '' });
|
||||||
|
|
||||||
const onAddRow = async () => {
|
const onAddItem = async (isDir: boolean) => {
|
||||||
const createRow = data.value?.find((row: { isCreate: any }) => row.isCreate);
|
const createRow = data.value?.find((row: { isCreate: any }) => row.isCreate);
|
||||||
if (createRow) {
|
if (createRow) {
|
||||||
MsgWarning(i18n.global.t('commons.msg.creatingInfo'));
|
MsgWarning(i18n.global.t('commons.msg.creatingInfo'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
newFlower.value = i18n.global.t('file.noNameFolder');
|
newFolder.value = isDir ? i18n.global.t('file.noNameFolder') : i18n.global.t('file.noNameFile');
|
||||||
rowName.value = newFlower.value;
|
if (props.dir === isDir) {
|
||||||
selectRow.value.name = newFlower.value;
|
rowName.value = newFolder.value;
|
||||||
|
selectRow.value.name = newFolder.value;
|
||||||
const basePath = req.path === '/' ? req.path : `${req.path}/`;
|
const basePath = req.path === '/' ? req.path : `${req.path}/`;
|
||||||
selectRow.value.path = `${basePath}${newFlower.value}`;
|
selectRow.value.path = `${basePath}${newFolder.value}`;
|
||||||
|
}
|
||||||
data.value?.unshift({
|
data.value?.unshift({
|
||||||
path: selectRow.value.path,
|
path: selectRow.value.path,
|
||||||
isCreate: true,
|
isCreate: true,
|
||||||
isDir: true,
|
isDir: isDir,
|
||||||
name: newFlower.value,
|
name: newFolder.value,
|
||||||
});
|
});
|
||||||
disBtn.value = true;
|
disBtn.value = true;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
rowRefs.value.focus();
|
rowRefs.value.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cancelFolder = (row: any) => {
|
||||||
|
data.value.shift();
|
||||||
|
row.isCreate = false;
|
||||||
|
disBtn.value = false;
|
||||||
|
selectRow.value = {};
|
||||||
|
rowName.value = '';
|
||||||
|
newFolder.value = '';
|
||||||
|
};
|
||||||
|
|
||||||
const handleChange = (value: string, row: any) => {
|
const handleChange = (value: string, row: any) => {
|
||||||
if (rowName.value === row.name) {
|
if (rowName.value === row.name) {
|
||||||
selectRow.value.name = value;
|
selectRow.value.name = value;
|
||||||
@ -271,14 +301,15 @@ const handleChange = (value: string, row: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const createFlower = async (row: any) => {
|
const createFolder = async (row: any) => {
|
||||||
const basePath = req.path === '/' ? req.path : `${req.path}/`;
|
const basePath = req.path === '/' ? req.path : `${req.path}/`;
|
||||||
addForm.path = `${basePath}${newFlower.value}`;
|
addForm.path = `${basePath}${newFolder.value}`;
|
||||||
if (addForm.path.indexOf('.1panel_clash') > -1) {
|
if (addForm.path.indexOf('.1panel_clash') > -1) {
|
||||||
MsgWarning(i18n.global.t('file.clashDitNotSupport'));
|
MsgWarning(i18n.global.t('file.clashDitNotSupport'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addForm.name = newFlower.value;
|
addForm.isDir = row.isDir;
|
||||||
|
addForm.name = newFolder.value;
|
||||||
let addItem = {};
|
let addItem = {};
|
||||||
Object.assign(addItem, addForm);
|
Object.assign(addItem, addForm);
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
@ -66,6 +66,8 @@ const message = {
|
|||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
open: 'Open',
|
open: 'Open',
|
||||||
notSave: 'Not Save',
|
notSave: 'Not Save',
|
||||||
|
createNewFolder: 'Create new folder',
|
||||||
|
createNewFile: 'Create new file',
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
timeStart: 'Time start',
|
timeStart: 'Time start',
|
||||||
@ -1252,6 +1254,7 @@ const message = {
|
|||||||
saveAndOpenNewFile: 'The file has been modified, do you want to save and open the new file?',
|
saveAndOpenNewFile: 'The file has been modified, do you want to save and open the new file?',
|
||||||
noEdit: 'The file has not been modified, no need to do this!',
|
noEdit: 'The file has not been modified, no need to do this!',
|
||||||
noNameFolder: 'Untitled Folder',
|
noNameFolder: 'Untitled Folder',
|
||||||
|
noNameFile: 'Untitled File',
|
||||||
},
|
},
|
||||||
ssh: {
|
ssh: {
|
||||||
autoStart: 'Auto Start',
|
autoStart: 'Auto Start',
|
||||||
|
@ -65,6 +65,8 @@ const message = {
|
|||||||
preview: '預覽',
|
preview: '預覽',
|
||||||
open: '打開',
|
open: '打開',
|
||||||
notSave: '不保存',
|
notSave: '不保存',
|
||||||
|
createNewFolder: '新建資料夾',
|
||||||
|
createNewFile: '新建檔案',
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
timeStart: '開始時間',
|
timeStart: '開始時間',
|
||||||
@ -1189,6 +1191,7 @@ const message = {
|
|||||||
saveAndOpenNewFile: '檔案已被修改,是否保存並打開新檔案?',
|
saveAndOpenNewFile: '檔案已被修改,是否保存並打開新檔案?',
|
||||||
noEdit: '檔案未修改,無需此操作!',
|
noEdit: '檔案未修改,無需此操作!',
|
||||||
noNameFolder: '未命名資料夾',
|
noNameFolder: '未命名資料夾',
|
||||||
|
noNameFile: '未命名檔案',
|
||||||
},
|
},
|
||||||
ssh: {
|
ssh: {
|
||||||
autoStart: '開機自啟',
|
autoStart: '開機自啟',
|
||||||
|
@ -65,6 +65,8 @@ const message = {
|
|||||||
preview: '预览',
|
preview: '预览',
|
||||||
open: '打开',
|
open: '打开',
|
||||||
notSave: '不保存',
|
notSave: '不保存',
|
||||||
|
createNewFolder: '新建文件夹',
|
||||||
|
createNewFile: '新建文件',
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
timeStart: '开始时间',
|
timeStart: '开始时间',
|
||||||
@ -1190,6 +1192,7 @@ const message = {
|
|||||||
saveAndOpenNewFile: '文件已被修改,是否保存并打开新文件?',
|
saveAndOpenNewFile: '文件已被修改,是否保存并打开新文件?',
|
||||||
noEdit: '文件未修改,无需此操作!',
|
noEdit: '文件未修改,无需此操作!',
|
||||||
noNameFolder: '未命名文件夹',
|
noNameFolder: '未命名文件夹',
|
||||||
|
noNameFile: '未命名文件',
|
||||||
},
|
},
|
||||||
ssh: {
|
ssh: {
|
||||||
autoStart: '开机自启',
|
autoStart: '开机自启',
|
||||||
|
Loading…
Reference in New Issue
Block a user