Fix handling of backup tasks; closes #2067
This commit is contained in:
parent
364b645b81
commit
693b9eab0c
5 changed files with 35 additions and 11 deletions
|
@ -58,7 +58,7 @@ class ScheduleTaskController extends ClientApiController
|
||||||
'schedule_id' => $schedule->id,
|
'schedule_id' => $schedule->id,
|
||||||
'sequence_id' => ($lastTask->sequence_id ?? 0) + 1,
|
'sequence_id' => ($lastTask->sequence_id ?? 0) + 1,
|
||||||
'action' => $request->input('action'),
|
'action' => $request->input('action'),
|
||||||
'payload' => $request->input('payload'),
|
'payload' => $request->input('payload') ?? '',
|
||||||
'time_offset' => $request->input('time_offset'),
|
'time_offset' => $request->input('time_offset'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class ScheduleTaskController extends ClientApiController
|
||||||
|
|
||||||
$this->repository->update($task->id, [
|
$this->repository->update($task->id, [
|
||||||
'action' => $request->input('action'),
|
'action' => $request->input('action'),
|
||||||
'payload' => $request->input('payload'),
|
'payload' => $request->input('payload') ?? '',
|
||||||
'time_offset' => $request->input('time_offset'),
|
'time_offset' => $request->input('time_offset'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class StoreTaskRequest extends ViewScheduleRequest
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'action' => 'required|in:command,power,backup',
|
'action' => 'required|in:command,power,backup',
|
||||||
'payload' => 'required_unless:action,backup|string',
|
'payload' => 'required_unless:action,backup|string|nullable',
|
||||||
'time_offset' => 'required|numeric|min:0|max:900',
|
'time_offset' => 'required|numeric|min:0|max:900',
|
||||||
'sequence_id' => 'sometimes|required|numeric|min:1',
|
'sequence_id' => 'sometimes|required|numeric|min:1',
|
||||||
];
|
];
|
||||||
|
|
|
@ -90,7 +90,7 @@ class Task extends Model
|
||||||
'schedule_id' => 'required|numeric|exists:schedules,id',
|
'schedule_id' => 'required|numeric|exists:schedules,id',
|
||||||
'sequence_id' => 'required|numeric|min:1',
|
'sequence_id' => 'required|numeric|min:1',
|
||||||
'action' => 'required|string',
|
'action' => 'required|string',
|
||||||
'payload' => 'required|string',
|
'payload' => 'required_unless:action,backup|string',
|
||||||
'time_offset' => 'required|numeric|between:0,900',
|
'time_offset' => 'required|numeric|between:0,900',
|
||||||
'is_queued' => 'boolean',
|
'is_queued' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
|
@ -14,12 +14,26 @@ import Can from '@/components/elements/Can';
|
||||||
import useServer from '@/plugins/useServer';
|
import useServer from '@/plugins/useServer';
|
||||||
import useFlash from '@/plugins/useFlash';
|
import useFlash from '@/plugins/useFlash';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
|
import { faFileArchive } from '@fortawesome/free-solid-svg-icons/faFileArchive';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
schedule: Schedule;
|
schedule: Schedule;
|
||||||
task: Task;
|
task: Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getActionDetails = (action: string): [ string, any ] => {
|
||||||
|
switch (action) {
|
||||||
|
case 'command':
|
||||||
|
return ['Send Command', faCode];
|
||||||
|
case 'power':
|
||||||
|
return ['Send Power Action', faToggleOn];
|
||||||
|
case 'backup':
|
||||||
|
return ['Create Backup', faFileArchive];
|
||||||
|
default:
|
||||||
|
return ['Unknown Action', faCode];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default ({ schedule, task }: Props) => {
|
export default ({ schedule, task }: Props) => {
|
||||||
const { uuid } = useServer();
|
const { uuid } = useServer();
|
||||||
const { clearFlashes, addError } = useFlash();
|
const { clearFlashes, addError } = useFlash();
|
||||||
|
@ -43,6 +57,8 @@ export default ({ schedule, task }: Props) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [ title, icon ] = getActionDetails(task.action);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'flex items-center bg-neutral-700 border border-neutral-600 mb-2 px-6 py-4 rounded'}>
|
<div className={'flex items-center bg-neutral-700 border border-neutral-600 mb-2 px-6 py-4 rounded'}>
|
||||||
<SpinnerOverlay visible={isLoading} fixed={true} size={'large'}/>
|
<SpinnerOverlay visible={isLoading} fixed={true} size={'large'}/>
|
||||||
|
@ -56,14 +72,19 @@ export default ({ schedule, task }: Props) => {
|
||||||
onDismissed={() => setVisible(false)}
|
onDismissed={() => setVisible(false)}
|
||||||
onConfirmed={() => onConfirmDeletion()}
|
onConfirmed={() => onConfirmDeletion()}
|
||||||
/>
|
/>
|
||||||
<FontAwesomeIcon icon={task.action === 'command' ? faCode : faToggleOn} className={'text-lg text-white'}/>
|
<FontAwesomeIcon icon={icon} className={'text-lg text-white'}/>
|
||||||
<div className={'flex-1'}>
|
<div className={'flex-1'}>
|
||||||
<p className={'ml-6 text-neutral-300 mb-2 uppercase text-xs'}>
|
<p className={'ml-6 text-neutral-300 uppercase text-xs'}>
|
||||||
{task.action === 'command' ? 'Send command' : 'Send power action'}
|
{title}
|
||||||
</p>
|
</p>
|
||||||
<code className={'ml-6 font-mono bg-neutral-800 rounded py-1 px-2 text-sm'}>
|
{task.payload &&
|
||||||
{task.payload}
|
<div className={'ml-6 mt-2'}>
|
||||||
</code>
|
{task.action === 'backup' && <p className={'text-xs uppercase text-neutral-400 mb-1'}>Ignoring files & folders:</p>}
|
||||||
|
<div className={'font-mono bg-neutral-800 rounded py-1 px-2 text-sm w-auto whitespace-pre inline-block'}>
|
||||||
|
{task.payload}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
{task.sequenceId > 1 &&
|
{task.sequenceId > 1 &&
|
||||||
<div className={'mr-6'}>
|
<div className={'mr-6'}>
|
||||||
|
|
|
@ -71,7 +71,10 @@ const TaskDetailsForm = ({ isEditingTask }: { isEditingTask: boolean }) => {
|
||||||
:
|
:
|
||||||
<div>
|
<div>
|
||||||
<label className={'input-dark-label'}>Ignored Files</label>
|
<label className={'input-dark-label'}>Ignored Files</label>
|
||||||
<FormikFieldWrapper name={'payload'}>
|
<FormikFieldWrapper
|
||||||
|
name={'payload'}
|
||||||
|
description={'Optional. Include the files and folders to be excluded in this backup. By default, the contents of your .pteroignore file will be used.'}
|
||||||
|
>
|
||||||
<FormikField as={'textarea'} name={'payload'} className={'input-dark h-32'}/>
|
<FormikField as={'textarea'} name={'payload'} className={'input-dark h-32'}/>
|
||||||
</FormikFieldWrapper>
|
</FormikFieldWrapper>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue