148 lines
3.7 KiB
Vue
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>
|