chore:调度文件拆分
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
import { type Schedule, type CronPreview } from "../../services/api";
|
||||
import Icon from "../../components/common/Icon";
|
||||
import { formatTime } from "./utils";
|
||||
|
||||
type ScheduleForm = {
|
||||
scheduleName: string;
|
||||
description: string;
|
||||
triggerType: "manual" | "cron" | "api";
|
||||
cronExpression: string;
|
||||
timezone: string;
|
||||
enabled: boolean;
|
||||
maxConcurrency: string;
|
||||
failurePolicy: "stop" | "continue";
|
||||
};
|
||||
|
||||
export function ScheduleInspector({
|
||||
schedule,
|
||||
form,
|
||||
cronResult,
|
||||
busy,
|
||||
onChange,
|
||||
onPreview,
|
||||
onSave,
|
||||
}: {
|
||||
schedule: Schedule | null;
|
||||
form: ScheduleForm;
|
||||
cronResult: CronPreview | null;
|
||||
busy: boolean;
|
||||
onChange: (form: ScheduleForm) => void;
|
||||
onPreview: () => void;
|
||||
onSave: () => void;
|
||||
}) {
|
||||
if (!schedule) {
|
||||
return (
|
||||
<div className="schedule-inspector-empty">
|
||||
<Icon name="settings" size={28} />
|
||||
<strong>调度属性</strong>
|
||||
<p>选中调度方案后可配置触发方式、Cron 和执行策略。</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="schedule-inspector">
|
||||
<section>
|
||||
<h3>基本信息</h3>
|
||||
<label>
|
||||
<span>调度名称</span>
|
||||
<input
|
||||
value={form.scheduleName}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
scheduleName: event.target.value,
|
||||
})}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>说明</span>
|
||||
<textarea
|
||||
rows={2}
|
||||
value={form.description}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
description: event.target.value,
|
||||
})}
|
||||
/>
|
||||
</label>
|
||||
<label className="schedule-switch-row">
|
||||
<span>
|
||||
<b>启用调度</b>
|
||||
<small>DAG 有效后才能启用</small>
|
||||
</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={form.enabled}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
enabled: event.target.checked,
|
||||
})}
|
||||
/>
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>触发器</h3>
|
||||
<label>
|
||||
<span>触发方式</span>
|
||||
<select
|
||||
value={form.triggerType}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
triggerType: event.target.value as typeof form.triggerType,
|
||||
enabled: event.target.value === "cron" ? form.enabled : false,
|
||||
})}
|
||||
>
|
||||
<option value="manual">手动触发</option>
|
||||
<option value="cron">Cron 定时</option>
|
||||
<option value="api">API 触发</option>
|
||||
</select>
|
||||
</label>
|
||||
{form.triggerType === "cron" && (
|
||||
<>
|
||||
<label>
|
||||
<span>Cron(分 时 日 月 周)</span>
|
||||
<input
|
||||
value={form.cronExpression}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
cronExpression: event.target.value,
|
||||
})}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>时区</span>
|
||||
<input
|
||||
value={form.timezone}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
timezone: event.target.value,
|
||||
})}
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
className="inspector-secondary-button"
|
||||
type="button"
|
||||
disabled={busy}
|
||||
onClick={onPreview}
|
||||
>
|
||||
预览未来 5 次
|
||||
</button>
|
||||
{cronResult && (
|
||||
<ol className="cron-preview-list">
|
||||
{cronResult.occurrences.map((item) => (
|
||||
<li key={item.utc_time}>
|
||||
{new Date(item.local_time).toLocaleString("zh-CN", {
|
||||
hour12: false,
|
||||
})}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>执行策略</h3>
|
||||
<div className="inspector-grid">
|
||||
<label>
|
||||
<span>最大并发</span>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max="64"
|
||||
value={form.maxConcurrency}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
maxConcurrency: event.target.value,
|
||||
})}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<span>失败策略</span>
|
||||
<select
|
||||
value={form.failurePolicy}
|
||||
onChange={(event) => onChange({
|
||||
...form,
|
||||
failurePolicy: event.target.value as "stop" | "continue",
|
||||
})}
|
||||
>
|
||||
<option value="stop">停止后续</option>
|
||||
<option value="continue">继续执行</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div className="schedule-next-run">
|
||||
<span>下一次执行</span>
|
||||
<strong>{formatTime(schedule.next_run_at)}</strong>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<button
|
||||
className="inspector-primary-button"
|
||||
type="button"
|
||||
disabled={busy}
|
||||
onClick={onSave}
|
||||
>
|
||||
保存调度属性
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user