import type { ColumnDef } from '@tanstack/vue-table' import type { Composer } from 'vue-i18n' import { Download, File, List, MoreHorizontal, Pencil, Power, PowerOff, Trash2 } from 'lucide-vue-next' import { h } from 'vue' import type { CloudVariable } from '@/pages/admin/cloud-variables/data/schema' import { Copy } from '@/components/sva-ui/copy' import Badge from '@/components/ui/badge/Badge.vue' import Button from '@/components/ui/button/Button.vue' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' export function getColumns(actions: { onEdit: (row: CloudVariable) => void onDelete: (row: CloudVariable) => void onToggleStatus: (row: CloudVariable) => void onDownload: (row: CloudVariable) => void onViewRecords: (row: CloudVariable) => void }, t: Composer['t']): ColumnDef[] { return [ { accessorKey: 'key', header: () => t('admin.cloudVariables.columns.key'), cell: ({ row }) => { const key = row.getValue('key') as string if (!key) return '-' return h('div', { class: 'flex items-center space-x-2' }, [ h('code', { class: 'text-xs bg-muted px-2 py-1 rounded font-mono' }, key), h(Copy, { class: 'h-4 w-4', size: 'sm', content: key }), ]) }, }, { accessorKey: 'default_value', header: () => t('admin.cloudVariables.columns.defaultValue'), cell: ({ row }) => { const value = row.getValue('default_value') as string const varType = row.original.var_type if (!value) return '-' if (varType === 'binary') { const originalName = row.original.original_name || value return h('div', { class: 'flex items-center gap-2' }, [ h(File, { class: 'h-4 w-4 text-muted-foreground' }), h('span', { class: 'max-w-xs truncate', title: originalName }, originalName), ]) } return h('div', { class: 'max-w-xs truncate', title: value }, value) }, }, { accessorKey: 'scope', header: () => t('admin.cloudVariables.columns.scope'), cell: ({ row }) => { const scope = row.getValue('scope') as string if (scope === 'app') { return h(Badge, { variant: 'default' }, () => t('admin.cloudVariables.appScope')) } return h(Badge, { variant: 'secondary' }, () => t('admin.cloudVariables.userScope')) }, }, { accessorKey: 'write_permission', header: () => t('admin.cloudVariables.create.writePermission'), cell: ({ row }) => { const permission = row.getValue('write_permission') as string if (permission === 'user') { return h(Badge, { variant: 'outline', class: 'bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-300' }, () => t('admin.cloudVariables.create.userWritable')) } return h(Badge, { variant: 'outline' }, () => t('admin.cloudVariables.create.developerOnly')) }, }, { accessorKey: 'var_type', header: () => t('admin.cloudVariables.columns.type'), cell: ({ row }) => { const type = row.getValue('var_type') as string const typeMap: Record = { integer: t('admin.cloudVariables.types.integer'), decimal: t('admin.cloudVariables.types.decimal'), string: t('admin.cloudVariables.types.string'), binary: t('admin.cloudVariables.types.binary'), stream: '记录', } return h(Badge, { variant: 'outline' }, () => typeMap[type || 'string'] || type || 'string') }, }, { accessorKey: 'description', header: () => t('admin.cloudVariables.columns.description'), cell: ({ row }) => { const description = row.getValue('description') as string if (!description) return '-' return h('div', { class: 'max-w-xs truncate', title: description }, description) }, }, { accessorKey: 'application_name', header: () => t('admin.cloudVariables.columns.application'), cell: ({ row }) => { const appName = row.getValue('application_name') as string if (!appName) { const appId = row.original.app_id if (!appId) return h(Badge, { variant: 'outline' }, () => t('admin.cloudVariables.notLinked')) return '-' } return h(Badge, { variant: 'outline' }, () => appName) }, }, { accessorKey: 'status', header: () => t('admin.cloudVariables.columns.status'), cell: ({ row }) => { const status = row.getValue('status') as string const isActive = status === 'active' return h(Badge, { variant: isActive ? 'default' : 'destructive' }, () => isActive ? t('admin.cloudVariables.statusActive') : t('admin.cloudVariables.statusInactive')) }, }, { accessorKey: 'created_at', header: () => t('admin.cloudVariables.columns.createdAt'), cell: ({ row }) => { const createdAt = row.getValue('created_at') if (!createdAt) return '-' try { const date = new Date(createdAt as string) if (Number.isNaN(date.getTime())) return '-' return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }) } catch { return '-' } }, }, { id: 'actions', header: () => h('span', { class: 'sr-only' }, t('common.actions')), cell: ({ row }) => { const variable = row.original return h( DropdownMenu, {}, { default: () => [ h(DropdownMenuTrigger, { asChild: true }, () => h(Button, { variant: 'ghost', class: 'h-8 w-8 p-0' }, () => [ h(MoreHorizontal, { class: 'h-4 w-4' }), h('span', { class: 'sr-only' }, t('common.openMenu')), ])), h( DropdownMenuContent, { align: 'end' }, () => { const items = [] if (variable.var_type === 'stream') { items.push( h(DropdownMenuItem, { onClick: () => actions.onViewRecords(variable) }, () => [ h(List, { class: 'mr-2 h-4 w-4' }), '查看记录', ]), ) } items.push( h(DropdownMenuItem, { onClick: () => actions.onEdit(variable) }, () => [ h(Pencil, { class: 'mr-2 h-4 w-4' }), t('admin.cloudVariables.edit'), ]), ) if (variable.var_type === 'binary') { items.push( h(DropdownMenuItem, { onClick: () => actions.onDownload(variable) }, () => [ h(Download, { class: 'mr-2 h-4 w-4' }), '下载文件', ]), ) } items.push( h(DropdownMenuItem, { onClick: () => actions.onToggleStatus(variable) }, () => [ variable.status === 'active' ? h(PowerOff, { class: 'mr-2 h-4 w-4' }) : h(Power, { class: 'mr-2 h-4 w-4' }), variable.status === 'active' ? t('admin.cloudVariables.disable') : t('admin.cloudVariables.enable'), ]), h(DropdownMenuItem, { class: 'text-destructive', onClick: () => actions.onDelete(variable) }, () => [ h(Trash2, { class: 'mr-2 h-4 w-4' }), t('admin.cloudVariables.delete'), ]), ) return items }, ), ], }, ) }, enableSorting: false, enableHiding: false, }, ] }