diff --git a/app/react/portainer/environments/update-schedules/common/RollbackOptions.tsx b/app/react/portainer/environments/update-schedules/common/RollbackOptions.tsx index e0b40cf3d..4b4265a65 100644 --- a/app/react/portainer/environments/update-schedules/common/RollbackOptions.tsx +++ b/app/react/portainer/environments/update-schedules/common/RollbackOptions.tsx @@ -23,7 +23,7 @@ export function RollbackOptions() { if (!count) { return ( - The are no rollback options available for yor selected groups(s) + There are no rollback options available for your selected groups(s) ); } @@ -73,6 +73,7 @@ function useSelectVersionOnMount() { useEffect(() => { switch (previousVersions.length) { case 0: + setFieldValue('version', ''); setFieldError('version', 'No rollback options available'); break; case 1: diff --git a/app/react/portainer/environments/update-schedules/common/RollbackScheduleDetailsFieldset.tsx b/app/react/portainer/environments/update-schedules/common/RollbackScheduleDetailsFieldset.tsx index 132430f43..069de8aad 100644 --- a/app/react/portainer/environments/update-schedules/common/RollbackScheduleDetailsFieldset.tsx +++ b/app/react/portainer/environments/update-schedules/common/RollbackScheduleDetailsFieldset.tsx @@ -1,11 +1,19 @@ import { RollbackOptions } from './RollbackOptions'; import { ScheduledTimeField } from './ScheduledTimeField'; -export function RollbackScheduleDetailsFieldset() { +interface Props { + hasTimeZone: boolean; + hasGroupSelected: boolean; +} + +export function RollbackScheduleDetailsFieldset({ + hasTimeZone, + hasGroupSelected, +}: Props) { return (
- + {hasTimeZone && hasGroupSelected && }
); } diff --git a/app/react/portainer/environments/update-schedules/common/ScheduleTypeSelector.tsx b/app/react/portainer/environments/update-schedules/common/ScheduleTypeSelector.tsx index 9810b4ee4..579346b7a 100644 --- a/app/react/portainer/environments/update-schedules/common/ScheduleTypeSelector.tsx +++ b/app/react/portainer/environments/update-schedules/common/ScheduleTypeSelector.tsx @@ -1,10 +1,14 @@ import { useFormikContext } from 'formik'; import { number } from 'yup'; +import { useEffect } from 'react'; import { NavTabs } from '@@/NavTabs'; import { ScheduleType } from '../types'; +import { useEdgeGroupsEnvironmentIds } from './useEdgeGroupsEnvironmentIds'; +import { useEnvironments } from './useEnvironments'; +import { defaultValue } from './ScheduledTimeField'; import { FormValues } from './types'; import { UpdateScheduleDetailsFieldset } from './UpdateScheduleDetailsFieldset'; import { RollbackScheduleDetailsFieldset } from './RollbackScheduleDetailsFieldset'; @@ -12,6 +16,24 @@ import { RollbackScheduleDetailsFieldset } from './RollbackScheduleDetailsFields export function ScheduleTypeSelector() { const { values, setFieldValue } = useFormikContext(); + 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 (
@@ -20,12 +42,25 @@ export function ScheduleTypeSelector() { { id: ScheduleType.Update, label: 'Update', - children: , + children: ( + + ), }, { id: ScheduleType.Rollback, label: 'Rollback', - children: , + children: ( + + ), }, ]} selectedId={values.type} diff --git a/app/react/portainer/environments/update-schedules/common/UpdateScheduleDetailsFieldset.tsx b/app/react/portainer/environments/update-schedules/common/UpdateScheduleDetailsFieldset.tsx index 72f05a71a..629107b2f 100644 --- a/app/react/portainer/environments/update-schedules/common/UpdateScheduleDetailsFieldset.tsx +++ b/app/react/portainer/environments/update-schedules/common/UpdateScheduleDetailsFieldset.tsx @@ -1,50 +1,40 @@ -import { useFormikContext } from 'formik'; import semverCompare from 'semver-compare'; import _ from 'lodash'; -import { useEffect } from 'react'; -import { EdgeTypes, EnvironmentId } from '@/react/portainer/environments/types'; -import { useEnvironmentList } from '@/react/portainer/environments/queries/useEnvironmentList'; +import { Environment } from '@/react/portainer/environments/types'; import { TextTip } from '@@/Tip/TextTip'; -import { FormValues } from './types'; -import { useEdgeGroupsEnvironmentIds } from './useEdgeGroupsEnvironmentIds'; import { VersionSelect } from './VersionSelect'; -import { defaultValue, ScheduledTimeField } from './ScheduledTimeField'; +import { ScheduledTimeField } from './ScheduledTimeField'; -export function UpdateScheduleDetailsFieldset() { - const { values, setFieldValue } = useFormikContext(); +interface Props { + environments: Environment[]; + hasTimeZone: boolean; + hasNoTimeZone: boolean; + hasGroupSelected: boolean; + version: string; +} - const environmentIdsQuery = useEdgeGroupsEnvironmentIds(values.groupIds); - - const edgeGroupsEnvironmentIds = environmentIdsQuery.data || []; - const environments = useEnvironments(edgeGroupsEnvironmentIds); +export function UpdateScheduleDetailsFieldset({ + environments, + hasTimeZone, + hasNoTimeZone, + hasGroupSelected, + version, +}: Props) { const minVersion = _.first( _.compact(environments.map((env) => env.Agent.Version)).sort( (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 ( <> - {edgeGroupsEnvironmentIds.length > 0 ? ( - !!values.version && ( + {environments.length > 0 ? ( + !!version && ( - {edgeGroupsEnvironmentIds.length} environment(s) will be updated to{' '} - {values.version} + {environments.length} environment(s) will be updated to {version} ) ) : ( @@ -52,10 +42,9 @@ export function UpdateScheduleDetailsFieldset() { No environments options for the selected edge groups )} - - {hasTimeZone && } + {hasTimeZone && hasGroupSelected && } {hasNoTimeZone && ( These edge groups have older versions of the edge agent that do not @@ -65,14 +54,3 @@ export function UpdateScheduleDetailsFieldset() { ); } - -function useEnvironments(environmentsIds: Array) { - const environmentsQuery = useEnvironmentList( - { endpointIds: environmentsIds, types: EdgeTypes }, - undefined, - undefined, - environmentsIds.length > 0 - ); - - return environmentsQuery.environments; -} diff --git a/app/react/portainer/environments/update-schedules/common/useEnvironments.ts b/app/react/portainer/environments/update-schedules/common/useEnvironments.ts new file mode 100644 index 000000000..ee1f91d7b --- /dev/null +++ b/app/react/portainer/environments/update-schedules/common/useEnvironments.ts @@ -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) { + const environmentsQuery = useEnvironmentList( + { endpointIds: environmentsIds, types: EdgeTypes }, + undefined, + undefined, + environmentsIds.length > 0 + ); + + return environmentsQuery.environments; +}