mirror of https://github.com/portainer/portainer
fix(schedule): update date picker after removing edge group [EE-4963] (#8418)
parent
3470ea049a
commit
402a62a5e2
|
@ -23,7 +23,7 @@ export function RollbackOptions() {
|
||||||
if (!count) {
|
if (!count) {
|
||||||
return (
|
return (
|
||||||
<TextTip>
|
<TextTip>
|
||||||
The are no rollback options available for yor selected groups(s)
|
There are no rollback options available for your selected groups(s)
|
||||||
</TextTip>
|
</TextTip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ function useSelectVersionOnMount() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch (previousVersions.length) {
|
switch (previousVersions.length) {
|
||||||
case 0:
|
case 0:
|
||||||
|
setFieldValue('version', '');
|
||||||
setFieldError('version', 'No rollback options available');
|
setFieldError('version', 'No rollback options available');
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
import { RollbackOptions } from './RollbackOptions';
|
import { RollbackOptions } from './RollbackOptions';
|
||||||
import { ScheduledTimeField } from './ScheduledTimeField';
|
import { ScheduledTimeField } from './ScheduledTimeField';
|
||||||
|
|
||||||
export function RollbackScheduleDetailsFieldset() {
|
interface Props {
|
||||||
|
hasTimeZone: boolean;
|
||||||
|
hasGroupSelected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RollbackScheduleDetailsFieldset({
|
||||||
|
hasTimeZone,
|
||||||
|
hasGroupSelected,
|
||||||
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="mt-3">
|
<div className="mt-3">
|
||||||
<RollbackOptions />
|
<RollbackOptions />
|
||||||
<ScheduledTimeField />
|
{hasTimeZone && hasGroupSelected && <ScheduledTimeField />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import { number } from 'yup';
|
import { number } from 'yup';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { NavTabs } from '@@/NavTabs';
|
import { NavTabs } from '@@/NavTabs';
|
||||||
|
|
||||||
import { ScheduleType } from '../types';
|
import { ScheduleType } from '../types';
|
||||||
|
|
||||||
|
import { useEdgeGroupsEnvironmentIds } from './useEdgeGroupsEnvironmentIds';
|
||||||
|
import { useEnvironments } from './useEnvironments';
|
||||||
|
import { defaultValue } from './ScheduledTimeField';
|
||||||
import { FormValues } from './types';
|
import { FormValues } from './types';
|
||||||
import { UpdateScheduleDetailsFieldset } from './UpdateScheduleDetailsFieldset';
|
import { UpdateScheduleDetailsFieldset } from './UpdateScheduleDetailsFieldset';
|
||||||
import { RollbackScheduleDetailsFieldset } from './RollbackScheduleDetailsFieldset';
|
import { RollbackScheduleDetailsFieldset } from './RollbackScheduleDetailsFieldset';
|
||||||
|
@ -12,6 +16,24 @@ import { RollbackScheduleDetailsFieldset } from './RollbackScheduleDetailsFields
|
||||||
export function ScheduleTypeSelector() {
|
export function ScheduleTypeSelector() {
|
||||||
const { values, setFieldValue } = useFormikContext<FormValues>();
|
const { values, setFieldValue } = useFormikContext<FormValues>();
|
||||||
|
|
||||||
|
const environmentIdsQuery = useEdgeGroupsEnvironmentIds(values.groupIds);
|
||||||
|
|
||||||
|
const edgeGroupsEnvironmentIds = environmentIdsQuery.data || [];
|
||||||
|
const environments = useEnvironments(edgeGroupsEnvironmentIds);
|
||||||
|
|
||||||
|
// old version is version that doesn't support scheduling of updates
|
||||||
|
const hasNoTimeZone = environments.some((env) => !env.LocalTimeZone);
|
||||||
|
const hasTimeZone = environments.some((env) => env.LocalTimeZone);
|
||||||
|
const hasGroupSelected = values.groupIds.length > 0;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!hasTimeZone || !hasGroupSelected) {
|
||||||
|
setFieldValue('scheduledTime', '');
|
||||||
|
} else if (!values.scheduledTime) {
|
||||||
|
setFieldValue('scheduledTime', defaultValue());
|
||||||
|
}
|
||||||
|
}, [setFieldValue, hasTimeZone, values.scheduledTime, hasGroupSelected]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<div className="col-sm-12">
|
<div className="col-sm-12">
|
||||||
|
@ -20,12 +42,25 @@ export function ScheduleTypeSelector() {
|
||||||
{
|
{
|
||||||
id: ScheduleType.Update,
|
id: ScheduleType.Update,
|
||||||
label: 'Update',
|
label: 'Update',
|
||||||
children: <UpdateScheduleDetailsFieldset />,
|
children: (
|
||||||
|
<UpdateScheduleDetailsFieldset
|
||||||
|
environments={environments}
|
||||||
|
hasTimeZone={hasTimeZone}
|
||||||
|
hasNoTimeZone={hasNoTimeZone}
|
||||||
|
hasGroupSelected={hasGroupSelected}
|
||||||
|
version={values.version}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: ScheduleType.Rollback,
|
id: ScheduleType.Rollback,
|
||||||
label: 'Rollback',
|
label: 'Rollback',
|
||||||
children: <RollbackScheduleDetailsFieldset />,
|
children: (
|
||||||
|
<RollbackScheduleDetailsFieldset
|
||||||
|
hasTimeZone={hasTimeZone}
|
||||||
|
hasGroupSelected={hasGroupSelected}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
selectedId={values.type}
|
selectedId={values.type}
|
||||||
|
|
|
@ -1,50 +1,40 @@
|
||||||
import { useFormikContext } from 'formik';
|
|
||||||
import semverCompare from 'semver-compare';
|
import semverCompare from 'semver-compare';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { EdgeTypes, EnvironmentId } from '@/react/portainer/environments/types';
|
import { Environment } from '@/react/portainer/environments/types';
|
||||||
import { useEnvironmentList } from '@/react/portainer/environments/queries/useEnvironmentList';
|
|
||||||
|
|
||||||
import { TextTip } from '@@/Tip/TextTip';
|
import { TextTip } from '@@/Tip/TextTip';
|
||||||
|
|
||||||
import { FormValues } from './types';
|
|
||||||
import { useEdgeGroupsEnvironmentIds } from './useEdgeGroupsEnvironmentIds';
|
|
||||||
import { VersionSelect } from './VersionSelect';
|
import { VersionSelect } from './VersionSelect';
|
||||||
import { defaultValue, ScheduledTimeField } from './ScheduledTimeField';
|
import { ScheduledTimeField } from './ScheduledTimeField';
|
||||||
|
|
||||||
export function UpdateScheduleDetailsFieldset() {
|
interface Props {
|
||||||
const { values, setFieldValue } = useFormikContext<FormValues>();
|
environments: Environment[];
|
||||||
|
hasTimeZone: boolean;
|
||||||
|
hasNoTimeZone: boolean;
|
||||||
|
hasGroupSelected: boolean;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|
||||||
const environmentIdsQuery = useEdgeGroupsEnvironmentIds(values.groupIds);
|
export function UpdateScheduleDetailsFieldset({
|
||||||
|
environments,
|
||||||
const edgeGroupsEnvironmentIds = environmentIdsQuery.data || [];
|
hasTimeZone,
|
||||||
const environments = useEnvironments(edgeGroupsEnvironmentIds);
|
hasNoTimeZone,
|
||||||
|
hasGroupSelected,
|
||||||
|
version,
|
||||||
|
}: Props) {
|
||||||
const minVersion = _.first(
|
const minVersion = _.first(
|
||||||
_.compact<string>(environments.map((env) => env.Agent.Version)).sort(
|
_.compact<string>(environments.map((env) => env.Agent.Version)).sort(
|
||||||
(a, b) => semverCompare(a, b)
|
(a, b) => semverCompare(a, b)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// old version is version that doesn't support scheduling of updates
|
|
||||||
const hasNoTimeZone = environments.some((env) => !env.LocalTimeZone);
|
|
||||||
const hasTimeZone = environments.some((env) => env.LocalTimeZone);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!hasTimeZone) {
|
|
||||||
setFieldValue('scheduledTime', '');
|
|
||||||
} else if (!values.scheduledTime) {
|
|
||||||
setFieldValue('scheduledTime', defaultValue());
|
|
||||||
}
|
|
||||||
}, [setFieldValue, hasTimeZone, values.scheduledTime]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{edgeGroupsEnvironmentIds.length > 0 ? (
|
{environments.length > 0 ? (
|
||||||
!!values.version && (
|
!!version && (
|
||||||
<TextTip color="blue">
|
<TextTip color="blue">
|
||||||
{edgeGroupsEnvironmentIds.length} environment(s) will be updated to{' '}
|
{environments.length} environment(s) will be updated to {version}
|
||||||
{values.version}
|
|
||||||
</TextTip>
|
</TextTip>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
|
@ -52,10 +42,9 @@ export function UpdateScheduleDetailsFieldset() {
|
||||||
No environments options for the selected edge groups
|
No environments options for the selected edge groups
|
||||||
</TextTip>
|
</TextTip>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<VersionSelect minVersion={minVersion} />
|
<VersionSelect minVersion={minVersion} />
|
||||||
|
|
||||||
{hasTimeZone && <ScheduledTimeField />}
|
{hasTimeZone && hasGroupSelected && <ScheduledTimeField />}
|
||||||
{hasNoTimeZone && (
|
{hasNoTimeZone && (
|
||||||
<TextTip>
|
<TextTip>
|
||||||
These edge groups have older versions of the edge agent that do not
|
These edge groups have older versions of the edge agent that do not
|
||||||
|
@ -65,14 +54,3 @@ export function UpdateScheduleDetailsFieldset() {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useEnvironments(environmentsIds: Array<EnvironmentId>) {
|
|
||||||
const environmentsQuery = useEnvironmentList(
|
|
||||||
{ endpointIds: environmentsIds, types: EdgeTypes },
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
environmentsIds.length > 0
|
|
||||||
);
|
|
||||||
|
|
||||||
return environmentsQuery.environments;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { useEnvironmentList } from '@/react/portainer/environments/queries/useEnvironmentList';
|
||||||
|
import { EdgeTypes, EnvironmentId } from '@/react/portainer/environments/types';
|
||||||
|
|
||||||
|
export function useEnvironments(environmentsIds: Array<EnvironmentId>) {
|
||||||
|
const environmentsQuery = useEnvironmentList(
|
||||||
|
{ endpointIds: environmentsIds, types: EdgeTypes },
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
environmentsIds.length > 0
|
||||||
|
);
|
||||||
|
|
||||||
|
return environmentsQuery.environments;
|
||||||
|
}
|
Loading…
Reference in New Issue