diff --git a/dashboard/src/views/ConversationPage.vue b/dashboard/src/views/ConversationPage.vue index 7df69da95..ad391b299 100644 --- a/dashboard/src/views/ConversationPage.vue +++ b/dashboard/src/views/ConversationPage.vue @@ -1135,129 +1135,157 @@ export default { diff --git a/dashboard/src/views/CronJobPage.vue b/dashboard/src/views/CronJobPage.vue index 657d453b4..8d4e4a3ea 100644 --- a/dashboard/src/views/CronJobPage.vue +++ b/dashboard/src/views/CronJobPage.vue @@ -1,218 +1,153 @@ @@ -254,36 +189,21 @@ const recurringCount = computed(() => jobs.value.filter((job) => !job.run_once). const sortedJobs = computed(() => [...jobs.value].sort((a, b) => { - if (a.enabled !== b.enabled) { - return a.enabled ? -1 : 1 - } - + if (a.enabled !== b.enabled) { return a.enabled ? -1 : 1 } const nextA = parseTimeValue(a.next_run_time ?? a.run_at) const nextB = parseTimeValue(b.next_run_time ?? b.run_at) - if (nextA !== nextB) { if (!nextA) return 1 if (!nextB) return -1 return nextA - nextB } - return String(a.name || '').localeCompare(String(b.name || '')) }) ) const overviewCards = computed(() => [ - { - label: tm('overview.totalTasks'), - value: String(jobs.value.length), - note: tm('overview.totalTasksNote'), - icon: 'mdi-calendar-multiple' - }, - { - label: tm('overview.enabledTasks'), - value: String(enabledJobsCount.value), - note: tm('overview.enabledTasksNote'), - icon: 'mdi-check-circle-outline' - } + { label: tm('overview.totalTasks'), value: String(jobs.value.length), note: tm('overview.totalTasksNote'), icon: 'mdi-calendar-multiple' }, + { label: tm('overview.enabledTasks'), value: String(enabledJobsCount.value), note: tm('overview.enabledTasksNote'), icon: 'mdi-check-circle-outline' } ]) function toast(message: string, color: 'success' | 'error' | 'warning' = 'success') { @@ -298,34 +218,23 @@ function parseTimeValue(value: any): number { function formatTime(val: any): string { if (!val) return tm('table.notAvailable') - try { - return new Date(val).toLocaleString() - } catch { - return String(val) - } + try { return new Date(val).toLocaleString() } catch { return String(val) } } function jobTypeLabel(item: any): string { if (item.run_once) return tm('table.type.once') const type = item.job_type || 'active_agent' - const map: Record = { - active_agent: tm('table.type.activeAgent'), - workflow: tm('table.type.workflow') - } + const map: Record = { active_agent: tm('table.type.activeAgent'), workflow: tm('table.type.workflow') } return map[type] || tm('table.type.unknown', { type }) } function scheduleLabel(item: any): string { - if (item.run_once) { - return formatTime(item.run_at) - } + if (item.run_once) return formatTime(item.run_at) return item.cron_expression || tm('table.notAvailable') } function scheduleMeta(item: any): string { - if (item.run_once) { - return tm('table.type.once') - } + if (item.run_once) return tm('table.type.once') return item.timezone || tm('table.timezoneLocal') } @@ -335,252 +244,247 @@ async function loadJobs() { const res = await axios.get('/api/cron/jobs') if (res.data.status === 'ok') { const data = Array.isArray(res.data.data) ? res.data.data : [] - jobs.value = data.map((job: any) => ({ - ...job, - session: job?.payload?.session || job?.session || '' - })) - } else { - toast(res.data.message || tm('messages.loadFailed'), 'error') - } - } catch (e: any) { - toast(e?.response?.data?.message || tm('messages.loadFailed'), 'error') - } finally { - loading.value = false - } + jobs.value = data.map((job: any) => ({ ...job, session: job?.payload?.session || job?.session || '' })) + } else { toast(res.data.message || tm('messages.loadFailed'), 'error') } + } catch (e: any) { toast(e?.response?.data?.message || tm('messages.loadFailed'), 'error') } + finally { loading.value = false } } async function loadPlatforms() { try { const res = await axios.get('/api/platform/stats') if (res.data.status === 'ok' && Array.isArray(res.data.data?.platforms)) { - proactivePlatforms.value = res.data.data.platforms - .filter((p: any) => p?.meta?.support_proactive_message) - .map((p: any) => ({ - id: p?.id || p?.meta?.id || 'unknown', - name: p?.meta?.name || p?.type || '', - display_name: p?.meta?.display_name || p?.display_name - })) + proactivePlatforms.value = res.data.data.platforms.filter((p: any) => p?.meta?.support_proactive_message).map((p: any) => ({ + id: p?.id || p?.meta?.id || 'unknown', + name: p?.meta?.name || p?.type || '', + display_name: p?.meta?.display_name || p?.display_name + })) } - } catch { - // Ignore platform fetch failures and keep the fallback state. - } + } catch { /* Ignore */ } } async function toggleJob(job: any) { try { const res = await axios.patch(`/api/cron/jobs/${job.job_id}`, { enabled: job.enabled }) - if (res.data.status !== 'ok') { - toast(res.data.message || tm('messages.updateFailed'), 'error') - await loadJobs() - } - } catch (e: any) { - toast(e?.response?.data?.message || tm('messages.updateFailed'), 'error') - await loadJobs() - } + if (res.data.status !== 'ok') { toast(res.data.message || tm('messages.updateFailed'), 'error'); await loadJobs() } + } catch (e: any) { toast(e?.response?.data?.message || tm('messages.updateFailed'), 'error'); await loadJobs() } } async function deleteJob(job: any) { try { const res = await axios.delete(`/api/cron/jobs/${job.job_id}`) - if (res.data.status === 'ok') { - toast(tm('messages.deleteSuccess')) - jobs.value = jobs.value.filter((item) => item.job_id !== job.job_id) - } else { - toast(res.data.message || tm('messages.deleteFailed'), 'error') - } - } catch (e: any) { - toast(e?.response?.data?.message || tm('messages.deleteFailed'), 'error') - } + if (res.data.status === 'ok') { toast(tm('messages.deleteSuccess')); jobs.value = jobs.value.filter((item) => item.job_id !== job.job_id) } + else { toast(res.data.message || tm('messages.deleteFailed'), 'error') } + } catch (e: any) { toast(e?.response?.data?.message || tm('messages.deleteFailed'), 'error') } } -function openCreate() { - resetNewJob() - createDialog.value = true -} +function openCreate() { resetNewJob(); createDialog.value = true } function resetNewJob() { - newJob.value = { - run_once: false, - name: '', - note: '', - cron_expression: '', - run_at: '', - session: '', - timezone: '', - enabled: true - } + newJob.value = { run_once: false, name: '', note: '', cron_expression: '', run_at: '', session: '', timezone: '', enabled: true } } async function createJob() { - if (!newJob.value.session) { - toast(tm('messages.sessionRequired'), 'warning') - return - } - if (!newJob.value.note) { - toast(tm('messages.noteRequired'), 'warning') - return - } - if (!newJob.value.run_once && !newJob.value.cron_expression) { - toast(tm('messages.cronRequired'), 'warning') - return - } - if (newJob.value.run_once && !newJob.value.run_at) { - toast(tm('messages.runAtRequired'), 'warning') - return - } - + if (!newJob.value.session) { toast(tm('messages.sessionRequired'), 'warning'); return } + if (!newJob.value.note) { toast(tm('messages.noteRequired'), 'warning'); return } + if (!newJob.value.run_once && !newJob.value.cron_expression) { toast(tm('messages.cronRequired'), 'warning'); return } + if (newJob.value.run_once && !newJob.value.run_at) { toast(tm('messages.runAtRequired'), 'warning'); return } creating.value = true try { const res = await axios.post('/api/cron/jobs', { ...newJob.value }) - if (res.data.status === 'ok') { - toast(tm('messages.createSuccess')) - createDialog.value = false - resetNewJob() - await loadJobs() - } else { - toast(res.data.message || tm('messages.createFailed'), 'error') - } - } catch (e: any) { - toast(e?.response?.data?.message || tm('messages.createFailed'), 'error') - } finally { - creating.value = false - } + if (res.data.status === 'ok') { toast(tm('messages.createSuccess')); createDialog.value = false; resetNewJob(); await loadJobs() } + else { toast(res.data.message || tm('messages.createFailed'), 'error') } + } catch (e: any) { toast(e?.response?.data?.message || tm('messages.createFailed'), 'error') } + finally { creating.value = false } } -onMounted(() => { - loadJobs() - loadPlatforms() -}) +onMounted(() => { loadJobs(); loadPlatforms() }) diff --git a/dashboard/src/views/SessionManagementPage.vue b/dashboard/src/views/SessionManagementPage.vue index e6a3367f1..1c81f1b4a 100644 --- a/dashboard/src/views/SessionManagementPage.vue +++ b/dashboard/src/views/SessionManagementPage.vue @@ -1,5 +1,5 @@