Files
xiaoxia-saas/apps/web/src/pages/generate/components/Step2MaterialSelect.tsx
T
xiaoxia 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
feat(assets): 素材余量角标 + Step2 过滤已用尽素材 (#1548)
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-08-30 01:26:00 +08:00

103 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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