1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 05:45:22 +02:00

feat(edge/jobs): migrate item view to react [EE-2220] (#11887)
Some checks failed
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
ci / build_images (map[arch:arm platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:s390x platform:linux version:]) (push) Has been cancelled
/ triage (push) Has been cancelled
Lint / Run linters (push) Has been cancelled
Test / test-client (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:linux]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
Test / test-server (map[arch:arm64 platform:linux]) (push) Has been cancelled
ci / build_manifests (push) Has been cancelled

This commit is contained in:
Chaim Lev-Ari 2024-06-06 21:07:39 +03:00 committed by GitHub
parent 62c2bf86aa
commit eb6d251a73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 778 additions and 886 deletions

View file

@ -2,7 +2,8 @@ import { useFormikContext } from 'formik';
import { SwitchField } from '@@/form-components/SwitchField';
import { FormValues } from './types';
import { FormValues } from '../../CreateView/types';
import { RecurringFieldset, defaultCronExpression } from './RecurringFieldset';
import { ScheduledDateFieldset } from './ScheduledDateFieldset';

View file

@ -1,14 +1,33 @@
import { useFormikContext } from 'formik';
import { Calendar, Edit } from 'lucide-react';
import { FormSection } from '@@/form-components/FormSection';
import { BoxSelector } from '@@/BoxSelector';
import { BoxSelector, BoxSelectorOption } from '@@/BoxSelector';
import { cronMethodOptions } from '../../CreateView/cron-method-options';
import { FormValues } from '../../CreateView/types';
import { FormValues } from './types';
import { AdvancedCronFieldset } from './AdvancedCronFieldset';
import { BasicCronFieldset } from './BasicCronFieldset';
export const cronMethodOptions: ReadonlyArray<BoxSelectorOption<string>> = [
{
id: 'config_basic',
value: 'basic',
icon: Calendar,
iconType: 'badge',
label: 'Basic configuration',
description: 'Select date from calendar',
},
{
id: 'config_advanced',
value: 'advanced',
icon: Edit,
iconType: 'badge',
label: 'Advanced configuration',
description: 'Write your own cron rule',
},
] as const;
export function JobConfigurationFieldset() {
const { values, setFieldValue } = useFormikContext<FormValues>();

View file

@ -0,0 +1,79 @@
import { addHours, getDate, getHours, getMinutes, getMonth } from 'date-fns';
import moment from 'moment';
import { defaultCronExpression, timeOptions } from './RecurringFieldset';
interface RecurringViewModel {
cronMethod: 'basic' | 'advanced';
cronExpression: string;
recurring: boolean;
recurringOption: (typeof timeOptions)[number]['value'];
dateTime: Date;
}
interface RecurringRequestModel {
recurring: boolean;
cronExpression: string;
}
export function toRecurringRequest(
values: RecurringViewModel
): RecurringRequestModel {
if (values.cronMethod !== 'basic') {
return {
recurring: true,
cronExpression: values.cronExpression,
};
}
if (values.recurring) {
return {
recurring: true,
cronExpression: values.recurringOption,
};
}
return {
recurring: false,
cronExpression: dateTimeToCron(values.dateTime),
};
function dateTimeToCron(date: Date) {
return [
getMinutes(date),
getHours(date),
getDate(date),
getMonth(date) + 1,
'*',
].join(' ');
}
}
export function toRecurringViewModel(
{ cronExpression, recurring }: RecurringRequestModel = {
cronExpression: defaultCronExpression,
recurring: true,
}
): RecurringViewModel {
const defaultTime = addHours(new Date(), 1);
const scheduled = timeOptions.find((v) => v.value === cronExpression);
return {
recurring,
cronExpression,
recurringOption: scheduled?.value || defaultCronExpression,
cronMethod: recurring && !scheduled ? 'advanced' : 'basic',
dateTime: cronExpression
? cronToDateTime(cronExpression, defaultTime)
: defaultTime,
};
}
function cronToDateTime(cron: string, defaultTime: Date): Date {
const strings = cron.split(' ');
if (strings.length > 4) {
return moment(cron, 'm H D M').toDate();
}
return defaultTime;
}

View file

@ -1,20 +0,0 @@
import { EdgeGroup } from '@/react/edge/edge-groups/types';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { timeOptions } from './RecurringFieldset';
export interface FormValues {
name: string;
recurring: boolean;
edgeGroupIds: Array<EdgeGroup['Id']>;
environmentIds: Array<EnvironmentId>;
method: 'editor' | 'upload';
fileContent: string;
file: File | undefined;
cronMethod: 'basic' | 'advanced';
dateTime: Date; // basic !recurring
recurringOption: (typeof timeOptions)[number]['value']; // basic recurring
cronExpression: string; // advanced
}

View file

@ -1,72 +0,0 @@
import {
SchemaOf,
array,
boolean,
date,
mixed,
number,
object,
string,
} from 'yup';
import { useMemo } from 'react';
import { file } from '@@/form-components/yup-file-validation';
import { EdgeJob } from '../../types';
import { FormValues } from './types';
import { useNameValidation } from './NameField';
import { cronValidation } from './AdvancedCronFieldset';
import { timeOptions } from './RecurringFieldset';
export function useValidation({
id,
}: { id?: EdgeJob['Id'] } = {}): SchemaOf<FormValues> {
const nameValidation = useNameValidation(id);
return useMemo(
() =>
object({
name: nameValidation,
recurring: boolean().default(false),
cronExpression: string().default('').when('cronMethod', {
is: 'advanced',
then: cronValidation().required(),
}),
edgeGroupIds: array(number().required()),
environmentIds: array(number().required()),
method: mixed<'editor' | 'upload'>()
.oneOf(['editor', 'upload'])
.default('editor'),
file: file().when('method', {
is: 'upload',
then: object().required('This field is required.'),
}),
fileContent: string()
.default('')
.when('method', {
is: 'editor',
then: (schema) => schema.required('This field is required.'),
}),
cronMethod: mixed<'basic' | 'advanced'>()
.oneOf(['basic', 'advanced'])
.default('basic'),
dateTime: date()
.default(new Date())
.when(['recurring', 'cronMethod'], {
is: (recurring: boolean, cronMethod: 'basic' | 'advanced') =>
!recurring && cronMethod === 'basic',
then: (schema) => schema.required('This field is required.'),
}),
recurringOption: mixed()
.oneOf(timeOptions.map((o) => o.value))
.when(['recurring', 'cronMethod'], {
is: (recurring: boolean, cronMethod: 'basic' | 'advanced') =>
recurring && cronMethod === 'basic',
then: (schema) => schema.required('This field is required.'),
}),
}),
[nameValidation]
);
}