Update schedules API
This commit is contained in:
parent
bfd92c314d
commit
feffdacf57
21 changed files with 172 additions and 167 deletions
|
@ -115,3 +115,35 @@ interface Subuser extends Model {
|
|||
|
||||
can (permission: SubuserPermission): boolean;
|
||||
}
|
||||
|
||||
interface Schedule extends Model {
|
||||
id: number;
|
||||
name: string;
|
||||
cron: {
|
||||
dayOfWeek: string;
|
||||
month: string;
|
||||
dayOfMonth: string;
|
||||
hour: string;
|
||||
minute: string;
|
||||
};
|
||||
isActive: boolean;
|
||||
isProcessing: boolean;
|
||||
onlyWhenOnline: boolean;
|
||||
lastRunAt: Date | null;
|
||||
nextRunAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
tasks: Task[];
|
||||
}
|
||||
|
||||
interface Task extends Model {
|
||||
id: number;
|
||||
sequenceId: number;
|
||||
action: string;
|
||||
payload: string;
|
||||
timeOffset: number;
|
||||
isQueued: boolean;
|
||||
continueOnFailure: boolean;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
|
|
@ -109,4 +109,41 @@ export default class Transformers {
|
|||
can: permission => (attributes.permissions || []).indexOf(permission) >= 0,
|
||||
};
|
||||
}
|
||||
|
||||
static toServerTask ({ attributes }: FractalResponseData): Models.Task {
|
||||
return {
|
||||
id: attributes.id,
|
||||
sequenceId: attributes.sequence_id,
|
||||
action: attributes.action,
|
||||
payload: attributes.payload,
|
||||
timeOffset: attributes.time_offset,
|
||||
isQueued: attributes.is_queued,
|
||||
continueOnFailure: attributes.continue_on_failure,
|
||||
createdAt: new Date(attributes.created_at),
|
||||
updatedAt: new Date(attributes.updated_at),
|
||||
};
|
||||
}
|
||||
|
||||
static toServerSchedule ({ attributes }: FractalResponseData): Models.Schedule {
|
||||
return {
|
||||
id: attributes.id,
|
||||
name: attributes.name,
|
||||
cron: {
|
||||
dayOfWeek: attributes.cron.day_of_week,
|
||||
month: attributes.cron.month,
|
||||
dayOfMonth: attributes.cron.day_of_month,
|
||||
hour: attributes.cron.hour,
|
||||
minute: attributes.cron.minute,
|
||||
},
|
||||
isActive: attributes.is_active,
|
||||
isProcessing: attributes.is_processing,
|
||||
onlyWhenOnline: attributes.only_when_online,
|
||||
lastRunAt: attributes.last_run_at ? new Date(attributes.last_run_at) : null,
|
||||
nextRunAt: attributes.next_run_at ? new Date(attributes.next_run_at) : null,
|
||||
createdAt: new Date(attributes.created_at),
|
||||
updatedAt: new Date(attributes.updated_at),
|
||||
// @ts-expect-error
|
||||
tasks: (attributes.relationships?.tasks?.data || []).map((row: any) => this.toServerTask(row.attributes)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
88
resources/scripts/api/server/schedules.ts
Normal file
88
resources/scripts/api/server/schedules.ts
Normal file
|
@ -0,0 +1,88 @@
|
|||
import http from '@/api/http';
|
||||
import { Schedule, Task, Transformers } from '@definitions/user';
|
||||
|
||||
type CreateScheduleData = Pick<Schedule, 'cron' | 'name' | 'onlyWhenOnline' | 'isActive'> & { id?: number }
|
||||
|
||||
interface CreateTaskData {
|
||||
action: string;
|
||||
payload: string;
|
||||
timeOffset: string | number;
|
||||
continueOnFailure: boolean;
|
||||
}
|
||||
|
||||
const createOrUpdateSchedule = async (uuid: string, schedule: CreateScheduleData): Promise<Schedule> => {
|
||||
const { data } = await http.post(`/api/client/servers/${uuid}/schedules${schedule.id ? `/${schedule.id}` : ''}`, {
|
||||
is_active: schedule.isActive,
|
||||
only_when_online: schedule.onlyWhenOnline,
|
||||
name: schedule.name,
|
||||
minute: schedule.cron.minute,
|
||||
hour: schedule.cron.hour,
|
||||
day_of_month: schedule.cron.dayOfMonth,
|
||||
month: schedule.cron.month,
|
||||
day_of_week: schedule.cron.dayOfWeek,
|
||||
});
|
||||
|
||||
return Transformers.toServerSchedule(data);
|
||||
};
|
||||
|
||||
const createOrUpdateScheduleTask = async (uuid: string, schedule: number, task: number | undefined, data: CreateTaskData): Promise<Task> => {
|
||||
const { data: response } = await http.post(`/api/client/servers/${uuid}/schedules/${schedule}/tasks${task ? `/${task}` : ''}`, {
|
||||
action: data.action,
|
||||
payload: data.payload,
|
||||
continue_on_failure: data.continueOnFailure,
|
||||
time_offset: data.timeOffset,
|
||||
});
|
||||
|
||||
return Transformers.toServerTask(response);
|
||||
};
|
||||
|
||||
const deleteSchedule = (uuid: string, schedule: number): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.delete(`/api/client/servers/${uuid}/schedules/${schedule}`)
|
||||
.then(() => resolve())
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
const deleteScheduleTask = (uuid: string, scheduleId: number, taskId: number): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.delete(`/api/client/servers/${uuid}/schedules/${scheduleId}/tasks/${taskId}`)
|
||||
.then(() => resolve())
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
const getServerSchedule = (uuid: string, schedule: number): Promise<Schedule> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.get(`/api/client/servers/${uuid}/schedules/${schedule}`, {
|
||||
params: {
|
||||
include: [ 'tasks' ],
|
||||
},
|
||||
})
|
||||
.then(({ data }) => resolve(Transformers.toServerSchedule(data)))
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
const getServerSchedules = async (uuid: string): Promise<Schedule[]> => {
|
||||
const { data } = await http.get(`/api/client/servers/${uuid}/schedules`, {
|
||||
params: {
|
||||
include: [ 'tasks' ],
|
||||
},
|
||||
});
|
||||
|
||||
return (data.data || []).map(Transformers.toServerSchedule);
|
||||
};
|
||||
|
||||
const triggerScheduleExecution = async (server: string, schedule: number): Promise<void> =>
|
||||
await http.post(`/api/client/servers/${server}/schedules/${schedule}/execute`);
|
||||
|
||||
export {
|
||||
deleteSchedule,
|
||||
deleteScheduleTask,
|
||||
createOrUpdateSchedule,
|
||||
createOrUpdateScheduleTask,
|
||||
getServerSchedule,
|
||||
getServerSchedules,
|
||||
triggerScheduleExecution,
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
import { rawDataToServerSchedule, Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import http from '@/api/http';
|
||||
|
||||
type Data = Pick<Schedule, 'cron' | 'name' | 'onlyWhenOnline' | 'isActive'> & { id?: number }
|
||||
|
||||
export default async (uuid: string, schedule: Data): Promise<Schedule> => {
|
||||
const { data } = await http.post(`/api/client/servers/${uuid}/schedules${schedule.id ? `/${schedule.id}` : ''}`, {
|
||||
is_active: schedule.isActive,
|
||||
only_when_online: schedule.onlyWhenOnline,
|
||||
name: schedule.name,
|
||||
minute: schedule.cron.minute,
|
||||
hour: schedule.cron.hour,
|
||||
day_of_month: schedule.cron.dayOfMonth,
|
||||
month: schedule.cron.month,
|
||||
day_of_week: schedule.cron.dayOfWeek,
|
||||
});
|
||||
|
||||
return rawDataToServerSchedule(data.attributes);
|
||||
};
|
|
@ -1,20 +0,0 @@
|
|||
import { rawDataToServerTask, Task } from '@/api/server/schedules/getServerSchedules';
|
||||
import http from '@/api/http';
|
||||
|
||||
interface Data {
|
||||
action: string;
|
||||
payload: string;
|
||||
timeOffset: string | number;
|
||||
continueOnFailure: boolean;
|
||||
}
|
||||
|
||||
export default async (uuid: string, schedule: number, task: number | undefined, data: Data): Promise<Task> => {
|
||||
const { data: response } = await http.post(`/api/client/servers/${uuid}/schedules/${schedule}/tasks${task ? `/${task}` : ''}`, {
|
||||
action: data.action,
|
||||
payload: data.payload,
|
||||
continue_on_failure: data.continueOnFailure,
|
||||
time_offset: data.timeOffset,
|
||||
});
|
||||
|
||||
return rawDataToServerTask(response.attributes);
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
import http from '@/api/http';
|
||||
|
||||
export default (uuid: string, schedule: number): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.delete(`/api/client/servers/${uuid}/schedules/${schedule}`)
|
||||
.then(() => resolve())
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
import http from '@/api/http';
|
||||
|
||||
export default (uuid: string, scheduleId: number, taskId: number): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.delete(`/api/client/servers/${uuid}/schedules/${scheduleId}/tasks/${taskId}`)
|
||||
.then(() => resolve())
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
import http from '@/api/http';
|
||||
import { rawDataToServerSchedule, Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
|
||||
export default (uuid: string, schedule: number): Promise<Schedule> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.get(`/api/client/servers/${uuid}/schedules/${schedule}`, {
|
||||
params: {
|
||||
include: [ 'tasks' ],
|
||||
},
|
||||
})
|
||||
.then(({ data }) => resolve(rawDataToServerSchedule(data.attributes)))
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
|
@ -1,77 +0,0 @@
|
|||
import http from '@/api/http';
|
||||
|
||||
export interface Schedule {
|
||||
id: number;
|
||||
name: string;
|
||||
cron: {
|
||||
dayOfWeek: string;
|
||||
month: string;
|
||||
dayOfMonth: string;
|
||||
hour: string;
|
||||
minute: string;
|
||||
};
|
||||
isActive: boolean;
|
||||
isProcessing: boolean;
|
||||
onlyWhenOnline: boolean;
|
||||
lastRunAt: Date | null;
|
||||
nextRunAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
|
||||
tasks: Task[];
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id: number;
|
||||
sequenceId: number;
|
||||
action: string;
|
||||
payload: string;
|
||||
timeOffset: number;
|
||||
isQueued: boolean;
|
||||
continueOnFailure: boolean;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export const rawDataToServerTask = (data: any): Task => ({
|
||||
id: data.id,
|
||||
sequenceId: data.sequence_id,
|
||||
action: data.action,
|
||||
payload: data.payload,
|
||||
timeOffset: data.time_offset,
|
||||
isQueued: data.is_queued,
|
||||
continueOnFailure: data.continue_on_failure,
|
||||
createdAt: new Date(data.created_at),
|
||||
updatedAt: new Date(data.updated_at),
|
||||
});
|
||||
|
||||
export const rawDataToServerSchedule = (data: any): Schedule => ({
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
cron: {
|
||||
dayOfWeek: data.cron.day_of_week,
|
||||
month: data.cron.month,
|
||||
dayOfMonth: data.cron.day_of_month,
|
||||
hour: data.cron.hour,
|
||||
minute: data.cron.minute,
|
||||
},
|
||||
isActive: data.is_active,
|
||||
isProcessing: data.is_processing,
|
||||
onlyWhenOnline: data.only_when_online,
|
||||
lastRunAt: data.last_run_at ? new Date(data.last_run_at) : null,
|
||||
nextRunAt: data.next_run_at ? new Date(data.next_run_at) : null,
|
||||
createdAt: new Date(data.created_at),
|
||||
updatedAt: new Date(data.updated_at),
|
||||
|
||||
tasks: (data.relationships?.tasks?.data || []).map((row: any) => rawDataToServerTask(row.attributes)),
|
||||
});
|
||||
|
||||
export default async (uuid: string): Promise<Schedule[]> => {
|
||||
const { data } = await http.get(`/api/client/servers/${uuid}/schedules`, {
|
||||
params: {
|
||||
include: [ 'tasks' ],
|
||||
},
|
||||
});
|
||||
|
||||
return (data.data || []).map((row: any) => rawDataToServerSchedule(row.attributes));
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
import http from '@/api/http';
|
||||
|
||||
export default async (server: string, schedule: number): Promise<void> =>
|
||||
await http.post(`/api/client/servers/${server}/schedules/${schedule}/execute`);
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState } from 'react';
|
||||
import deleteSchedule from '@/api/server/schedules/deleteSchedule';
|
||||
import { deleteSchedule } from '@/api/server/schedules';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import { Actions, useStoreActions } from 'easy-peasy';
|
||||
import { ApplicationStore } from '@/state';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useContext, useEffect } from 'react';
|
||||
import { Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule } from '@definitions/user';
|
||||
import Field from '@/components/elements/Field';
|
||||
import { Form, Formik, FormikHelpers } from 'formik';
|
||||
import FormikSwitch from '@/components/elements/FormikSwitch';
|
||||
import createOrUpdateSchedule from '@/api/server/schedules/createOrUpdateSchedule';
|
||||
import { createOrUpdateSchedule } from '@/api/server/schedules';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule } from '@definitions/user';
|
||||
import TaskDetailsModal from '@/components/server/schedules/TaskDetailsModal';
|
||||
import Button from '@/components/elements/Button';
|
||||
import tw from 'twin.macro';
|
||||
|
|
|
@ -2,10 +2,10 @@ import React, { useCallback, useState } from 'react';
|
|||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||
import tw from 'twin.macro';
|
||||
import Button from '@/components/elements/Button';
|
||||
import triggerScheduleExecution from '@/api/server/schedules/triggerScheduleExecution';
|
||||
import { triggerScheduleExecution } from '@/api/server/schedules';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import useFlash from '@/plugins/useFlash';
|
||||
import { Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule } from '@definitions/user';
|
||||
|
||||
const RunScheduleButton = ({ schedule }: { schedule: Schedule }) => {
|
||||
const [ loading, setLoading ] = useState(false);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import getServerSchedules from '@/api/server/schedules/getServerSchedules';
|
||||
import { getServerSchedules } from '@/api/server/schedules';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import Spinner from '@/components/elements/Spinner';
|
||||
import { useHistory, useRouteMatch } from 'react-router-dom';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import tw from 'twin.macro';
|
||||
import { Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule } from '@definitions/user';
|
||||
|
||||
interface Props {
|
||||
cron: Schedule['cron'];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import getServerSchedule from '@/api/server/schedules/getServerSchedule';
|
||||
import { getServerSchedule } from '@/api/server/schedules';
|
||||
import Spinner from '@/components/elements/Spinner';
|
||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
import EditScheduleModal from '@/components/server/schedules/EditScheduleModal';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule } from '@definitions/user';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faCalendarAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { format } from 'date-fns';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Schedule, Task } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule, Task } from '@definitions/user';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import {
|
||||
faArrowCircleDown,
|
||||
|
@ -10,7 +10,7 @@ import {
|
|||
faToggleOn,
|
||||
faTrashAlt,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import deleteScheduleTask from '@/api/server/schedules/deleteScheduleTask';
|
||||
import { deleteScheduleTask } from '@/api/server/schedules';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||
import TaskDetailsModal from '@/components/server/schedules/TaskDetailsModal';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useContext, useEffect } from 'react';
|
||||
import { Schedule, Task } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule, Task } from '@definitions/user';
|
||||
import { Field as FormikField, Form, Formik, FormikHelpers, useField } from 'formik';
|
||||
import { ServerContext } from '@/state/server';
|
||||
import createOrUpdateScheduleTask from '@/api/server/schedules/createOrUpdateScheduleTask';
|
||||
import { createOrUpdateScheduleTask } from '@/api/server/schedules';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import Field from '@/components/elements/Field';
|
||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { action, Action } from 'easy-peasy';
|
||||
import { Schedule } from '@/api/server/schedules/getServerSchedules';
|
||||
import { Schedule } from '@definitions/user';
|
||||
|
||||
export interface ServerScheduleStore {
|
||||
data: Schedule[];
|
||||
|
|
Loading…
Reference in a new issue