mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-09-05 06:04:35 +08:00
fix: Resolve file renaming and other operational conflicts (#10162)
This commit is contained in:
parent
8663ed129d
commit
abf3247c50
11 changed files with 47 additions and 15 deletions
|
@ -112,7 +112,7 @@ const rightClick = ref({
|
|||
currentRow: null,
|
||||
});
|
||||
const handleRightClick = (row, column, event) => {
|
||||
tableRef.value.refElTable.clearSelection();
|
||||
clearSelects();
|
||||
tableRef.value.refElTable.toggleRowSelection(row);
|
||||
if (!props.rightButtons) {
|
||||
return;
|
||||
|
@ -128,7 +128,7 @@ const handleRightClick = (row, column, event) => {
|
|||
};
|
||||
const closeRightClick = () => {
|
||||
rightClick.value.visible = false;
|
||||
tableRef.value.refElTable.clearSelection();
|
||||
clearSelects();
|
||||
document.removeEventListener('click', closeRightClick);
|
||||
};
|
||||
const disabled = computed(() => {
|
||||
|
|
|
@ -1509,6 +1509,7 @@ const message = {
|
|||
noShowHide: 'Don’t show hidden files',
|
||||
cancelUpload: 'Cancel Upload',
|
||||
cancelUploadHelper: 'Whether to cancel the upload, after cancellation the upload list will be cleared.',
|
||||
keepOneTab: 'Keep at least one tab',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: 'Auto start',
|
||||
|
@ -3660,7 +3661,7 @@ const message = {
|
|||
taskName: 'Task Name',
|
||||
cronJobType: 'Task Type',
|
||||
clamPath: 'Scan Directory',
|
||||
cronjob: 'Cronjob',
|
||||
cronjob: 'Cronjob execution {0} failed',
|
||||
app: 'Backup App',
|
||||
web: 'Backup Website',
|
||||
database: 'Backup Database',
|
||||
|
|
|
@ -1453,6 +1453,7 @@ const message = {
|
|||
noShowHide: '隠しファイルを表示しない',
|
||||
cancelUpload: 'アップロードをキャンセル',
|
||||
cancelUploadHelper: 'アップロードをキャンセルするかどうか、キャンセル後、アップロードリストはクリアされます。',
|
||||
keepOneTab: '少なくとも1つのタブを保持してください',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: 'オートスタート',
|
||||
|
@ -3538,7 +3539,7 @@ const message = {
|
|||
taskName: 'タスク名',
|
||||
cronJobType: 'タスクタイプ',
|
||||
clamPath: 'スキャンディレクトリ',
|
||||
cronjob: 'Cronジョブ',
|
||||
cronjob: 'スケジュールタスクの実行{0}で異常が発生しました',
|
||||
app: 'アプリバックアップ',
|
||||
web: 'ウェブサイトバックアップ',
|
||||
database: 'データベースバックアップ',
|
||||
|
|
|
@ -1438,6 +1438,7 @@ const message = {
|
|||
noShowHide: '숨김 파일 숨기기',
|
||||
cancelUpload: '업로드 취소',
|
||||
cancelUploadHelper: '업로드를 취소할지 여부, 취소 후 업로드 목록이 비워집니다.',
|
||||
keepOneTab: '최소한 하나의 탭을 유지하세요',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: '자동 시작',
|
||||
|
@ -3476,7 +3477,7 @@ const message = {
|
|||
taskName: '작업 이름',
|
||||
cronJobType: '작업 유형',
|
||||
clamPath: '검사 디렉토리',
|
||||
cronjob: '크론 작업',
|
||||
cronjob: '예약 작업 실행 {0} 중 오류가 발생했습니다',
|
||||
app: '백업 애플리케이션',
|
||||
web: '백업 웹사이트',
|
||||
database: '백업 데이터베이스',
|
||||
|
|
|
@ -1496,6 +1496,7 @@ const message = {
|
|||
cancelUpload: 'Batalkan Muat Naik',
|
||||
cancelUploadHelper:
|
||||
'Adakah hendak membatalkan muat naik, selepas pembatalan senarai muat naik akan dikosongkan.',
|
||||
keepOneTab: 'Pastikan sekurang-kurangnya satu tab dikekalkan',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: 'Mula automatik',
|
||||
|
@ -3624,7 +3625,7 @@ const message = {
|
|||
taskName: 'Nama Tugas',
|
||||
cronJobType: 'Jenis Tugas',
|
||||
clamPath: 'Direktori Imbasan',
|
||||
cronjob: 'Cronjob',
|
||||
cronjob: 'Pelaksanaan tugas berjadual {0} gagal',
|
||||
app: 'Sandaran Aplikasi',
|
||||
web: 'Sandaran Laman Web',
|
||||
database: 'Sandaran Pangkalan Data',
|
||||
|
|
|
@ -1483,6 +1483,7 @@ const message = {
|
|||
noShowHide: 'Não mostrar arquivos ocultos',
|
||||
cancelUpload: 'Cancelar Upload',
|
||||
cancelUploadHelper: 'Deseja cancelar o upload, após o cancelamento, a lista de upload será limpa.',
|
||||
keepOneTab: 'Mantenha pelo menos uma aba',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: 'Início automático',
|
||||
|
@ -3632,7 +3633,7 @@ const message = {
|
|||
taskName: 'Nome da Tarefa',
|
||||
cronJobType: 'Tipo de Tarefa',
|
||||
clamPath: 'Diretório de Varredura',
|
||||
cronjob: 'Tarefa Cron',
|
||||
cronjob: 'Tarefa Cron agendada {0} falhou',
|
||||
app: 'Backup do Aplicativo',
|
||||
web: 'Backup do Site',
|
||||
database: 'Backup do Banco de Dados',
|
||||
|
|
|
@ -1484,6 +1484,7 @@ const message = {
|
|||
noShowHide: 'Не показывать скрытые файлы',
|
||||
cancelUpload: 'Отменить загрузку',
|
||||
cancelUploadHelper: 'Отменить загрузку или нет, после отмены список загрузок будет очищен.',
|
||||
keepOneTab: 'Необходимо оставить как минимум одну вкладку',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: 'Автозапуск',
|
||||
|
@ -3618,7 +3619,7 @@ const message = {
|
|||
taskName: 'Имя задачи',
|
||||
cronJobType: 'Тип задачи',
|
||||
clamPath: 'Директория проверки',
|
||||
cronjob: 'Задача Cron',
|
||||
cronjob: 'Ошибка при выполнении Задача cron {0}',
|
||||
app: 'Резервное копирование приложения',
|
||||
web: 'Резервное копирование сайта',
|
||||
database: 'Резервное копирование базы данных',
|
||||
|
|
|
@ -1526,6 +1526,7 @@ const message = {
|
|||
noShowHide: 'Gizli dosyaları gösterme',
|
||||
cancelUpload: 'Yüklemeyi İptal Et',
|
||||
cancelUploadHelper: 'Yüklemeyi iptal etmek ister misiniz, iptal sonrası yükleme listesi temizlenecektir.',
|
||||
keepOneTab: 'En az bir sekme açık kalmalıdır',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: 'Otomatik başlat',
|
||||
|
@ -3693,7 +3694,7 @@ const message = {
|
|||
success: 'Uyarı Başarılı',
|
||||
pushing: 'Gönderiliyor...',
|
||||
error: 'Uyarı Başarısız',
|
||||
cleanLog: 'Günlükleri Temizle',
|
||||
cleanLog: 'Zamanlanmış görev yürütmesi {0} hatası',
|
||||
cleanAlertLogs: 'Uyarı Günlüklerini Temizle',
|
||||
daily: 'Günlük Uyarı Sayısı: {0}',
|
||||
cumulative: 'Toplam Uyarı Sayısı: {0}',
|
||||
|
|
|
@ -1438,6 +1438,7 @@ const message = {
|
|||
noShowHide: '不顯示隱藏檔案',
|
||||
cancelUpload: '取消上傳',
|
||||
cancelUploadHelper: '是否取消上傳,取消後將清空上傳列表',
|
||||
keepOneTab: '至少保留一個標籤頁',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: '開機自啟',
|
||||
|
@ -3405,7 +3406,7 @@ const message = {
|
|||
taskName: '任務名稱',
|
||||
cronJobType: '任務類型',
|
||||
clamPath: '掃描目錄',
|
||||
cronjob: '計劃任務',
|
||||
cronjob: '計劃任務執行{0}異常',
|
||||
app: '備份應用',
|
||||
web: '備份網站',
|
||||
database: '備份資料庫',
|
||||
|
|
|
@ -1433,6 +1433,7 @@ const message = {
|
|||
noShowHide: '不显示隐藏文件',
|
||||
cancelUpload: '取消上传',
|
||||
cancelUploadHelper: '是否取消上传,取消后将清空上传列表',
|
||||
keepOneTab: '至少保留一个标签页',
|
||||
},
|
||||
ssh: {
|
||||
autoStart: '开机自启',
|
||||
|
|
|
@ -471,7 +471,8 @@
|
|||
:autofocus="isEdit"
|
||||
class="table-link table-input"
|
||||
placeholder="file name"
|
||||
@blur="handleRename(row)"
|
||||
@keydown.enter="handleRename(row)"
|
||||
@blur="onRenameBlur($event, row)"
|
||||
/>
|
||||
<span v-else class="table-link" @click="open(row)" type="primary">
|
||||
{{ row.name }}
|
||||
|
@ -584,7 +585,7 @@
|
|||
</LayoutContent>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :closable="false">
|
||||
<el-tab-pane :closable="false" v-if="editableTabs.length < 6">
|
||||
<template #label>
|
||||
<el-icon @click="addTab()"><Plus /></el-icon>
|
||||
</template>
|
||||
|
@ -906,8 +907,8 @@ const updateButtons = async () => {
|
|||
|
||||
const handlePath = () => {
|
||||
nextTick(function () {
|
||||
let breadCrumbWidth = breadCrumbRef.value.offsetWidth;
|
||||
let pathWidth = toolRef.value.offsetWidth;
|
||||
let breadCrumbWidth = breadCrumbRef.value?.offsetWidth;
|
||||
let pathWidth = toolRef.value?.offsetWidth;
|
||||
if (pathWidth - breadCrumbWidth < 50 && paths.value.length > 1) {
|
||||
const removed = paths.value.shift();
|
||||
if (removed) hidePaths.value.push(removed);
|
||||
|
@ -1281,6 +1282,20 @@ const openRename = (item: File.File) => {
|
|||
hideRightMenu();
|
||||
};
|
||||
|
||||
const onRenameBlur = (e: FocusEvent, row: File.File) => {
|
||||
const related = e.relatedTarget as HTMLElement | null;
|
||||
if (
|
||||
related &&
|
||||
(related.closest('.fu-table-more-button') || related.closest('.fu-table-more-button .el-dropdown__item'))
|
||||
) {
|
||||
setTimeout(() => {
|
||||
getCurrentRename()?.focus();
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
handleRename(row);
|
||||
};
|
||||
|
||||
const handleRename = async (row: File.File): Promise<void> => {
|
||||
if (fileRename.newName === fileRename.oldName) {
|
||||
isEdit.value = false;
|
||||
|
@ -1584,7 +1599,7 @@ onMounted(() => {
|
|||
req.path = globalStore.lastFilePath;
|
||||
getPaths(req.path);
|
||||
}
|
||||
pathWidth.value = getCurrentPath().offsetWidth;
|
||||
pathWidth.value = getCurrentPath()?.offsetWidth;
|
||||
paths.value = [];
|
||||
|
||||
const segments = editableTabsValue.value.split('/').filter(Boolean);
|
||||
|
@ -1670,6 +1685,9 @@ function updateTab(newPath?: string) {
|
|||
|
||||
const addTab = () => {
|
||||
let tabIndex = editableTabs.value.length;
|
||||
if (tabIndex >= 6) {
|
||||
return;
|
||||
}
|
||||
const newTabId = `${++tabIndex}`;
|
||||
editableTabs.value.push({
|
||||
id: newTabId,
|
||||
|
@ -1695,6 +1713,11 @@ const changeTab = (targetPath: TabPaneName) => {
|
|||
};
|
||||
|
||||
const removeTab = (targetPath: TabPaneName) => {
|
||||
let tabIndex = editableTabs.value.length;
|
||||
if (tabIndex === 1) {
|
||||
MsgWarning(i18n.global.t('file.keepOneTab'));
|
||||
return;
|
||||
}
|
||||
editableTabsKey.value = targetPath.toString();
|
||||
const tabs = editableTabs.value;
|
||||
let activeKey = editableTabsKey.value;
|
||||
|
|
Loading…
Add table
Reference in a new issue