56 lines
1.8 KiB
Vue
56 lines
1.8 KiB
Vue
<script setup lang="ts" generic="Task extends { [key: string]: any;}">
|
|
import type { Row } from '@tanstack/vue-table'
|
|
|
|
interface DataTableRowActionsProps {
|
|
row: Row<Task>
|
|
menus: {
|
|
label: string
|
|
divider?: boolean
|
|
icon?: string
|
|
click: (row: Row<Task>) => void
|
|
child?: {
|
|
label: string
|
|
icon?: string
|
|
click: (row: Row<Task>) => void
|
|
}[]
|
|
}[]
|
|
}
|
|
defineProps<DataTableRowActionsProps>()
|
|
</script>
|
|
|
|
<template>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger as-child>
|
|
<Button
|
|
variant="ghost"
|
|
class="flex h-8 w-8 p-0 data-[state=open]:bg-muted"
|
|
>
|
|
<Iconify icon="ph:dots-three-outline-fill" class="w-4 h-4" />
|
|
<span class="sr-only">Open menu</span>
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end" class="w-[160px]">
|
|
<template v-for="menu in menus" :key="menu.label">
|
|
<DropdownMenuSeparator v-if="menu.divider" />
|
|
<DropdownMenuSub v-else-if="(menu?.child?.length ?? 0) > 0" :label="menu.label">
|
|
<DropdownMenuSubTrigger>{{ menu.label }}</DropdownMenuSubTrigger>
|
|
<DropdownMenuSubContent>
|
|
<DropdownMenuItem v-for="child in menu.child" :key="child.label" @click="child.click(row)">
|
|
{{ child.label }}
|
|
<DropdownMenuShortcut>
|
|
<Iconify :icon="child.icon" class="size-4" />
|
|
</DropdownMenuShortcut>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuSubContent>
|
|
</DropdownMenuSub>
|
|
<DropdownMenuItem v-else @click="menu.click(row)">
|
|
{{ menu.label }}
|
|
<DropdownMenuShortcut>
|
|
<Iconify :icon="menu.icon" class="size-4" />
|
|
</DropdownMenuShortcut>
|
|
</DropdownMenuItem>
|
|
</template>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</template>
|