mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-22 10:51:02 +01:00
feat(task): add update logic for task intervals for backup/sync
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import axios from 'axios';
|
||||
import Alert from '@ui/Alert';
|
||||
|
||||
export const getAllTasks = async () => {
|
||||
try {
|
||||
@@ -37,3 +38,23 @@ export const triggerTask = async taskId => {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const updateTaskInterval = async (taskId, intervalMinutes) => {
|
||||
try {
|
||||
const response = await axios.put(`/api/tasks/${taskId}`, {
|
||||
interval_minutes: intervalMinutes
|
||||
});
|
||||
Alert.success(response.data.message || 'Task interval updated successfully');
|
||||
return {
|
||||
success: true,
|
||||
data: response.data
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error.response?.data?.error || 'Failed to update task interval';
|
||||
Alert.error(errorMessage);
|
||||
return {
|
||||
success: false,
|
||||
error: errorMessage
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
// components/settings/TaskCard.jsx
|
||||
import React from 'react';
|
||||
import {Play, Loader} from 'lucide-react';
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {Play, Loader, Edit2, Check, X} from 'lucide-react';
|
||||
import NumberInput from '@ui/NumberInput';
|
||||
import {updateTaskInterval} from '@/api/task';
|
||||
|
||||
const TaskCard = ({task, onTrigger, isTriggering}) => {
|
||||
const TaskCard = ({task, onTrigger, isTriggering, isLast, onIntervalUpdate}) => {
|
||||
const [intervalValue, setIntervalValue] = useState(task.interval_minutes);
|
||||
const [originalValue, setOriginalValue] = useState(task.interval_minutes);
|
||||
|
||||
// Only allow editing for Repository Sync and Backup tasks
|
||||
const isEditable = task.type === 'Sync' || task.type === 'Backup';
|
||||
const formatDateTime = dateString => {
|
||||
if (!dateString) return 'Never';
|
||||
return new Date(dateString).toLocaleString();
|
||||
@@ -13,8 +20,32 @@ const TaskCard = ({task, onTrigger, isTriggering}) => {
|
||||
return `${duration}s`;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setIntervalValue(task.interval_minutes);
|
||||
setOriginalValue(task.interval_minutes);
|
||||
}, [task.interval_minutes]);
|
||||
|
||||
useEffect(() => {
|
||||
if (intervalValue !== originalValue && intervalValue > 0) {
|
||||
const updateInterval = async () => {
|
||||
const result = await updateTaskInterval(task.id, intervalValue);
|
||||
if (result.success) {
|
||||
setOriginalValue(intervalValue);
|
||||
// Refresh task data to get new next_run time
|
||||
if (onIntervalUpdate) {
|
||||
onIntervalUpdate();
|
||||
}
|
||||
} else {
|
||||
// Reset to original value if update failed
|
||||
setIntervalValue(originalValue);
|
||||
}
|
||||
};
|
||||
updateInterval();
|
||||
}
|
||||
}, [intervalValue]);
|
||||
|
||||
return (
|
||||
<tr className='bg-gray-900 border-b border-gray-700'>
|
||||
<tr className={`bg-gray-900 ${!isLast ? 'border-b border-gray-700' : ''}`}>
|
||||
<td className='py-4 px-4'>
|
||||
<div className='flex items-center space-x-3'>
|
||||
<span className='font-medium text-gray-100'>
|
||||
@@ -23,7 +54,21 @@ const TaskCard = ({task, onTrigger, isTriggering}) => {
|
||||
</div>
|
||||
</td>
|
||||
<td className='py-4 px-4 text-gray-300'>
|
||||
{task.interval_minutes} minutes
|
||||
{isEditable ? (
|
||||
<div className='flex items-center space-x-2'>
|
||||
<NumberInput
|
||||
value={intervalValue}
|
||||
onChange={setIntervalValue}
|
||||
min={1}
|
||||
max={43200}
|
||||
step={1}
|
||||
className='w-24'
|
||||
/>
|
||||
<span className='text-gray-400 text-sm'>minutes</span>
|
||||
</div>
|
||||
) : (
|
||||
<span>{task.interval_minutes} minutes</span>
|
||||
)}
|
||||
</td>
|
||||
<td className='py-4 px-4 text-gray-300'>
|
||||
{formatDateTime(task.last_run)}
|
||||
|
||||
@@ -77,12 +77,14 @@ const TaskContainer = () => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tasks.map(task => (
|
||||
{tasks.map((task, index) => (
|
||||
<TaskCard
|
||||
key={task.id}
|
||||
task={task}
|
||||
onTrigger={handleTriggerTask}
|
||||
isTriggering={triggeringTask === task.id}
|
||||
isLast={index === tasks.length - 1}
|
||||
onIntervalUpdate={fetchTasks}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
@@ -5,6 +5,8 @@ import {ChevronUp, ChevronDown} from 'lucide-react';
|
||||
const NumberInput = ({
|
||||
value,
|
||||
onChange,
|
||||
onBlur = () => {},
|
||||
onFocus = () => {},
|
||||
className = '',
|
||||
step = 1,
|
||||
disabled = false,
|
||||
@@ -24,26 +26,26 @@ const NumberInput = ({
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
const handleBlur = (e) => {
|
||||
setIsFocused(false);
|
||||
const numValue =
|
||||
localValue === '' || localValue === '-' ? 0 : parseInt(localValue);
|
||||
|
||||
if (min !== undefined && numValue < min) {
|
||||
onChange(min);
|
||||
return;
|
||||
}
|
||||
if (max !== undefined && numValue > max) {
|
||||
} else if (max !== undefined && numValue > max) {
|
||||
onChange(max);
|
||||
return;
|
||||
} else {
|
||||
onChange(numValue);
|
||||
}
|
||||
|
||||
onChange(numValue);
|
||||
|
||||
onBlur(e);
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
const handleFocus = (e) => {
|
||||
setIsFocused(true);
|
||||
setLocalValue(value.toString());
|
||||
onFocus(e);
|
||||
};
|
||||
|
||||
const increment = () => {
|
||||
|
||||
Reference in New Issue
Block a user