forked from pterodactyl/panel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScheduleTaskRow.tsx
More file actions
123 lines (117 loc) · 5.26 KB
/
ScheduleTaskRow.tsx
File metadata and controls
123 lines (117 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import React, { useState } from 'react';
import { Schedule, Task } from '@/api/server/schedules/getServerSchedules';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faClock, faCode, faFileArchive, faPencilAlt, faToggleOn, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import deleteScheduleTask from '@/api/server/schedules/deleteScheduleTask';
import { httpErrorToHuman } from '@/api/http';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import TaskDetailsModal from '@/components/server/schedules/TaskDetailsModal';
import Can from '@/components/elements/Can';
import useFlash from '@/plugins/useFlash';
import { ServerContext } from '@/state/server';
import tw from 'twin.macro';
import ConfirmationModal from '@/components/elements/ConfirmationModal';
import Icon from '@/components/elements/Icon';
interface Props {
schedule: Schedule;
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) => {
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const { clearFlashes, addError } = useFlash();
const [ visible, setVisible ] = useState(false);
const [ isLoading, setIsLoading ] = useState(false);
const [ isEditing, setIsEditing ] = useState(false);
const appendSchedule = ServerContext.useStoreActions(actions => actions.schedules.appendSchedule);
const onConfirmDeletion = () => {
setIsLoading(true);
clearFlashes('schedules');
deleteScheduleTask(uuid, schedule.id, task.id)
.then(() => appendSchedule({
...schedule,
tasks: schedule.tasks.filter(t => t.id !== task.id),
}))
.catch(error => {
console.error(error);
setIsLoading(false);
addError({ message: httpErrorToHuman(error), key: 'schedules' });
});
};
const [ title, icon ] = getActionDetails(task.action);
return (
<div css={tw`sm:flex items-center p-3 sm:p-6 border-b border-neutral-800`}>
<SpinnerOverlay visible={isLoading} fixed size={'large'}/>
{isEditing && <TaskDetailsModal
schedule={schedule}
task={task}
onDismissed={() => setIsEditing(false)}
/>}
<ConfirmationModal
title={'Confirm task deletion'}
buttonText={'Delete Task'}
onConfirmed={onConfirmDeletion}
visible={visible}
onModalDismissed={() => setVisible(false)}
>
Are you sure you want to delete this task? This action cannot be undone.
</ConfirmationModal>
<FontAwesomeIcon icon={icon} css={tw`text-lg text-white hidden md:block`}/>
<div css={tw`flex-none sm:flex-1 w-full sm:w-auto overflow-x-auto`}>
<p css={tw`md:ml-6 text-neutral-200 uppercase text-sm`}>
{title}
</p>
{task.payload &&
<div css={tw`md:ml-6 mt-2`}>
{task.action === 'backup' &&
<p css={tw`text-xs uppercase text-neutral-400 mb-1`}>Ignoring files & folders:</p>}
<div css={tw`font-mono bg-neutral-800 rounded py-1 px-2 text-sm w-auto inline-block whitespace-pre-wrap break-all`}>
{task.payload}
</div>
</div>
}
</div>
<div css={tw`mt-3 sm:mt-0 flex items-center w-full sm:w-auto`}>
{task.sequenceId > 1 && task.timeOffset > 0 &&
<div css={tw`mr-6`}>
<div css={tw`flex items-center px-2 py-1 bg-neutral-500 text-sm rounded-full`}>
<Icon icon={faClock} css={tw`w-3 h-3 mr-2`}/>
{task.timeOffset}s later
</div>
</div>
}
<Can action={'schedule.update'}>
<button
type={'button'}
aria-label={'Edit scheduled task'}
css={tw`block text-sm p-2 text-neutral-500 hover:text-neutral-100 transition-colors duration-150 mr-4 ml-auto sm:ml-0`}
onClick={() => setIsEditing(true)}
>
<FontAwesomeIcon icon={faPencilAlt}/>
</button>
</Can>
<Can action={'schedule.update'}>
<button
type={'button'}
aria-label={'Delete scheduled task'}
css={tw`block text-sm p-2 text-neutral-500 hover:text-red-600 transition-colors duration-150`}
onClick={() => setVisible(true)}
>
<FontAwesomeIcon icon={faTrashAlt}/>
</button>
</Can>
</div>
</div>
);
};