feat(division): wip tree select component

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
This commit is contained in:
Khafid Prayoga
2025-09-11 09:50:18 +07:00
parent 266d5f740b
commit ba6485a3e7
13 changed files with 902 additions and 51 deletions

No files matched your search

+8 -7
View File
@@ -1,12 +1,11 @@
<script setup lang="ts">
import type { HeaderPrep } from '~/components/pub/custom-ui/data/types'
import AppDivisonEntryForm from '~/components/app/divison/entry-form.vue'
import AppDivisionEntry from './entry.vue'
import Dialog from '~/components/pub/base/modal/dialog.vue'
import RecordConfirmation from '~/components/pub/custom-ui/confirmation/record-confirmation.vue'
import { ActionEvents } from '~/components/pub/custom-ui/data/types'
import Header from '~/components/pub/custom-ui/nav-header/header.vue'
import { usePaginatedList } from '~/composables/usePaginatedList'
import { division as divisionConf, schema as schemaConf } from './entry'
// #region State & Computed
// Dialog state
@@ -30,7 +29,8 @@ async function fetchDivisionData(params: any) {
urlParams.append('search', params.q)
}
return await xfetch(`/api/v1/patient?${urlParams.toString()}`)
// return await xfetch(`/api/v1/patient?${urlParams.toString()}`)
return await xfetch('/api/v1/_dev/division/list')
}
// Menggunakan composable untuk pagination
@@ -192,10 +192,11 @@ function handleCancelConfirmation() {
<AppDivisonList :data="data" :pagination-meta="paginationMeta" @page-change="handlePageChange" />
<Dialog v-model:open="isFormEntryDialogOpen" title="Tambah Divisi" size="lg" prevent-outside>
<AppDivisonEntryForm
:division="divisionConf" :schema="schemaConf"
:initial-values="{ name: '', code: '', parentId: '' }" @submit="onSubmitForm" @cancel="onCancelForm"
/>
<AppDivisionEntry
:initial-values="{ name: '', code: '', parentId: '' }"
@submit="onSubmitForm"
@cancel="onCancelForm"
/>
</Dialog>
<!-- Record Confirmation Modal -->