feat(studio): manage style presets

This commit is contained in:
2026-09-10 14:21:10 +08:00
parent ecdbf4d768
commit 85e23ccee3
3 changed files with 46 additions and 8 deletions
+16 -8
View File
@@ -1,9 +1,14 @@
import { createFileRoute } from '@tanstack/react-router'
import { PERM, requirePermission } from '@/auth/permissions'
import { useCan } from '@/auth/store'
import { useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import type { ColumnDef } from '@tanstack/react-table'
import type { StudioStylePreset } from '@/api/types'
import { fetchStylePresets } from '@/api/modules/studio'
import { deleteStylePreset, fetchStylePresets } from '@/api/modules/studio'
import { handleApiError } from '@/lib/errors'
import { StylePresetEditSheet } from '@/features/studio/style-preset-edit-sheet'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { useListPage } from '@/lib/list-page'
import { DetailSheet } from '@/features/studio/detail-sheet'
import { DataTable } from '@/components/data-table/data-table'
@@ -30,13 +35,19 @@ const TYPE_LABELS: Record<string, string> = {
}
function StylePresetsPage() {
const canManage = useCan(PERM.STUDIO_MANAGE)
const queryClient = useQueryClient()
const [type, setType] = useState('all')
const [detail, setDetail] = useState<StudioStylePreset | null>(null)
const [editing, setEditing] = useState<StudioStylePreset | null>(null)
const [creating, setCreating] = useState(false)
const list = useListPage(
'studio-style-presets',
fetchStylePresets,
type === 'all' ? {} : { type },
)
const refresh = () => { void queryClient.invalidateQueries({ queryKey: ['studio-style-presets'] }); void list.query.refetch() }
const remove = async (row: StudioStylePreset) => { try { await deleteStylePreset(row.id); refresh() } catch (error) { handleApiError(error) } }
const columns: ColumnDef<StudioStylePreset>[] = [
{ header: '名称', cell: ({ row }) => <span className="font-medium">{row.original.name}</span> },
@@ -53,9 +64,7 @@ function StylePresetsPage() {
{
header: '操作',
cell: ({ row }) => (
<Button size="sm" variant="ghost" onClick={() => setDetail(row.original)}>
</Button>
<div className="flex gap-1.5"><Button size="sm" variant="ghost" onClick={() => setDetail(row.original)}></Button>{canManage && <Button size="sm" variant="outline" onClick={() => setEditing(row.original)}></Button>}{canManage && <ConfirmDialog trigger={<Button size="sm" variant="destructive"></Button>} title="删除风格预设?" confirmLabel="删除" destructive onConfirm={() => remove(row.original)} />}</div>
),
},
]
@@ -65,8 +74,7 @@ function StylePresetsPage() {
<PageHeader
title="风格预设"
description="Agent 的风格库(preset / hybrid 模式),按 type + name 幂等"
actions={
<Select value={type} onValueChange={setType}>
actions={<div className="flex gap-2">{canManage && <Button onClick={() => setCreating(true)}></Button>}<Select value={type} onValueChange={setType}>
<SelectTrigger size="sm" className="w-32">
<SelectValue />
</SelectTrigger>
@@ -76,9 +84,9 @@ function StylePresetsPage() {
<SelectItem value="image"></SelectItem>
<SelectItem value="bundle"></SelectItem>
</SelectContent>
</Select>
}
</Select></div>}
/>
<StylePresetEditSheet preset={editing} creating={creating} onOpenChange={(open) => { if (!open) { setEditing(null); setCreating(false) } }} onSaved={refresh} />
<DataTable
columns={columns}
data={list.rows}