Skip to content

Commit f95ccd4

Browse files
fixed: [UIE-9539] Turn off generational plan features if no g7 and g8 plans are returned (#13136)
* fixed: [UIE-9539] turn off generational plan features if no g7 and g8 plans are returned * fixed: [UIE-9539] addressed review comment * fixed: [UIE-9539] updated info content in dedicated cpu tab * fixed: [UIE-9539] updated info content in dedicated cpu tab and configured it to fallback to previous message if generational plans are not there in dedicated
1 parent 02ce696 commit f95ccd4

File tree

10 files changed

+334
-25
lines changed

10 files changed

+334
-25
lines changed

packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlanContainer.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,10 @@ export const KubernetesPlanContainer = (
110110
wholePanelIsDisabled,
111111
} = props;
112112
const shouldDisplayNoRegionSelectedMessage = !selectedRegionId;
113-
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled();
113+
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
114+
plans,
115+
planType
116+
);
114117

115118
/**
116119
* This features allows us to divide the GPU plans into two separate tables.
@@ -297,6 +300,7 @@ export const KubernetesPlanContainer = (
297300
filterOptions={table}
298301
key={`k8-plan-filter-${idx}`}
299302
plans={filteredPlans}
303+
planType={planType}
300304
renderPlanSelection={renderPlanSelection}
301305
shouldDisplayNoRegionSelectedMessage={
302306
shouldDisplayNoRegionSelectedMessage
@@ -309,6 +313,7 @@ export const KubernetesPlanContainer = (
309313
<KubernetesPlanSelectionTable
310314
key={planType}
311315
plans={plans}
316+
planType={planType}
312317
renderPlanSelection={renderPlanSelection}
313318
shouldDisplayNoRegionSelectedMessage={
314319
shouldDisplayNoRegionSelectedMessage
@@ -394,6 +399,7 @@ export const KubernetesPlanContainer = (
394399
filterEmptyStateMessage={tableEmptyState?.message}
395400
key={planType ?? 'all'}
396401
plans={paginatedPlans}
402+
planType={planType}
397403
renderPlanSelection={renderPlanSelection}
398404
shouldDisplayNoRegionSelectedMessage={
399405
shouldDisplayNoRegionSelectedMessage

packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlanSelectionTable.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { TableRowEmpty } from 'src/components/TableRowEmpty/TableRowEmpty';
99
import { useIsGenerationalPlansEnabled } from 'src/utilities/linodes';
1010
import { PLAN_SELECTION_NO_REGION_SELECTED_MESSAGE } from 'src/utilities/pricing/constants';
1111

12+
import type { LinodeTypeClass } from '@linode/api-v4';
1213
import type { PlanSelectionFilterOptionsTable } from 'src/features/components/PlansPanel/PlanContainer';
1314
import type { PlanWithAvailability } from 'src/features/components/PlansPanel/types';
1415

@@ -19,6 +20,7 @@ interface KubernetesPlanSelectionTableProps {
1920
filterEmptyStateMessage?: string;
2021
filterOptions?: PlanSelectionFilterOptionsTable;
2122
plans?: PlanWithAvailability[];
23+
planType?: LinodeTypeClass;
2224
renderPlanSelection?: (plans: PlanWithAvailability[]) => React.JSX.Element[];
2325
shouldDisplayNoRegionSelectedMessage: boolean;
2426
}
@@ -40,10 +42,14 @@ export const KubernetesPlanSelectionTable = (
4042
filterEmptyStateMessage,
4143
filterOptions,
4244
plans,
45+
planType,
4346
renderPlanSelection,
4447
shouldDisplayNoRegionSelectedMessage,
4548
} = props;
46-
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled();
49+
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
50+
plans,
51+
planType
52+
);
4753

4854
// Determine spacing based on feature flag:
4955
// - If generationalPlans is enabled (pagination mode) -> spacingBottom={0}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export const KubernetesPlansPanel = (props: Props) => {
144144
isSelectedRegionEligibleForPlan={isSelectedRegionEligibleForPlan(
145145
plan
146146
)}
147+
plans={plansForThisLinodeTypeClass}
147148
planType={plan}
148149
regionsData={regionsData}
149150
/>

packages/manager/src/features/components/PlansPanel/PlanContainer.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ export const PlanContainer = (props: PlanContainerProps) => {
116116
} = props;
117117
const location = useLocation();
118118
const flags = useFlags();
119-
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled();
119+
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
120+
plans,
121+
planType
122+
);
120123

121124
// Show the Transfer column if, for any plan, the api returned data and we're not in the Database Create flow
122125
const showTransfer =

packages/manager/src/features/components/PlansPanel/PlanInformation.tsx

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as React from 'react';
33

44
import { Link } from 'src/components/Link';
55
import { useFlags } from 'src/hooks/useFlags';
6+
import { useIsGenerationalPlansEnabled } from 'src/utilities/linodes';
67

78
import { APLNotice } from './APLNotice';
89
import {
@@ -19,6 +20,7 @@ import { PlansAvailabilityNotice } from './PlansAvailabilityNotice';
1920
import { PlanNoticeTypography } from './PlansAvailabilityNotice.styles';
2021
import { planTabInfoContent } from './utils';
2122

23+
import type { PlanSelectionType } from './types';
2224
import type { Region } from '@linode/api-v4';
2325
import type { LinodeTypeClass } from '@linode/api-v4/lib/linodes';
2426
import type { Theme } from '@mui/material/styles';
@@ -37,6 +39,10 @@ export interface PlanInformationProps extends ExtendedPlanType {
3739
isAPLEnabled?: boolean;
3840
isResize?: boolean;
3941
isSelectedRegionEligibleForPlan: boolean;
42+
/**
43+
* Array of plans for this plan type class.
44+
*/
45+
plans?: PlanSelectionType[];
4046
regionsData?: Region[];
4147
}
4248

