mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 22:18:07 +08:00
feat: 增加路径选择弹出框组件
This commit is contained in:
parent
1b0660f4a3
commit
1afe79068a
119
frontend/src/components/file-list/index.vue
Normal file
119
frontend/src/components/file-list/index.vue
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<template>
|
||||||
|
<el-popover placement="right" :width="400" trigger="click" :title="'文件列表'">
|
||||||
|
<template #reference>
|
||||||
|
<el-button :icon="Folder"></el-button>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<BreadCrumbs>
|
||||||
|
<BreadCrumbItem @click="jump(-1)" :right="paths.length == 0">root</BreadCrumbItem>
|
||||||
|
<BreadCrumbItem
|
||||||
|
v-for="(item, key) in paths"
|
||||||
|
:key="key"
|
||||||
|
@click="jump(key)"
|
||||||
|
:right="key == paths.length - 1"
|
||||||
|
>{{ item }}</BreadCrumbItem
|
||||||
|
>
|
||||||
|
</BreadCrumbs>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-input :prefix-icon="Search"> </el-input>
|
||||||
|
<el-table :data="data" highlight-current-row height="40vh">
|
||||||
|
<el-table-column width="40" fix>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-checkbox v-model="rowName" :true-label="row.name" @click="checkFile(row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column show-overflow-tooltip fix>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon>
|
||||||
|
<svg-icon v-else className="table-icon" iconName="p-file-normal"></svg-icon>
|
||||||
|
<el-link :underline="false" @click="open(row)">{{ row.name }}</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { File } from '@/api/interface/file';
|
||||||
|
import { GetFilesList } from '@/api/modules/files';
|
||||||
|
import { Folder, Search } from '@element-plus/icons-vue';
|
||||||
|
import BreadCrumbs from '@/components/bread-crumbs/index.vue';
|
||||||
|
import BreadCrumbItem from '@/components/bread-crumbs/bread-crumbs-item.vue';
|
||||||
|
import { onMounted, onUpdated, reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
let rowName = ref('');
|
||||||
|
let data = ref();
|
||||||
|
let loading = ref(false);
|
||||||
|
let paths = ref<string[]>([]);
|
||||||
|
let req = reactive({ path: '/', expand: true });
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
path: {
|
||||||
|
type: String,
|
||||||
|
default: '/',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const em = defineEmits(['choose']);
|
||||||
|
|
||||||
|
const checkFile = (row: any) => {
|
||||||
|
rowName.value = row.name;
|
||||||
|
em('choose', row.path);
|
||||||
|
};
|
||||||
|
|
||||||
|
const open = async (row: File.File) => {
|
||||||
|
if (row.isDir) {
|
||||||
|
const name = row.name;
|
||||||
|
paths.value.push(name);
|
||||||
|
if (req.path === '/') {
|
||||||
|
req.path = req.path + name;
|
||||||
|
} else {
|
||||||
|
req.path = req.path + '/' + name;
|
||||||
|
}
|
||||||
|
search(req);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const jump = async (index: number) => {
|
||||||
|
let path = '/';
|
||||||
|
if (index != -1) {
|
||||||
|
const jPaths = paths.value.slice(0, index + 1);
|
||||||
|
for (let i in jPaths) {
|
||||||
|
path = path + '/' + jPaths[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.path = path;
|
||||||
|
search(req);
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = async (req: File.ReqFile) => {
|
||||||
|
loading.value = true;
|
||||||
|
await GetFilesList(req)
|
||||||
|
.then((res) => {
|
||||||
|
data.value = res.data.items;
|
||||||
|
req.path = res.data.path;
|
||||||
|
const pathArray = req.path.split('/');
|
||||||
|
paths.value = [];
|
||||||
|
for (const p of pathArray) {
|
||||||
|
if (p != '') {
|
||||||
|
paths.value.push(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
req.path = props.path;
|
||||||
|
search(req);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUpdated(() => {
|
||||||
|
req.path = props.path;
|
||||||
|
search(req);
|
||||||
|
});
|
||||||
|
</script>
|
@ -12,7 +12,9 @@
|
|||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('file.compressDst')" prop="dst">
|
<el-form-item :label="$t('file.compressDst')" prop="dst">
|
||||||
<el-input v-model="form.dst"></el-input>
|
<el-input v-model="form.dst">
|
||||||
|
<template #append> <FileList :path="props.dst" @choose="getLinkPath"></FileList> </template
|
||||||
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-checkbox v-model="form.replace" :label="$t('file.replace')"></el-checkbox>
|
<el-checkbox v-model="form.replace" :label="$t('file.replace')"></el-checkbox>
|
||||||
@ -35,6 +37,7 @@ import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
|||||||
import { Rules } from '@/global/form-rues';
|
import { Rules } from '@/global/form-rues';
|
||||||
import { CompressExtention, CompressType } from '@/enums/files';
|
import { CompressExtention, CompressType } from '@/enums/files';
|
||||||
import { CompressFile } from '@/api/modules/files';
|
import { CompressFile } from '@/api/modules/files';
|
||||||
|
import FileList from '@/components/file-list/index.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
open: {
|
open: {
|
||||||
@ -87,6 +90,10 @@ const handleClose = () => {
|
|||||||
em('close', open);
|
em('close', open);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getLinkPath = (path: string) => {
|
||||||
|
form.value.dst = path;
|
||||||
|
};
|
||||||
|
|
||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
form.value = {
|
form.value = {
|
||||||
dst: dst.value,
|
dst: dst.value,
|
||||||
|
@ -20,8 +20,12 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="addForm.isLink" :label="$t('file.linkPath')" prop="linkPath">
|
<el-form-item v-if="addForm.isLink" :label="$t('file.linkPath')" prop="linkPath">
|
||||||
<el-input v-model="addForm.linkPath"
|
<el-input v-model="addForm.linkPath">
|
||||||
/></el-form-item>
|
<template #append>
|
||||||
|
<FileList @choose="getLinkPath"></FileList>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-checkbox v-if="addForm.isDir" v-model="setRole" :label="$t('file.setRole')"></el-checkbox>
|
<el-checkbox v-if="addForm.isDir" v-model="setRole" :label="$t('file.setRole')"></el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -47,6 +51,7 @@ import { CreateFile } from '@/api/modules/files';
|
|||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import FileRole from '@/components/file-role/index.vue';
|
import FileRole from '@/components/file-role/index.vue';
|
||||||
import { Rules } from '@/global/form-rues';
|
import { Rules } from '@/global/form-rues';
|
||||||
|
import FileList from '@/components/file-list/index.vue';
|
||||||
|
|
||||||
const fileForm = ref<FormInstance>();
|
const fileForm = ref<FormInstance>();
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
@ -84,6 +89,10 @@ let getPath = computed(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getLinkPath = (path: string) => {
|
||||||
|
addForm.linkPath = path;
|
||||||
|
};
|
||||||
|
|
||||||
const submit = async (formEl: FormInstance | undefined) => {
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
<el-input v-model="name" disabled></el-input>
|
<el-input v-model="name" disabled></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('file.deCompressDst')" prop="dst">
|
<el-form-item :label="$t('file.deCompressDst')" prop="dst">
|
||||||
<el-input v-model="form.dst"></el-input>
|
<el-input v-model="form.dst">
|
||||||
|
<template #append> <FileList :path="props.dst" @choose="getLinkPath"></FileList> </template
|
||||||
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -32,6 +34,7 @@ import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
|||||||
import { Rules } from '@/global/form-rues';
|
import { Rules } from '@/global/form-rues';
|
||||||
import { DeCompressFile } from '@/api/modules/files';
|
import { DeCompressFile } from '@/api/modules/files';
|
||||||
import { Mimetypes } from '@/global/mimetype';
|
import { Mimetypes } from '@/global/mimetype';
|
||||||
|
import FileList from '@/components/file-list/index.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
open: {
|
open: {
|
||||||
@ -79,6 +82,10 @@ const getFileType = (mime: string): string => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getLinkPath = (path: string) => {
|
||||||
|
form.value.dst = path;
|
||||||
|
};
|
||||||
|
|
||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
form.value = {
|
form.value = {
|
||||||
dst: dst.value,
|
dst: dst.value,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user