3862996045
CI/CD Pipeline / Check if frontend-only change (push) Waiting to run
CI/CD Pipeline / Validate - Code Quality (push) Waiting to run
CI/CD Pipeline / Validate - Type Check (mypy) (push) Waiting to run
CI/CD Pipeline / Validate - Migration (alembic) (push) Waiting to run
CI/CD Pipeline / Unit Tests (push) Blocked by required conditions
CI/CD Pipeline / Integration Tests (push) Blocked by required conditions
CI/CD Pipeline / Frontend Lint (push) Waiting to run
CI/CD Pipeline / Frontend Unit Tests (push) Blocked by required conditions
CI/CD Pipeline / PR Build API Image (push) Waiting to run
CI/CD Pipeline / PR Build Web Image (push) Waiting to run
CI/CD Pipeline / PR Build Worker Image (push) Waiting to run
CI/CD Pipeline / Build Staging API Image (push) Waiting to run
CI/CD Pipeline / Build Staging Web Image (push) Waiting to run
CI/CD Pipeline / Build Staging Worker Image (push) Waiting to run
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Blocked by required conditions
CI/CD Pipeline / Staging E2E Tests (push) Blocked by required conditions
CI/CD Pipeline / Staging API Integration Tests (push) Blocked by required conditions
CI/CD Pipeline / Build Production API Image (push) Waiting to run
CI/CD Pipeline / Build Production Web Image (push) Waiting to run
CI/CD Pipeline / Build Production Worker Image (push) Waiting to run
CI/CD Pipeline / Deploy Production (push) Blocked by required conditions
CI/CD Pipeline / Production Browser E2E (push) Blocked by required conditions
CI/CD Pipeline / ACR Image Cleanup (push) Blocked by required conditions
87 lines
2.1 KiB
TypeScript
87 lines
2.1 KiB
TypeScript
/**
|
||
* 保存/更新模板弹窗 — V21 设计系统
|
||
* 分类使用 Select 关联后端分类 API(P1-5)
|
||
*/
|
||
import React from "react"
|
||
import { Modal, Input, Select } from "@/components/ui"
|
||
import type { TemplateCategory } from "@/api/editing-planner"
|
||
|
||
interface SaveModalProps {
|
||
open: boolean
|
||
loading: boolean
|
||
isUpdate: boolean
|
||
draftName: string
|
||
draftCategory: string
|
||
draftTags: string
|
||
categories: TemplateCategory[]
|
||
estimatedDuration: number
|
||
onNameChange: (v: string) => void
|
||
onCategoryChange: (v: string) => void
|
||
onTagsChange: (v: string) => void
|
||
onSave: () => void
|
||
onCancel: () => void
|
||
}
|
||
|
||
const SaveModal: React.FC<SaveModalProps> = ({
|
||
open,
|
||
loading,
|
||
isUpdate,
|
||
draftName,
|
||
draftCategory,
|
||
draftTags,
|
||
categories,
|
||
estimatedDuration,
|
||
onNameChange,
|
||
onCategoryChange,
|
||
onTagsChange,
|
||
onSave,
|
||
onCancel,
|
||
}) => {
|
||
return (
|
||
<Modal
|
||
title={isUpdate ? "更新模板" : "保存模板"}
|
||
open={open}
|
||
onCancel={onCancel}
|
||
onOk={onSave}
|
||
confirmLoading={loading}
|
||
okText="保存"
|
||
>
|
||
<div className="ep-modal-field">
|
||
<label>模板名称 *</label>
|
||
<Input
|
||
placeholder="输入模板名称"
|
||
value={draftName}
|
||
onChange={(e) => onNameChange(e.target.value)}
|
||
/>
|
||
</div>
|
||
|
||
<div className="ep-modal-field">
|
||
<label>分类</label>
|
||
<Select
|
||
placeholder="选择分类"
|
||
value={draftCategory || undefined}
|
||
onChange={(v: string) => onCategoryChange(v || "")}
|
||
allowClear
|
||
showSearch
|
||
options={categories.map((c) => ({ value: c.name, label: c.name }))}
|
||
/>
|
||
</div>
|
||
|
||
<div className="ep-modal-field">
|
||
<label>标签(逗号分隔)</label>
|
||
<Input
|
||
placeholder="例如:vlog, 日常"
|
||
value={draftTags}
|
||
onChange={(e) => onTagsChange(e.target.value)}
|
||
/>
|
||
</div>
|
||
|
||
<div className="ep-modal-info">
|
||
⏱️ 预估时长:<strong>~{estimatedDuration}s</strong>
|
||
</div>
|
||
</Modal>
|
||
)
|
||
}
|
||
|
||
export default SaveModal
|