@@ -51,6 +57,7 @@ export const PlanInformation = (props: PlanInformationProps) => {
5157
isAPLEnabled,
5258
isResize,
5359
isSelectedRegionEligibleForPlan,
60+
plans,
5461
planType,
5562
regionsData,
5663
} = props;
@@ -142,10 +149,10 @@ export const PlanInformation = (props: PlanInformationProps) => {
142149
<Notice
143150
dataTestId={limitedAvailabilityBannerTestId}
144151
sx={(theme: Theme) => ({
145-
marginBottom: theme.spacing(3),
152+
marginBottom: theme.spacingFunction(24),
146153
marginLeft: 0,
147154
marginTop: 0,
148-
padding: `${theme.spacing(0.5)} ${theme.spacing(2)}`,
155+
padding: `${theme.spacingFunction(4)} ${theme.spacingFunction(16)}`,
149156
})}
150157
variant="warning"
151158
>
@@ -158,15 +165,30 @@ export const PlanInformation = (props: PlanInformationProps) => {
158165
additionalBanners.map((banner, index) => (
159166
<React.Fragment key={index}>{banner}</React.Fragment>
160167
))}
161-
<ClassDescriptionCopy planType={planType} />
168+
<ClassDescriptionCopy plans={plans} planType={planType} />
162169
</>
163170
);
164171
};
165172

166173
export const limitedAvailabilityBannerTestId = 'limited-availability-banner';
167174

