Skip to content

Commit

Permalink
Rework useOpenshiftVersions from a hook into React context (#2632)
Browse files Browse the repository at this point in the history
Co-authored-by: Montse Ortega <ammont82@users.noreply.github.com>
  • Loading branch information
jgyselov and ammont82 authored Jul 8, 2024
1 parent 2315fef commit 9e1a58e
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import Day2WizardFooter from './Day2WizardFooter';
import Day2HostStaticIpConfigurations from './Day2StaticIpHostConfigurations';
import { mapClusterCpuArchToInfraEnvCpuArch } from '../../../services/CpuArchitectureService';
import CpuArchitectureDropdown from '../../clusterConfiguration/CpuArchitectureDropdown';
import { useOpenshiftVersions, usePullSecret } from '../../../hooks';
import { usePullSecret } from '../../../hooks';
import { useOpenshiftVersionsContext } from '../../clusterWizard/OpenshiftVersionsContext';
import {
Cluster,
InfraEnv,
Expand Down Expand Up @@ -86,7 +87,7 @@ const Day2ClusterDetails = () => {
const [initialValues, setInitialValues] = React.useState<Day2ClusterDetailValues | null>(null);
const [isSubmitting, setSubmitting] = React.useState(false);
const [isAlternativeCpuSelected, setIsAlternativeCpuSelected] = React.useState(false);
const { getCpuArchitectures } = useOpenshiftVersions();
const { getCpuArchitectures } = useOpenshiftVersionsContext();
const cpuArchitecturesByVersionImage = getCpuArchitectures(day2Cluster.openshiftVersion);
const day1CpuArchitecture = mapClusterCpuArchToInfraEnvCpuArch(day2Cluster.cpuArchitecture);
const [errorState, setErrorState] = React.useState<Error | null>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { OcmClusterType } from '../AddHosts';
import HostsClusterDetailTab from './HostsClusterDetailTab';
import clustersAPI from '../../../common/api/assisted-service/ClustersAPI';
import { OpenshiftVersionsContextProvider } from '../clusterWizard/OpenshiftVersionsContext';

const clusterWithoutMetrics = {
id: 'ocm-cluster-id',
Expand Down Expand Up @@ -81,11 +82,13 @@ export const HostsClusterDetailTabMock: React.FC<
return (
<PageSection variant={PageSectionVariants.light} isFilled>
{tabShown ? (
<HostsClusterDetailTab
cluster={getCluster(tabShown)}
allEnabledFeatures={STANDALONE_DEPLOYMENT_ENABLED_FEATURES}
isVisible
/>
<OpenshiftVersionsContextProvider>
<HostsClusterDetailTab
cluster={getCluster(tabShown)}
allEnabledFeatures={STANDALONE_DEPLOYMENT_ENABLED_FEATURES}
isVisible
/>
</OpenshiftVersionsContextProvider>
) : (
<Grid hasGutter>
<ToolbarButton variant={ButtonVariant.primary} onClick={() => onAddHosts('no-metrics')}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import CpuArchitectureDropdown, {
import { OcmBaseDomainField } from './OcmBaseDomainField';
import OcmSNOControlGroup from './OcmSNOControlGroup';
import useSupportLevelsAPI from '../../hooks/useSupportLevelsAPI';
import { useOpenshiftVersions } from '../../hooks';
import { useOpenshiftVersionsContext } from '../clusterWizard/OpenshiftVersionsContext';
import { ExternalPlatformDropdown } from './platformIntegration/ExternalPlatformDropdown';
import { HostsNetworkConfigurationType } from '../../services/types';
import { useNewFeatureSupportLevel } from '../../../common/components/newFeatureSupportLevels';
Expand Down Expand Up @@ -68,7 +68,7 @@ export const OcmClusterDetailsFormFields = ({
const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
const isOracleCloudPlatformIntegrationEnabled = useFeature('ASSISTED_INSTALLER_PLATFORM_OCI');
const { openshiftVersion, platform } = values;
const { getCpuArchitectures } = useOpenshiftVersions();
const { getCpuArchitectures } = useOpenshiftVersionsContext();
const cpuArchitecturesByVersionImage = getCpuArchitectures(openshiftVersion);
const clusterWizardContext = useClusterWizardContext();
const featureSupportLevelData = useSupportLevelsAPI(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { OpenShiftVersionDropdown } from '../../../common/components/ui/OpenShif
import { OpenShiftVersionModal } from './OpenShiftVersionModal';
import { useFormikContext } from 'formik';
import { getOpenshiftVersionHelperText } from './OpenshiftVersionHelperText';
import { useOpenshiftVersions } from '../../hooks';
import { useOpenshiftVersionsContext } from '../clusterWizard/OpenshiftVersionsContext';

type OcmOpenShiftVersionSelectProps = {
versions: OpenshiftVersionOptionType[];
Expand Down Expand Up @@ -50,7 +50,7 @@ const OcmOpenShiftVersionSelect = ({ versions }: OcmOpenShiftVersionSelectProps)
return [];
}, [selectOptions, customOpenshiftSelect]);

const { versions: allVersions } = useOpenshiftVersions(false);
const { allVersions } = useOpenshiftVersionsContext();

const getHelperText = (value: string | undefined, inModal?: boolean) => {
return getOpenshiftVersionHelperText(allVersions, value, t, inModal);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { Button, ButtonVariant, FormGroup, Modal, ModalVariant } from '@patternfly/react-core';
import './OpenshiftVersionModal.css';
import { OpenshiftSelectWithSearch } from '../../../common/components/ui/OpenshiftSelectWithSearch';
import { useOpenshiftVersions } from '../../hooks';
import { useOpenshiftVersionsContext } from '../clusterWizard/OpenshiftVersionsContext';
import { HelperTextType } from '../../../common/components/ui/OpenShiftVersionDropdown';
import { useFormikContext } from 'formik';
import { ClusterDetailsValues, OpenshiftVersionOptionType } from '../../../common';
Expand All @@ -17,7 +17,7 @@ export const OpenShiftVersionModal = ({
getHelperText,
}: OpenShiftVersionModalProps) => {
const { setFieldValue } = useFormikContext<ClusterDetailsValues>();
const { versions } = useOpenshiftVersions(false);
const { allVersions: versions } = useOpenshiftVersionsContext();
const onClose = () => setOpenshiftVersionModalOpen(false);
const [customOpenshiftSelect, setCustomOpenshiftSelect] = useState<OpenshiftVersionOptionType>(); // Cambiar el tipo según lo que esperes aquí

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
UiIcon,
} from '../../../../common';
import { useClusterWizardContext } from '../../clusterWizard/ClusterWizardContext';
import { useOpenshiftVersions } from '../../../hooks';
import { useOpenshiftVersionsContext } from '../../clusterWizard/OpenshiftVersionsContext';
import { wizardStepNames } from '../../clusterWizard/constants';
import {
ClusterWizardStepsType,
Expand Down Expand Up @@ -118,7 +118,7 @@ const getCheckIcon = (validationStatuses: string[]) => {
const PreflightChecksDetailCollapsed = ({ cluster }: { cluster: Cluster }) => {
const { t } = useTranslation();
const featureSupportLevelData = useNewFeatureSupportLevel();
const { isSupportedOpenShiftVersion } = useOpenshiftVersions();
const { isSupportedOpenShiftVersion } = useOpenshiftVersionsContext();

const { isFullySupported } = React.useMemo<SupportLevelMemo>(
() => getSupportLevelInfo(cluster, featureSupportLevelData, isSupportedOpenShiftVersion, t),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { UiIcon, getOpenshiftVersionText } from '../../../common';
import { useOpenshiftVersions } from '../../hooks';
import { useOpenshiftVersionsContext } from '../clusterWizard/OpenshiftVersionsContext';
import { ExclamationTriangleIcon } from '@patternfly/react-icons/dist/js/icons/exclamation-triangle-icon';
import { Popover, Text, TextContent, TextVariants } from '@patternfly/react-core';
import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
Expand Down Expand Up @@ -28,7 +28,7 @@ const UnsupportedVersion = ({ version }: { version: string }) => {

const OpenShiftVersionDetail = ({ cluster }: { cluster: Cluster }) => {
const { openshiftVersion } = cluster;
const { isSupportedOpenShiftVersion, versions } = useOpenshiftVersions(false);
const { isSupportedOpenShiftVersion, latestVersions: versions } = useOpenshiftVersionsContext();
const isSupported = isSupportedOpenShiftVersion(openshiftVersion);

const version = React.useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { getApiErrorMessage, handleApiError, isUnknownServerError } from '../../
import { setServerUpdateError, updateCluster } from '../../store/slices/current-cluster/slice';
import { useClusterWizardContext } from './ClusterWizardContext';
import { canNextClusterDetails, ClusterWizardFlowStateNew } from './wizardTransition';
import { useOpenshiftVersions, useManagedDomains, useUsedClusterNames } from '../../hooks';
import { useManagedDomains, useUsedClusterNames } from '../../hooks';
import { useOpenshiftVersionsContext } from './OpenshiftVersionsContext';
import ClusterDetailsForm from './ClusterDetailsForm';
import ClusterWizardNavigation from './ClusterWizardNavigation';
import { routeBasePath } from '../../config';
Expand Down Expand Up @@ -35,8 +36,8 @@ const ClusterDetails = ({ cluster, infraEnv }: ClusterDetailsProps) => {
const {
error: errorOCPVersions,
loading: loadingOCPVersions,
versions,
} = useOpenshiftVersions(true);
latestVersions: versions,
} = useOpenshiftVersionsContext();

const handleClusterUpdate = React.useCallback(
async (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React, { createContext } from 'react';
import { CpuArchitecture, OpenshiftVersionOptionType } from '../../../common';
import { getApiErrorMessage, handleApiError } from '../../../common/api';
import { SupportedOpenshiftVersionsAPI } from '../../services/apis';
import { Cluster, OpenshiftVersion } from '@openshift-assisted/types/assisted-installer-service';
import { getKeys } from '../../../common/utils';

const supportedVersionLevels = ['production', 'maintenance'];

type OpenShiftVersion = Cluster['openshiftVersion'];
type OpenshiftVersionsContextType = {
allVersions: OpenshiftVersionOptionType[];
latestVersions: OpenshiftVersionOptionType[];
isSupportedOpenShiftVersion: (version: OpenShiftVersion) => boolean;
getCpuArchitectures: (version: OpenShiftVersion) => CpuArchitecture[];
error?: { title: string; message: string };
loading: boolean;
};

const OpenshiftVersionsContext = createContext<OpenshiftVersionsContextType | null>(null);

export const OpenshiftVersionsContextProvider = ({ children }: { children: React.ReactNode }) => {
const [allVersions, setAllVersions] = React.useState<OpenshiftVersionOptionType[]>([]);
const [latestVersions, setLatestVersions] = React.useState<OpenshiftVersionOptionType[]>([]);
const [error, setError] = React.useState<{ title: string; message: string }>();

const sortVersions = (versions: OpenshiftVersionOptionType[]) => {
return versions.sort((version1, version2) =>
version1.value.localeCompare(version2.value, undefined, { numeric: true }),
);
};

const getVersions = React.useCallback(
async (latest: boolean, setVersions: (versions: OpenshiftVersionOptionType[]) => void) => {
try {
const { data } = await SupportedOpenshiftVersionsAPI.list(latest);

const versions = getKeys(data).map((key) => {
const versionItem = data[key] as OpenshiftVersion;
const version = versionItem.displayName;

return {
label: `OpenShift ${version}`,
value: key as string,
version,
default: Boolean(versionItem.default),
supportLevel: versionItem.supportLevel,
cpuArchitectures: versionItem.cpuArchitectures as CpuArchitecture[],
};
}) as OpenshiftVersionOptionType[];

setVersions(sortVersions(versions));
} catch (e) {
handleApiError(e, (e) => {
setError({
title: 'Failed to retrieve list of supported OpenShift versions.',
message: getApiErrorMessage(e),
});
});
}
},
[],
);

React.useEffect(() => {
if (!allVersions.length) {
void getVersions(false, setAllVersions);
}
}, [allVersions, getVersions]);

React.useEffect(() => {
if (!latestVersions.length) {
void getVersions(true, setLatestVersions);
}
}, [getVersions, latestVersions]);

const findVersionItemByVersion = React.useCallback(
(version: OpenShiftVersion) => {
return allVersions?.find(({ value: versionKey }) => {
// For version 4.10 match 4.10, 4.10.3, not 4.1, 4.1.5
const versionNameMatch = new RegExp(`^${versionKey}(\\..+)?$`);
return versionNameMatch.test(version || '');
});
},
[allVersions],
);

const isSupportedOpenShiftVersion = React.useCallback(
(version: OpenShiftVersion) => {
if (allVersions?.length === 0) {
// Till the data are loaded
return true;
}
const selectedVersion = findVersionItemByVersion(version);
return supportedVersionLevels.includes(selectedVersion?.supportLevel || '');
},
[findVersionItemByVersion, allVersions],
);

const getCpuArchitectures = React.useCallback(
(version: OpenShiftVersion) => {
// TODO (multi-arch) confirm this is correctly retrieving the associated version
const matchingVersion = findVersionItemByVersion(version);
return matchingVersion?.cpuArchitectures ?? [];
},
[findVersionItemByVersion],
);

return (
<OpenshiftVersionsContext.Provider
value={{
allVersions,
latestVersions,
loading: !error && (allVersions?.length === 0 || latestVersions?.length === 0),
error,
isSupportedOpenShiftVersion,
getCpuArchitectures,
}}
>
{children}
</OpenshiftVersionsContext.Provider>
);
};

export const useOpenshiftVersionsContext = () => {
const context = React.useContext(OpenshiftVersionsContext);
if (!context) {
throw new Error('useOpenshiftVersionsContext must be used within OpenshiftVersionsContext');
}
return context;
};
41 changes: 23 additions & 18 deletions libs/ui-lib/lib/ocm/components/clusters/ClusterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { NewFeatureSupportLevelProvider } from '../featureSupportLevels';
import { usePullSecret } from '../../hooks';
import { Cluster, InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
import { AssistedInstallerHeader } from './AssistedInstallerHeader';
import { OpenshiftVersionsContextProvider } from '../clusterWizard/OpenshiftVersionsContext';

type MatchParams = {
clusterId: string;
Expand Down Expand Up @@ -72,7 +73,9 @@ const ClusterPageGeneric: React.FC<{ clusterId: string; showBreadcrumbs?: boolea
};
return (
<AddHostsContextProvider cluster={cluster} resetCluster={onReset}>
<AddHosts />
<OpenshiftVersionsContextProvider>
<AddHosts />
</OpenshiftVersionsContextProvider>
</AddHostsContextProvider>
);
} else if (
Expand Down Expand Up @@ -168,23 +171,25 @@ const ClusterPageGeneric: React.FC<{ clusterId: string; showBreadcrumbs?: boolea
loadingUI={<ClusterLoading />}
errorUI={<ClusterUiError />}
>
<NewFeatureSupportLevelProvider
loadingUi={<ClusterLoading />}
cluster={cluster}
cpuArchitecture={infraEnv.cpuArchitecture as CpuArchitecture}
openshiftVersion={cluster.openshiftVersion}
platformType={cluster.platform?.type}
>
{/* TODO(mlibra): Will be reworked within https://issues.redhat.com/browse/AGENT-522
<RebootNodeZeroModal cluster={cluster} />
*/}
{getContent(cluster, infraEnv)}
{uiState === ResourceUIState.POLLING_ERROR && <ClusterPollingErrorModal />}
{uiState === ResourceUIState.UPDATE_ERROR && <ClusterUpdateErrorModal />}
<CancelInstallationModal />
<ResetClusterModal />
<DiscoveryImageModal />
</NewFeatureSupportLevelProvider>
<OpenshiftVersionsContextProvider>
<NewFeatureSupportLevelProvider
loadingUi={<ClusterLoading />}
cluster={cluster}
cpuArchitecture={infraEnv.cpuArchitecture as CpuArchitecture}
openshiftVersion={cluster.openshiftVersion}
platformType={cluster.platform?.type}
>
{/* TODO(mlibra): Will be reworked within https://issues.redhat.com/browse/AGENT-522
<RebootNodeZeroModal cluster={cluster} />
*/}
{getContent(cluster, infraEnv)}
{uiState === ResourceUIState.POLLING_ERROR && <ClusterPollingErrorModal />}
{uiState === ResourceUIState.UPDATE_ERROR && <ClusterUpdateErrorModal />}
<CancelInstallationModal />
<ResetClusterModal />
<DiscoveryImageModal />
</NewFeatureSupportLevelProvider>
</OpenshiftVersionsContextProvider>
</ClusterDefaultConfigurationProvider>
</ModalDialogsContextProvider>
</SentryErrorMonitorContextProvider>
Expand Down
19 changes: 11 additions & 8 deletions libs/ui-lib/lib/ocm/components/clusters/NewClusterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ClusterUiError } from './ClusterPageErrors';
import { NewFeatureSupportLevelProvider } from '../featureSupportLevels';
import { AssistedInstallerHeader } from './AssistedInstallerHeader';
import { ModalDialogsContextProvider } from '../hosts/ModalDialogsContext';
import { OpenshiftVersionsContextProvider } from '../clusterWizard/OpenshiftVersionsContext';

const NewClusterPageGeneric: React.FC<{ pageTitleSection?: ReactNode }> = ({
pageTitleSection,
Expand All @@ -23,14 +24,16 @@ const NewClusterPageGeneric: React.FC<{ pageTitleSection?: ReactNode }> = ({
loadingUI={<ClusterLoading />}
errorUI={<ClusterUiError />}
>
<NewFeatureSupportLevelProvider loadingUi={<ClusterLoading />}>
{pageTitleSection}
<PageSection variant={PageSectionVariants.light} isFilled>
<ClusterWizardContextProvider>
<NewClusterWizard />
</ClusterWizardContextProvider>
</PageSection>
</NewFeatureSupportLevelProvider>
<OpenshiftVersionsContextProvider>
<NewFeatureSupportLevelProvider loadingUi={<ClusterLoading />}>
{pageTitleSection}
<PageSection variant={PageSectionVariants.light} isFilled>
<ClusterWizardContextProvider>
<NewClusterWizard />
</ClusterWizardContextProvider>
</PageSection>
</NewFeatureSupportLevelProvider>
</OpenshiftVersionsContextProvider>
</ClusterDefaultConfigurationProvider>
</ModalDialogsContextProvider>
</SentryErrorMonitorContextProvider>
Expand Down
Loading

0 comments on commit 9e1a58e

Please sign in to comment.