Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pci-common): add 3AZ region and 1AZ chip #14672

Open
wants to merge 2 commits into
base: maintenance/manager-pci-common-v0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fetchIcebergV6 } from '@ovh-ux/manager-core-api';

export type TRegion = {
name: string;
type: string;
type: 'region' | 'localzone' | 'region-3-az' | string;
status: string;
continentCode: string;
services: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { render, screen } from '@testing-library/react';
import { describe, it } from 'vitest';
import { wrapper } from '@/wrapperRenders';
import { Region3AZChip } from '@/components/region-selector/Region3AZChip.component';
import { URL_INFO } from '@/components/region-selector/constants';

describe('Region3AZChip', () => {
it.each([undefined, false, true])(
'should render chip with showTooltip %s with correct texts and links',
(showTooltip: boolean | undefined) => {
render(<Region3AZChip showTooltip={showTooltip} />, { wrapper });

expect(
screen.getByText('pci_project_flavors_zone_3AZ'),
).toBeInTheDocument();

if (showTooltip ?? true) {
expect(
screen.getByText('pci_project_flavors_zone_3AZ_tooltip'),
).toBeInTheDocument();

const link = screen.getByText('pci_project_flavors_zone_tooltip_link');
expect(link).toBeInTheDocument();
expect(link).toHaveAttribute('href', URL_INFO.REGION_3AZ.DEFAULT);
} else {
expect(
screen.queryByText('pci_project_flavors_zone_3AZ_tooltip'),
).not.toBeInTheDocument();
expect(
screen.queryByText('pci_project_flavors_zone_tooltip_link'),
).not.toBeInTheDocument();
}
},
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { useContext } from 'react';
import { Links, LinkType } from '@ovh-ux/manager-react-components';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ShellContext } from '@ovh-ux/manager-react-shell-client';
import {
ODS_CHIP_SIZE,
ODS_ICON_NAME,
ODS_ICON_SIZE,
ODS_TEXT_LEVEL,
ODS_TEXT_SIZE,
} from '@ovhcloud/ods-components';
import {
OsdsChip,
OsdsIcon,
OsdsPopover,
OsdsPopoverContent,
OsdsText,
} from '@ovhcloud/ods-components/react';
import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core';
import { useTranslation } from 'react-i18next';
import { URL_INFO } from './constants';

export function Region3AZChip({
showTooltip = true,
}: Readonly<{
showTooltip?: boolean;
}>) {
const { t } = useTranslation('pci-region-selector');
const context = useContext(ShellContext);
const { ovhSubsidiary } = context.environment.getUser();
const documentURL =
URL_INFO.REGION_3AZ[ovhSubsidiary] || URL_INFO.REGION_3AZ.DEFAULT;

const chip = (
<OsdsChip
size={ODS_CHIP_SIZE.sm}
class="chip-3AZ"
onClick={(event) => event.stopPropagation()}
>
<OsdsText level={ODS_TEXT_LEVEL.body} size={ODS_TEXT_SIZE._500}>
{t('pci_project_flavors_zone_3AZ')}
</OsdsText>
{showTooltip && (
<OsdsIcon
name={ODS_ICON_NAME.HELP}
size={ODS_ICON_SIZE.xs}
className="ml-2"
/>
)}
</OsdsChip>
);

if (showTooltip) {
return (
<OsdsPopover>
<span slot="popover-trigger">{chip}</span>
<OsdsPopoverContent>
<OsdsText
color={ODS_THEME_COLOR_INTENT.text}
level={ODS_TEXT_LEVEL.body}
>
{t('pci_project_flavors_zone_3AZ_tooltip')}
</OsdsText>
&nbsp;
<Links
tab-index="-1"
label={t('pci_project_flavors_zone_tooltip_link')}
type={LinkType.external}
target={OdsHTMLAnchorElementTarget._blank}
href={documentURL}
/>
</OsdsPopoverContent>
</OsdsPopover>
);
}

return chip;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,134 @@
import { render, screen } from '@testing-library/react';
import { RegionGlobalzoneChip } from './RegionGlobalzoneChip.component';
import { vi } from 'vitest';
import {
useFeatureAvailability,
UseFeatureAvailabilityResult,
} from '@ovh-ux/manager-react-components';
import {
FEATURE_REGION_1AZ,
RegionGlobalzoneChip,
} from './RegionGlobalzoneChip.component';
import { wrapper } from '@/wrapperRenders';
import { URL_INFO } from '@/components/region-selector/constants';
import { useHas3AZ } from '@/hooks/useHas3AZ/useHas3AZ';

vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => {
const module = await importOriginal<
typeof import('@ovh-ux/manager-react-components')
>();
return { ...module, useFeatureAvailability: vi.fn() };
});

vi.mock('@/hooks/useHas3AZ/useHas3AZ');

enum ExpectedType {
GLOBAL_REGIONS = 'GLOBAL_REGIONS',
'1AZ_REGIONS' = '1AZ_REGIONS',
}

const EXPECTED_VALUES = {
[ExpectedType.GLOBAL_REGIONS]: {
label: 'pci_project_flavors_zone_global_region',
tooltip: 'pci_project_flavors_zone_globalregions_tooltip',
link: URL_INFO.GLOBAL_REGIONS.DEFAULT,
},
[ExpectedType['1AZ_REGIONS']]: {
label: 'pci_project_flavors_zone_1AZ',
tooltip: 'pci_project_flavors_zone_1AZ_with_3AZ_tooltip',
link: URL_INFO['1AZ_REGIONS'].DEFAULT,
},
};

describe('RegionGlobalzoneChip', () => {
it('renders chip with correct text', () => {
render(<RegionGlobalzoneChip />, { wrapper });
expect(
screen.getByText('pci_project_flavors_zone_global_region'),
).toBeInTheDocument();
});
it.each([
[undefined, undefined, ExpectedType.GLOBAL_REGIONS],
[undefined, false, ExpectedType.GLOBAL_REGIONS],
[undefined, true, ExpectedType['1AZ_REGIONS']],
[false, undefined, ExpectedType.GLOBAL_REGIONS],
[false, false, ExpectedType.GLOBAL_REGIONS],
[false, true, ExpectedType['1AZ_REGIONS']],
[true, undefined, ExpectedType.GLOBAL_REGIONS],
[true, false, ExpectedType.GLOBAL_REGIONS],
[true, true, ExpectedType['1AZ_REGIONS']],
])(
'should render chip with showTooltip %s show1AZ %s with correct texts and links',
(
showTooltip: boolean | undefined,
show1AZ: boolean | undefined,
expectedType,
) => {
const expected = EXPECTED_VALUES[expectedType];

vi.mocked(useFeatureAvailability).mockImplementationOnce(
(features) =>
({
data: {
...Object.fromEntries(
features.map((feature) => [feature, false]),
),
[FEATURE_REGION_1AZ]: show1AZ,
},
isLoading: false,
} as UseFeatureAvailabilityResult),
);

render(<RegionGlobalzoneChip showTooltip={showTooltip} />, { wrapper });

expect(screen.getByText(expected.label)).toBeInTheDocument();

if (showTooltip ?? true) {
expect(screen.getByText(expected.tooltip)).toBeInTheDocument();

const link = screen.getByText('pci_project_flavors_zone_tooltip_link');
expect(link).toBeInTheDocument();
expect(link).toHaveAttribute('href', expected.link);
} else {
expect(screen.queryByText(expected.tooltip)).not.toBeInTheDocument();
expect(
screen.queryByText('pci_project_flavors_zone_tooltip_link'),
).not.toBeInTheDocument();
}
},
);

it.each([
['render', true, false],
['not render', true, true],
['not render', false, true],
['not render', false, false],
])(
'should %s 3AZ tooltip text when feature availability is %s and 3AZ availability is %s',
(expected: string, show1AZ: boolean, has3AZ: boolean) => {
vi.mocked(useFeatureAvailability).mockImplementationOnce(
(features) =>
({
data: {
...Object.fromEntries(
features.map((feature) => [feature, false]),
),
[FEATURE_REGION_1AZ]: show1AZ,
},
isLoading: false,
} as UseFeatureAvailabilityResult),
);

vi.mocked(useHas3AZ).mockReturnValue(has3AZ);

render(<RegionGlobalzoneChip />, { wrapper });

if (expected === 'render') {
expect(
screen.getByText('pci_project_flavors_zone_1AZ_with_3AZ_tooltip'),
).toBeInTheDocument();
} else if (show1AZ) {
expect(
screen.queryByText('pci_project_flavors_zone_1AZ_tooltip'),
).toBeInTheDocument();
} else {
expect(
screen.queryByText('pci_project_flavors_zone_globalregions_tooltip'),
).toBeInTheDocument();
}
},
);
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import React, { useContext } from 'react';
import { Links, LinkType } from '@ovh-ux/manager-react-components';
import {
Links,
LinkType,
useFeatureAvailability,
} from '@ovh-ux/manager-react-components';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ShellContext } from '@ovh-ux/manager-react-shell-client';
import {
Expand All @@ -19,54 +23,81 @@ import {
import { OdsHTMLAnchorElementTarget } from '@ovhcloud/ods-common-core';
import { useTranslation } from 'react-i18next';
import { URL_INFO } from './constants';
import { useHas3AZ } from '../../hooks/useHas3AZ/useHas3AZ';

export const FEATURE_REGION_1AZ = 'public-cloud:region-1AZ';

export function RegionGlobalzoneChip() {
export function RegionGlobalzoneChip({
showTooltip = true,
}: Readonly<{
showTooltip?: boolean;
}>) {
const { t } = useTranslation('pci-region-selector');
const { data } = useFeatureAvailability([FEATURE_REGION_1AZ]);
const context = useContext(ShellContext);
const { ovhSubsidiary } = context.environment.getUser();
const getDocumentUrl = (linkType: string) =>
URL_INFO[linkType as keyof typeof URL_INFO][ovhSubsidiary] ||
URL_INFO[linkType as keyof typeof URL_INFO].DEFAULT;

return (
<OsdsPopover>
<span slot="popover-trigger">
<OsdsChip
const linkType = data?.[FEATURE_REGION_1AZ]
? '1AZ_REGIONS'
: 'GLOBAL_REGIONS';
const tooltipUrl =
URL_INFO[linkType][ovhSubsidiary] || URL_INFO[linkType].DEFAULT;

const has3AZ = useHas3AZ();

const chip = (
<OsdsChip
class="chip-1AZ"
size={ODS_CHIP_SIZE.sm}
onClick={(event) => event.stopPropagation()}
>
<OsdsText level={ODS_TEXT_LEVEL.body} size={ODS_TEXT_SIZE._500}>
{t(
`pci_project_flavors_zone_${
data?.[FEATURE_REGION_1AZ] ? '1AZ' : 'global_region'
}`,
)}
</OsdsText>
{showTooltip && (
<OsdsIcon
name={ODS_ICON_NAME.HELP}
size={ODS_ICON_SIZE.xs}
className="ml-2"
color={ODS_THEME_COLOR_INTENT.primary}
size={ODS_CHIP_SIZE.sm}
onClick={(event) => event.stopPropagation()}
>
/>
)}
</OsdsChip>
);

if (showTooltip) {
return (
<OsdsPopover>
<span slot="popover-trigger">{chip}</span>
<OsdsPopoverContent>
<OsdsText
color={ODS_THEME_COLOR_INTENT.primary}
color={ODS_THEME_COLOR_INTENT.text}
level={ODS_TEXT_LEVEL.body}
size={ODS_TEXT_SIZE._500}
>
{t('pci_project_flavors_zone_global_region')}
{data?.[FEATURE_REGION_1AZ] && !has3AZ
? t('pci_project_flavors_zone_1AZ_with_3AZ_tooltip')
: t(
`pci_project_flavors_zone_${
data?.[FEATURE_REGION_1AZ] ? '1AZ' : 'globalregions'
}_tooltip`,
)}
</OsdsText>
<OsdsIcon
name={ODS_ICON_NAME.HELP}
size={ODS_ICON_SIZE.xs}
className="ml-2"
color={ODS_THEME_COLOR_INTENT.primary}
&nbsp;
<Links
tab-index="-1"
label={t('pci_project_flavors_zone_tooltip_link')}
type={LinkType.external}
target={OdsHTMLAnchorElementTarget._blank}
href={tooltipUrl}
/>
</OsdsChip>
</span>
<OsdsPopoverContent>
<OsdsText
color={ODS_THEME_COLOR_INTENT.text}
level={ODS_TEXT_LEVEL.body}
>
{t('pci_project_flavors_zone_globalregions_tooltip')}
</OsdsText>
&nbsp;
<Links
tab-index="-1"
label={t('pci_project_flavors_zone_tooltip_link')}
type={LinkType.external}
target={OdsHTMLAnchorElementTarget._blank}
href={getDocumentUrl('GLOBAL_REGIONS')}
/>
</OsdsPopoverContent>
</OsdsPopover>
);
</OsdsPopoverContent>
</OsdsPopover>
);
}

return chip;
}
Loading
Loading