feat(division): update division list components and add mock api - Replace patient API endpoint with division mock endpoint - Simplify table columns and headers for division list - Add mock API endpoint for division list with tree/flat format feat(select-tree): add collapsible tree select component with lazy loading Implement a tree select component with collapsible sections and lazy loading of child items. Includes: - Collapsible component wrappers for Vue - Command component wrappers for combobox functionality - Tree select item component with loading states - Example implementation in dev page todo: - scroll on overflow - long text truncate possibly with tooltip - more than > 5 depth of child - mutate the children lazy - integration backend for search based text and return keys feat(select-tree): add command-item component for tree selection adjust hover bg-accent (remove state on-highlighted at styling) to avoid conflict on global component refactor(select-tree): extract TreeItem interface to shared type file Move TreeItem interface to a dedicated type file for better code organization and reusability. Update components to import the interface and add styling improvements to the tree-select component. adjust text size for tree to sm refactor(select-tree): rename tree-select-item to leaf and improve component - Rename component to better reflect its purpose as a leaf node - Improve UI with better spacing and hover states - Simplify toggle logic using v-model - Add checkmark icon for selected items checkpoint wip
82 lines
2.5 KiB
Vue
82 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
import TreeSelect from '~/components/pub/base/select-tree/tree-select.vue'
|
|
|
|
definePageMeta({
|
|
layout: 'blank',
|
|
})
|
|
|
|
// Tipe data untuk konsistensi
|
|
interface TreeItem {
|
|
value: string
|
|
label: string
|
|
hasChildren: boolean
|
|
children?: TreeItem[]
|
|
}
|
|
|
|
// State untuk data pohon. Awalnya hanya berisi data level atas.
|
|
const treeData = ref<TreeItem[]>([
|
|
{ value: 'frontend', label: 'Frontend', hasChildren: true },
|
|
{ value: 'backend', label: 'Backend', hasChildren: true },
|
|
{ value: 'devops', label: 'DevOps', hasChildren: false },
|
|
])
|
|
|
|
// State untuk menampung nilai yang dipilih
|
|
const selectedValue = ref<string>()
|
|
|
|
// --- INI BAGIAN PENTING: LOGIKA API DAN MANIPULASI DATA ---
|
|
|
|
// Helper: Fungsi rekursif untuk mencari dan menyisipkan data anak ke dalam state
|
|
function findAndInsertChildren(nodes: TreeItem[], parentId: string, newChildren: TreeItem[]) {
|
|
for (const node of nodes) {
|
|
if (node.value === parentId) {
|
|
node.children = newChildren
|
|
return true
|
|
}
|
|
if (node.children && findAndInsertChildren(node.children, parentId, newChildren)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Fungsi yang akan dipanggil oleh komponen TreeSelectItem untuk mengambil data
|
|
async function handleFetchChildren(parentId: string) {
|
|
console.log(`Mengambil data anak untuk parent: ${parentId}`)
|
|
|
|
// Simulasi panggilan API ke backend Anda
|
|
await new Promise(resolve => setTimeout(resolve, 500)) // Delay 0.5 detik
|
|
|
|
let childrenData: TreeItem[] = []
|
|
if (parentId === 'frontend') {
|
|
childrenData = [
|
|
{ value: 'vue', label: 'Vue.js', hasChildren: true },
|
|
{ value: 'react', label: 'React.js', hasChildren: false },
|
|
]
|
|
} else if (parentId === 'backend') {
|
|
childrenData = [
|
|
{ value: 'nodejs', label: 'Node.js', hasChildren: false },
|
|
{ value: 'golang', label: 'Go', hasChildren: false },
|
|
]
|
|
} else if (parentId === 'vue') { // Contoh untuk level yang lebih dalam
|
|
childrenData = [
|
|
{ value: 'nuxt', label: 'Nuxt.js', hasChildren: false },
|
|
]
|
|
}
|
|
// Akhir simulasi
|
|
|
|
// Masukkan data anak yang baru didapat ke dalam state treeData
|
|
findAndInsertChildren(treeData.value, parentId, childrenData)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="p-10">
|
|
<h1 class="mb-4 text-2xl font-bold">Tree Select (Lazy Loading)</h1>
|
|
<TreeSelect v-model="selectedValue" :data="treeData" :on-fetch-children="handleFetchChildren" />
|
|
<p class="mt-4">
|
|
Value yang terpilih:
|
|
<span class="p-1 font-mono text-sm rounded-md bg-slate-100">{{ selectedValue || 'Belum ada' }}</span>
|
|
</p>
|
|
</div>
|
|
</template>
|