Initial commit: 网络验证平台
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
import type { ColumnDef } from '@tanstack/vue-table'
|
||||
import type { Composer } from 'vue-i18n'
|
||||
|
||||
import { Ban, Eye, MoreHorizontal, Send, Trash2 } from 'lucide-vue-next'
|
||||
import { h } from 'vue'
|
||||
|
||||
import type { Webhook } from '@/pages/developer/extension/data/schema'
|
||||
|
||||
import Badge from '@/components/ui/badge/Badge.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
|
||||
export function getWebhookColumns(actions: {
|
||||
onToggleStatus: (row: Webhook) => void
|
||||
onTest: (row: Webhook) => void
|
||||
onViewLogs?: (row: Webhook) => void
|
||||
onDelete: (row: Webhook) => void
|
||||
}, t: Composer['t']): ColumnDef<Webhook>[] {
|
||||
return [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: () => t('developer.extension.webhooks.columns.name'),
|
||||
cell: ({ row }) => {
|
||||
const name = row.getValue('name') as string
|
||||
return name || '-'
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'url',
|
||||
header: () => t('developer.extension.webhooks.columns.url'),
|
||||
cell: ({ row }) => {
|
||||
const url = row.getValue('url') as string
|
||||
return url ? h('code', { class: 'text-xs bg-muted px-2 py-1 rounded font-mono max-w-[200px] truncate inline-block' }, url) : '-'
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'application_name',
|
||||
header: () => t('developer.extension.webhooks.columns.application'),
|
||||
cell: ({ row }) => {
|
||||
const appName = row.getValue('application_name') as string
|
||||
return appName ? h(Badge, { variant: 'secondary' }, () => appName) : '-'
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'events',
|
||||
header: () => t('developer.extension.webhooks.columns.events'),
|
||||
cell: ({ row }) => {
|
||||
const events = row.getValue('events') as string
|
||||
try {
|
||||
const eventList = JSON.parse(events || '[]')
|
||||
return h('div', { class: 'flex flex-wrap gap-1' }, eventList.slice(0, 3).map((event: string) =>
|
||||
h(Badge, { variant: 'outline', class: 'text-xs' }, () => event),
|
||||
))
|
||||
}
|
||||
catch {
|
||||
return '-'
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'status',
|
||||
header: () => t('developer.extension.webhooks.columns.status'),
|
||||
cell: ({ row }) => {
|
||||
const status = row.getValue('status') as string
|
||||
return h(Badge, { variant: status === 'active' ? 'default' : 'secondary' }, () =>
|
||||
status === 'active' ? t('developer.extension.enabled') : t('developer.extension.disabled'))
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'retry_count',
|
||||
header: () => t('developer.extension.webhooks.columns.retryCount'),
|
||||
cell: ({ row }) => {
|
||||
const retryCount = row.getValue('retry_count') as number
|
||||
return retryCount ?? '-'
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'timeout',
|
||||
header: () => t('developer.extension.webhooks.columns.timeout'),
|
||||
cell: ({ row }) => {
|
||||
const timeout = row.getValue('timeout') as number
|
||||
return timeout ? `${timeout}s` : '-'
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
header: () => t('developer.extension.webhooks.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 webhook = row.original
|
||||
const isDisabled = webhook.status === 'inactive'
|
||||
|
||||
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' },
|
||||
() => [
|
||||
h(DropdownMenuItem, { onClick: () => actions.onTest(webhook) }, () => [
|
||||
h(Send, { class: 'mr-2 h-4 w-4' }),
|
||||
t('developer.extension.webhooks.test'),
|
||||
]),
|
||||
actions.onViewLogs
|
||||
? h(DropdownMenuItem, { onClick: () => actions.onViewLogs?.(webhook) }, () => [
|
||||
h(Eye, { class: 'mr-2 h-4 w-4' }),
|
||||
t('developer.extension.webhooks.viewLogs'),
|
||||
])
|
||||
: null,
|
||||
h(DropdownMenuItem, { onClick: () => actions.onToggleStatus(webhook) }, () => [
|
||||
h(Ban, { class: 'mr-2 h-4 w-4' }),
|
||||
isDisabled ? t('developer.extension.webhooks.enable') : t('developer.extension.webhooks.disable'),
|
||||
]),
|
||||
h(DropdownMenuSeparator),
|
||||
h(DropdownMenuItem, { class: 'text-destructive', onClick: () => actions.onDelete(webhook) }, () => [
|
||||
h(Trash2, { class: 'mr-2 h-4 w-4' }),
|
||||
t('developer.extension.webhooks.delete'),
|
||||
]),
|
||||
],
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
},
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user