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:
parent
75f40fe485
commit
1e4c4e2616
54 changed files with 254 additions and 187 deletions
|
@ -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',
|
||||
]);
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue