File size: 2,850 Bytes
8ede856
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<template>
    <div class="base-move-target-node">
        <v-list-item :active="selectedFolderId === folder.folder_id" :disabled="isDisabled"
            @click.stop="!isDisabled && $emit('select', folder.folder_id)" rounded="lg"
            :style="{ paddingLeft: `${(depth + 1) * 16}px` }" class="folder-item">
            <template v-slot:prepend>
                <v-btn v-if="hasChildren" icon variant="text" size="x-small" @click.stop="toggleExpand"
                    class="expand-btn" :disabled="isDisabled">
                    <v-icon size="16">{{ isExpanded ? 'mdi-chevron-down' : 'mdi-chevron-right' }}</v-icon>
                </v-btn>
                <div v-else class="expand-placeholder"></div>
                <v-icon :color="isDisabled ? 'grey' : (selectedFolderId === folder.folder_id ? 'primary' : '')">
                    {{ isExpanded ? 'mdi-folder-open' : 'mdi-folder' }}
                </v-icon>
            </template>
            <v-list-item-title class="text-truncate">{{ folder.name }}</v-list-item-title>
        </v-list-item>

        <!-- 子文件夹 -->
        <v-expand-transition>
            <div v-show="isExpanded && hasChildren">
                <BaseMoveTargetNode v-for="child in folder.children" :key="child.folder_id" :folder="child" :depth="depth + 1"
                    :selected-folder-id="selectedFolderId" :disabled-folder-ids="disabledFolderIds"
                    @select="$emit('select', $event)" />
            </div>
        </v-expand-transition>
    </div>
</template>

<script lang="ts">
import { defineComponent, type PropType } from 'vue';
import type { FolderTreeNode } from './types';

export default defineComponent({
    name: 'BaseMoveTargetNode',
    props: {
        folder: {
            type: Object as PropType<FolderTreeNode>,
            required: true
        },
        depth: {
            type: Number,
            default: 0
        },
        selectedFolderId: {
            type: String as PropType<string | null>,
            default: null
        },
        disabledFolderIds: {
            type: Array as PropType<string[]>,
            default: () => []
        }
    },
    emits: ['select'],
    data() {
        return {
            isExpanded: true
        };
    },
    computed: {
        hasChildren(): boolean {
            return this.folder.children && this.folder.children.length > 0;
        },
        isDisabled(): boolean {
            return this.disabledFolderIds.includes(this.folder.folder_id);
        }
    },
    methods: {
        toggleExpand() {
            this.isExpanded = !this.isExpanded;
        }
    }
});
</script>

<style scoped>
.base-move-target-node {
    width: 100%;
}

.folder-item {
    min-height: 36px;
}

.expand-btn {
    margin-right: 4px;
}

.expand-placeholder {
    width: 28px;
    flex-shrink: 0;
}
</style>