Files
simrsx-fe/app/components/app/division/tree.vue
T
2025-10-20 23:41:23 +07:00

166 lines
5.7 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import TreeSelect from '~/components/pub/my-ui/select-tree/tree-select.vue'
/**
* DEMO COMPONENT - Tree Select dengan Lazy Loading
*
* Komponen ini adalah contoh penggunaan TreeSelect dengan data teknologi.
* Untuk penggunaan dalam aplikasi nyata, lihat komponen content/division/entry.vue
* yang menggunakan tree select untuk data divisi rumah sakit.
*/
// Tipe data untuk konsistensi
interface TreeItem {
value: string
label: string
hasChildren: boolean
children?: TreeItem[]
}
// State untuk data pohon demo - data teknologi sebagai contoh
const treeData = ref<TreeItem[]>([
{ value: 'frontend', label: 'Frontend Development', hasChildren: true },
{ value: 'backend', label: 'Backend Development', hasChildren: true },
{ value: 'mobile', label: 'Mobile Development', hasChildren: true },
{ value: 'devops', label: 'DevOps & Infrastructure', hasChildren: false },
])
// State untuk menampung nilai yang dipilih
const selectedValue = ref<string>()
// --- DEMO LOGIC: SIMULASI API DAN MANIPULASI DATA ---
// Helper: Fungsi rekursif untuk mencari dan menyisipkan data anak ke dalam state
function findAndInsertChildren(nodes: TreeItem[], parentId: string, newChildren: TreeItem[]): boolean {
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]
if (node && node.value === parentId) {
// Gunakan Vue.set equivalent untuk memastikan reactivity
node.children = [...newChildren]
console.log(`[findAndInsertChildren] Updated children for ${parentId}:`, node.children)
return true
}
if (node && node.children && findAndInsertChildren(node.children, parentId, newChildren)) {
return true
}
}
return false
}
// Fungsi demo untuk simulasi fetch data dari API
async function handleFetchChildren(parentId: string): Promise<void> {
console.log(`[DEMO] Mengambil data anak untuk parent: ${parentId}`)
// Simulasi delay API call
await new Promise(resolve => setTimeout(resolve, 600))
let childrenData: TreeItem[] = []
// Sample data berdasarkan parent ID
switch (parentId) {
case 'frontend':
childrenData = [
{ value: 'vue', label: 'Vue.js', hasChildren: true },
{ value: 'react', label: 'React.js', hasChildren: true },
{ value: 'angular', label: 'Angular', hasChildren: false },
{ value: 'svelte', label: 'Svelte', hasChildren: false },
]
break
case 'backend':
childrenData = [
{ value: 'nodejs', label: 'Node.js', hasChildren: true },
{ value: 'python', label: 'Python', hasChildren: true },
{ value: 'golang', label: 'Go', hasChildren: false },
{ value: 'rust', label: 'Rust', hasChildren: false },
]
break
case 'mobile':
childrenData = [
{ value: 'flutter', label: 'Flutter', hasChildren: false },
{ value: 'react-native', label: 'React Native', hasChildren: false },
{ value: 'ionic', label: 'Ionic', hasChildren: false },
]
break
case 'vue':
childrenData = [
{ value: 'nuxt', label: 'Nuxt.js', hasChildren: false },
{ value: 'quasar', label: 'Quasar', hasChildren: false },
]
break
case 'react':
childrenData = [
{ value: 'nextjs', label: 'Next.js', hasChildren: false },
{ value: 'gatsby', label: 'Gatsby', hasChildren: false },
]
break
case 'nodejs':
childrenData = [
{ value: 'express', label: 'Express.js', hasChildren: false },
{ value: 'nestjs', label: 'NestJS', hasChildren: false },
{ value: 'fastify', label: 'Fastify', hasChildren: false },
]
break
case 'python':
childrenData = [
{ value: 'django', label: 'Django', hasChildren: false },
{ value: 'fastapi', label: 'FastAPI', hasChildren: false },
{ value: 'flask', label: 'Flask', hasChildren: false },
]
break
}
// Insert data ke dalam tree state
const success = findAndInsertChildren(treeData.value, parentId, childrenData)
console.log(`[DEMO] Insert children result:`, success)
// Force trigger reactivity
triggerRef(treeData)
console.log(`[DEMO] Current tree data:`, JSON.stringify(treeData.value, null, 2))
}
</script>
<template>
<div class="p-10 max-w-2xl mx-auto">
<div class="mb-6">
<h1 class="mb-2 text-3xl font-bold text-slate-800">Demo: Tree Select dengan Lazy Loading</h1>
<p class="text-slate-600">
Contoh penggunaan komponen TreeSelect dengan data teknologi.
Pilih item untuk melihat sub-kategori yang dimuat secara lazy.
</p>
</div>
<div class="mb-6 p-4 bg-blue-50 border border-blue-200 rounded-lg">
<h3 class="font-semibold text-blue-800 mb-2">💡 Catatan untuk Developer:</h3>
<p class="text-sm text-blue-700">
Untuk implementasi nyata dengan data divisi rumah sakit,
lihat komponen <code class="px-1 bg-blue-100 rounded">content/division/entry.vue</code>
</p>
</div>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-slate-700 mb-2">
Pilih Teknologi:
</label>
<TreeSelect
v-model="selectedValue"
:data="treeData"
:on-fetch-children="handleFetchChildren"
/>
</div>
<div class="p-4 bg-slate-50 rounded-lg">
<p class="text-sm text-slate-600 mb-1">Value yang terpilih:</p>
<span class="px-3 py-1 font-mono text-sm bg-white border rounded-md">
{{ selectedValue || 'Belum ada yang dipilih' }}
</span>
</div>
</div>
<div class="mt-8 text-xs text-slate-500">
<p>🔄 Data dimuat secara lazy saat node parent dibuka</p>
<p> Simulasi delay 600ms untuk menampilkan loading state</p>
</div>
</div>
</template>