652bbfe12b
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 4m26s
CI/CD Pipeline / Check push changed paths (push) Successful in 4m27s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 5m34s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 5m58s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 6m5s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 6m9s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 7m19s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m42s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m40s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m33s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 2m4s
CI/CD Pipeline / Retag skipped Staging API Image (push) Successful in 45s
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Successful in 46s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m59s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 58s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 10m9s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 10m22s
AI Code Review / AI Code Review (pull_request) Successful in 8m12s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m55s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m35s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 5m1s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 5m17s
CI/CD Pipeline / Integration Tests (push) Successful in 5m10s
CI/CD Pipeline / Unit Tests (push) Successful in 16m2s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 11m29s
CI/CD Pipeline / CI Gate (pull_request) Successful in 23s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 421h42m5s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 421h42m5s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 421h42m6s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 421h42m7s
CI/CD Pipeline / Production Browser E2E (push) Failing after 421h43m31s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 421h42m7s
CI/CD Pipeline / Deploy Production (push) Failing after 421h43m31s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 421h43m32s
CI/CD Pipeline / Build Production Web Image (push) Failing after 421h43m32s
CI/CD Pipeline / Build Production API Image (push) Failing after 421h43m32s
CI/CD Pipeline / Retag skipped Staging Web Image (push) Failing after 421h51m31s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 421h52m12s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 421h53m18s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 421h53m20s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 421h53m26s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 421h53m22s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 421h53m28s
CI/CD Pipeline / Build Staging Worker Image (push) Failing after 421h53m34s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 421h53m30s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 421h54m51s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 421h53m32s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Failing after 421h55m8s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 421h57m24s
CI/CD Pipeline / Build Staging API Image (push) Failing after 421h53m38s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 421h59m29s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 421h54m53s
CI/CD Pipeline / PR Build API Image (push) Failing after 421h59m33s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 421h54m55s
CI/CD Pipeline / Frontend Lint (push) Failing after 421h59m35s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 421h59m36s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 422h16m11s
CI/CD Pipeline / Canary Release to Production (push) Failing after 422h17m36s
CI/CD Pipeline / CI Gate (push) Failing after 422h17m37s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 422h26m19s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 422h27m29s
CI/CD Pipeline / PR Build Web Image (push) Failing after 422h33m36s
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
103 lines
3.3 KiB
TypeScript
103 lines
3.3 KiB
TypeScript
/**
|
||
* Step 2 素材选择组件
|
||
*/
|
||
import React from "react"
|
||
import type { TemplateSegment } from "@/api/templates/types"
|
||
import type { EditPlanClip } from "@/api/template-editor"
|
||
import { useStep2Materials } from "../hooks/useStep2Materials"
|
||
import MaterialModeTabs from "./material/MaterialModeTabs"
|
||
import ManualMaterialList from "./material/ManualMaterialList"
|
||
import SmartMatchInput from "./material/SmartMatchInput"
|
||
import SmartMatchResults from "./material/SmartMatchResults"
|
||
|
||
interface Step2MaterialSelectProps {
|
||
materialMode: "manual" | "auto"
|
||
onMaterialModeChange: (mode: "manual" | "auto") => void
|
||
selectedMaterials: string[]
|
||
onSelectedMaterialsChange: (ids: string[]) => void
|
||
smartSelectedIds: string[]
|
||
onSmartSelectedIdsChange: (ids: string[]) => void
|
||
/** 当前选中的模板/草稿 ID,用于自动保存 */
|
||
selectedTemplate?: string
|
||
/** 当前模板的 segments(用于构建 clips duration) */
|
||
templateSegments?: TemplateSegment[]
|
||
/** 服务端 clips 创建成功后的回调 */
|
||
onServerClipsChange?: (clips: EditPlanClip[]) => void
|
||
}
|
||
|
||
const Step2MaterialSelect: React.FC<Step2MaterialSelectProps> = (props) => {
|
||
const m = useStep2Materials(props)
|
||
|
||
return (
|
||
<div className="xx-form-section">
|
||
<h3>📦 选择素材</h3>
|
||
|
||
<MaterialModeTabs mode={m.materialMode} onModeChange={m.onMaterialModeChange} />
|
||
|
||
<div className="xx-form-field" style={{ marginTop: 12 }}>
|
||
<label>选择视频库</label>
|
||
<select
|
||
value={m.selectedLibraryId}
|
||
onChange={(e) => m.setSelectedLibraryId(e.target.value)}
|
||
>
|
||
{m.libraries.map((lib) => (
|
||
<option key={lib.id} value={lib.id}>
|
||
{lib.name}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
|
||
{m.materialMode === "manual" && (
|
||
<>
|
||
<div
|
||
style={{
|
||
marginTop: 14,
|
||
display: "flex",
|
||
alignItems: "center",
|
||
gap: 10,
|
||
}}
|
||
>
|
||
<span className="xx-pill xx-pill-ok">已选 {m.selectedMaterials.length} 个素材</span>
|
||
</div>
|
||
|
||
<ManualMaterialList
|
||
materials={m.selectableMaterials}
|
||
materialsLoading={m.materialsLoading}
|
||
allExhausted={m.allMaterialsExhausted}
|
||
selectedMaterials={m.selectedMaterials}
|
||
onToggle={m.handleToggleMaterial}
|
||
/>
|
||
</>
|
||
)}
|
||
|
||
{m.materialMode === "auto" && (
|
||
<div className="xx-smart-match-section">
|
||
<SmartMatchInput
|
||
matching={m.smartMatching}
|
||
onMatch={m.handleSmartMatch}
|
||
hasMatched={m.hasMatched}
|
||
onRefresh={m.handleRefreshMatch}
|
||
materialsCount={m.selectableMaterials.items.length}
|
||
loading={m.materialsLoading}
|
||
/>
|
||
|
||
<SmartMatchResults
|
||
matchedAssets={m.smartMatchedResults}
|
||
selectedIds={m.smartSelectedIds}
|
||
matching={m.smartMatching}
|
||
hasMatched={m.hasMatched}
|
||
onToggle={m.handleToggleSmartSelect}
|
||
onSelectAll={m.handleSelectAllMatched}
|
||
onClear={m.handleClearSmartSelect}
|
||
formatDuration={m.formatDuration}
|
||
selectedTotalDuration={m.smartSelectedTotalDuration}
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default Step2MaterialSelect
|