1010// shared row cannot disagree about what the preset means.
1111import { useState , type ReactElement } from "react" ;
1212import { WebuiInline } from "../../../ui/layout-primitives.js" ;
13+ import { useWebuiBrowserCapabilities } from "../../../bindings/browser-capabilities.js" ;
14+ import { WebuiDialog } from "../../../ui/dialog.js" ;
1315
1416import type {
1517 WebuiCronSchedule ,
@@ -28,7 +30,7 @@ import {
2830 type WebuiCronSchedulePreset ,
2931} from "../projection/scheduling-panel.js" ;
3032import { WebuiButton } from "../../../ui/button.js" ;
31- import { WebuiField , WebuiFormLayout , WebuiSelect , WebuiTextarea , WebuiTextInput } from "../../../ui/field.js" ;
33+ import { WebuiField , WebuiFormLayout , WebuiSelectMenu , WebuiTextarea , WebuiTextInput } from "../../../ui/field.js" ;
3234
3335export interface SchedulingEditorViewProps {
3436 readonly mode : "create" | "edit" ;
@@ -51,7 +53,8 @@ export function SchedulingEditorView(props: SchedulingEditorViewProps): ReactEle
5153 event . preventDefault ( ) ;
5254 props . onSubmit ( ) ;
5355 } }
54- className = "mb-4 rounded-[8px] border border-border_default p-3"
56+ id = "webui-scheduling-editor-form"
57+ className = "flex flex-col gap-4"
5558 >
5659 < WebuiFormLayout >
5760 < WebuiField
@@ -100,20 +103,19 @@ export function SchedulingEditorView(props: SchedulingEditorViewProps): ReactEle
100103 />
101104 < WebuiField
102105 label = "周期"
103- control = { ( props ) => (
104- < WebuiSelect
105- { ...props }
106- controlSize = "dense"
106+ control = { ( controlProps , field ) => (
107+ < WebuiSelectMenu
108+ { ...controlProps }
109+ labelId = { field . labelId }
110+ className = "webui-control--dense"
107111 data-webui-scheduling-field = "preset"
112+ options = { ( Object . keys ( WEBUI_CRON_PRESET_LABELS ) as WebuiCronSchedulePreset [ ] ) . map ( ( preset ) => ( {
113+ value : preset ,
114+ label : WEBUI_CRON_PRESET_LABELS [ preset ] ,
115+ } ) ) }
108116 value = { draft . preset }
109- onChange = { ( event ) => onChange ( { preset : event . target . value as WebuiCronSchedulePreset } ) }
110- >
111- { ( Object . keys ( WEBUI_CRON_PRESET_LABELS ) as WebuiCronSchedulePreset [ ] ) . map ( ( preset ) => (
112- < option key = { preset } value = { preset } >
113- { WEBUI_CRON_PRESET_LABELS [ preset ] }
114- </ option >
115- ) ) }
116- </ WebuiSelect >
117+ onChange = { ( value ) => onChange ( { preset : value as WebuiCronSchedulePreset } ) }
118+ />
117119 ) }
118120 />
119121 { draft . preset === "daily" || draft . preset === "weekly"
@@ -242,21 +244,6 @@ export function SchedulingEditorView(props: SchedulingEditorViewProps): ReactEle
242244 { props . error }
243245 </ p >
244246 : null }
245- < WebuiInline gap = "small" className = "pt-1" >
246- < WebuiButton variant = "outline" size = "inline" type = "submit"
247- data-webui-scheduling-submit = "true"
248- disabled = { props . busy }
249-
250- >
251- { props . mode === "create" ? "创建" : "保存" }
252- </ WebuiButton >
253- < WebuiButton variant = "quiet-secondary" size = "inline" data-webui-scheduling-cancel = "true"
254- onClick = { props . onCancel }
255-
256- >
257- 取消
258- </ WebuiButton >
259- </ WebuiInline >
260247 </ WebuiFormLayout >
261248 </ form >
262249 ) ;
@@ -265,18 +252,22 @@ export function SchedulingEditorView(props: SchedulingEditorViewProps): ReactEle
265252export function SchedulingEditor ( props : {
266253 readonly owner : WebuiSchedulingOwner ;
267254 readonly task ?: WebuiCronTask ;
255+ readonly open : boolean ;
256+ readonly seed ?: Partial < WebuiCronDraft > ;
268257 /** The agent a new task belongs to; the panel passes the client's own. */
269258 readonly agentName ?: string ;
270259 readonly nowMs : ( ) => number ;
271260 readonly onDone : ( ) => void ;
261+ readonly onExitComplete : ( ) => void ;
272262} ) : ReactElement {
263+ const { dom } = useWebuiBrowserCapabilities ( ) ;
273264 // Read once: a narrowed `props.task` inside the submit closure loses the narrowing.
274265 const editingTask = props . task ;
275266 const mode = editingTask ? "edit" : "create" ;
276267 const [ initialDraft ] = useState < WebuiCronDraft > ( ( ) =>
277268 editingTask
278269 ? webuiCronDraftFromTask ( editingTask )
279- : { ...WEBUI_CRON_EMPTY_DRAFT , agentName : props . agentName ?? "" } ,
270+ : { ...WEBUI_CRON_EMPTY_DRAFT , agentName : props . agentName ?? "" , ... ( props . seed ?? { } ) } ,
280271 ) ;
281272 const [ draft , setDraft ] = useState < WebuiCronDraft > ( initialDraft ) ;
282273 const [ error , setError ] = useState < string | undefined > ( undefined ) ;
@@ -324,14 +315,41 @@ export function SchedulingEditor(props: {
324315 } ;
325316
326317 return (
327- < SchedulingEditorView
328- mode = { mode }
329- draft = { draft }
330- busy = { busy }
331- { ...( error === undefined ? { } : { error } ) }
332- onChange = { ( patch ) => setDraft ( ( current ) => ( { ...current , ...patch } ) ) }
333- onCancel = { props . onDone }
334- onSubmit = { ( ) => void submit ( ) }
335- />
318+ < WebuiDialog
319+ id = "webui-scheduling-editor-dialog"
320+ open = { props . open }
321+ title = { editingTask ? "编辑定时任务" : "新建定时任务" }
322+ description = { editingTask ? "调整任务内容和执行计划" : "设置任务指令与自动执行计划" }
323+ width = "wide"
324+ portalTarget = { dom . portalTarget ( ) }
325+ onClose = { props . onDone }
326+ onExitComplete = { props . onExitComplete }
327+ dismissOnEscape
328+ dismissOnBackdrop
329+ testId = "webui-scheduling-editor-dialog"
330+ footer = { (
331+ < WebuiInline gap = "small" >
332+ < WebuiButton variant = "secondary" size = "dialog" type = "button" data-webui-scheduling-cancel = "true" onClick = { props . onDone } >
333+ 取消
334+ </ WebuiButton >
335+ < WebuiButton variant = "primary" size = "dialog" type = "submit" form = "webui-scheduling-editor-form"
336+ data-webui-scheduling-submit = "true" loading = { busy }
337+ loadingLabel = { editingTask ? "保存中…" : "创建中…" }
338+ >
339+ { editingTask ? "保存" : "创建任务" }
340+ </ WebuiButton >
341+ </ WebuiInline >
342+ ) }
343+ >
344+ < SchedulingEditorView
345+ mode = { mode }
346+ draft = { draft }
347+ busy = { busy }
348+ { ...( error === undefined ? { } : { error } ) }
349+ onChange = { ( patch ) => setDraft ( ( current ) => ( { ...current , ...patch } ) ) }
350+ onCancel = { props . onDone }
351+ onSubmit = { ( ) => void submit ( ) }
352+ />
353+ </ WebuiDialog >
336354 ) ;
337355}
0 commit comments