168-
export const ClassDescriptionCopy = (props: ExtendedPlanType) => {
169-
const { planType } = props;
175+
interface ClassDescriptionCopyProps extends ExtendedPlanType {
176+
/**
177+
* Array of plans for this plan type class.
178+
*/
179+
plans?: PlanSelectionType[];
180+
}
181+
182+
export const ClassDescriptionCopy = (props: ClassDescriptionCopyProps) => {
183+
const { plans, planType } = props;
184+
185+
// Only check generational plans feature for dedicated plans
186+
// Other plan types don't have different legacy descriptions
187+
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
188+
plans,
189+
planType === 'dedicated' ? 'dedicated' : undefined
190+
);
191+
170192
let planTypeLabel: null | string;
171193
let docLink: null | string;
172194

@@ -200,18 +222,31 @@ export const ClassDescriptionCopy = (props: ExtendedPlanType) => {
200222
docLink = null;
201223
}
202224

225+
// Determine which typography to display
226+
let typography: string | undefined;
227+
228+
if (planType === 'dedicated') {
229+
// For dedicated plans, use typographyOld if generational plans are disabled
230+
typography = isGenerationalPlansEnabled
231+
? planTabInfoContent.dedicated?.typography
232+
: planTabInfoContent.dedicated?.typographyOld ||
233+
planTabInfoContent.dedicated?.typography;
234+
} else {
235+
// For all other plan types, just use typography
236+
typography =
237+
planTabInfoContent[planType as keyof typeof planTabInfoContent]
238+
?.typography;
239+
}
240+
203241
return planTypeLabel && docLink ? (
204242
<Typography
205243
sx={(theme: Theme) => ({
206-
marginBottom: theme.spacing(3),
207-
marginTop: theme.spacing(1),
244+
marginBottom: theme.spacingFunction(24),
245+
marginTop: theme.spacingFunction(8),
208246
})}
209247
>
210-
{
211-
planTabInfoContent[planType as keyof typeof planTabInfoContent]
212-
?.typography
213-
}{' '}
214-
<Link to={docLink}>Learn more</Link> about our {planTypeLabel} plans.
248+
{typography} <Link to={docLink}>Learn more</Link> about our{' '}
249+
{planTypeLabel} plans.
215250
</Typography>
216251
) : null;
217252
};

packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ export const PlanSelectionTable = (props: PlanSelectionTableProps) => {
5959
showUsableStorage,
6060
} = props;
6161
const flags = useFlags();
62-
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled();
62+
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
63+
plans,
64+
planType
65+
);
6366

6467
// Determine spacing based on feature flag:
6568
// - If generationalPlans is enabled (pagination mode) -> spacingBottom={0}

packages/manager/src/features/components/PlansPanel/PlansPanel.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export const PlansPanel = (props: PlansPanelProps) => {
209209
isSelectedRegionEligibleForPlan={isSelectedRegionEligibleForPlan(
210210
plan
211211
)}
212+
plans={plansForThisLinodeTypeClass}
212213
planType={plan}
213214
regionsData={regionsData || []}
214215
/>

packages/manager/src/features/components/PlansPanel/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ export const planTabInfoContent = {
237237
key: 'dedicated',
238238
title: 'Dedicated CPU',
239239
typography:
240+
'Dedicated CPU instances are built for full-duty workloads needing consistent performance. Choose from different hardware generations — newer plans feature the latest hardware. Select Compute Optimized (1:2) for CPU-heavy tasks or General Purpose (1:4) for balanced workloads.',
241+
typographyOld:
240242
'Dedicated CPU instances are good for full-duty workloads where consistent performance is important.',
241243
},
242244
gpu: {
@@ -504,7 +506,7 @@ export const useShouldDisablePremiumPlansTab = ({
504506
types: LinodeType[] | PlanSelectionType[] | undefined;
505507
}): boolean => {
506508
const { isGenerationalPlansEnabled, allowedPlans } =
507-
useIsGenerationalPlansEnabled();
509+
useIsGenerationalPlansEnabled(types, 'premium');
508510
// Check if any public premium plans are available.
509511
// We can omit "Premium HT" and "Premium nested" plans as customers don't deploy them using cloud manager.
510512
const arePublicPremiumPlansAvailable = types?.some(

0 commit comments

Comments
 (0)