Skip to content

Commit 9d5672c

Browse files
authored
upcoming: [M3-9495] - Disable APL for LKE-E clusters (#11809)
* Show the APL section only for standard cluster tiers * Added changeset: Disable APL for LKE-E clusters on create flow * WIP - poc for what disabled, rather than hidden, section would look like * Update with proposed UX changes * Update test coverage with mocked endpoints, UX changes * Tweak changeset * Update chip text size to small for consistency with other chips * Fix bug preventing 'no' button from being checked
1 parent ecee4bc commit 9d5672c

5 files changed

Lines changed: 121 additions & 6 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Upcoming Features
3+
---
4+
5+
Disable Akamai App Plaform beta for LKE-E clusters on create flow ([#11809](https://github.com/linode/manager/pull/11809))

packages/manager/cypress/e2e/core/kubernetes/lke-create.spec.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import { randomItem, randomLabel, randomNumber } from 'support/util/random';
4141
import { getRegionById } from 'support/util/regions';
4242
import { chooseRegion } from 'support/util/regions';
4343

44-
import { lkeEnterpriseTypeFactory } from 'src/factories';
44+
import { accountBetaFactory, lkeEnterpriseTypeFactory } from 'src/factories';
4545
import {
4646
accountFactory,
4747
dedicatedTypeFactory,
@@ -459,6 +459,7 @@ describe('LKE Cluster Creation with APL enabled', () => {
459459
ui.regionSelect.find().click().type(`${clusterRegion.label}{enter}`);
460460

461461
cy.findByTestId('apl-label').should('have.text', 'Akamai App Platform');
462+
cy.findByTestId('apl-beta-chip').should('have.text', 'BETA');
462463
cy.findByTestId('apl-radio-button-yes').should('be.visible').click();
463464
cy.findByTestId('ha-radio-button-yes').should('be.disabled');
464465
cy.get(
@@ -1087,6 +1088,7 @@ describe('LKE Cluster Creation with LKE-E', () => {
10871088
* - Confirms that HA is enabled by default with LKE-E selection
10881089
* - Confirms an LKE-E supported region can be selected
10891090
* - Confirms an LKE-E supported k8 version can be selected
1091+
* - Confirms the APL section is disabled while it remains unsupported
10901092
* - Confirms at least one IP must be provided for ACL
10911093
* - Confirms the checkout bar displays the correct LKE-E info
10921094
* - Confirms an enterprise cluster can be created with the correct chip, version, and price
@@ -1102,6 +1104,12 @@ describe('LKE Cluster Creation with LKE-E', () => {
11021104
});
11031105
const mockedEnterpriseClusterPools = [nanodeMemoryPool, dedicatedCpuPool];
11041106

1107+
mockGetAccountBeta(
1108+
accountBetaFactory.build({
1109+
id: 'apl',
1110+
label: 'Akamai App Platform Beta',
1111+
})
1112+
).as('getAccountBeta');
11051113
mockGetAccount(
11061114
accountFactory.build({
11071115
capabilities: [
@@ -1216,6 +1224,17 @@ describe('LKE Cluster Creation with LKE-E', () => {
12161224
.should('be.enabled')
12171225
.click();
12181226

1227+
// Confirm the APL section is disabled and unsupported.
1228+
cy.findByTestId('apl-label').should('be.visible');
1229+
cy.findByTestId('apl-beta-chip').should(
1230+
'have.text',
1231+
'BETA - COMING SOON'
1232+
);
1233+
cy.findByTestId('apl-radio-button-yes').should('be.disabled');
1234+
cy.findByTestId('apl-radio-button-no').within(() => {
1235+
cy.findByRole('radio').should('be.disabled').should('be.checked');
1236+
});
1237+
12191238
// Confirm the expected available plans display.
12201239
validEnterprisePlanTabs.forEach((tab) => {
12211240
ui.tabList.findTabByTitle(tab).should('be.visible');
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import userEvent from '@testing-library/user-event';
2+
import React from 'react';
3+
4+
import { renderWithTheme } from 'src/utilities/testHelpers';
5+
6+
import { ApplicationPlatform } from './ApplicationPlatform';
7+
8+
const MockDefaultProps = {
9+
isSectionDisabled: false,
10+
setAPL: vi.fn(),
11+
setHighAvailability: vi.fn(),
12+
};
13+
14+
describe('ApplicationPlatform', () => {
15+
it('renders enabled but unchecked radio buttons with the section enabled', () => {
16+
const { getByRole } = renderWithTheme(
17+
<ApplicationPlatform {...MockDefaultProps} />
18+
);
19+
const yesRadio = getByRole('radio', { name: /yes/i });
20+
const noRadio = getByRole('radio', { name: /no/i });
21+
22+
expect(yesRadio).toBeEnabled();
23+
expect(yesRadio).not.toBeChecked();
24+
expect(noRadio).toBeEnabled();
25+
expect(noRadio).not.toBeChecked();
26+
});
27+
28+
it('toggles checked state correctly with the section enabled', async () => {
29+
const { getByRole } = renderWithTheme(
30+
<ApplicationPlatform {...MockDefaultProps} />
31+
);
32+
const yesRadio = getByRole('radio', { name: /yes/i });
33+
const noRadio = getByRole('radio', { name: /no/i });
34+
35+
// Confirm both buttons can be clicked.
36+
await userEvent.click(yesRadio);
37+
expect(yesRadio).toBeChecked();
38+
expect(noRadio).not.toBeChecked();
39+
40+
await userEvent.click(noRadio);
41+
expect(noRadio).toBeChecked();
42+
expect(yesRadio).not.toBeChecked();
43+
});
44+
45+
it('renders disabled radio buttons and the "no" option checked with the section disabled', () => {
46+
const { getByRole } = renderWithTheme(
47+
<ApplicationPlatform {...MockDefaultProps} isSectionDisabled />
48+
);
49+
const yesRadio = getByRole('radio', { name: /yes/i });
50+
const noRadio = getByRole('radio', { name: /no/i });
51+
52+
expect(yesRadio).toBeDisabled();
53+
expect(yesRadio).not.toBeChecked();
54+
expect(noRadio).toBeDisabled();
55+
expect(noRadio).toBeChecked();
56+
});
57+
});

packages/manager/src/features/Kubernetes/CreateCluster/ApplicationPlatform.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { FormLabel } from 'src/components/FormLabel';
1313
import { Link } from 'src/components/Link';
1414

1515
export interface APLProps {
16+
isSectionDisabled: boolean;
1617
setAPL: (apl: boolean) => void;
1718
setHighAvailability: (ha: boolean | undefined) => void;
1819
}
@@ -27,8 +28,27 @@ export const APLCopy = () => (
2728
</Typography>
2829
);
2930

31+
const APL_UNSUPPORTED_CHIP_COPY = ' - COMING SOON';
32+
3033
export const ApplicationPlatform = (props: APLProps) => {
31-
const { setAPL, setHighAvailability } = props;
34+
const { isSectionDisabled, setAPL, setHighAvailability } = props;
35+
36+
const [isAPLChecked, setIsAPLChecked] = React.useState<boolean | undefined>(
37+
isSectionDisabled ? false : undefined
38+
);
39+
const [isAPLNotChecked, setIsAPLNotChecked] = React.useState<
40+
boolean | undefined
41+
>(isSectionDisabled ? true : undefined);
42+
43+
/**
44+
* Reset the radio buttons to the correct default state once the user toggles cluster tiers.
45+
*/
46+
React.useEffect(() => {
47+
setIsAPLChecked(isSectionDisabled ? false : undefined);
48+
setIsAPLNotChecked(isSectionDisabled ? true : undefined);
49+
}, [isSectionDisabled]);
50+
51+
const CHIP_COPY = `BETA${isSectionDisabled ? APL_UNSUPPORTED_CHIP_COPY : ''}`;
3252

3353
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
3454
setAPL(e.target.value === 'yes');
@@ -49,22 +69,32 @@ export const ApplicationPlatform = (props: APLProps) => {
4969
>
5070
<Box alignItems="center" display="flex" flexDirection="row">
5171
<Typography data-testid="apl-label">Akamai App Platform</Typography>
52-
<Chip color="primary" label="BETA" sx={{ ml: 1 }} />
72+
<Chip
73+
color="primary"
74+
data-testid="apl-beta-chip"
75+
label={CHIP_COPY}
76+
size="small"
77+
sx={{ ml: 1 }}
78+
/>
5379
</Box>
5480
</FormLabel>
5581
<APLCopy />
5682
<RadioGroup onChange={(e) => handleChange(e)}>
5783
<FormControlLabel
5884
control={<Radio data-testid="apl-radio-button-yes" />}
59-
label={<Typography>Yes, enable Akamai App Platform.</Typography>}
85+
disabled={isSectionDisabled}
86+
label="Yes, enable Akamai App Platform."
6087
name="yes"
6188
value="yes"
89+
checked={isAPLChecked}
6290
/>
6391
<FormControlLabel
6492
control={<Radio data-testid="apl-radio-button-no" />}
93+
disabled={isSectionDisabled}
6594
label="No"
6695
name="no"
6796
value="no"
97+
checked={isAPLNotChecked}
6898
/>
6999
</RadioGroup>
70100
</FormControl>

packages/manager/src/features/Kubernetes/CreateCluster/CreateCluster.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ export const CreateCluster = () => {
115115
isLoading: isLoadingKubernetesTypes,
116116
} = useKubernetesTypesQuery(selectedTier === 'enterprise');
117117

118+
// LKE-E does not support APL at this time.
119+
const isAPLSupported = showAPL && selectedTier === 'standard';
120+
118121
const handleClusterTierSelection = (tier: KubernetesTier) => {
119122
setSelectedTier(tier);
120123

@@ -242,7 +245,7 @@ export const CreateCluster = () => {
242245
region: selectedRegion?.id,
243246
};
244247

245-
if (showAPL) {
248+
if (isAPLSupported) {
246249
payload = { ...payload, apl_enabled };
247250
}
248251

@@ -251,7 +254,7 @@ export const CreateCluster = () => {
251254
}
252255

253256
const createClusterFn =
254-
showAPL || isLkeEnterpriseLAFeatureEnabled
257+
isAPLSupported || isLkeEnterpriseLAFeatureEnabled
255258
? createKubernetesClusterBeta
256259
: createKubernetesCluster;
257260

@@ -453,6 +456,7 @@ export const CreateCluster = () => {
453456
<StyledStackWithTabletBreakpoint>
454457
<Stack>
455458
<ApplicationPlatform
459+
isSectionDisabled={!isAPLSupported}
456460
setAPL={setApl_enabled}
457461
setHighAvailability={setHighAvailability}
458462
/>

0 commit comments

Comments
 (0)