101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { createFileRoute } from '@tanstack/react-router'
|
|
import { useState } from 'react'
|
|
import type { ColumnDef } from '@tanstack/react-table'
|
|
import type { StudioStylePreset } from '@/api/types'
|
|
import { fetchStylePresets } from '@/api/modules/studio'
|
|
import { useListPage } from '@/lib/list-page'
|
|
import { DetailSheet } from '@/features/studio/detail-sheet'
|
|
import { DataTable } from '@/components/data-table/data-table'
|
|
import { PageHeader } from '@/components/page-header'
|
|
import { Badge } from '@/components/ui/badge'
|
|
import { Button } from '@/components/ui/button'
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@/components/ui/select'
|
|
|
|
export const Route = createFileRoute('/_authed/studio/style-presets')({
|
|
component: StylePresetsPage,
|
|
})
|
|
|
|
const TYPE_LABELS: Record<string, string> = {
|
|
article: '文章风格',
|
|
image: '图片风格',
|
|
bundle: '组合',
|
|
}
|
|
|
|
function StylePresetsPage() {
|
|
const [type, setType] = useState('all')
|
|
const [detail, setDetail] = useState<StudioStylePreset | null>(null)
|
|
const list = useListPage(
|
|
'studio-style-presets',
|
|
fetchStylePresets,
|
|
type === 'all' ? {} : { type },
|
|
)
|
|
|
|
const columns: ColumnDef<StudioStylePreset>[] = [
|
|
{ header: '名称', cell: ({ row }) => <span className="font-medium">{row.original.name}</span> },
|
|
{
|
|
header: '类型',
|
|
cell: ({ row }) => (
|
|
<Badge variant="secondary">{TYPE_LABELS[row.original.type] ?? row.original.type}</Badge>
|
|
),
|
|
},
|
|
{
|
|
header: '更新时间',
|
|
cell: ({ row }) => new Date(row.original.updated_at).toLocaleString('zh-CN'),
|
|
},
|
|
{
|
|
header: '操作',
|
|
cell: ({ row }) => (
|
|
<Button size="sm" variant="ghost" onClick={() => setDetail(row.original)}>
|
|
详情
|
|
</Button>
|
|
),
|
|
},
|
|
]
|
|
|
|
return (
|
|
<div>
|
|
<PageHeader
|
|
title="风格预设"
|
|
description="Agent 的风格库(preset / hybrid 模式),按 type + name 幂等"
|
|
actions={
|
|
<Select value={type} onValueChange={setType}>
|
|
<SelectTrigger size="sm" className="w-32">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="all">全部类型</SelectItem>
|
|
<SelectItem value="article">文章风格</SelectItem>
|
|
<SelectItem value="image">图片风格</SelectItem>
|
|
<SelectItem value="bundle">组合</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
}
|
|
/>
|
|
<DataTable
|
|
columns={columns}
|
|
data={list.rows}
|
|
pagination={list.pagination}
|
|
loading={list.loading}
|
|
onPageChange={list.setPage}
|
|
onPageSizeChange={list.setPageSize}
|
|
/>
|
|
<DetailSheet
|
|
open={detail !== null}
|
|
onOpenChange={(open) => !open && setDetail(null)}
|
|
title={detail?.name ?? '风格预设'}
|
|
fields={[
|
|
{ label: '类型', value: detail && (TYPE_LABELS[detail.type] ?? detail.type) },
|
|
{ label: 'ID', value: <code className="font-mono text-xs">{detail?.id}</code> },
|
|
]}
|
|
jsonBlocks={[{ label: '风格定义 payload', value: detail?.payload }]}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|