import React from 'react'; import useSWR from 'swr'; import LoadingSpinner from '../../Common/LoadingSpinner'; import { FormattedRelativeTime, defineMessages, useIntl, MessageDescriptor, } from 'react-intl'; import Button from '../../Common/Button'; import Table from '../../Common/Table'; import Spinner from '../../../assets/spinner.svg'; import axios from 'axios'; import { useToasts } from 'react-toast-notifications'; import Badge from '../../Common/Badge'; import { CacheItem } from '../../../../server/interfaces/api/settingsInterfaces'; import { formatBytes } from '../../../utils/numberHelpers'; const messages: { [messageName: string]: MessageDescriptor } = defineMessages({ jobs: 'Jobs', jobsDescription: 'Overseerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered below. Manually running a job will not alter its schedule.', jobname: 'Job Name', jobtype: 'Type', nextexecution: 'Next Execution', runnow: 'Run Now', canceljob: 'Cancel Job', jobstarted: '{jobname} started.', jobcancelled: '{jobname} canceled.', process: 'Process', command: 'Command', cache: 'Cache', cacheDescription: 'Overseerr caches requests to external API endpoints to optimize performance and avoid making unnecessary API calls.', cacheflushed: '{cachename} cache flushed.', cachename: 'Cache Name', cachehits: 'Hits', cachemisses: 'Misses', cachekeys: 'Total Keys', cacheksize: 'Key Size', cachevsize: 'Value Size', flushcache: 'Flush Cache', unknownJob: 'Unknown Job', 'plex-recently-added-sync': 'Plex Recently Added Sync', 'plex-full-sync': 'Plex Full Library Sync', 'radarr-sync': 'Radarr Sync', 'sonarr-sync': 'Sonarr Sync', 'download-sync': 'Download Sync', 'download-sync-reset': 'Download Sync Reset', }); interface Job { id: string; name: string; type: 'process' | 'command'; nextExecutionTime: string; running: boolean; } const SettingsJobs: React.FC = () => { const intl = useIntl(); const { addToast } = useToasts(); const { data, error, revalidate } = useSWR('/api/v1/settings/jobs', { refreshInterval: 5000, }); const { data: cacheData, revalidate: cacheRevalidate } = useSWR( '/api/v1/settings/cache', { refreshInterval: 10000, } ); if (!data && !error) { return ; } const runJob = async (job: Job) => { await axios.post(`/api/v1/settings/jobs/${job.id}/run`); addToast( intl.formatMessage(messages.jobstarted, { jobname: intl.formatMessage(messages[job.id] ?? messages.unknownJob), }), { appearance: 'success', autoDismiss: true, } ); revalidate(); }; const cancelJob = async (job: Job) => { await axios.post(`/api/v1/settings/jobs/${job.id}/cancel`); addToast( intl.formatMessage(messages.jobcancelled, { jobname: intl.formatMessage(messages[job.id] ?? messages.unknownJob), }), { appearance: 'error', autoDismiss: true, } ); revalidate(); }; const flushCache = async (cache: CacheItem) => { await axios.post(`/api/v1/settings/cache/${cache.id}/flush`); addToast( intl.formatMessage(messages.cacheflushed, { cachename: cache.name }), { appearance: 'success', autoDismiss: true, } ); cacheRevalidate(); }; return ( <>

{intl.formatMessage(messages.jobs)}

{intl.formatMessage(messages.jobsDescription)}

{intl.formatMessage(messages.jobname)}{intl.formatMessage(messages.jobtype)}{intl.formatMessage(messages.nextexecution)} {data?.map((job) => (
{job.running && } {intl.formatMessage( messages[job.id] ?? messages.unknownJob )}
{job.type === 'process' ? intl.formatMessage(messages.process) : intl.formatMessage(messages.command)}
{job.running ? ( ) : ( )} ))}

{intl.formatMessage(messages.cache)}

{intl.formatMessage(messages.cacheDescription)}

{intl.formatMessage(messages.cachename)}{intl.formatMessage(messages.cachehits)}{intl.formatMessage(messages.cachemisses)}{intl.formatMessage(messages.cachekeys)}{intl.formatMessage(messages.cacheksize)}{intl.formatMessage(messages.cachevsize)} {cacheData?.map((cache) => ( {cache.name}{intl.formatNumber(cache.stats.hits)}{intl.formatNumber(cache.stats.misses)}{intl.formatNumber(cache.stats.keys)}{formatBytes(cache.stats.ksize)}{formatBytes(cache.stats.vsize)} ))}
); }; export default SettingsJobs;