mirror of
https://github.com/tnb-labs/panel.git
synced 2026-10-13 16:58:05 +08:00
fix(file): 补齐弹窗关闭与后台任务结束后的列表刷新
- 终端弹窗关闭后刷新列表,终端里增删的文件此前要手动刷新才能看到 - 编辑器关闭或最小化时刷新列表,同步保存后的大小和修改时间;编辑时列表被遮罩盖住,无需每次保存都刷新 - 压缩、解压、远程下载是后台任务,提交后轮询任务状态,队列清空再刷新一次;多处提交共用一个轮询,查询失败静默停止 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,9 +5,11 @@ import { useGettext } from 'vue3-gettext'
|
||||
import api from '@/api/panel/file'
|
||||
import { useFileStore } from '@/stores'
|
||||
import { generateRandomString, lastDirectory } from '@/utils'
|
||||
import { useFileOps } from '@/views/file/composables/useFileOps'
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
const fileStore = useFileStore()
|
||||
const { refreshAfterTasks } = useFileOps()
|
||||
const show = defineModel<boolean>('show', { type: Boolean, required: true })
|
||||
const path = defineModel<string>('path', { type: String, required: true })
|
||||
// 打开时快照选中项,弹窗内移除不影响列表选中状态
|
||||
@@ -39,6 +41,7 @@ const handleArchive = () => {
|
||||
window.$message.success(
|
||||
$gettext('Compress task created successfully, please check the task list for progress'),
|
||||
)
|
||||
refreshAfterTasks()
|
||||
})
|
||||
.onComplete(() => {
|
||||
loading.value = false
|
||||
|
||||
@@ -99,6 +99,12 @@ function loadFile(path: string) {
|
||||
openInEditor(path)
|
||||
}
|
||||
|
||||
// 列表重新可见时恢复快捷键,并刷新以同步保存后的大小和修改时间
|
||||
function releaseList() {
|
||||
window.$bus.emit('file:keyboard-resume')
|
||||
window.$bus.emit('file:refresh')
|
||||
}
|
||||
|
||||
// 打开时自动加载文件
|
||||
watch(show, (newShow) => {
|
||||
if (newShow && filePath.value) {
|
||||
@@ -112,8 +118,7 @@ watch(show, (newShow) => {
|
||||
// 加载文件
|
||||
loadFile(filePath.value)
|
||||
} else if (!newShow) {
|
||||
// 恢复文件管理的键盘快捷键
|
||||
window.$bus.emit('file:keyboard-resume')
|
||||
releaseList()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -127,7 +132,7 @@ watch(filePath, (newPath) => {
|
||||
// 监听最小化状态
|
||||
watch(minimized, (isMinimized) => {
|
||||
if (isMinimized) {
|
||||
window.$bus.emit('file:keyboard-resume')
|
||||
releaseList()
|
||||
} else {
|
||||
window.$bus.emit('file:keyboard-pause')
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ const { $gettext } = useGettext()
|
||||
const themeVars = useThemeVars()
|
||||
const fileStore = useFileStore()
|
||||
const { handlePaste: doPaste } = usePaste()
|
||||
const { deletePaths, movePath, markClipboard } = useFileOps()
|
||||
const { deletePaths, movePath, markClipboard, refreshAfterTasks } = useFileOps()
|
||||
|
||||
const props = defineProps<{
|
||||
tabId: string
|
||||
@@ -774,6 +774,10 @@ const openTerminal = (item: any) => {
|
||||
terminalModal.value = true
|
||||
}
|
||||
|
||||
watch(terminalModal, (show) => {
|
||||
if (!show) window.$bus.emit('file:refresh')
|
||||
})
|
||||
|
||||
// 打开属性弹窗
|
||||
const openProperty = (item: any) => {
|
||||
propertyFileInfo.value = item as FileInfo
|
||||
@@ -1291,6 +1295,7 @@ const handleUnCompress = () => {
|
||||
window.$message.success(
|
||||
$gettext('Uncompress task created successfully, please check the task list for progress'),
|
||||
)
|
||||
refreshAfterTasks()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const { $gettext } = useGettext()
|
||||
const fileStore = useFileStore()
|
||||
const uploadStore = useUploadStore()
|
||||
const { handlePaste: doPaste } = usePaste()
|
||||
const { deletePaths, markClipboard } = useFileOps()
|
||||
const { deletePaths, markClipboard, refreshAfterTasks } = useFileOps()
|
||||
|
||||
const props = defineProps<{
|
||||
tabId: string
|
||||
@@ -29,6 +29,9 @@ const selected = computed(() => tab.value.selected)
|
||||
|
||||
// 终端弹窗
|
||||
const terminalModal = ref(false)
|
||||
watch(terminalModal, (show) => {
|
||||
if (!show) window.$bus.emit('file:refresh')
|
||||
})
|
||||
|
||||
const download = ref(false)
|
||||
const downloadLoading = ref(false)
|
||||
@@ -57,6 +60,7 @@ const handleDownload = () => {
|
||||
window.$message.success(
|
||||
$gettext('Download task created successfully, please check the task list for progress'),
|
||||
)
|
||||
refreshAfterTasks()
|
||||
})
|
||||
.onComplete(() => {
|
||||
downloadLoading.value = false
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { promiseTimeout } from '@vueuse/core'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import file from '@/api/panel/file'
|
||||
import task from '@/api/panel/task'
|
||||
import { useEditorStore, useFileStore } from '@/stores'
|
||||
import { lastDirectory } from '@/utils/file'
|
||||
|
||||
// 多处同时提交任务时共用一个轮询
|
||||
let waitingTasks = false
|
||||
|
||||
// 文件操作的统一入口
|
||||
// 操作成功后的编辑器标签页同步、列表刷新、选中清理在此收敛,调用方只负责确认交互
|
||||
// 请求失败的错误弹窗由全局拦截器负责
|
||||
@@ -56,5 +61,21 @@ export function useFileOps() {
|
||||
)
|
||||
}
|
||||
|
||||
return { deletePaths, movePath, markClipboard }
|
||||
// 压缩、解压、远程下载是后台任务,结果要等任务跑完才出现,轮询到队列清空再刷新列表
|
||||
async function refreshAfterTasks() {
|
||||
if (waitingTasks) return
|
||||
waitingTasks = true
|
||||
try {
|
||||
do {
|
||||
await promiseTimeout(1000)
|
||||
} while ((await task.status()).task)
|
||||
window.$bus.emit('file:refresh')
|
||||
} catch {
|
||||
/* empty */
|
||||
} finally {
|
||||
waitingTasks = false
|
||||
}
|
||||
}
|
||||
|
||||
return { deletePaths, movePath, markClipboard, refreshAfterTasks }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user