fix(schedule): update date picker after removing edge group [EE-4963] (#8418)

pull/8437/head
Oscar Zhou 2023-02-02 11:14:48 +13:00 committed by GitHub
parent 3470ea049a
commit 402a62a5e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 47 deletions

View File

@ -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:

View File

@ -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>
); );
} }

View File

@ -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}

View File

@ -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;
}

View File

@ -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;
}