mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 21:38:57 +08:00
parent
282e196534
commit
e4e2d76f75
1 changed files with 633 additions and 650 deletions
|
|
@ -14,7 +14,6 @@
|
||||||
:label="item.name == '' ? $t('file.root') : item.name"
|
:label="item.name == '' ? $t('file.root') : item.name"
|
||||||
:name="item.id"
|
:name="item.id"
|
||||||
>
|
>
|
||||||
<div>
|
|
||||||
<div class="flex sm:flex-row flex-col justify-start gap-y-2 items-center gap-x-4" ref="toolRef">
|
<div class="flex sm:flex-row flex-col justify-start gap-y-2 items-center gap-x-4" ref="toolRef">
|
||||||
<div class="flex-shrink-0 flex sm:w-min w-full items-center justify-start">
|
<div class="flex-shrink-0 flex sm:w-min w-full items-center justify-start">
|
||||||
<el-tooltip :content="$t('file.back')" placement="top">
|
<el-tooltip :content="$t('file.back')" placement="top">
|
||||||
|
|
@ -54,11 +53,7 @@
|
||||||
<el-icon :size="20"><HomeFilled /></el-icon>
|
<el-icon :size="20"><HomeFilled /></el-icon>
|
||||||
</el-link>
|
</el-link>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span v-for="(path, index) in paths" :key="path.url" class="inline-flex items-center">
|
||||||
v-for="(path, index) in paths"
|
|
||||||
:key="path.url"
|
|
||||||
class="inline-flex items-center"
|
|
||||||
>
|
|
||||||
<span class="mr-2 arrow">></span>
|
<span class="mr-2 arrow">></span>
|
||||||
<template v-if="index === 0 && hidePaths.length > 0">
|
<template v-if="index === 0 && hidePaths.length > 0">
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
|
|
@ -151,11 +146,7 @@
|
||||||
<el-icon :size="20"><HomeFilled /></el-icon>
|
<el-icon :size="20"><HomeFilled /></el-icon>
|
||||||
</el-link>
|
</el-link>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span v-for="(path, index) in paths" :key="path.url" class="inline-flex items-center">
|
||||||
v-for="(path, index) in paths"
|
|
||||||
:key="path.url"
|
|
||||||
class="inline-flex items-center"
|
|
||||||
>
|
|
||||||
<span class="mr-2 arrow">></span>
|
<span class="mr-2 arrow">></span>
|
||||||
<template v-if="index === 0 && hidePaths.length > 0">
|
<template v-if="index === 0 && hidePaths.length > 0">
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
|
|
@ -187,6 +178,8 @@
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
<span class="mr-2 arrow">></span>
|
<span class="mr-2 arrow">></span>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
class="box-item"
|
class="box-item"
|
||||||
|
|
@ -337,17 +330,11 @@
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<template v-for="(mount, index) in hostMount" :key="mount.path">
|
<template v-for="(mount, index) in hostMount" :key="mount.path">
|
||||||
<el-dropdown-item
|
<el-dropdown-item v-if="index == 0" @click.stop="jump(mount.path)">
|
||||||
v-if="index == 0"
|
|
||||||
@click.stop="jump(mount.path)"
|
|
||||||
>
|
|
||||||
{{ mount.path }} ({{ $t('file.root') }})
|
{{ mount.path }} ({{ $t('file.root') }})
|
||||||
{{ formatFileSize(mount.free) }}
|
{{ formatFileSize(mount.free) }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item v-if="index != 0" @click.stop="jump(mount.path)">
|
||||||
v-if="index != 0"
|
|
||||||
@click.stop="jump(mount.path)"
|
|
||||||
>
|
|
||||||
{{ mount.path }} ({{ $t('home.mount') }})
|
{{ mount.path }} ({{ $t('home.mount') }})
|
||||||
{{ formatFileSize(mount.free) }}
|
{{ formatFileSize(mount.free) }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
|
|
@ -554,12 +541,7 @@
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column :label="$t('file.size')" prop="size" min-width="100" :sortable="'custom'">
|
||||||
:label="$t('file.size')"
|
|
||||||
prop="size"
|
|
||||||
min-width="100"
|
|
||||||
:sortable="'custom'"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -618,9 +600,8 @@
|
||||||
</ComplexTable>
|
</ComplexTable>
|
||||||
</template>
|
</template>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :closable="false" :disabled="editableTabs.length > 6">
|
<el-tab-pane :name="editableTabsKey" :closable="false" :disabled="editableTabs.length > 6">
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-icon @click="addTab()"><Plus /></el-icon>
|
<el-icon @click="addTab()"><Plus /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -712,6 +693,7 @@ import { CompressExtension, CompressType } from '@/enums/files';
|
||||||
import type { TabPaneName } from 'element-plus';
|
import type { TabPaneName } from 'element-plus';
|
||||||
import { getComponentInfo } from '@/api/modules/host';
|
import { getComponentInfo } from '@/api/modules/host';
|
||||||
import { routerToNameWithQuery } from '@/utils/router';
|
import { routerToNameWithQuery } from '@/utils/router';
|
||||||
|
import { loadBaseDir } from '@/api/modules/setting';
|
||||||
|
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
|
|
@ -747,6 +729,7 @@ const initData = () => ({
|
||||||
});
|
});
|
||||||
let req = reactive(initData());
|
let req = reactive(initData());
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
|
const baseDir = ref();
|
||||||
const paths = ref<FilePaths[]>([]);
|
const paths = ref<FilePaths[]>([]);
|
||||||
const hidePaths = ref<FilePaths[]>([]);
|
const hidePaths = ref<FilePaths[]>([]);
|
||||||
let pathWidth = ref(0);
|
let pathWidth = ref(0);
|
||||||
|
|
@ -973,14 +956,15 @@ const updateButtons = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePath = () => {
|
const handlePath = (depth = 0) => {
|
||||||
|
if (depth > 10) return;
|
||||||
nextTick(function () {
|
nextTick(function () {
|
||||||
let breadCrumbWidth = breadCrumbRef.value?.offsetWidth;
|
let breadCrumbWidth = breadCrumbRef.value?.offsetWidth;
|
||||||
let pathWidth = toolRef.value?.offsetWidth;
|
let pathWidth = toolRef.value?.offsetWidth;
|
||||||
if (pathWidth - breadCrumbWidth < 50 && paths.value.length > 1) {
|
if (pathWidth - breadCrumbWidth < 50 && paths.value.length > 1) {
|
||||||
const removed = paths.value.shift();
|
const removed = paths.value.shift();
|
||||||
if (removed) hidePaths.value.push(removed);
|
if (removed) hidePaths.value.push(removed);
|
||||||
handlePath();
|
handlePath(depth + 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -995,19 +979,22 @@ const btnResizeHandler = debounce(() => {
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
const observeResize = () => {
|
const observeResize = () => {
|
||||||
const el = getCurrentPath() as any;
|
const el = getCurrentPath();
|
||||||
if (!el) return;
|
const ele = getCurrentBtnWrapper();
|
||||||
let resizeObserver = new ResizeObserver(() => {
|
if (!el || !ele) return;
|
||||||
resizeHandler();
|
|
||||||
|
const observe = new ResizeObserver((entries) => {
|
||||||
|
const isElChanged = entries.some((entry) => entry.target === el);
|
||||||
|
const isEleChanged = entries.some((entry) => entry.target === ele);
|
||||||
|
|
||||||
|
if (isElChanged) resizeHandler();
|
||||||
|
if (isEleChanged) btnResizeHandler();
|
||||||
});
|
});
|
||||||
|
|
||||||
const ele = getCurrentBtnWrapper() as any;
|
observe.observe(el);
|
||||||
if (!ele) return;
|
observe.observe(ele);
|
||||||
resizeObserver = new ResizeObserver(() => {
|
|
||||||
btnResizeHandler();
|
resizeObserver = observe;
|
||||||
});
|
|
||||||
resizeObserver.observe(el);
|
|
||||||
resizeObserver.observe(ele);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function watchTitleHeight() {
|
function watchTitleHeight() {
|
||||||
|
|
@ -1738,18 +1725,6 @@ function hideRightMenu() {
|
||||||
getCurrentTable().closeRightClick();
|
getCurrentTable().closeRightClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
initShowHidden();
|
|
||||||
initTabsAndPaths();
|
|
||||||
getHostMount();
|
|
||||||
initHistory();
|
|
||||||
checkFFmpeg();
|
|
||||||
nextTick(function () {
|
|
||||||
handlePath();
|
|
||||||
observeResize();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function initShowHidden() {
|
function initShowHidden() {
|
||||||
const showHidden = localStorage.getItem('show-hidden');
|
const showHidden = localStorage.getItem('show-hidden');
|
||||||
if (showHidden === null) {
|
if (showHidden === null) {
|
||||||
|
|
@ -1765,7 +1740,6 @@ function initTabsAndPaths() {
|
||||||
let path = getInitialPath();
|
let path = getInitialPath();
|
||||||
req.path = path;
|
req.path = path;
|
||||||
getPaths(path);
|
getPaths(path);
|
||||||
editableTabsValue.value = path;
|
|
||||||
updateTab(path);
|
updateTab(path);
|
||||||
paths.value = buildPaths(path);
|
paths.value = buildPaths(path);
|
||||||
pathWidth.value = getCurrentPath()?.offsetWidth;
|
pathWidth.value = getCurrentPath()?.offsetWidth;
|
||||||
|
|
@ -1788,21 +1762,28 @@ function initHistory() {
|
||||||
|
|
||||||
function getInitialPath(): string {
|
function getInitialPath(): string {
|
||||||
const routePath = router.currentRoute.value.query.path;
|
const routePath = router.currentRoute.value.query.path;
|
||||||
if (routePath) {
|
if (routePath != undefined) {
|
||||||
const p = String(routePath);
|
const p = String(routePath);
|
||||||
globalStore.setLastFilePath(p);
|
globalStore.setLastFilePath(p);
|
||||||
return p;
|
return p;
|
||||||
} else if (globalStore.lastFilePath && globalStore.lastFilePath !== '') {
|
} else if (
|
||||||
|
typeof globalStore.lastFilePath === 'string' &&
|
||||||
|
globalStore.lastFilePath.trim() !== '' &&
|
||||||
|
globalStore.lastFilePath !== 'undefined'
|
||||||
|
) {
|
||||||
return globalStore.lastFilePath;
|
return globalStore.lastFilePath;
|
||||||
}
|
}
|
||||||
|
const tab = editableTabs.value.find((t) => t.id === editableTabsKey.value);
|
||||||
|
if (tab) {
|
||||||
|
globalStore.setLastFilePath(tab.path);
|
||||||
|
return tab.path;
|
||||||
|
}
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
const editableTabsKey = ref('');
|
const editableTabsKey = ref('');
|
||||||
const editableTabsValue = ref('');
|
|
||||||
const editableTabsName = ref('');
|
|
||||||
const editableTabs = ref([
|
const editableTabs = ref([
|
||||||
{ id: '1', name: 'opt', path: '/opt' },
|
{ id: '1', name: getLastPath(baseDir.value), path: baseDir.value },
|
||||||
{ id: '2', name: 'home', path: '/home' },
|
{ id: '2', name: 'home', path: '/home' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -1811,17 +1792,9 @@ function initTabs() {
|
||||||
if (savedTabs) {
|
if (savedTabs) {
|
||||||
editableTabs.value = JSON.parse(savedTabs);
|
editableTabs.value = JSON.parse(savedTabs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const savedTabsKey = localStorage.getItem('editableTabsKey');
|
const savedTabsKey = localStorage.getItem('editableTabsKey');
|
||||||
if (savedTabsKey) {
|
if (savedTabsKey) {
|
||||||
editableTabsKey.value = savedTabsKey;
|
editableTabsKey.value = savedTabsKey;
|
||||||
const tab = editableTabs.value.find((t) => t.id === savedTabsKey);
|
|
||||||
if (tab) {
|
|
||||||
editableTabsValue.value = tab.path;
|
|
||||||
editableTabsName.value = tab.name;
|
|
||||||
} else {
|
|
||||||
setFirstTab();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setFirstTab();
|
setFirstTab();
|
||||||
}
|
}
|
||||||
|
|
@ -1831,19 +1804,18 @@ function setFirstTab() {
|
||||||
if (editableTabs.value.length > 0) {
|
if (editableTabs.value.length > 0) {
|
||||||
const first = editableTabs.value[0];
|
const first = editableTabs.value[0];
|
||||||
editableTabsKey.value = first.id;
|
editableTabsKey.value = first.id;
|
||||||
editableTabsValue.value = first.path;
|
} else {
|
||||||
editableTabsName.value = first.name;
|
initTabs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
function saveStorageTabs() {
|
||||||
[editableTabs, editableTabsKey],
|
localStorage.setItem('editableTabs', JSON.stringify(editableTabs.value));
|
||||||
([newTabs, newKey]) => {
|
}
|
||||||
localStorage.setItem('editableTabs', JSON.stringify(newTabs));
|
|
||||||
localStorage.setItem('editableTabsKey', newKey);
|
function saveStorageTabsKey() {
|
||||||
},
|
localStorage.setItem('editableTabsKey', editableTabsKey.value);
|
||||||
{ deep: true },
|
}
|
||||||
);
|
|
||||||
|
|
||||||
function getLastPath(path: string): string {
|
function getLastPath(path: string): string {
|
||||||
if (!path) return '';
|
if (!path) return '';
|
||||||
|
|
@ -1852,58 +1824,56 @@ function getLastPath(path: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTab(newPath?: string) {
|
function updateTab(newPath?: string) {
|
||||||
const tab = editableTabs.value.find((t) => t.id === editableTabsKey.value);
|
editableTabs.value = editableTabs.value.map((tab) => {
|
||||||
if (tab) {
|
if (tab.id === editableTabsKey.value) {
|
||||||
tab.path = newPath;
|
return {
|
||||||
tab.name = getLastPath(newPath);
|
...tab,
|
||||||
|
path: newPath,
|
||||||
|
name: getLastPath(newPath),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return tab;
|
||||||
|
});
|
||||||
|
saveStorageTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadPath = async () => {
|
||||||
|
const pathRes = await loadBaseDir();
|
||||||
|
baseDir.value = pathRes.data;
|
||||||
|
};
|
||||||
|
|
||||||
const addTab = () => {
|
const addTab = () => {
|
||||||
if (editableTabs.value.length >= 6) {
|
if (editableTabs.value.length >= 6) {
|
||||||
MsgWarning(i18n.global.t('file.notCanTab'));
|
MsgWarning(i18n.global.t('file.notCanTab'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const usedIds = editableTabs.value.map((t) => Number(t.id));
|
const usedIds = new Set(editableTabs.value.map((t) => Number(t.id)));
|
||||||
let newId = null;
|
const newId = Array.from({ length: 6 }, (_, i) => i + 1).find((id) => !usedIds.has(id));
|
||||||
for (let i = 1; i <= 6; i++) {
|
|
||||||
if (!usedIds.includes(i)) {
|
if (!newId) {
|
||||||
newId = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (newId === null) {
|
|
||||||
MsgWarning(i18n.global.t('file.notCanTab'));
|
MsgWarning(i18n.global.t('file.notCanTab'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
editableTabs.value.push({
|
editableTabs.value.push({
|
||||||
id: String(newId),
|
id: String(newId),
|
||||||
name: 'opt',
|
name: getLastPath(baseDir.value),
|
||||||
path: '/opt',
|
path: baseDir.value,
|
||||||
});
|
});
|
||||||
editableTabsKey.value = String(newId);
|
editableTabsKey.value = String(newId);
|
||||||
changeTab(String(newId));
|
changeTab(newId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeTab = (targetPath: TabPaneName) => {
|
const changeTab = (targetPath: TabPaneName) => {
|
||||||
if (targetPath === 99) {
|
if (targetPath === 99) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
editableTabsKey.value = targetPath.toString();
|
const current = editableTabs.value.find((tab) => tab.id === targetPath.toString());
|
||||||
const current = editableTabs.value.find((tab) => tab.id === editableTabsKey.value);
|
editableTabsKey.value = current.id;
|
||||||
editableTabsName.value = current ? current.name : '';
|
saveStorageTabs();
|
||||||
editableTabsValue.value = current ? current.path : '';
|
saveStorageTabsKey();
|
||||||
req.path = editableTabsValue.value;
|
req.path = current ? current.path : '';
|
||||||
paths.value = [];
|
globalStore.setLastFilePath(req.path);
|
||||||
const segments = editableTabsValue.value.split('/').filter(Boolean);
|
getPaths(req.path);
|
||||||
let url = '';
|
|
||||||
segments.forEach((segment) => {
|
|
||||||
url += '/' + segment;
|
|
||||||
paths.value.push({
|
|
||||||
url,
|
|
||||||
name: segment,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1923,7 +1893,7 @@ const removeTab = (targetId: TabPaneName) => {
|
||||||
}
|
}
|
||||||
editableTabs.value = tabs.filter((t) => String(t.id) !== target);
|
editableTabs.value = tabs.filter((t) => String(t.id) !== target);
|
||||||
editableTabsKey.value = String(nextActive);
|
editableTabsKey.value = String(nextActive);
|
||||||
changeTab(String(nextActive));
|
changeTab(nextActive);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkFFmpeg = () => {
|
const checkFFmpeg = () => {
|
||||||
|
|
@ -1932,6 +1902,19 @@ const checkFFmpeg = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadPath();
|
||||||
|
initShowHidden();
|
||||||
|
initTabsAndPaths();
|
||||||
|
getHostMount();
|
||||||
|
initHistory();
|
||||||
|
checkFFmpeg();
|
||||||
|
nextTick(function () {
|
||||||
|
handlePath();
|
||||||
|
observeResize();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (resizeObserver) resizeObserver.disconnect();
|
if (resizeObserver) resizeObserver.disconnect();
|
||||||
window.removeEventListener('resize', watchTitleHeight);
|
window.removeEventListener('resize', watchTitleHeight);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue