f72d640e8c
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 29s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 33s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m23s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 1m40s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m46s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m2s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m48s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m55s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m14s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 5m21s
AI Code Review / AI Code Review (pull_request) Successful in 6m38s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 8m15s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m40s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 24m23s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 4s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 161h48m7s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 161h48m10s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 161h48m10s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 162h11m54s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 162h11m55s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 162h11m57s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 162h11m59s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 162h12m0s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 162h12m3s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 162h12m4s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 162h12m4s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 162h12m39s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 162h22m53s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 162h22m56s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 162h46m41s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 162h46m46s
修复 #1828 前端对接代码的 prettier check 失败,仅格式调整无逻辑改动。
98 lines
3.3 KiB
TypeScript
98 lines
3.3 KiB
TypeScript
/**
|
|
* AI数字人 — 标题库选择弹窗
|
|
* 复用智能剪辑的标题库 API,选择标题后填入输入框
|
|
*/
|
|
import React, { useEffect, useState } from "react"
|
|
import { getTitles } from "@/api/titles"
|
|
import type { TitleItem } from "@/api/titles/types"
|
|
|
|
interface TitleLibraryModalProps {
|
|
open: boolean
|
|
onClose: () => void
|
|
onSelect: (title: string) => void
|
|
}
|
|
|
|
const TitleLibraryModal: React.FC<TitleLibraryModalProps> = ({ open, onClose, onSelect }) => {
|
|
const [titles, setTitles] = useState<TitleItem[]>([])
|
|
const [loading, setLoading] = useState(false)
|
|
const [search, setSearch] = useState("")
|
|
|
|
useEffect(() => {
|
|
if (!open) return
|
|
setLoading(true)
|
|
getTitles()
|
|
.then((items) => setTitles(items))
|
|
.catch(() => setTitles([]))
|
|
.finally(() => setLoading(false))
|
|
}, [open])
|
|
|
|
const filtered = titles.filter(
|
|
(t) => !search || t.content.toLowerCase().includes(search.toLowerCase()),
|
|
)
|
|
|
|
if (!open) return null
|
|
|
|
return (
|
|
<div className="aa-modal-overlay" onClick={onClose}>
|
|
<div className="aa-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 600 }}>
|
|
<div className="aa-modal__header">
|
|
<span className="aa-modal__title">从标题库选择</span>
|
|
<button className="aa-modal__close" onClick={onClose}></button>
|
|
</div>
|
|
<div className="aa-modal__body">
|
|
<div style={{ marginBottom: 12 }}>
|
|
<input
|
|
className="aa-input"
|
|
placeholder="搜索标题..."
|
|
value={search}
|
|
onChange={(e) => setSearch(e.target.value)}
|
|
/>
|
|
</div>
|
|
{loading ? (
|
|
<div style={{ textAlign: "center", padding: 40, color: "#8c8ca1" }}>加载中...</div>
|
|
) : filtered.length === 0 ? (
|
|
<div style={{ textAlign: "center", padding: 40, color: "#8c8ca1" }}>
|
|
暂无标题,请先在标题库创建
|
|
</div>
|
|
) : (
|
|
<div style={{ maxHeight: 400, overflowY: "auto" }}>
|
|
{filtered.map((t) => (
|
|
<div
|
|
key={t.id}
|
|
style={{
|
|
padding: "12px 16px",
|
|
marginBottom: 8,
|
|
background: "#f8f8fc",
|
|
borderRadius: 8,
|
|
cursor: "pointer",
|
|
transition: "background 0.2s",
|
|
}}
|
|
onMouseEnter={(e) => (e.currentTarget.style.background = "#eef0ff")}
|
|
onMouseLeave={(e) => (e.currentTarget.style.background = "#f8f8fc")}
|
|
onClick={() => {
|
|
onSelect(t.content)
|
|
onClose()
|
|
}}
|
|
>
|
|
<div style={{ fontSize: 14, color: "#1a1a2e", marginBottom: 4 }}>{t.content}</div>
|
|
<div style={{ fontSize: 12, color: "#8c8ca1" }}>
|
|
{t.word_count ?? t.content.length}字 ·{" "}
|
|
{t.created_at ? new Date(t.created_at).toLocaleDateString() : ""}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="aa-modal__footer">
|
|
<button className="aa-btn" onClick={onClose}>
|
|
取消
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default TitleLibraryModal
|