refactor(cron): simplify cron job creation by removing agent selection
- Remove agent selection UI and logic from cron job dialog - Use job's agentId or default agent directly instead of selecting from list - Update UI text and styling to reflect simplified workflow - Remove unused imports and agent-related state management
This commit is contained in:
@@ -21,7 +21,7 @@ import type {
|
||||
CronJobCreateInput,
|
||||
CronJobDelivery,
|
||||
} from '../../lib/cron-types';
|
||||
import { agentsStore, chatStore, useAgentsStore } from '../../stores';
|
||||
import { agentsStore, useAgentsStore } from '../../stores';
|
||||
|
||||
type FeedbackTone = 'success' | 'error' | 'info' | 'warning';
|
||||
|
||||
@@ -34,7 +34,6 @@ type DialogProps = {
|
||||
open: boolean;
|
||||
job: CronJob | null;
|
||||
saving: boolean;
|
||||
agents: AgentSummary[];
|
||||
defaultAgentId: string;
|
||||
channelGroups: CronDeliveryChannelGroup[];
|
||||
channelsLoading: boolean;
|
||||
@@ -1097,7 +1096,7 @@ function StatCard({ label, value, tone, icon: Icon }: StatCardProps) {
|
||||
: 'bg-[#E8E6DE] text-[#7A7668] dark:bg-[#2a2a2d] dark:text-gray-400';
|
||||
|
||||
return (
|
||||
<div className="min-h-[130px] rounded-[24px] border border-transparent bg-white /60 p-5 transition-colors hover:bg-white dark:border-[#2a2a2d] dark:bg-[#1f1f22] dark:hover:bg-[#222225]">
|
||||
<div className="min-h-[130px] rounded-2xl border border-transparent bg-[#eeece3] /30 p-5 transition-colors hover:bg-[#eeece3] /60 dark:border-[#2a2a2d] dark:bg-[#1f1f22] dark:hover:bg-[#222225]">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className={cn('flex h-11 w-11 items-center justify-center rounded-full', iconWrapperClass)}>
|
||||
<Icon className="h-5 w-5" />
|
||||
@@ -1269,29 +1268,10 @@ function CronJobCard({
|
||||
);
|
||||
}
|
||||
|
||||
function getSuggestedAgentId(agents: AgentSummary[], defaultAgentId: string, currentJob: CronJob | null): string {
|
||||
const jobAgentId = getString(currentJob?.agentId);
|
||||
if (jobAgentId) return normalizeAgentId(jobAgentId);
|
||||
|
||||
const currentChatAgentId = getString(chatStore.getState().currentAgentId);
|
||||
const normalizedCurrentChatAgentId = normalizeAgentId(currentChatAgentId || defaultAgentId || DEFAULT_AGENT_ID);
|
||||
|
||||
if (agents.some((agent) => agent.id === normalizedCurrentChatAgentId)) {
|
||||
return normalizedCurrentChatAgentId;
|
||||
}
|
||||
|
||||
if (agents.some((agent) => agent.id === normalizeAgentId(defaultAgentId))) {
|
||||
return normalizeAgentId(defaultAgentId);
|
||||
}
|
||||
|
||||
return agents[0]?.id || normalizeAgentId(defaultAgentId || DEFAULT_AGENT_ID);
|
||||
}
|
||||
|
||||
function CronTaskDialog({
|
||||
open,
|
||||
job,
|
||||
saving,
|
||||
agents,
|
||||
defaultAgentId,
|
||||
channelGroups,
|
||||
channelsLoading,
|
||||
@@ -1300,7 +1280,6 @@ function CronTaskDialog({
|
||||
onSave,
|
||||
}: DialogProps) {
|
||||
const [name, setName] = useState('');
|
||||
const [selectedAgentId, setSelectedAgentId] = useState(normalizeAgentId(defaultAgentId || DEFAULT_AGENT_ID));
|
||||
const [message, setMessage] = useState('');
|
||||
const [schedule, setSchedule] = useState('0 9 * * *');
|
||||
const [enabled, setEnabled] = useState(true);
|
||||
@@ -1336,9 +1315,8 @@ function CronTaskDialog({
|
||||
setTargetsLoading(false);
|
||||
setTargetsError(null);
|
||||
setDeliveryTargetScopeKey('');
|
||||
setSelectedAgentId(getSuggestedAgentId(agents, defaultAgentId, job));
|
||||
setValidationError(null);
|
||||
}, [agents, defaultAgentId, job, open]);
|
||||
}, [job, open]);
|
||||
|
||||
const availableChannelGroups = useMemo(
|
||||
() => ensureChannelGroupSelection(channelGroups, deliveryChannel, selectedDeliveryAccountId),
|
||||
@@ -1387,13 +1365,6 @@ function CronTaskDialog({
|
||||
}
|
||||
}, [deliveryMode, open, selectedChannelGroup, selectedDeliveryAccountId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
if (agents.length === 0) return;
|
||||
if (agents.some((agent) => agent.id === selectedAgentId)) return;
|
||||
setSelectedAgentId(getSuggestedAgentId(agents, defaultAgentId, job));
|
||||
}, [agents, defaultAgentId, job, open, selectedAgentId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || deliveryMode !== 'announce') {
|
||||
setDeliveryTargetScopeKey('');
|
||||
@@ -1477,8 +1448,7 @@ function CronTaskDialog({
|
||||
|
||||
const finalSchedule = useCustom ? customSchedule.trim() : schedule;
|
||||
const nextRunPreview = finalSchedule ? estimateNextRun(finalSchedule) : null;
|
||||
const hasSelectableAgents = agents.length > 0;
|
||||
const selectedAgent = agents.find((agent) => agent.id === selectedAgentId);
|
||||
const resolvedAgentId = normalizeAgentId(getString(job?.agentId) || defaultAgentId || DEFAULT_AGENT_ID);
|
||||
const selectedAccount = selectedChannelGroup?.accounts.find((account) => account.accountId === selectedDeliveryAccountId);
|
||||
const deliveryPreview =
|
||||
deliveryMode === 'announce'
|
||||
@@ -1499,11 +1469,6 @@ function CronTaskDialog({
|
||||
return;
|
||||
}
|
||||
|
||||
if (!selectedAgentId.trim()) {
|
||||
setValidationError('请先选择要执行任务的 Agent。');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message.trim()) {
|
||||
setValidationError('请填写提醒内容。');
|
||||
return;
|
||||
@@ -1530,7 +1495,7 @@ function CronTaskDialog({
|
||||
|
||||
await onSave({
|
||||
name: name.trim(),
|
||||
agentId: normalizeAgentId(selectedAgentId),
|
||||
agentId: resolvedAgentId,
|
||||
message: message.trim(),
|
||||
schedule: finalSchedule,
|
||||
enabled,
|
||||
@@ -1549,7 +1514,7 @@ function CronTaskDialog({
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30 p-4 backdrop-blur-[1px]">
|
||||
<div className="max-h-[calc(100vh-48px)] w-full max-w-[720px] overflow-hidden rounded-[20px] bg-white shadow-[0_25px_50px_-12px_rgba(0,0,0,0.2)] dark:bg-[#1f1f22]">
|
||||
<div className="flex items-start justify-between border-b border-black/5 bg-white px-8 py-6 dark:border-[#2a2a2d] dark:bg-[#1f1f22]">
|
||||
<div className="flex items-start justify-between border-b border-black/5 bg-white px-8 py-4 dark:border-[#2a2a2d] dark:bg-[#1f1f22]">
|
||||
<div>
|
||||
<h2
|
||||
className="mb-2 text-[24px] font-normal tracking-tight text-[#171717] dark:text-[#f3f4f6]"
|
||||
@@ -1558,7 +1523,7 @@ function CronTaskDialog({
|
||||
{job ? '编辑定时任务' : '新建定时任务'}
|
||||
</h2>
|
||||
<p className="text-[14px] text-[#99A0AE] dark:text-gray-500">
|
||||
现在可以为任务指定 Agent、发送渠道和目标收件人,和 ClawX 的调度职责保持一致。
|
||||
现在可以为任务配置发送渠道和目标收件人,和 ClawX 的调度职责保持一致。
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -1570,9 +1535,9 @@ function CronTaskDialog({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="max-h-[calc(100vh-210px)] overflow-y-auto px-8 py-8">
|
||||
<div className="max-h-[calc(100vh-230px)] overflow-y-auto p-4">
|
||||
<div className="space-y-6">
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-[1.1fr_0.9fr]">
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<div>
|
||||
<label className="mb-2.5 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">任务名称</label>
|
||||
<input
|
||||
@@ -1582,33 +1547,10 @@ function CronTaskDialog({
|
||||
className="h-11 w-full rounded-xl border border-transparent bg-[#EDECE4] px-4 text-[14px] text-[#171717] outline-none transition-colors focus:border-[#3B6DE8] dark:bg-[#222225] dark:text-[#f3f4f6]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="mb-2.5 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">执行 Agent</label>
|
||||
<SelectField
|
||||
value={selectedAgentId}
|
||||
onChange={(event) => setSelectedAgentId(event.target.value)}
|
||||
disabled={!hasSelectableAgents}
|
||||
>
|
||||
{hasSelectableAgents ? (
|
||||
agents.map((agent) => (
|
||||
<option key={agent.id} value={agent.id}>
|
||||
{agent.name}
|
||||
{agent.isDefault ? ' · 默认' : ''}
|
||||
</option>
|
||||
))
|
||||
) : (
|
||||
<option value="">暂无可用 Agent</option>
|
||||
)}
|
||||
</SelectField>
|
||||
<p className="mt-2 text-[12px] font-medium text-[#99A0AE] dark:text-gray-500">
|
||||
{selectedAgent ? getAgentDetail(selectedAgent.id, new Map(agents.map((agent) => [agent.id, agent])), defaultAgentId) : 'Agent 列表加载后可选择执行归属。'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="mb-2.5 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">提醒内容</label>
|
||||
<label className="mb-2.5 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">消息/提示词</label>
|
||||
<textarea
|
||||
value={message}
|
||||
onChange={(event) => setMessage(event.target.value)}
|
||||
@@ -1619,7 +1561,7 @@ function CronTaskDialog({
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="mb-2.5 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">执行计划</label>
|
||||
<label className="mb-2.5 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">调度计划</label>
|
||||
{!useCustom ? (
|
||||
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
{SCHEDULE_PRESETS.map((preset) => {
|
||||
@@ -1674,12 +1616,12 @@ function CronTaskDialog({
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mb-1 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">发送方式</div>
|
||||
<p className="mb-3 text-[12px] text-[#99A0AE] dark:text-gray-500">任务可以只执行,也可以在完成后把结果发送到指定渠道和目标。</p>
|
||||
<div className="mb-1 block text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">投递设置</div>
|
||||
<p className="mb-3 text-[12px] text-[#99A0AE] dark:text-gray-500">选择仅在 NIANXX 内保留结果,或把最终结果推送到外部通道。</p>
|
||||
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
{[
|
||||
{ key: 'none', title: '仅执行任务', desc: '不额外推送到渠道' },
|
||||
{ key: 'announce', title: '执行并发送', desc: '选择渠道账号与目标收件人' },
|
||||
{ key: 'none', title: '仅在NIANXX内', desc: '任务照常运行,结果只保留在应用内。' },
|
||||
{ key: 'announce', title: '发送到外部通道', desc: '将最终结果投递到已配置的消息通道。' },
|
||||
].map((item) => {
|
||||
const active = deliveryMode === item.key;
|
||||
return (
|
||||
@@ -1802,7 +1744,7 @@ function CronTaskDialog({
|
||||
<div className="flex items-center justify-between rounded-2xl border border-black/5 bg-[#E8E6DE]/50 p-4 dark:border-[#2a2a2d] dark:bg-[#222225]">
|
||||
<div>
|
||||
<div className="text-[14px] font-bold text-[#171717]/80 dark:text-[#f3f4f6]/80">立即启用</div>
|
||||
<div className="mt-0.5 text-[13px] text-[#99A0AE] dark:text-gray-500">保存后按当前计划自动进入调度。</div>
|
||||
<div className="mt-0.5 text-[13px] text-[#99A0AE] dark:text-gray-500">创建后立即开始运行此任务。</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
@@ -1843,7 +1785,7 @@ function CronTaskDialog({
|
||||
onClick={() => {
|
||||
void handleSubmit();
|
||||
}}
|
||||
disabled={saving || !hasSelectableAgents}
|
||||
disabled={saving}
|
||||
>
|
||||
{saving ? <SpinnerIcon className="mr-2 h-4 w-4 animate-spin" /> : <PlusIcon className="mr-2 h-4 w-4" />}
|
||||
{saving ? '保存中...' : job ? '保存修改' : '创建任务'}
|
||||
@@ -2098,7 +2040,7 @@ export default function CronPage() {
|
||||
定时任务
|
||||
</h1>
|
||||
<p className="text-[17px] font-medium text-[#171717]/70 dark:text-[#9ca3af]">
|
||||
为 Cron 任务绑定执行 Agent 与发送渠道,让调度、执行和投递信息在一个页面里闭环。
|
||||
为 Cron 任务配置执行计划与发送渠道,让调度、执行和投递信息在一个页面里闭环。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -2153,7 +2095,7 @@ export default function CronPage() {
|
||||
<ClockIcon className="mb-4 h-10 w-10 opacity-50" />
|
||||
<h3 className="mb-2 text-lg font-medium text-[#171717] dark:text-[#f3f4f6]">还没有定时任务</h3>
|
||||
<p className="mb-6 max-w-md text-center text-[14px]">
|
||||
现在创建的任务可以直接绑定执行 Agent,并预留好渠道账号和发送目标。
|
||||
现在可以创建任务并预留好渠道账号和发送目标。
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
@@ -2204,7 +2146,6 @@ export default function CronPage() {
|
||||
open={dialogOpen}
|
||||
job={editingJob}
|
||||
saving={dialogSaving}
|
||||
agents={agents}
|
||||
defaultAgentId={defaultAgentId}
|
||||
channelGroups={channelGroups}
|
||||
channelsLoading={channelsLoading}
|
||||
|
||||
Reference in New Issue
Block a user