diff --git a/web/src/views/file/ListView.vue b/web/src/views/file/ListView.vue index 84b9e6b4..f6f9fc1f 100644 --- a/web/src/views/file/ListView.vue +++ b/web/src/views/file/ListView.vue @@ -70,6 +70,12 @@ const inlineRenameItem = ref(null) const inlineRenameName = ref('') const inlineRenameInputRef = ref(null) +// 内联新建状态 +const inlineCreateActive = ref(false) +const inlineCreateIsDir = ref(false) +const inlineCreateName = ref('') +const inlineCreateInputRef = ref(null) + // 设置内联重命名输入框 ref 的函数 const setInlineRenameRef = (el: any) => { if (el) { @@ -77,6 +83,78 @@ const setInlineRenameRef = (el: any) => { } } +// 设置内联新建输入框 ref 的函数 +const setInlineCreateRef = (el: any) => { + if (el) { + inlineCreateInputRef.value = el + } +} + +// 启动内联新建 +const startInlineCreate = (isDir: boolean) => { + // 取消正在进行的重命名 + cancelInlineRename() + + inlineCreateActive.value = true + inlineCreateIsDir.value = isDir + inlineCreateName.value = '' + + // 等待 DOM 更新后聚焦输入框 + nextTick(() => { + if (inlineCreateInputRef.value) { + inlineCreateInputRef.value.focus() + } + }) +} + +// 取消内联新建 +const cancelInlineCreate = () => { + inlineCreateActive.value = false + inlineCreateIsDir.value = false + inlineCreateName.value = '' +} + +// 提交内联新建 +const submitInlineCreate = () => { + if (!inlineCreateActive.value) return + + const name = inlineCreateName.value.trim() + + // 如果名称为空,直接取消 + if (!name) { + cancelInlineCreate() + return + } + + // 验证名称 + if (!checkName(name)) { + window.$message.error($gettext('Invalid name')) + return + } + + const fullPath = path.value + '/' + name + + useRequest(file.create(fullPath, inlineCreateIsDir.value)) + .onSuccess(() => { + window.$bus.emit('file:refresh') + window.$message.success($gettext('Created successfully')) + }) + .onComplete(() => { + cancelInlineCreate() + }) +} + +// 处理内联新建键盘事件 +const handleInlineCreateKeydown = (event: KeyboardEvent) => { + if (event.key === 'Enter') { + event.preventDefault() + submitInlineCreate() + } else if (event.key === 'Escape') { + event.preventDefault() + cancelInlineCreate() + } +} + const unCompressModal = ref(false) const unCompressModel = ref({ path: '', @@ -1136,6 +1214,7 @@ onMounted(() => { window.$bus.on('file:refresh', refresh) window.$bus.on('file:keyboard-pause', pauseKeyboard) window.$bus.on('file:keyboard-resume', resumeKeyboard) + window.$bus.on('file:inline-create', startInlineCreate) // 添加全局鼠标事件监听 document.addEventListener('mousemove', onSelectionMove) @@ -1157,6 +1236,7 @@ onUnmounted(() => { window.$bus.off('file:refresh', refresh) window.$bus.off('file:keyboard-pause', pauseKeyboard) window.$bus.off('file:keyboard-resume', resumeKeyboard) + window.$bus.off('file:inline-create', startInlineCreate) document.removeEventListener('mousemove', onSelectionMove) document.removeEventListener('mouseup', onSelectionEnd) document.removeEventListener('keydown', handleKeyDown) @@ -1206,6 +1286,53 @@ onUnmounted(() => {
{{ $gettext('Actions') }}
+ +
+ + + + +
+
('permission', { type: Boolean, required: const terminalModal = ref(false) const upload = ref(false) -const create = ref(false) -const createModel = ref({ - dir: false, - path: '' -}) const download = ref(false) const downloadModel = ref({ path: '', @@ -33,23 +28,8 @@ const downloadModel = ref({ }) const showCreate = (value: string) => { - createModel.value.dir = value !== 'file' - createModel.value.path = '' - create.value = true -} - -const handleCreate = () => { - if (!checkName(createModel.value.path)) { - window.$message.error($gettext('Invalid name')) - return - } - - const fullPath = path.value + '/' + createModel.value.path - useRequest(file.create(fullPath, createModel.value.dir)).onSuccess(() => { - create.value = false - window.$bus.emit('file:refresh') - window.$message.success($gettext('Created successfully')) - }) + // 触发内联新建事件 + window.$bus.emit('file:inline-create', value !== 'file') } const handleDownload = () => { @@ -299,24 +279,6 @@ const handleSortSelect = (key: string) => {
- - - - - - - - {{ $gettext('Submit') }} - -