From c5ec8ccd32976577ea5dc9289775ff083983797c Mon Sep 17 00:00:00 2001 From: Khafid Prayoga Date: Tue, 16 Sep 2025 15:14:37 +0700 Subject: [PATCH] fix(select-tree): adjust tree node indentation and alignment logic - Add level prop to track node hierarchy - Fix indentation calculation for leaves and nodes - Simplify alignment logic based on node level --- app/components/pub/base/select-tree/leaf.vue | 2 +- .../pub/base/select-tree/tree-node.vue | 11 +++-------- .../pub/base/select-tree/tree-select.vue | 1 + .../pub/base/select-tree/tree-view.vue | 16 +++++++++++++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/components/pub/base/select-tree/leaf.vue b/app/components/pub/base/select-tree/leaf.vue index 1dc8c892..81dabf2b 100644 --- a/app/components/pub/base/select-tree/leaf.vue +++ b/app/components/pub/base/select-tree/leaf.vue @@ -21,7 +21,7 @@ function handleSelect(value: string) { {{ item.label }} diff --git a/app/components/pub/base/select-tree/tree-node.vue b/app/components/pub/base/select-tree/tree-node.vue index da7a0bdf..e390b7bb 100644 --- a/app/components/pub/base/select-tree/tree-node.vue +++ b/app/components/pub/base/select-tree/tree-node.vue @@ -7,14 +7,13 @@ const props = defineProps<{ item: TreeItem selectedValue?: string onFetchChildren: (parentId: string) => Promise + level?: number }>() const emit = defineEmits(['select']) -// Computed untuk memastikan reactivity pada children const hasChildren = computed(() => props.item.children && props.item.children.length > 0) -// State terpisah untuk chevron animation dan loading const isOpen = ref(false) const isLoading = ref(false) const isChevronRotated = ref(false) @@ -27,14 +26,11 @@ function handleLabelClick() { handleSelect(props.item.value) } -// Watch untuk handle fetch data ketika collapsible dibuka watch(isOpen, async (newValue) => { console.log(`[TreeNode] ${props.item.label} - isOpen changed to:`, newValue) - // Update chevron rotation berdasarkan open state isChevronRotated.value = newValue - // Jika membuka dan belum ada children, fetch data if (newValue && props.item.hasChildren && !props.item.children && !isLoading.value) { console.log(`[TreeNode] Fetching children for: ${props.item.label}`) isLoading.value = true @@ -65,9 +61,7 @@ watch(isOpen, async (newValue) => { variant="ghost" class="h-4 w-4 p-0 flex items-center justify-center" > - - { - +
{{ isLoading ? 'Memuat...' : 'Tidak ada data' }}
@@ -102,6 +96,7 @@ watch(isOpen, async (newValue) => { :data="item.children!" :selected-value="selectedValue" :on-fetch-children="onFetchChildren" + :level="(level || 0) + 1" @select="handleSelect" />
diff --git a/app/components/pub/base/select-tree/tree-select.vue b/app/components/pub/base/select-tree/tree-select.vue index 3a7cafd8..d0525336 100644 --- a/app/components/pub/base/select-tree/tree-select.vue +++ b/app/components/pub/base/select-tree/tree-select.vue @@ -58,6 +58,7 @@ const selectedLabel = computed(() => { :data="data" :selected-value="modelValue" :on-fetch-children="onFetchChildren" + :level="0" @select="handleSelect" /> diff --git a/app/components/pub/base/select-tree/tree-view.vue b/app/components/pub/base/select-tree/tree-view.vue index abe6c0de..dfc51d5c 100644 --- a/app/components/pub/base/select-tree/tree-view.vue +++ b/app/components/pub/base/select-tree/tree-view.vue @@ -7,6 +7,7 @@ const props = defineProps<{ data: TreeItem[] selectedValue?: string onFetchChildren: (parentId: string) => Promise + level?: number }>() const emit = defineEmits(['select']) @@ -19,25 +20,34 @@ function handleSelect(value: string) { const hasAnyChildrenInLevel = computed(() => { return props.data.some(item => item.hasChildren) }) + +// Computed untuk menentukan apakah perlu alignment berdasarkan level +const shouldAlignLeaves = computed(() => { + // Di root level (level 0), selalu align leaf dengan tree nodes jika ada mixed content + // Di level lain, hanya align jika ada mixed content + const isRootLevel = (props.level || 0) === 0 + const hasMixedContent = hasAnyChildrenInLevel.value && props.data.some(item => !item.hasChildren) + + return isRootLevel ? hasAnyChildrenInLevel.value : hasMixedContent +})