Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions ui/src/api/admin/workspace/folder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { del, get, post, put } from '../core/request'
import type { FolderSource, FolderItem, RequestParams, FolderRequest } from '@/api/types'
import type { FolderSource, FolderItem, RequestParams, FolderPayload } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'

const getPrefix = (source: FolderSource) => {
Expand All @@ -13,17 +13,17 @@ const getFolderTree = (source: FolderSource, query?: RequestParams) => {
}

/** 更新 Workspace 的文件夹。 */
const putFolder = (folderId: string, source: FolderSource, payload?: FolderRequest) => {
return put<FolderRequest, FolderItem>(`${getPrefix(source)}/${folderId}`, payload)
const putFolder = (folderId: string, source: FolderSource, payload?: FolderPayload) => {
return put<FolderPayload, FolderItem>(`${getPrefix(source)}/${folderId}`, payload)
}

/** 在指定资源模块中创建 Workspace 文件夹。 */
const postFolder = (source: FolderSource, payload: FolderRequest) => {
return post<FolderRequest, FolderItem>(getPrefix(source), payload)
const postFolder = (source: FolderSource, payload: FolderPayload) => {
return post<FolderPayload, FolderItem>(getPrefix(source), payload)
}

/** 删除指定 Workspace 文件夹及其中的资源。 */
const deleteFolder = (source: FolderSource, folderId: string) => {
const deleteFolder = (folderId: string, source: FolderSource) => {
return del<boolean>(`${getPrefix(source)}/${folderId}`)
}

Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/types/folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface FolderItem {
workspace_id?: string
}

export interface FolderRequest {
export interface FolderPayload {
desc?: string | null
name?: string
parent_id?: string | null
Expand Down
104 changes: 56 additions & 48 deletions ui/src/components/business/folder-tree/FolderFormDialog.vue
Original file line number Diff line number Diff line change
@@ -1,104 +1,112 @@
<script setup lang="ts">
import { computed, nextTick, reactive, ref, useTemplateRef } from 'vue'
import { reactive, ref, useTemplateRef } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import type { WorkspaceFolder } from '@/api/types'
import type { FolderFormSubmit } from './types'
import FolderApi from '@/api/admin/workspace/folder'
import type { FolderItem, FolderSource } from '@/api/types'
import { MsgSuccess } from '@/utils/message'

defineOptions({ name: 'FolderFormDialog' })

defineProps<{
loading: boolean
const props = defineProps<{
title: string
source: FolderSource
}>()

const emit = defineEmits<{
submit: [form: FolderFormSubmit]
refresh: [folder: FolderItem, isEdit: boolean]
}>()

interface FolderForm {
desc: string
name: string
parent_id: string
}

const folderFormRef = useTemplateRef<FormInstance>('folderFormRef')
const visible = ref(false)
const editingFolderId = ref('')
const folderForm = reactive<FolderForm>({
const editId = ref('')
const folderForm = reactive({
desc: '',
name: '',
parent_id: '',
})

const dialogTitle = computed(() => (editingFolderId.value ? '编辑文件夹' : '创建文件夹'))
const rules: FormRules<FolderForm> = {
const rules: FormRules<typeof folderForm> = {
name: [{ message: '请输入文件夹名称', required: true, trigger: 'blur' }],
}

function resetData() {
editingFolderId.value = ''
folderForm.desc = ''
folderForm.name = ''
folderForm.parent_id = ''
folderFormRef.value?.clearValidate()
const loading = ref(false)
function handleSubmit() {
folderFormRef.value?.validate((valid) => {
if (!valid) return
loading.value = true
const isEdit = Boolean(editId.value)
const request = isEdit
? FolderApi.putFolder(editId.value, props.source, folderForm)
: FolderApi.postFolder(props.source, folderForm)

return request
.then((folder) => {
MsgSuccess(isEdit ? '保存成功' : '创建成功')
visible.value = false
emit('refresh', folder, isEdit)
})
.finally(() => {
loading.value = false
})
})
}

function open(parentId: string, folder?: WorkspaceFolder) {
resetData()
editingFolderId.value = folder?.id ?? ''
folderForm.desc = folder?.desc ?? ''
folderForm.name = folder?.name ?? ''
folderForm.parent_id = folder?.parent_id ?? parentId
function open(id: string, folder?: FolderItem) {
if (folder) {
// 编辑当前id
editId.value = folder?.id
folderForm.name = folder?.name ?? ''
folderForm.desc = folder?.desc ?? ''
folderForm.parent_id = folder.parent_id ?? ''
} else {
// 给当前id添加子id
folderForm.parent_id = id
}

visible.value = true
nextTick(() => folderFormRef.value?.clearValidate())
}

function close() {
visible.value = false
resetData()
}

function handleSubmit() {
folderFormRef.value?.validate((valid) => {
if (!valid) return
emit('submit', {
folderId: editingFolderId.value || undefined,
payload: {
desc: folderForm.desc.trim(),
name: folderForm.name.trim(),
parent_id: folderForm.parent_id,
},
})
})
function resetData() {
editId.value = ''
folderForm.desc = ''
folderForm.name = ''
folderForm.parent_id = ''
folderFormRef.value?.clearValidate()
}

defineExpose({ close, open })
</script>

<template>
<MkDialog v-model="visible" :title="dialogTitle" width="600" @closed="resetData">
<MkDialog v-model="visible" :title="title" @closed="resetData">
<el-form
ref="folderFormRef"
:model="folderForm"
:rules="rules"
label-position="top"
require-asterisk-position="right"
@submit.prevent
>
<el-form-item label="名称" prop="name">
<el-input
v-model="folderForm.name"
maxlength="64"
placeholder="请输入文件夹名称"
placeholder="请输入名称"
show-word-limit
@blur="folderForm.name = folderForm.name.trim()"
/>
</el-form-item>
<el-form-item label="描述" prop="desc">
<el-input
v-model="folderForm.desc"
:autosize="{ minRows: 3 }"
maxlength="200"
placeholder="请输入文件夹描述"
placeholder="请输入描述"
maxlength="128"
show-word-limit
:autosize="{ minRows: 3 }"
type="textarea"
@blur="folderForm.desc = folderForm.desc.trim()"
/>
Expand All @@ -108,7 +116,7 @@ defineExpose({ close, open })
<template #footer>
<el-button :disabled="loading" @click="close">取消</el-button>
<el-button type="primary" :loading="loading" @click="handleSubmit">
{{ editingFolderId ? '保存' : '创建' }}
{{ editId ? '保存' : '创建' }}
</el-button>
</template>
</MkDialog>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import type { WorkspaceFolder } from '@/api/types'
import type { FolderMoveSubmit } from './types'
import FolderVirtualizedTree from './VirtualizedTree.vue'
import type { FolderMoveSubmit } from './types.ts'
import FolderTree from './index.vue'

defineOptions({ name: 'MoveFolderDialog' })

Expand Down Expand Up @@ -79,24 +79,31 @@ function handleSubmit() {
})
}

// function handleMoveFolder({ folder, targetFolderId }: FolderMoveSubmit) {
// submiting.value = true
// return FolderApi.putFolder(workspaceId, props.source, folder.id, {
// parent_id: targetFolderId,
// })
// .then((updatedFolder) => {
// MsgSuccess('移动成功')
// moveFolderDialogRef.value?.close()
// return loadFolders().then(() => emit('moved', updatedFolder))
// })
// .finally(() => {
// submiting.value = false
// })
// }

defineExpose({ close, open })
</script>

<template>
<MkDialog v-model="visible" title="移动到" width="600" @closed="resetData">
<div class="flex h-100 flex-col gap-3">
<MkSearchInput v-model="searchKeyword" class="shrink-0" />
<div class="min-h-0 flex-1 rounded-md border p-2">
<FolderVirtualizedTree
:can-manage="false"
:current-node-key="selectedTargetId"
:data="moveFolders"
:filter-text="searchKeyword"
@select="handleTargetSelect"
/>
</div>
</div>

<MkDialog v-model="visible" title="移动到" @closed="resetData">
<FolderTree
:current-node-key="selectedTargetId"
:data="moveFolders"
@select="handleTargetSelect"
/>
<template #footer>
<el-button :disabled="loading" @click="close">取消</el-button>
<el-button type="primary" :disabled="!canSubmit" :loading="loading" @click="handleSubmit">
Expand Down
5 changes: 2 additions & 3 deletions ui/src/components/business/folder-tree/VirtualizedTree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ function containsCurrentFolder(folder: FolderTreeNode): boolean {
}

function handleStat<T extends FolderStat>(stat: T): T {
stat.open = stat.level === 1
if (props.filterText || containsCurrentFolder(stat.data)) stat.open = true
return stat
}
Expand Down Expand Up @@ -157,8 +156,8 @@ function handleAfterDrop() {
</slot>
</template>

<template #action-dropdown="{ row }">
<slot name="action-dropdown" :row="row"></slot>
<template #action-dropdown>
<slot name="action-dropdown" :row="node"></slot>
</template>
</MkListItem>
</template>
Expand Down
Loading
Loading