refactor(app): move settings components to react [EE-3442] (#7625)
parent
5777c18297
commit
1e21961e6a
|
@ -1,6 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
const categories = [
|
||||
'docker',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { useSettings } from '@/portainer/settings/queries';
|
||||
import { useSettings } from '@/react/portainer/settings/queries';
|
||||
import { useGroups } from '@/portainer/environment-groups/queries';
|
||||
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
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,7 +1,7 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useSettings } from '@/portainer/settings/queries';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
import { useSettings } from '@/react/portainer/settings/queries';
|
||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
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;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { useStatus } from '@/portainer/services/api/status.service';
|
||||
import { useSettings } from '@/portainer/settings/queries';
|
||||
import { useSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
export function useAgentDetails() {
|
||||
const settingsQuery = useSettings((settings) => settings.AgentSecret);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useRouter } from '@uirouter/react';
|
||||
|
||||
import { usePublicSettings } from '../settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
export enum FeatureFlag {
|
||||
EdgeRemoteUpdate = 'edgeRemoteUpdate',
|
||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
|||
|
||||
import { isoDateFromTimestamp } from '@/portainer/filters/filters';
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as kcService from '@/kubernetes/services/kubeconfig.service';
|
|||
import * as notifications from '@/portainer/services/notifications';
|
||||
import { EnvironmentType } from '@/portainer/environments/types';
|
||||
import { usePaginationLimitState } from '@/portainer/hooks/usePaginationLimitState';
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
import {
|
||||
Query,
|
||||
useEnvironmentList,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import axios, { parseAxiosError } from 'Portainer/services/axios';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
import { FDOConfiguration, DeviceConfiguration, Profile } from './model';
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import axios, { parseAxiosError } from 'Portainer/services/axios';
|
||||
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
|
||||
import {
|
||||
|
|
|
@ -14,6 +14,9 @@ import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
|||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
||||
import { withI18nSuspense } from '@/react-tools/withI18nSuspense';
|
||||
import { SettingsFDO } from '@/react/portainer/settings/EdgeComputeView/SettingsFDO';
|
||||
import { SettingsOpenAMT } from '@/react/portainer/settings/EdgeComputeView/SettingsOpenAMT';
|
||||
import { InternalAuth } from '@/react/portainer/settings/AuthenticationView/InternalAuth';
|
||||
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
import { TagSelector } from '@@/TagSelector';
|
||||
|
@ -128,4 +131,13 @@ export const componentsModule = angular
|
|||
'onSubmit',
|
||||
'onError',
|
||||
])
|
||||
)
|
||||
.component(
|
||||
'settingsFdo',
|
||||
r2a(withUIRouter(withReactQuery(SettingsFDO)), ['onSubmit', 'settings'])
|
||||
)
|
||||
.component('settingsOpenAmt', r2a(SettingsOpenAMT, ['onSubmit', 'settings']))
|
||||
.component(
|
||||
'internalAuth',
|
||||
r2a(InternalAuth, ['onSaveSettings', 'isLoading', 'value', 'onChange'])
|
||||
).name;
|
||||
|
|
|
@ -5,6 +5,9 @@ import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
|||
import { r2a } from '@/react-tools/react2angular';
|
||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
||||
import { CreateAccessToken } from '@/react/portainer/account/CreateAccessTokenView';
|
||||
import { EdgeComputeSettingsView } from '@/react/portainer/settings/EdgeComputeView/EdgeComputeSettingsView';
|
||||
import { withI18nSuspense } from '@/react-tools/withI18nSuspense';
|
||||
|
||||
import { wizardModule } from './wizard';
|
||||
import { teamsModule } from './teams';
|
||||
|
@ -19,4 +22,18 @@ export const viewsModule = angular
|
|||
.component(
|
||||
'homeView',
|
||||
r2a(withUIRouter(withReactQuery(withCurrentUser(HomeView))), [])
|
||||
)
|
||||
.component(
|
||||
'createAccessToken',
|
||||
r2a(withI18nSuspense(withUIRouter(CreateAccessToken)), [
|
||||
'onSubmit',
|
||||
'onError',
|
||||
])
|
||||
)
|
||||
.component(
|
||||
'settingsEdgeCompute',
|
||||
r2a(withReactQuery(withCurrentUser(EdgeComputeSettingsView)), [
|
||||
'onSubmit',
|
||||
'settings',
|
||||
])
|
||||
).name;
|
||||
|
|
|
@ -2,10 +2,9 @@ import angular from 'angular';
|
|||
import ldapModule from './ldap';
|
||||
import { autoUserProvisionToggle } from './auto-user-provision-toggle';
|
||||
import { saveAuthSettingsButton } from './save-auth-settings-button';
|
||||
import { InternalAuthAngular } from './internal-auth';
|
||||
|
||||
export default angular
|
||||
.module('portainer.settings.authentication', [ldapModule])
|
||||
.component('internalAuth', InternalAuthAngular)
|
||||
|
||||
.component('saveAuthSettingsButton', saveAuthSettingsButton)
|
||||
.component('autoUserProvisionToggle', autoUserProvisionToggle).name;
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export { InternalAuthAngular, InternalAuth } from './InternalAuth';
|
|
@ -1,11 +0,0 @@
|
|||
import { react2angular } from '@/react-tools/react2angular';
|
||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
||||
|
||||
import { SettingsFDO } from './SettingsFDO';
|
||||
|
||||
const SettingsFDOAngular = react2angular(
|
||||
withUIRouter(withReactQuery(SettingsFDO)),
|
||||
['settings', 'onSubmit']
|
||||
);
|
||||
export { SettingsFDO, SettingsFDOAngular };
|
|
@ -1,9 +0,0 @@
|
|||
import { react2angular } from '@/react-tools/react2angular';
|
||||
|
||||
import { SettingsOpenAMT } from './SettingsOpenAMT';
|
||||
|
||||
const SettingsOpenAMTAngular = react2angular(SettingsOpenAMT, [
|
||||
'settings',
|
||||
'onSubmit',
|
||||
]);
|
||||
export { SettingsOpenAMT, SettingsOpenAMTAngular };
|
|
@ -3,12 +3,4 @@ import angular from 'angular';
|
|||
import authenticationModule from './authentication';
|
||||
import generalModule from './general';
|
||||
|
||||
import { SettingsFDOAngular } from './edge-compute/SettingsFDO';
|
||||
import { SettingsOpenAMTAngular } from './edge-compute/SettingsOpenAMT';
|
||||
import { EdgeComputeSettingsViewAngular } from './edge-compute/EdgeComputeSettingsView';
|
||||
|
||||
export default angular
|
||||
.module('portainer.settings', [authenticationModule, generalModule])
|
||||
.component('settingsEdgeCompute', EdgeComputeSettingsViewAngular)
|
||||
.component('settingsFdo', SettingsFDOAngular)
|
||||
.component('settingsOpenAmt', SettingsOpenAMTAngular).name;
|
||||
export default angular.module('portainer.settings', [authenticationModule, generalModule]).name;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
import { Icon } from '@@/Icon';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import { useInfo } from 'Docker/services/system.service';
|
||||
import { EnvironmentId } from 'Portainer/environments/types';
|
||||
|
||||
import { useInfo } from '@/docker/services/system.service';
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
import { ResourceControlViewModel } from '@/react/portainer/access-control/models/ResourceControlViewModel';
|
||||
|
||||
import { DockerContainer, ContainerStatus } from './types';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Fragment } from 'react';
|
||||
import DockerNetworkHelper from 'Docker/helpers/networkHelper';
|
||||
|
||||
import DockerNetworkHelper from '@/docker/helpers/networkHelper';
|
||||
import { Authorized } from '@/portainer/hooks/useUser';
|
||||
|
||||
import { Table, TableContainer, TableTitle } from '@@/datatables';
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { notifySuccess } from '@/portainer/services/notifications';
|
||||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
import { isLimitedToBE } from '@/portainer/feature-flags/feature-flags.service';
|
||||
import {
|
||||
usePublicSettings,
|
||||
useUpdateDefaultRegistrySettingsMutation,
|
||||
} from 'Portainer/settings/queries';
|
||||
import { notifySuccess } from 'Portainer/services/notifications';
|
||||
import { FeatureId } from 'Portainer/feature-flags/enums';
|
||||
|
||||
import { isLimitedToBE } from '@/portainer/feature-flags/feature-flags.service';
|
||||
} from '@/react/portainer/settings/queries';
|
||||
|
||||
import { Tooltip } from '@@/Tip/Tooltip';
|
||||
import { Button } from '@@/buttons';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import clsx from 'clsx';
|
||||
import { usePublicSettings } from 'Portainer/settings/queries';
|
||||
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
export function DefaultRegistryDomain() {
|
||||
const settingsQuery = usePublicSettings({
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { usePublicSettings } from 'Portainer/settings/queries';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
export function DefaultRegistryName() {
|
||||
const settingsQuery = usePublicSettings({
|
||||
select: (settings) => settings.DefaultRegistry?.Hide,
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { react2angular } from '@/react-tools/react2angular';
|
||||
import { confirmDestructive } from '@/portainer/services/modal.service/confirm';
|
||||
import { Settings } from '@/react/portainer/settings/types';
|
||||
|
||||
import { FormSectionTitle } from '@@/form-components/FormSectionTitle';
|
||||
|
||||
import { SaveAuthSettingsButton } from '../components/SaveAuthSettingsButton';
|
||||
import { Settings } from '../../types';
|
||||
|
||||
import { PasswordLengthSlider } from './components/PasswordLengthSlider/PasswordLengthSlider';
|
||||
import { PasswordLengthSlider } from './PasswordLengthSlider/PasswordLengthSlider';
|
||||
import { SaveAuthSettingsButton } from './SaveAuthSettingsButton';
|
||||
|
||||
export interface Props {
|
||||
onSaveSettings(): void;
|
||||
|
@ -69,10 +67,3 @@ export function InternalAuth({
|
|||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const InternalAuthAngular = react2angular(InternalAuth, [
|
||||
'onSaveSettings',
|
||||
'isLoading',
|
||||
'value',
|
||||
'onChange',
|
||||
]);
|
|
@ -2,10 +2,10 @@ import RcSlider from 'rc-slider';
|
|||
import clsx from 'clsx';
|
||||
import { Lock, XCircle, CheckCircle } from 'react-feather';
|
||||
|
||||
import { Badge } from '@/portainer/settings/authentication/internal-auth/components/Badge';
|
||||
|
||||
import 'rc-slider/assets/index.css';
|
||||
|
||||
import { Badge } from '../Badge';
|
||||
|
||||
import styles from './PasswordLengthSlider.module.css';
|
||||
|
||||
export interface Props {
|
|
@ -0,0 +1 @@
|
|||
export { InternalAuth } from './InternalAuth';
|
|
@ -4,7 +4,7 @@ import { useCallback, useEffect } from 'react';
|
|||
|
||||
import { baseHref } from '@/portainer/helpers/pathHelper';
|
||||
import { notifySuccess } from '@/portainer/services/notifications';
|
||||
import { useUpdateSettingsMutation } from '@/portainer/settings/queries';
|
||||
import { useUpdateSettingsMutation } from '@/react/portainer/settings/queries';
|
||||
|
||||
import { LoadingButton } from '@@/buttons/LoadingButton';
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
|
@ -2,12 +2,13 @@ import { useMutation } from 'react-query';
|
|||
import { useEffect } from 'react';
|
||||
|
||||
import { generateKey } from '@/portainer/environments/environment.service/edge';
|
||||
import { useSettings } from '@/portainer/settings/queries';
|
||||
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
|
||||
import { commandsTabs } from '@/react/edge/components/EdgeScriptForm/scripts';
|
||||
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||
|
||||
import { useSettings } from '../../queries';
|
||||
|
||||
import { AutoEnvCreationSettingsForm } from './AutoEnvCreationSettingsForm';
|
||||
|
||||
const commands = {
|
|
@ -0,0 +1,142 @@
|
|||
import { Form, Formik } from 'formik';
|
||||
import { useReducer } from 'react';
|
||||
|
||||
import { EdgeCheckinIntervalField } from '@/edge/components/EdgeCheckInIntervalField';
|
||||
import { EdgeAsyncIntervalsForm } from '@/edge/components/EdgeAsyncIntervalsForm';
|
||||
import { notifySuccess } from '@/portainer/services/notifications';
|
||||
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
import { Switch } from '@@/form-components/SwitchField/Switch';
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||
import { FormSection } from '@@/form-components/FormSection';
|
||||
import { LoadingButton } from '@@/buttons/LoadingButton';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
|
||||
import { useSettings, useUpdateSettingsMutation } from '../../queries';
|
||||
|
||||
import { FormValues } from './types';
|
||||
|
||||
const asyncIntervalFieldSettings = {
|
||||
ping: {
|
||||
label: 'Edge agent default ping frequency',
|
||||
tooltip:
|
||||
'Interval used by default by each Edge agent to ping the Portainer instance. Affects Edge environment management and Edge compute features.',
|
||||
},
|
||||
snapshot: {
|
||||
label: 'Edge agent default snapshot frequency',
|
||||
tooltip:
|
||||
'Interval used by default by each Edge agent to snapshot the agent state.',
|
||||
},
|
||||
command: {
|
||||
label: 'Edge agent default command frequency',
|
||||
tooltip: 'Interval used by default by each Edge agent to execute commands.',
|
||||
},
|
||||
};
|
||||
|
||||
export function DeploymentSyncOptions() {
|
||||
const settingsQuery = useSettings();
|
||||
const settingsMutation = useUpdateSettingsMutation();
|
||||
const [formKey, resetForm] = useReducer((state) => state + 1, 0);
|
||||
|
||||
if (!settingsQuery.data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const initialValues = {
|
||||
Edge: settingsQuery.data.Edge,
|
||||
EdgeAgentCheckinInterval: settingsQuery.data.EdgeAgentCheckinInterval,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<Widget>
|
||||
<WidgetTitle icon="svg-laptop" title="Deployment sync options" />
|
||||
<WidgetBody>
|
||||
<Formik<FormValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleSubmit}
|
||||
key={formKey}
|
||||
>
|
||||
{({ errors, setFieldValue, values, isValid, dirty }) => (
|
||||
<Form className="form-horizontal">
|
||||
<FormControl
|
||||
inputId="edge_async_mode"
|
||||
label="Use Async mode by default"
|
||||
size="small"
|
||||
errors={errors?.Edge?.AsyncMode}
|
||||
tooltip="Using Async allows the ability to define different ping,
|
||||
snapshot and command frequencies."
|
||||
>
|
||||
<Switch
|
||||
id="edge_async_mode"
|
||||
name="edge_async_mode"
|
||||
className="space-right"
|
||||
checked={values.Edge.AsyncMode}
|
||||
onChange={(e) =>
|
||||
setFieldValue('Edge.AsyncMode', e.valueOf())
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<TextTip color="orange">
|
||||
Enabling Async disables the tunnel function.
|
||||
</TextTip>
|
||||
|
||||
<FormSection title="Check-in Intervals">
|
||||
{!values.Edge.AsyncMode ? (
|
||||
<EdgeCheckinIntervalField
|
||||
value={values.EdgeAgentCheckinInterval}
|
||||
onChange={(value) =>
|
||||
setFieldValue('EdgeAgentCheckinInterval', value)
|
||||
}
|
||||
isDefaultHidden
|
||||
label="Edge agent default poll frequency"
|
||||
tooltip="Interval used by default by each Edge agent to check in with the Portainer instance. Affects Edge environment management and Edge compute features."
|
||||
/>
|
||||
) : (
|
||||
<EdgeAsyncIntervalsForm
|
||||
values={values.Edge}
|
||||
onChange={(value) => setFieldValue('Edge', value)}
|
||||
isDefaultHidden
|
||||
fieldSettings={asyncIntervalFieldSettings}
|
||||
/>
|
||||
)}
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="Actions">
|
||||
<div className="form-group mt-5">
|
||||
<div className="col-sm-12">
|
||||
<LoadingButton
|
||||
disabled={!isValid || !dirty}
|
||||
data-cy="settings-deploySyncOptionsButton"
|
||||
isLoading={settingsMutation.isLoading}
|
||||
loadingText="Saving settings..."
|
||||
>
|
||||
Save settings
|
||||
</LoadingButton>
|
||||
</div>
|
||||
</div>
|
||||
</FormSection>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</WidgetBody>
|
||||
</Widget>
|
||||
</div>
|
||||
);
|
||||
|
||||
function handleSubmit(values: FormValues) {
|
||||
settingsMutation.mutate(
|
||||
{
|
||||
Edge: values.Edge,
|
||||
EdgeAgentCheckinInterval: values.EdgeAgentCheckinInterval,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
notifySuccess('Success', 'Settings updated successfully');
|
||||
resetForm();
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export interface FormValues {
|
||||
Edge: {
|
||||
PingInterval: number;
|
||||
SnapshotInterval: number;
|
||||
CommandInterval: number;
|
||||
AsyncMode: boolean;
|
||||
};
|
||||
EdgeAgentCheckinInterval: number;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { boolean, number, object, SchemaOf } from 'yup';
|
||||
|
||||
import { options as asyncIntervalOptions } from '@/edge/components/EdgeAsyncIntervalsForm';
|
||||
|
||||
import { FormValues } from './types';
|
||||
|
||||
const intervals = asyncIntervalOptions.map((option) => option.value);
|
||||
|
||||
export function validationSchema(): SchemaOf<FormValues> {
|
||||
return object({
|
||||
EdgeAgentCheckinInterval: number().required('This field is required.'),
|
||||
Edge: 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),
|
||||
AsyncMode: boolean().default(false),
|
||||
}),
|
||||
});
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
|
||||
import { Settings } from '../types';
|
||||
import { Settings } from '@/react/portainer/settings/types';
|
||||
|
||||
import { EdgeComputeSettings } from './EdgeComputeSettings';
|
||||
import { AutomaticEdgeEnvCreation } from './AutomaticEdgeEnvCreation';
|
||||
|
@ -21,8 +17,3 @@ export function EdgeComputeSettingsView({ settings, onSubmit }: Props) {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const EdgeComputeSettingsViewAngular = r2a(
|
||||
withReactQuery(withCurrentUser(EdgeComputeSettingsView)),
|
||||
['settings', 'onSubmit']
|
||||
);
|
|
@ -1,6 +1,5 @@
|
|||
import { useTable, usePagination, useSortBy } from 'react-table';
|
||||
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||
import { FDOProfilesDatatableActions } from 'Portainer/settings/edge-compute/FDOProfilesDatatable/FDOProfilesDatatableActions';
|
||||
|
||||
import { Profile } from '@/portainer/hostmanagement/fdo/model';
|
||||
import PortainerError from '@/portainer/error';
|
||||
|
@ -24,6 +23,7 @@ import {
|
|||
|
||||
import { useFDOProfiles } from './useFDOProfiles';
|
||||
import { useColumns } from './columns';
|
||||
import { FDOProfilesDatatableActions } from './FDOProfilesDatatableActions';
|
||||
|
||||
export interface FDOProfilesTableSettings
|
||||
extends SortableTableSettings,
|
|
@ -2,7 +2,6 @@ import { useEffect, useState } from 'react';
|
|||
import { Formik, Field, Form } from 'formik';
|
||||
|
||||
import { FDOConfiguration } from '@/portainer/hostmanagement/fdo/model';
|
||||
import { FDOProfilesDatatableContainer } from '@/portainer/settings/edge-compute/FDOProfilesDatatable/FDOProfilesDatatableContainer';
|
||||
|
||||
import { Switch } from '@@/form-components/SwitchField/Switch';
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
|
@ -12,6 +11,8 @@ import { LoadingButton } from '@@/buttons/LoadingButton';
|
|||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { Input } from '@@/form-components/Input';
|
||||
|
||||
import { FDOProfilesDatatableContainer } from '../FDOProfilesDatatable/FDOProfilesDatatableContainer';
|
||||
|
||||
import styles from './SettingsFDO.module.css';
|
||||
import { validationSchema } from './SettingsFDO.validation';
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { SettingsFDO } from './SettingsFDO';
|
|
@ -0,0 +1 @@
|
|||
export { SettingsOpenAMT } from './SettingsOpenAMT';
|
|
@ -0,0 +1,7 @@
|
|||
export interface Settings {
|
||||
EdgeAgentCheckinInterval: number;
|
||||
EnableEdgeComputeFeatures: boolean;
|
||||
TrustOnFirstConnect: boolean;
|
||||
EnforceEdgeID: boolean;
|
||||
EdgePortainerUrl: string;
|
||||
}
|
|
@ -5,8 +5,7 @@ import {
|
|||
withError,
|
||||
withInvalidate,
|
||||
} from '@/react-tools/react-query';
|
||||
|
||||
import { PublicSettingsViewModel } from '../models/settings';
|
||||
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
||||
|
||||
import {
|
||||
getSettings,
|
|
@ -1,6 +1,5 @@
|
|||
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
||||
|
||||
import axios, { parseAxiosError } from '../services/axios';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
import { DefaultRegistry, PublicSettingsResponse, Settings } from './types';
|
||||
|
|
@ -3,7 +3,7 @@ import { useMutation, useQueryClient } from 'react-query';
|
|||
import { Trash2, Users } from 'react-feather';
|
||||
|
||||
import { confirmDeletionAsync } from '@/portainer/services/modal.service/confirm';
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
import {
|
||||
mutationOptions,
|
||||
withError,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useRouter } from '@uirouter/react';
|
|||
|
||||
import { useUsers } from '@/portainer/users/queries';
|
||||
import { useUser } from '@/portainer/hooks/useUser';
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
FileText,
|
||||
} from 'react-feather';
|
||||
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
import {
|
||||
FeatureFlag,
|
||||
useFeatureFlag,
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Home } from 'react-feather';
|
|||
|
||||
import { useUser } from '@/portainer/hooks/useUser';
|
||||
import { useIsTeamLeader } from '@/portainer/users/queries';
|
||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
||||
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||
|
||||
import styles from './Sidebar.module.css';
|
||||
import { EdgeComputeSidebar } from './EdgeComputeSidebar';
|
||||
|
|
|
@ -9,7 +9,7 @@ import { EnvironmentGroup } from '@/portainer/environment-groups/types';
|
|||
import { Tag } from '@/portainer/tags/types';
|
||||
import { StatusResponse } from '@/portainer/services/api/status.service';
|
||||
import { createMockTeams } from '@/react-tools/test-mocks';
|
||||
import { PublicSettingsResponse } from '@/portainer/settings/types';
|
||||
import { PublicSettingsResponse } from '@/react/portainer/settings/types';
|
||||
import { UserId } from '@/portainer/users/types';
|
||||
|
||||
import { azureHandlers } from './setup-handlers/azure';
|
||||
|
|
|
@ -30,12 +30,7 @@
|
|||
"paths": {
|
||||
// paths relative to the baseUrl
|
||||
"@@/*": ["react/components/*"],
|
||||
"@/*": ["./*", "../app/*"],
|
||||
"Agent/*": ["agent/*"],
|
||||
"Azure/*": ["azure/*"],
|
||||
"Docker/*": ["docker/*"],
|
||||
"Kubernetes/*": ["kubernetes/*"],
|
||||
"Portainer/*": ["portainer/*"]
|
||||
"@/*": ["./*", "../app/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["api", "build", "dist", "distribution", "node_modules", "test", "webpack"],
|
||||
|
|
Loading…
Reference in New Issue