Files
simrsx-fe/app/components/app/encounter/dropdown-action.vue
T
2025-12-03 15:06:58 +07:00

148 lines
3.7 KiB
Vue

<script setup lang="ts">
import type { LinkItem, ListItemDto } from '~/components/pub/my-ui/data/types'
import { ActionEvents } from '~/components/pub/my-ui/data/types'
const props = defineProps<{
rec: ListItemDto
}>()
const recId = inject<Ref<number>>('rec_id')!
const recAction = inject<Ref<string>>('rec_action')!
const recItem = inject<Ref<any>>('rec_item')!
const activeServicePosition = inject<Ref<string>>('activeServicePosition')! // previously: activePosition
const activeKey = ref<string | null>(null)
const linkItemsFiltered = ref<LinkItem[]>([])
const baseLinkItems: LinkItem[] = [
{
label: 'Detail',
value: 'detail',
groups: ['medical', 'registration'],
onClick: () => {
proceedItem(ActionEvents.showDetail)
},
icon: 'i-lucide-eye',
},
{
label: 'Edit',
value: 'edit',
groups: ['registration'],
onClick: () => {
proceedItem(ActionEvents.showEdit)
},
icon: 'i-lucide-pencil',
},
{
label: 'Process',
value: 'process',
groups: ['medical'],
onClick: () => {
proceedItem(ActionEvents.showProcess)
},
icon: 'i-lucide-shuffle',
},
{
label: 'Print',
value: 'print',
groups: ['registration'],
onClick: () => {
proceedItem(ActionEvents.showPrint)
},
icon: 'i-lucide-printer',
},
{
label: 'Batalkan',
value: 'cancel',
groups: ['registration'],
onClick: () => {
proceedItem(ActionEvents.showCancel)
},
icon: 'i-lucide-circle-x',
},
{
label: 'Hapus',
value: 'remove',
groups: ['registration'],
onClick: () => {
proceedItem(ActionEvents.showConfirmDelete)
},
icon: 'i-lucide-trash',
},
]
const noneLinkItems: LinkItem[] = [
{
label: 'Nothing',
value: 'nothing',
icon: 'i-lucide-file',
},
]
linkItemsFiltered.value = [...baseLinkItems]
function proceedItem(action: string) {
recId.value = props.rec.id || 0
recItem.value = props.rec
recAction.value = action
}
function getLinks() {
switch (activeServicePosition.value) {
case 'medical':
linkItemsFiltered.value = baseLinkItems.filter((item) => item.groups?.includes('medical'))
break
case 'registration':
linkItemsFiltered.value = baseLinkItems.filter((item) => item.groups?.includes('registration'))
break
default:
linkItemsFiltered.value = noneLinkItems
break
}
}
watch(activeServicePosition, () => {
getLinks()
})
onMounted(() => {
getLinks()
})
</script>
<template>
<div>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<SidebarMenuButton
size="lg"
class="data-[state=open]:text-sidebar-accent-foreground data-[state=open]:bg-white dark:data-[state=open]:bg-slate-800"
>
<Icon
name="i-lucide-chevrons-up-down"
class="ml-auto size-4"
/>
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
class="w-[--radix-dropdown-menu-trigger-width] min-w-40 rounded-lg border border-slate-200 bg-white text-black dark:border-slate-700 dark:bg-slate-800 dark:text-white"
align="end"
>
<DropdownMenuGroup>
<DropdownMenuItem
v-for="item in linkItemsFiltered"
:key="item.label"
class="hover:bg-gray-100 dark:hover:bg-slate-700"
@click="item.onClick"
@mouseenter="activeKey = item.label"
@mouseleave="activeKey = null"
>
<Icon :name="item.icon ?? ''" />
<span :class="activeKey === item.label ? 'text-sidebar-accent-foreground' : ''">{{ item.label }}</span>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</div>
</template>