mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-17 17:47:33 +08:00
webui cron: use enabled channel/recipient dropdowns from config allow_from and default to non-group ids
This commit is contained in:
@@ -15,13 +15,48 @@ const initialCronForm = {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isNonGroupRecipient = (channel: string, id: string) => {
|
||||||
|
const ch = String(channel || '').toLowerCase();
|
||||||
|
const v = String(id || '').trim();
|
||||||
|
if (!v) return false;
|
||||||
|
if (ch === 'telegram') {
|
||||||
|
if (v.startsWith('-')) return false;
|
||||||
|
if (v.startsWith('telegram:')) {
|
||||||
|
const raw = v.slice('telegram:'.length);
|
||||||
|
if (raw.startsWith('-')) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ch === 'discord') {
|
||||||
|
if (v.startsWith('#') || v.startsWith('discord:channel:')) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const Cron: React.FC = () => {
|
const Cron: React.FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { cron, refreshCron, q } = useAppContext();
|
const { cron, refreshCron, q, cfg } = useAppContext();
|
||||||
const [isCronModalOpen, setIsCronModalOpen] = useState(false);
|
const [isCronModalOpen, setIsCronModalOpen] = useState(false);
|
||||||
const [editingCron, setEditingCron] = useState<CronJob | null>(null);
|
const [editingCron, setEditingCron] = useState<CronJob | null>(null);
|
||||||
const [cronForm, setCronForm] = useState(initialCronForm);
|
const [cronForm, setCronForm] = useState(initialCronForm);
|
||||||
|
|
||||||
|
const enabledChannels = React.useMemo(() => {
|
||||||
|
const channels = (cfg as any)?.channels || {};
|
||||||
|
return Object.keys(channels).filter((k) => {
|
||||||
|
const v = channels[k];
|
||||||
|
return v && typeof v === 'object' && v.enabled === true;
|
||||||
|
});
|
||||||
|
}, [cfg]);
|
||||||
|
|
||||||
|
const channelRecipients = React.useMemo(() => {
|
||||||
|
const channels = (cfg as any)?.channels || {};
|
||||||
|
const out: Record<string, string[]> = {};
|
||||||
|
enabledChannels.forEach((ch) => {
|
||||||
|
const arr = Array.isArray(channels?.[ch]?.allow_from) ? channels[ch].allow_from : [];
|
||||||
|
out[ch] = arr.map((x: any) => String(x || '').trim()).filter((id: string) => isNonGroupRecipient(ch, id));
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}, [cfg, enabledChannels]);
|
||||||
|
|
||||||
async function cronAction(action: 'delete' | 'enable' | 'disable', id: string) {
|
async function cronAction(action: 'delete' | 'enable' | 'disable', id: string) {
|
||||||
try {
|
try {
|
||||||
await fetch(`/webui/api/cron${q}`, {
|
await fetch(`/webui/api/cron${q}`, {
|
||||||
@@ -57,7 +92,9 @@ const Cron: React.FC = () => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setEditingCron(null);
|
setEditingCron(null);
|
||||||
setCronForm(initialCronForm);
|
const defaultChannel = enabledChannels[0] || initialCronForm.channel;
|
||||||
|
const defaultTo = (channelRecipients[defaultChannel] && channelRecipients[defaultChannel][0]) || '';
|
||||||
|
setCronForm({ ...initialCronForm, channel: defaultChannel, to: defaultTo });
|
||||||
}
|
}
|
||||||
setIsCronModalOpen(true);
|
setIsCronModalOpen(true);
|
||||||
}
|
}
|
||||||
@@ -223,21 +260,42 @@ const Cron: React.FC = () => {
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<label className="block">
|
<label className="block">
|
||||||
<span className="text-sm font-medium text-zinc-400 mb-1.5 block">{t('channel')}</span>
|
<span className="text-sm font-medium text-zinc-400 mb-1.5 block">{t('channel')}</span>
|
||||||
<input
|
<select
|
||||||
type="text"
|
|
||||||
value={cronForm.channel}
|
value={cronForm.channel}
|
||||||
onChange={(e) => setCronForm({ ...cronForm, channel: e.target.value })}
|
onChange={(e) => {
|
||||||
|
const nextChannel = e.target.value;
|
||||||
|
const candidates = channelRecipients[nextChannel] || [];
|
||||||
|
const nextTo = candidates.includes(cronForm.to) ? cronForm.to : (candidates[0] || '');
|
||||||
|
setCronForm({ ...cronForm, channel: nextChannel, to: nextTo });
|
||||||
|
}}
|
||||||
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 text-sm focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
|
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 text-sm focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
|
||||||
/>
|
>
|
||||||
|
{(enabledChannels.length > 0 ? enabledChannels : [cronForm.channel]).map((ch) => (
|
||||||
|
<option key={ch} value={ch}>{ch}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label className="block">
|
<label className="block">
|
||||||
<span className="text-sm font-medium text-zinc-400 mb-1.5 block">{t('to')}</span>
|
<span className="text-sm font-medium text-zinc-400 mb-1.5 block">{t('to')}</span>
|
||||||
<input
|
{((channelRecipients[cronForm.channel] || []).length > 0) ? (
|
||||||
type="text"
|
<select
|
||||||
value={cronForm.to}
|
value={cronForm.to}
|
||||||
onChange={(e) => setCronForm({ ...cronForm, to: e.target.value })}
|
onChange={(e) => setCronForm({ ...cronForm, to: e.target.value })}
|
||||||
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 text-sm focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
|
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 text-sm focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
|
||||||
/>
|
>
|
||||||
|
{(channelRecipients[cronForm.channel] || []).map((id) => (
|
||||||
|
<option key={id} value={id}>{id}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
) : (
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={cronForm.to}
|
||||||
|
onChange={(e) => setCronForm({ ...cronForm, to: e.target.value })}
|
||||||
|
placeholder="recipient id"
|
||||||
|
className="w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 text-sm focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user