1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

refactor(edge): move edge codebase to react (#7781)

This commit is contained in:
Chaim Lev-Ari 2022-11-21 09:51:55 +02:00 committed by GitHub
parent 75f40fe485
commit 1e4c4e2616
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 254 additions and 187 deletions

View file

@ -1,163 +0,0 @@
import { number, object, SchemaOf } from 'yup';
import { r2a } from '@/react-tools/react2angular';
import { FormControl } from '@@/form-components/FormControl';
import { Select } from '@@/form-components/Input';
import { Options, useIntervalOptions } from './useIntervalOptions';
export const EDGE_ASYNC_INTERVAL_USE_DEFAULT = -1;
export interface EdgeAsyncIntervalsValues {
PingInterval: number;
SnapshotInterval: number;
CommandInterval: number;
}
export const options: Options = [
{ label: 'Use default interval', value: -1, isDefault: true },
{
value: 0,
label: 'disabled',
},
{
value: 60,
label: '1 minute',
},
{
value: 60 * 60,
label: '1 hour',
},
{
value: 24 * 60 * 60,
label: '1 day',
},
{
value: 7 * 24 * 60 * 60,
label: '1 week',
},
];
const defaultFieldSettings = {
ping: {
label: 'Ping interval',
tooltip:
'Interval used by this Edge agent to check in with the Portainer instance',
},
snapshot: {
label: 'Snapshot interval',
tooltip: 'Interval used by this Edge agent to snapshot the agent state',
},
command: {
label: 'Command interval',
tooltip:
'Interval used by this Edge agent to fetch commands from the Portainer instance',
},
};
interface Props {
values: EdgeAsyncIntervalsValues;
isDefaultHidden?: boolean;
readonly?: boolean;
fieldSettings?: typeof defaultFieldSettings;
onChange(value: EdgeAsyncIntervalsValues): void;
}
export function EdgeAsyncIntervalsForm({
onChange,
values,
isDefaultHidden = false,
readonly = false,
fieldSettings = defaultFieldSettings,
}: Props) {
const pingIntervalOptions = useIntervalOptions(
'Edge.PingInterval',
options,
isDefaultHidden
);
const snapshotIntervalOptions = useIntervalOptions(
'Edge.SnapshotInterval',
options,
isDefaultHidden
);
const commandIntervalOptions = useIntervalOptions(
'Edge.CommandInterval',
options,
isDefaultHidden
);
return (
<>
<FormControl
inputId="edge_checkin_ping"
label={fieldSettings.ping.label}
tooltip={fieldSettings.ping.tooltip}
>
<Select
value={values.PingInterval}
name="PingInterval"
onChange={handleChange}
options={pingIntervalOptions}
disabled={readonly}
/>
</FormControl>
<FormControl
inputId="edge_checkin_snapshot"
label={fieldSettings.snapshot.label}
tooltip={fieldSettings.snapshot.tooltip}
>
<Select
value={values.SnapshotInterval}
name="SnapshotInterval"
onChange={handleChange}
options={snapshotIntervalOptions}
disabled={readonly}
/>
</FormControl>
<FormControl
inputId="edge_checkin_command"
label={fieldSettings.command.label}
tooltip={fieldSettings.command.tooltip}
>
<Select
value={values.CommandInterval}
name="CommandInterval"
onChange={handleChange}
options={commandIntervalOptions}
disabled={readonly}
/>
</FormControl>
</>
);
function handleChange(e: React.ChangeEvent<HTMLSelectElement>) {
onChange({ ...values, [e.target.name]: parseInt(e.target.value, 10) });
}
}
const intervals = options.map((option) => option.value);
export function edgeAsyncIntervalsValidation(): SchemaOf<EdgeAsyncIntervalsValues> {
return object({
PingInterval: number().required('This field is required.').oneOf(intervals),
SnapshotInterval: number()
.required('This field is required.')
.oneOf(intervals),
CommandInterval: number()
.required('This field is required.')
.oneOf(intervals),
});
}
export const EdgeAsyncIntervalsFormAngular = r2a(EdgeAsyncIntervalsForm, [
'values',
'onChange',
'isDefaultHidden',
'readonly',
'fieldSettings',
]);

View file

@ -1,114 +0,0 @@
import { useEffect, useState } from 'react';
import { r2a } from '@/react-tools/react2angular';
import { useSettings } from '@/react/portainer/settings/queries';
import { withReactQuery } from '@/react-tools/withReactQuery';
import { FormControl, Size } from '@@/form-components/FormControl';
import { Select } from '@@/form-components/Input';
interface Props {
value: number;
onChange(value: number): void;
isDefaultHidden?: boolean;
label?: string;
tooltip?: string;
readonly?: boolean;
size?: Size;
}
export const checkinIntervalOptions = [
{ label: 'Use default interval', value: 0 },
{
label: '5 seconds',
value: 5,
},
{
label: '10 seconds',
value: 10,
},
{
label: '30 seconds',
value: 30,
},
{ label: '5 minutes', value: 300 },
{ label: '1 hour', value: 3600 },
{ label: '1 day', value: 86400 },
];
export function EdgeCheckinIntervalField({
value,
readonly,
onChange,
isDefaultHidden = false,
label = 'Poll frequency',
tooltip = 'Interval used by this Edge agent to check in with the Portainer instance. Affects Edge environment management and Edge compute features.',
size = 'small',
}: Props) {
const options = useOptions(isDefaultHidden);
return (
<FormControl
inputId="edge_checkin"
label={label}
tooltip={tooltip}
size={size}
>
<Select
value={value}
onChange={(e) => {
onChange(parseInt(e.currentTarget.value, 10));
}}
options={options}
disabled={readonly}
/>
</FormControl>
);
}
export const EdgeCheckinIntervalFieldAngular = r2a(
withReactQuery(EdgeCheckinIntervalField),
[
'value',
'onChange',
'isDefaultHidden',
'tooltip',
'label',
'readonly',
'size',
]
);
function useOptions(isDefaultHidden: boolean) {
const [options, setOptions] = useState(checkinIntervalOptions);
const settingsQuery = useSettings(
(settings) => settings.EdgeAgentCheckinInterval
);
useEffect(() => {
if (isDefaultHidden) {
setOptions(checkinIntervalOptions.filter((option) => option.value !== 0));
}
if (!isDefaultHidden && typeof settingsQuery.data !== 'undefined') {
setOptions((options) => {
let label = `${settingsQuery.data} seconds`;
const option = options.find((o) => o.value === settingsQuery.data);
if (option) {
label = option.label;
}
return [
{
value: 0,
label: `Use default interval (${label})`,
},
...options.slice(1),
];
});
}
}, [settingsQuery.data, setOptions, isDefaultHidden]);
return options;
}

View file

@ -1,19 +0,0 @@
import angular from 'angular';
import { r2a } from '@/react-tools/react2angular';
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
import { withReactQuery } from '@/react-tools/withReactQuery';
import { EdgeCheckinIntervalFieldAngular } from './EdgeCheckInIntervalField';
export const componentsModule = angular
.module('app.edge.components', [])
.component(
'edgeScriptForm',
r2a(withReactQuery(EdgeScriptForm), [
'edgeInfo',
'commands',
'isNomadTokenVisible',
])
)
.component('edgeCheckinIntervalField', EdgeCheckinIntervalFieldAngular).name;

View file

@ -1,67 +0,0 @@
import _ from 'lodash';
import { useState, useEffect } from 'react';
import { useSettings } from '@/react/portainer/settings/queries';
type Option = {
label: string;
value: number;
};
type DefaultOption = Option & { isDefault: true };
export type Options = [DefaultOption, ...Option[]];
export function useIntervalOptions(
fieldName:
| 'Edge.PingInterval'
| 'Edge.SnapshotInterval'
| 'Edge.CommandInterval'
| 'EdgeAgentCheckinInterval',
initialOptions: Options,
isDefaultHidden: boolean
) {
const [{ value: defaultValue }] = initialOptions;
const [options, setOptions] = useState<Option[]>(initialOptions);
const settingsQuery = useSettings(
(settings) => _.get(settings, fieldName, 0) as number,
!isDefaultHidden
);
useEffect(() => {
if (isDefaultHidden) {
setOptions(initialOptions.slice(1));
}
if (
!isDefaultHidden &&
typeof settingsQuery.data !== 'undefined' &&
settingsQuery.data !== defaultValue
) {
setOptions((options) => {
let label = `${settingsQuery.data} seconds`;
const option = options.find((o) => o.value === settingsQuery.data);
if (option) {
label = option.label;
}
return [
{
value: defaultValue,
label: `Use default interval (${label})`,
},
...options.slice(1),
];
});
}
}, [
settingsQuery.data,
setOptions,
isDefaultHidden,
initialOptions,
defaultValue,
]);
return options;
}