mirror of https://github.com/portainer/portainer
refactor(app): move settings components to react [EE-3442] (#7625)
parent
5777c18297
commit
1e21961e6a
|
@ -1,6 +1,6 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
const categories = [
|
const categories = [
|
||||||
'docker',
|
'docker',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useState } from 'react';
|
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 { useGroups } from '@/portainer/environment-groups/queries';
|
||||||
|
|
||||||
import { PageHeader } from '@@/PageHeader';
|
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 { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { useSettings } from '@/portainer/settings/queries';
|
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
import { r2a } from '@/react-tools/react2angular';
|
||||||
|
import { useSettings } from '@/react/portainer/settings/queries';
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||||
|
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
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 { useStatus } from '@/portainer/services/api/status.service';
|
||||||
import { useSettings } from '@/portainer/settings/queries';
|
import { useSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
export function useAgentDetails() {
|
export function useAgentDetails() {
|
||||||
const settingsQuery = useSettings((settings) => settings.AgentSecret);
|
const settingsQuery = useSettings((settings) => settings.AgentSecret);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useRouter } from '@uirouter/react';
|
import { useRouter } from '@uirouter/react';
|
||||||
|
|
||||||
import { usePublicSettings } from '../settings/queries';
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
export enum FeatureFlag {
|
export enum FeatureFlag {
|
||||||
EdgeRemoteUpdate = 'edgeRemoteUpdate',
|
EdgeRemoteUpdate = 'edgeRemoteUpdate',
|
||||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { isoDateFromTimestamp } from '@/portainer/filters/filters';
|
import { isoDateFromTimestamp } from '@/portainer/filters/filters';
|
||||||
import { Environment } from '@/portainer/environments/types';
|
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';
|
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as kcService from '@/kubernetes/services/kubeconfig.service';
|
||||||
import * as notifications from '@/portainer/services/notifications';
|
import * as notifications from '@/portainer/services/notifications';
|
||||||
import { EnvironmentType } from '@/portainer/environments/types';
|
import { EnvironmentType } from '@/portainer/environments/types';
|
||||||
import { usePaginationLimitState } from '@/portainer/hooks/usePaginationLimitState';
|
import { usePaginationLimitState } from '@/portainer/hooks/usePaginationLimitState';
|
||||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
import {
|
import {
|
||||||
Query,
|
Query,
|
||||||
useEnvironmentList,
|
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';
|
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 { EnvironmentId } from '@/portainer/environments/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -14,6 +14,9 @@ import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
import { withUIRouter } from '@/react-tools/withUIRouter';
|
||||||
import { withI18nSuspense } from '@/react-tools/withI18nSuspense';
|
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 { PageHeader } from '@@/PageHeader';
|
||||||
import { TagSelector } from '@@/TagSelector';
|
import { TagSelector } from '@@/TagSelector';
|
||||||
|
@ -128,4 +131,13 @@ export const componentsModule = angular
|
||||||
'onSubmit',
|
'onSubmit',
|
||||||
'onError',
|
'onError',
|
||||||
])
|
])
|
||||||
|
)
|
||||||
|
.component(
|
||||||
|
'settingsFdo',
|
||||||
|
r2a(withUIRouter(withReactQuery(SettingsFDO)), ['onSubmit', 'settings'])
|
||||||
|
)
|
||||||
|
.component('settingsOpenAmt', r2a(SettingsOpenAMT, ['onSubmit', 'settings']))
|
||||||
|
.component(
|
||||||
|
'internalAuth',
|
||||||
|
r2a(InternalAuth, ['onSaveSettings', 'isLoading', 'value', 'onChange'])
|
||||||
).name;
|
).name;
|
||||||
|
|
|
@ -5,6 +5,9 @@ import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
import { r2a } from '@/react-tools/react2angular';
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
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 { wizardModule } from './wizard';
|
||||||
import { teamsModule } from './teams';
|
import { teamsModule } from './teams';
|
||||||
|
@ -19,4 +22,18 @@ export const viewsModule = angular
|
||||||
.component(
|
.component(
|
||||||
'homeView',
|
'homeView',
|
||||||
r2a(withUIRouter(withReactQuery(withCurrentUser(HomeView))), [])
|
r2a(withUIRouter(withReactQuery(withCurrentUser(HomeView))), [])
|
||||||
|
)
|
||||||
|
.component(
|
||||||
|
'createAccessToken',
|
||||||
|
r2a(withI18nSuspense(withUIRouter(CreateAccessToken)), [
|
||||||
|
'onSubmit',
|
||||||
|
'onError',
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.component(
|
||||||
|
'settingsEdgeCompute',
|
||||||
|
r2a(withReactQuery(withCurrentUser(EdgeComputeSettingsView)), [
|
||||||
|
'onSubmit',
|
||||||
|
'settings',
|
||||||
|
])
|
||||||
).name;
|
).name;
|
||||||
|
|
|
@ -2,10 +2,9 @@ import angular from 'angular';
|
||||||
import ldapModule from './ldap';
|
import ldapModule from './ldap';
|
||||||
import { autoUserProvisionToggle } from './auto-user-provision-toggle';
|
import { autoUserProvisionToggle } from './auto-user-provision-toggle';
|
||||||
import { saveAuthSettingsButton } from './save-auth-settings-button';
|
import { saveAuthSettingsButton } from './save-auth-settings-button';
|
||||||
import { InternalAuthAngular } from './internal-auth';
|
|
||||||
|
|
||||||
export default angular
|
export default angular
|
||||||
.module('portainer.settings.authentication', [ldapModule])
|
.module('portainer.settings.authentication', [ldapModule])
|
||||||
.component('internalAuth', InternalAuthAngular)
|
|
||||||
.component('saveAuthSettingsButton', saveAuthSettingsButton)
|
.component('saveAuthSettingsButton', saveAuthSettingsButton)
|
||||||
.component('autoUserProvisionToggle', autoUserProvisionToggle).name;
|
.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 authenticationModule from './authentication';
|
||||||
import generalModule from './general';
|
import generalModule from './general';
|
||||||
|
|
||||||
import { SettingsFDOAngular } from './edge-compute/SettingsFDO';
|
export default angular.module('portainer.settings', [authenticationModule, generalModule]).name;
|
||||||
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;
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
import { Icon } from '@@/Icon';
|
import { Icon } from '@@/Icon';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import _ from 'lodash';
|
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 { ResourceControlViewModel } from '@/react/portainer/access-control/models/ResourceControlViewModel';
|
||||||
|
|
||||||
import { DockerContainer, ContainerStatus } from './types';
|
import { DockerContainer, ContainerStatus } from './types';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import DockerNetworkHelper from 'Docker/helpers/networkHelper';
|
|
||||||
|
|
||||||
|
import DockerNetworkHelper from '@/docker/helpers/networkHelper';
|
||||||
import { Authorized } from '@/portainer/hooks/useUser';
|
import { Authorized } from '@/portainer/hooks/useUser';
|
||||||
|
|
||||||
import { Table, TableContainer, TableTitle } from '@@/datatables';
|
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 {
|
import {
|
||||||
usePublicSettings,
|
usePublicSettings,
|
||||||
useUpdateDefaultRegistrySettingsMutation,
|
useUpdateDefaultRegistrySettingsMutation,
|
||||||
} from 'Portainer/settings/queries';
|
} from '@/react/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';
|
|
||||||
|
|
||||||
import { Tooltip } from '@@/Tip/Tooltip';
|
import { Tooltip } from '@@/Tip/Tooltip';
|
||||||
import { Button } from '@@/buttons';
|
import { Button } from '@@/buttons';
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { usePublicSettings } from 'Portainer/settings/queries';
|
|
||||||
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
export function DefaultRegistryDomain() {
|
export function DefaultRegistryDomain() {
|
||||||
const settingsQuery = usePublicSettings({
|
const settingsQuery = usePublicSettings({
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { usePublicSettings } from 'Portainer/settings/queries';
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
export function DefaultRegistryName() {
|
export function DefaultRegistryName() {
|
||||||
const settingsQuery = usePublicSettings({
|
const settingsQuery = usePublicSettings({
|
||||||
select: (settings) => settings.DefaultRegistry?.Hide,
|
select: (settings) => settings.DefaultRegistry?.Hide,
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import { react2angular } from '@/react-tools/react2angular';
|
|
||||||
import { confirmDestructive } from '@/portainer/services/modal.service/confirm';
|
import { confirmDestructive } from '@/portainer/services/modal.service/confirm';
|
||||||
|
import { Settings } from '@/react/portainer/settings/types';
|
||||||
|
|
||||||
import { FormSectionTitle } from '@@/form-components/FormSectionTitle';
|
import { FormSectionTitle } from '@@/form-components/FormSectionTitle';
|
||||||
|
|
||||||
import { SaveAuthSettingsButton } from '../components/SaveAuthSettingsButton';
|
import { PasswordLengthSlider } from './PasswordLengthSlider/PasswordLengthSlider';
|
||||||
import { Settings } from '../../types';
|
import { SaveAuthSettingsButton } from './SaveAuthSettingsButton';
|
||||||
|
|
||||||
import { PasswordLengthSlider } from './components/PasswordLengthSlider/PasswordLengthSlider';
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
onSaveSettings(): void;
|
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 clsx from 'clsx';
|
||||||
import { Lock, XCircle, CheckCircle } from 'react-feather';
|
import { Lock, XCircle, CheckCircle } from 'react-feather';
|
||||||
|
|
||||||
import { Badge } from '@/portainer/settings/authentication/internal-auth/components/Badge';
|
|
||||||
|
|
||||||
import 'rc-slider/assets/index.css';
|
import 'rc-slider/assets/index.css';
|
||||||
|
|
||||||
|
import { Badge } from '../Badge';
|
||||||
|
|
||||||
import styles from './PasswordLengthSlider.module.css';
|
import styles from './PasswordLengthSlider.module.css';
|
||||||
|
|
||||||
export interface Props {
|
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 { baseHref } from '@/portainer/helpers/pathHelper';
|
||||||
import { notifySuccess } from '@/portainer/services/notifications';
|
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 { LoadingButton } from '@@/buttons/LoadingButton';
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
|
@ -2,12 +2,13 @@ import { useMutation } from 'react-query';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { generateKey } from '@/portainer/environments/environment.service/edge';
|
import { generateKey } from '@/portainer/environments/environment.service/edge';
|
||||||
import { useSettings } from '@/portainer/settings/queries';
|
|
||||||
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
|
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
|
||||||
import { commandsTabs } from '@/react/edge/components/EdgeScriptForm/scripts';
|
import { commandsTabs } from '@/react/edge/components/EdgeScriptForm/scripts';
|
||||||
|
|
||||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||||
|
|
||||||
|
import { useSettings } from '../../queries';
|
||||||
|
|
||||||
import { AutoEnvCreationSettingsForm } from './AutoEnvCreationSettingsForm';
|
import { AutoEnvCreationSettingsForm } from './AutoEnvCreationSettingsForm';
|
||||||
|
|
||||||
const commands = {
|
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 { Settings } from '@/react/portainer/settings/types';
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
|
||||||
|
|
||||||
import { Settings } from '../types';
|
|
||||||
|
|
||||||
import { EdgeComputeSettings } from './EdgeComputeSettings';
|
import { EdgeComputeSettings } from './EdgeComputeSettings';
|
||||||
import { AutomaticEdgeEnvCreation } from './AutomaticEdgeEnvCreation';
|
import { AutomaticEdgeEnvCreation } from './AutomaticEdgeEnvCreation';
|
||||||
|
@ -21,8 +17,3 @@ export function EdgeComputeSettingsView({ settings, onSubmit }: Props) {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EdgeComputeSettingsViewAngular = r2a(
|
|
||||||
withReactQuery(withCurrentUser(EdgeComputeSettingsView)),
|
|
||||||
['settings', 'onSubmit']
|
|
||||||
);
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { useTable, usePagination, useSortBy } from 'react-table';
|
import { useTable, usePagination, useSortBy } from 'react-table';
|
||||||
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||||
import { FDOProfilesDatatableActions } from 'Portainer/settings/edge-compute/FDOProfilesDatatable/FDOProfilesDatatableActions';
|
|
||||||
|
|
||||||
import { Profile } from '@/portainer/hostmanagement/fdo/model';
|
import { Profile } from '@/portainer/hostmanagement/fdo/model';
|
||||||
import PortainerError from '@/portainer/error';
|
import PortainerError from '@/portainer/error';
|
||||||
|
@ -24,6 +23,7 @@ import {
|
||||||
|
|
||||||
import { useFDOProfiles } from './useFDOProfiles';
|
import { useFDOProfiles } from './useFDOProfiles';
|
||||||
import { useColumns } from './columns';
|
import { useColumns } from './columns';
|
||||||
|
import { FDOProfilesDatatableActions } from './FDOProfilesDatatableActions';
|
||||||
|
|
||||||
export interface FDOProfilesTableSettings
|
export interface FDOProfilesTableSettings
|
||||||
extends SortableTableSettings,
|
extends SortableTableSettings,
|
|
@ -2,7 +2,6 @@ import { useEffect, useState } from 'react';
|
||||||
import { Formik, Field, Form } from 'formik';
|
import { Formik, Field, Form } from 'formik';
|
||||||
|
|
||||||
import { FDOConfiguration } from '@/portainer/hostmanagement/fdo/model';
|
import { FDOConfiguration } from '@/portainer/hostmanagement/fdo/model';
|
||||||
import { FDOProfilesDatatableContainer } from '@/portainer/settings/edge-compute/FDOProfilesDatatable/FDOProfilesDatatableContainer';
|
|
||||||
|
|
||||||
import { Switch } from '@@/form-components/SwitchField/Switch';
|
import { Switch } from '@@/form-components/SwitchField/Switch';
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
|
@ -12,6 +11,8 @@ import { LoadingButton } from '@@/buttons/LoadingButton';
|
||||||
import { TextTip } from '@@/Tip/TextTip';
|
import { TextTip } from '@@/Tip/TextTip';
|
||||||
import { Input } from '@@/form-components/Input';
|
import { Input } from '@@/form-components/Input';
|
||||||
|
|
||||||
|
import { FDOProfilesDatatableContainer } from '../FDOProfilesDatatable/FDOProfilesDatatableContainer';
|
||||||
|
|
||||||
import styles from './SettingsFDO.module.css';
|
import styles from './SettingsFDO.module.css';
|
||||||
import { validationSchema } from './SettingsFDO.validation';
|
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,
|
withError,
|
||||||
withInvalidate,
|
withInvalidate,
|
||||||
} from '@/react-tools/react-query';
|
} from '@/react-tools/react-query';
|
||||||
|
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
||||||
import { PublicSettingsViewModel } from '../models/settings';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getSettings,
|
getSettings,
|
|
@ -1,6 +1,5 @@
|
||||||
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
import { PublicSettingsViewModel } from '@/portainer/models/settings';
|
||||||
|
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||||
import axios, { parseAxiosError } from '../services/axios';
|
|
||||||
|
|
||||||
import { DefaultRegistry, PublicSettingsResponse, Settings } from './types';
|
import { DefaultRegistry, PublicSettingsResponse, Settings } from './types';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useMutation, useQueryClient } from 'react-query';
|
||||||
import { Trash2, Users } from 'react-feather';
|
import { Trash2, Users } from 'react-feather';
|
||||||
|
|
||||||
import { confirmDeletionAsync } from '@/portainer/services/modal.service/confirm';
|
import { confirmDeletionAsync } from '@/portainer/services/modal.service/confirm';
|
||||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
import {
|
import {
|
||||||
mutationOptions,
|
mutationOptions,
|
||||||
withError,
|
withError,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useRouter } from '@uirouter/react';
|
||||||
|
|
||||||
import { useUsers } from '@/portainer/users/queries';
|
import { useUsers } from '@/portainer/users/queries';
|
||||||
import { useUser } from '@/portainer/hooks/useUser';
|
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 { TextTip } from '@@/Tip/TextTip';
|
||||||
import { PageHeader } from '@@/PageHeader';
|
import { PageHeader } from '@@/PageHeader';
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
FileText,
|
FileText,
|
||||||
} from 'react-feather';
|
} from 'react-feather';
|
||||||
|
|
||||||
import { usePublicSettings } from '@/portainer/settings/queries';
|
import { usePublicSettings } from '@/react/portainer/settings/queries';
|
||||||
import {
|
import {
|
||||||
FeatureFlag,
|
FeatureFlag,
|
||||||
useFeatureFlag,
|
useFeatureFlag,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Home } from 'react-feather';
|
||||||
|
|
||||||
import { useUser } from '@/portainer/hooks/useUser';
|
import { useUser } from '@/portainer/hooks/useUser';
|
||||||
import { useIsTeamLeader } from '@/portainer/users/queries';
|
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 styles from './Sidebar.module.css';
|
||||||
import { EdgeComputeSidebar } from './EdgeComputeSidebar';
|
import { EdgeComputeSidebar } from './EdgeComputeSidebar';
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { EnvironmentGroup } from '@/portainer/environment-groups/types';
|
||||||
import { Tag } from '@/portainer/tags/types';
|
import { Tag } from '@/portainer/tags/types';
|
||||||
import { StatusResponse } from '@/portainer/services/api/status.service';
|
import { StatusResponse } from '@/portainer/services/api/status.service';
|
||||||
import { createMockTeams } from '@/react-tools/test-mocks';
|
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 { UserId } from '@/portainer/users/types';
|
||||||
|
|
||||||
import { azureHandlers } from './setup-handlers/azure';
|
import { azureHandlers } from './setup-handlers/azure';
|
||||||
|
|
|
@ -30,12 +30,7 @@
|
||||||
"paths": {
|
"paths": {
|
||||||
// paths relative to the baseUrl
|
// paths relative to the baseUrl
|
||||||
"@@/*": ["react/components/*"],
|
"@@/*": ["react/components/*"],
|
||||||
"@/*": ["./*", "../app/*"],
|
"@/*": ["./*", "../app/*"]
|
||||||
"Agent/*": ["agent/*"],
|
|
||||||
"Azure/*": ["azure/*"],
|
|
||||||
"Docker/*": ["docker/*"],
|
|
||||||
"Kubernetes/*": ["kubernetes/*"],
|
|
||||||
"Portainer/*": ["portainer/*"]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["api", "build", "dist", "distribution", "node_modules", "test", "webpack"],
|
"exclude": ["api", "build", "dist", "distribution", "node_modules", "test", "webpack"],
|
||||||
|
|
Loading…
Reference in New Issue