feat(dimzou): complete admin monitoring filters
This commit is contained in:
@@ -39,9 +39,12 @@ function DimzouTranslationsPage() {
|
|||||||
// language filter applies on Enter/blur to avoid a request per keystroke
|
// language filter applies on Enter/blur to avoid a request per keystroke
|
||||||
const [languageInput, setLanguageInput] = useState('')
|
const [languageInput, setLanguageInput] = useState('')
|
||||||
const [language, setLanguage] = useState('')
|
const [language, setLanguage] = useState('')
|
||||||
|
const [sourceInput, setSourceInput] = useState('')
|
||||||
|
const [sourceDocumentId, setSourceDocumentId] = useState('')
|
||||||
const filters: Record<string, string> = {}
|
const filters: Record<string, string> = {}
|
||||||
if (status !== 'all') filters.status = status
|
if (status !== 'all') filters.status = status
|
||||||
if (language) filters.language_code = language
|
if (language) filters.language_code = language
|
||||||
|
if (sourceDocumentId) filters.source_document_id = sourceDocumentId
|
||||||
|
|
||||||
const list = useListPage('dimzou-translations', fetchDimzouTranslations, filters)
|
const list = useListPage('dimzou-translations', fetchDimzouTranslations, filters)
|
||||||
|
|
||||||
@@ -119,7 +122,14 @@ function DimzouTranslationsPage() {
|
|||||||
canRetranslate ? (
|
canRetranslate ? (
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
trigger={
|
trigger={
|
||||||
<Button size="sm" variant="outline" disabled={!row.original.draft_version_id}>
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
disabled={
|
||||||
|
!row.original.draft_version_id ||
|
||||||
|
row.original.blocks.needs_translation + row.original.blocks.translation_failed === 0
|
||||||
|
}
|
||||||
|
>
|
||||||
重新机器翻译
|
重新机器翻译
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
@@ -150,6 +160,17 @@ function DimzouTranslationsPage() {
|
|||||||
placeholder="语言,如 en"
|
placeholder="语言,如 en"
|
||||||
className="h-8 w-28"
|
className="h-8 w-28"
|
||||||
/>
|
/>
|
||||||
|
<Input
|
||||||
|
value={sourceInput}
|
||||||
|
onChange={(event) => setSourceInput(event.target.value)}
|
||||||
|
onBlur={() => setSourceDocumentId(sourceInput.trim())}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter') setSourceDocumentId(sourceInput.trim())
|
||||||
|
}}
|
||||||
|
inputMode="numeric"
|
||||||
|
placeholder="源文档 ID"
|
||||||
|
className="h-8 w-28"
|
||||||
|
/>
|
||||||
<Select value={status} onValueChange={setStatus}>
|
<Select value={status} onValueChange={setStatus}>
|
||||||
<SelectTrigger size="sm" className="w-28">
|
<SelectTrigger size="sm" className="w-28">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { PageHeader } from '@/components/page-header'
|
|||||||
import { DetailSheet } from '@/features/studio/detail-sheet'
|
import { DetailSheet } from '@/features/studio/detail-sheet'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
@@ -45,13 +46,17 @@ const formatTime = (value?: string | null) =>
|
|||||||
|
|
||||||
function DimzouDocumentsPage() {
|
function DimzouDocumentsPage() {
|
||||||
const [state, setState] = useState<string>('all')
|
const [state, setState] = useState<string>('all')
|
||||||
|
const [queryInput, setQueryInput] = useState('')
|
||||||
|
const [query, setQuery] = useState('')
|
||||||
|
const [ownerInput, setOwnerInput] = useState('')
|
||||||
|
const [ownerUid, setOwnerUid] = useState('')
|
||||||
const [detailId, setDetailId] = useState<number | null>(null)
|
const [detailId, setDetailId] = useState<number | null>(null)
|
||||||
|
|
||||||
const list = useListPage(
|
const filters: Record<string, string> = {}
|
||||||
'dimzou-documents',
|
if (state !== 'all') filters.state = state
|
||||||
fetchDimzouDocuments,
|
if (query) filters.q = query
|
||||||
state === 'all' ? {} : { state },
|
if (ownerUid) filters.owner_uid = ownerUid
|
||||||
)
|
const list = useListPage('dimzou-documents', fetchDimzouDocuments, filters)
|
||||||
|
|
||||||
const detail = useQuery({
|
const detail = useQuery({
|
||||||
queryKey: ['dimzou-document', detailId],
|
queryKey: ['dimzou-document', detailId],
|
||||||
@@ -108,19 +113,37 @@ function DimzouDocumentsPage() {
|
|||||||
title="文档监控"
|
title="文档监控"
|
||||||
description="全站协作文档及其版本、译文与待审情况(只读)"
|
description="全站协作文档及其版本、译文与待审情况(只读)"
|
||||||
actions={
|
actions={
|
||||||
<Select value={state} onValueChange={setState}>
|
<div className="flex items-center gap-2">
|
||||||
<SelectTrigger size="sm" className="w-28">
|
<Input
|
||||||
<SelectValue />
|
className="h-8 w-36"
|
||||||
</SelectTrigger>
|
placeholder="搜索标题,回车"
|
||||||
<SelectContent>
|
value={queryInput}
|
||||||
<SelectItem value="all">全部状态</SelectItem>
|
onChange={(event) => setQueryInput(event.target.value)}
|
||||||
{Object.entries(STATE_LABELS).map(([value, label]) => (
|
onBlur={() => setQuery(queryInput.trim())}
|
||||||
<SelectItem key={value} value={value}>
|
onKeyDown={(event) => event.key === 'Enter' && setQuery(queryInput.trim())}
|
||||||
{label}
|
/>
|
||||||
</SelectItem>
|
<Input
|
||||||
))}
|
className="h-8 w-44"
|
||||||
</SelectContent>
|
placeholder="所有者 UID,回车"
|
||||||
</Select>
|
value={ownerInput}
|
||||||
|
onChange={(event) => setOwnerInput(event.target.value)}
|
||||||
|
onBlur={() => setOwnerUid(ownerInput.trim())}
|
||||||
|
onKeyDown={(event) => event.key === 'Enter' && setOwnerUid(ownerInput.trim())}
|
||||||
|
/>
|
||||||
|
<Select value={state} onValueChange={setState}>
|
||||||
|
<SelectTrigger size="sm" className="w-28">
|
||||||
|
<SelectValue />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="all">全部状态</SelectItem>
|
||||||
|
{Object.entries(STATE_LABELS).map(([value, label]) => (
|
||||||
|
<SelectItem key={value} value={value}>
|
||||||
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<DataTable
|
<DataTable
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { PageHeader } from '@/components/page-header'
|
|||||||
import { DetailSheet } from '@/features/studio/detail-sheet'
|
import { DetailSheet } from '@/features/studio/detail-sheet'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
@@ -28,13 +29,17 @@ const formatTime = (value?: string | null) =>
|
|||||||
|
|
||||||
function DimzouPublicationsPage() {
|
function DimzouPublicationsPage() {
|
||||||
const [visibility, setVisibility] = useState<string>('all')
|
const [visibility, setVisibility] = useState<string>('all')
|
||||||
|
const [queryInput, setQueryInput] = useState('')
|
||||||
|
const [query, setQuery] = useState('')
|
||||||
|
const [languageInput, setLanguageInput] = useState('')
|
||||||
|
const [language, setLanguage] = useState('')
|
||||||
const [detail, setDetail] = useState<DimzouPublication | null>(null)
|
const [detail, setDetail] = useState<DimzouPublication | null>(null)
|
||||||
|
|
||||||
const list = useListPage(
|
const filters: Record<string, string> = {}
|
||||||
'dimzou-publications',
|
if (visibility !== 'all') filters.visibility = visibility
|
||||||
fetchDimzouPublications,
|
if (query) filters.q = query
|
||||||
visibility === 'all' ? {} : { visibility },
|
if (language) filters.language = language
|
||||||
)
|
const list = useListPage('dimzou-publications', fetchDimzouPublications, filters)
|
||||||
|
|
||||||
const columns: ColumnDef<DimzouPublication>[] = [
|
const columns: ColumnDef<DimzouPublication>[] = [
|
||||||
{
|
{
|
||||||
@@ -92,7 +97,26 @@ function DimzouPublicationsPage() {
|
|||||||
title="发布监控"
|
title="发布监控"
|
||||||
description="全站已发布内容快照(只读)"
|
description="全站已发布内容快照(只读)"
|
||||||
actions={
|
actions={
|
||||||
<Select value={visibility} onValueChange={setVisibility}>
|
<div className="flex items-center gap-2">
|
||||||
|
<Input
|
||||||
|
className="h-8 w-36"
|
||||||
|
placeholder="搜索标题,回车"
|
||||||
|
value={queryInput}
|
||||||
|
onChange={(event) => setQueryInput(event.target.value)}
|
||||||
|
onBlur={() => setQuery(queryInput.trim())}
|
||||||
|
onKeyDown={(event) => event.key === 'Enter' && setQuery(queryInput.trim())}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
className="h-8 w-28"
|
||||||
|
placeholder="语言,如 zh-cn"
|
||||||
|
value={languageInput}
|
||||||
|
onChange={(event) => setLanguageInput(event.target.value)}
|
||||||
|
onBlur={() => setLanguage(languageInput.trim())}
|
||||||
|
onKeyDown={(event) =>
|
||||||
|
event.key === 'Enter' && setLanguage(languageInput.trim())
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Select value={visibility} onValueChange={setVisibility}>
|
||||||
<SelectTrigger size="sm" className="w-28">
|
<SelectTrigger size="sm" className="w-28">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -101,7 +125,8 @@ function DimzouPublicationsPage() {
|
|||||||
<SelectItem value="public">公开</SelectItem>
|
<SelectItem value="public">公开</SelectItem>
|
||||||
<SelectItem value="group_only">仅协作组</SelectItem>
|
<SelectItem value="group_only">仅协作组</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<DataTable
|
<DataTable
|
||||||
|
|||||||
Reference in New Issue
Block a user