1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-20 21:54:58 -04:00
Files
Sonarr/frontend/src/System/Tasks/Scheduled/ScheduledTaskRow.tsx
T
2025-11-11 18:28:47 -08:00

152 lines
4.4 KiB
TypeScript

import moment from 'moment';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRow from 'Components/Table/TableRow';
import { icons } from 'Helpers/Props';
import { executeCommand } from 'Store/Actions/commandActions';
import createCommandSelector from 'Store/Selectors/createCommandSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import { isCommandExecuting } from 'Utilities/Command';
import formatDate from 'Utilities/Date/formatDate';
import formatDateTime from 'Utilities/Date/formatDateTime';
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
import styles from './ScheduledTaskRow.css';
interface ScheduledTaskRowProps {
id: number;
taskName: string;
name: string;
interval: number;
lastExecution: string;
lastStartTime: string;
lastDuration: string;
nextExecution: string;
}
function ScheduledTaskRow({
taskName,
name,
interval,
lastExecution,
lastStartTime,
lastDuration,
nextExecution,
}: ScheduledTaskRowProps) {
const dispatch = useDispatch();
const { showRelativeDates, longDateFormat, shortDateFormat, timeFormat } =
useSelector(createUISettingsSelector());
const command = useSelector(createCommandSelector(taskName));
const [time, setTime] = useState(Date.now());
const isQueued = !!(command && command.status === 'queued');
const isExecuting = isCommandExecuting(command);
const isDisabled = interval === 0;
const executeNow = !isDisabled && moment().isAfter(nextExecution);
const hasNextExecutionTime = !isDisabled && !executeNow;
const hasLastStartTime = moment(lastStartTime).isAfter('2010-01-01');
const duration = useMemo(() => {
return moment
.duration(interval, 'minutes')
.humanize()
.replace(/an?(?=\s)/, '1');
}, [interval]);
const { lastExecutionTime, nextExecutionTime } = useMemo(() => {
const isDisabled = interval === 0;
if (showRelativeDates && time) {
return {
lastExecutionTime: moment(lastExecution).fromNow(),
nextExecutionTime: isDisabled ? '-' : moment(nextExecution).fromNow(),
};
}
return {
lastExecutionTime: formatDate(lastExecution, shortDateFormat),
nextExecutionTime: isDisabled
? '-'
: formatDate(nextExecution, shortDateFormat),
};
}, [
time,
interval,
lastExecution,
nextExecution,
showRelativeDates,
shortDateFormat,
]);
const handleExecutePress = useCallback(() => {
dispatch(executeCommand({ name: taskName }));
}, [taskName, dispatch]);
useEffect(() => {
const interval = setInterval(() => setTime(Date.now()), 1000);
return () => {
clearInterval(interval);
};
}, [setTime]);
return (
<TableRow>
<TableRowCell>{name}</TableRowCell>
<TableRowCell className={styles.interval}>
{isDisabled ? 'disabled' : duration}
</TableRowCell>
<TableRowCell
className={styles.lastExecution}
title={formatDateTime(lastExecution, longDateFormat, timeFormat)}
>
{lastExecutionTime}
</TableRowCell>
{hasLastStartTime ? (
<TableRowCell className={styles.lastDuration} title={lastDuration}>
{formatTimeSpan(lastDuration)}
</TableRowCell>
) : (
<TableRowCell className={styles.lastDuration}>-</TableRowCell>
)}
{isDisabled ? (
<TableRowCell className={styles.nextExecution}>-</TableRowCell>
) : null}
{executeNow && isQueued ? (
<TableRowCell className={styles.nextExecution}>queued</TableRowCell>
) : null}
{executeNow && !isQueued ? (
<TableRowCell className={styles.nextExecution}>now</TableRowCell>
) : null}
{hasNextExecutionTime ? (
<TableRowCell
className={styles.nextExecution}
title={formatDateTime(nextExecution, longDateFormat, timeFormat, {
includeSeconds: true,
})}
>
{nextExecutionTime}
</TableRowCell>
) : null}
<TableRowCell className={styles.actions}>
<SpinnerIconButton
name={icons.REFRESH}
spinningName={icons.REFRESH}
isSpinning={isExecuting}
onPress={handleExecutePress}
/>
</TableRowCell>
</TableRow>
);
}
export default ScheduledTaskRow;