Files
service-finder/frontend_admin/components/TreeNode.vue
2026-07-01 02:27:38 +00:00

68 lines
2.1 KiB
Vue

<template>
<div>
<div class="flex items-center gap-2 py-1">
<button
@click="$emit('toggle-expand', node.id)"
class="text-slate-500 hover:text-slate-300 transition w-4 h-4 flex items-center justify-center"
>
<svg
class="w-3 h-3 transition-transform"
:class="expandedIds.has(node.id) ? 'rotate-90' : ''"
fill="none" stroke="currentColor" viewBox="0 0 24 24"
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<label class="flex items-center gap-2 cursor-pointer flex-1">
<input
type="checkbox"
:checked="selectedIds.includes(node.id)"
@change="$emit('toggle', node.id)"
class="w-4 h-4 rounded border-slate-500 bg-slate-700 text-indigo-500 focus:ring-indigo-500/50"
/>
<span class="text-sm text-slate-300">{{ node.name_hu || node.name_en || node.key }}</span>
<span class="text-xs text-slate-500">(Szint {{ node.level }})</span>
</label>
</div>
<div v-if="expandedIds.has(node.id) && node.children?.length" class="ml-6 border-l border-slate-700 pl-3">
<div v-for="child in node.children" :key="child.id">
<TreeNode
:node="child"
:selected-ids="selectedIds"
:expanded-ids="expandedIds"
@toggle="(id: number) => $emit('toggle', id)"
@toggle-expand="(id: number) => $emit('toggle-expand', id)"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
/**
* Recursive TreeNode component for the category tree.
* Renders a checkbox tree with expand/collapse for nested categories.
*/
interface CategoryTreeNode {
id: number
key: string
name_hu?: string | null
name_en?: string | null
level: number
path?: string | null
is_official: boolean
children: CategoryTreeNode[]
}
defineProps<{
node: CategoryTreeNode
selectedIds: number[]
expandedIds: Set<number>
}>()
defineEmits<{
toggle: [id: number]
'toggle-expand': [id: number]
}>()
</script>