feat/device-order: final

This commit is contained in:
Andrian Roshandy
2025-11-19 03:36:24 +07:00
parent 468c6a164f
commit bfbe72be94
13 changed files with 527 additions and 183 deletions
@@ -0,0 +1,73 @@
<script setup lang="ts">
// Pubs
import * as DE from '~/components/pub/my-ui/doc-entry'
import * as CB from '~/components/pub/my-ui/combobox'
import Nav from '~/components/pub/my-ui/nav-footer/cl-sa.vue'
// This scope
import type { DeviceOrderItem } from '~/models/device-order-item';
import type { Device } from '~/models/device';
// Props
const props = defineProps<{
data: DeviceOrderItem
devices: Device[]
}>()
// Refs
const { devices } = toRefs(props)
const deviceItems = ref<CB.Item[]>([])
// Nav actions
type ClickType = 'close' | 'save'
// Emits
const emit = defineEmits<{
close: [],
save: [data: DeviceOrderItem],
'update:searchText': [value: string]
}>()
// Reactivities
watch(devices, (data) => {
deviceItems.value = CB.objectsToItems(data, 'code', 'name')
})
// Functions
function searchDeviceText(value: string) {
emit('update:searchText', value)
}
function navClick(type: ClickType) {
if (type === 'close') {
emit('close')
} else if (type === 'save') {
emit('save', props.data)
}
}
</script>
<template>
<DE.Block :colCount="4" :cellFlex="false">
<DE.Cell :colSpan="4">
<DE.Label>Nama</DE.Label>
<DE.Field>
<CB.Combobox
v-model="data.device_code"
:items="deviceItems"
@update:searchText="searchDeviceText"
/>
</DE.Field>
</DE.Cell>
<DE.Cell>
<DE.Label>Jumlah</DE.Label>
<DE.Field>
<Input v-model="data.quantity" type="number" />
</DE.Field>
</DE.Cell>
</DE.Block>
<Separator class="my-5" />
<div class="flex justify-center">
<Nav @click="navClick" />
</div>
</template>
@@ -1,36 +1,35 @@
import { defineAsyncComponent } from 'vue'
import type { Config } from '~/components/pub/my-ui/data-table'
import type { Config, RecComponent } from '~/components/pub/my-ui/data-table'
const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue'))
export const config: Config = {
cols: [{}, {}, { width: 50 }],
cols: [{}, { width: 200 }, { width: 100 }],
headers: [[{ label: 'Nama' }, { label: 'Jumlah' }, { label: '' }]],
keys: ['name', 'count', 'action'],
keys: ['device.name', 'quantity', 'action'],
delKeyNames: [
{ key: 'name', label: 'Nama' },
{ key: 'count', label: 'Jumlah' },
],
skeletonSize: 10
skeletonSize: 10,
// funcParsed: {
// parent: (rec: unknown): unknown => {
// const recX = rec as SmallDetailDto
// return recX.parent?.name || '-'
// },
// },
// funcComponent: {
// action(rec: object, idx: any) {
// const res: RecComponent = {
// idx,
// rec: rec as object,
// component: action,
// props: {
// size: 'sm',
// },
// }
// return res
// },
// }
components: {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
props: {
size: 'sm',
},
}
return res
},
}
}
@@ -1,13 +1,23 @@
<script setup lang="ts">
import DataTable from '~/components/pub/my-ui/data-table/data-table.vue'
import { config } from './list-entry.config'
import type { DeviceOrderItem } from '~/models/device-order-item';
defineProps<{
data: DeviceOrderItem[]
}>()
const emit = defineEmits<{
add: []
}>()
</script>
<template>
<DataTable v-bind="config" :rows="[]" class="border mb-3 2xl:mb-4" />
<DataTable v-bind="config" :rows="data" class="border mb-3 2xl:mb-4" />
<div>
<Button>
Tambah
<Button @click="emit('add')">
<Icon name="i-lucide-plus" />
Tambah Item
</Button>
</div>
</template>
@@ -0,0 +1,26 @@
<script setup lang="ts">
import type { DeviceOrder } from '~/models/device-order'
import * as DE from '~/components/pub/my-ui/doc-entry'
defineProps<{
data: DeviceOrder | null | undefined
}>()
</script>
<template>
<DE.Block mode="preview" label-size="small" class="!mb-0">
<DE.Cell>
<DE.Label>Tgl. Order</DE.Label>
<DE.Colon />
<DE.Field>
{{ data?.createdAt?.substring(0, 10) }}
</DE.Field>
</DE.Cell>
<DE.Cell>
<DE.Label>DPJP</DE.Label>
<DE.Colon />
<DE.Field>
{{ data?.doctor?.employee?.person?.name }}
</DE.Field>
</DE.Cell>
</DE.Block>
</template>
+20 -1
View File
@@ -1,6 +1,25 @@
<script setup lang="ts">
import * as DE from '~/components/pub/my-ui/doc-entry'
import type { DeviceOrder } from '~/models/device-order';
defineProps<{
data: DeviceOrder
}>()
</script>
<template>
Test
<DE.Block :col-count="2" mode="preview">
<DE.Cell>
<DE.Label>Tanggal</DE.Label>
<DE.Field>
{{ data?.createdAt?.substring(0, 10) }}
</DE.Field>
</DE.Cell>
<DE.Cell>
<DE.Label>DPJP</DE.Label>
<DE.Field>
{{ data?.doctor?.employee?.person?.name }}
</DE.Field>
</DE.Cell>
</DE.Block>
</template>
+31 -19
View File
@@ -1,10 +1,8 @@
import type { Config } from '~/components/pub/my-ui/data-table'
import type { Config, RecComponent } from '~/components/pub/my-ui/data-table'
import type { DeviceOrder } from '~/models/device-order'
// import type {} from
// import { defineAsyncComponent } from 'vue'
// const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue'))
import type { DeviceOrderItem } from '~/models/device-order-item'
const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dsd.vue'))
export const config: Config = {
cols: [{ width: 120 }, { }, { }, { }, { width: 50 }],
@@ -23,7 +21,21 @@ export const config: Config = {
htmls: {
items: (rec: unknown): unknown => {
const recX = rec as DeviceOrder
return recX.items?.length || 0
if (recX.items?.length > 0) {
let output = '<table><tbody>'
recX.items.forEach((item: DeviceOrderItem) => {
output += '' +
'<tr>'+
`<td class="pe-10">${item.device?.name}</td>` +
'<td class="w-4">:</td>' +
`<td class="w-10">${item.quantity}</td>` +
'</tr>'
})
output += '</tbody></table>'
return output
} else {
return '-'
}
},
},
parses: {
@@ -36,18 +48,18 @@ export const config: Config = {
// return recX.parent?.name || '-'
// },
},
// funcComponent: {
// action(rec: object, idx: any) {
// const res: RecComponent = {
// idx,
// rec: rec as object,
// component: action,
// props: {
// size: 'sm',
// },
// }
// return res
// },
// }
components: {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
props: {
size: 'sm',
},
}
return res
},
}
}