diff --git a/packages/manager/.changeset/pr-12821-added-1757419656849.md b/packages/manager/.changeset/pr-12821-added-1757419656849.md new file mode 100644 index 00000000000..53d2d0ee114 --- /dev/null +++ b/packages/manager/.changeset/pr-12821-added-1757419656849.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Added +--- + +Plan selection table grouping for the new NVIDIA Blackwell plans ([#12821](https://github.com/linode/manager/pull/12821)) diff --git a/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts b/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts index b125410b982..1cca8fad33d 100644 --- a/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts +++ b/packages/manager/cypress/e2e/core/linodes/plan-selection.spec.ts @@ -378,7 +378,6 @@ describe('displays specific linode plans for GPU', () => { mockAppendFeatureFlags({ gpuv2: { egressBanner: true, - planDivider: true, transferBanner: true, }, }).as('getFeatureFlags'); @@ -428,7 +427,6 @@ describe('displays specific kubernetes plans for GPU', () => { mockAppendFeatureFlags({ gpuv2: { egressBanner: true, - planDivider: true, transferBanner: true, }, }).as('getFeatureFlags'); diff --git a/packages/manager/src/featureFlags.ts b/packages/manager/src/featureFlags.ts index 9bcab347af9..faa09298da3 100644 --- a/packages/manager/src/featureFlags.ts +++ b/packages/manager/src/featureFlags.ts @@ -102,7 +102,6 @@ export interface CloudPulseResourceTypeMapFlag { interface GpuV2 { egressBanner: boolean; - planDivider: boolean; transferBanner: boolean; } @@ -161,6 +160,7 @@ export interface Flags { iam: BetaFeatureFlag; iamRbacPrimaryNavChanges: boolean; ipv6Sharing: boolean; + kubernetesBlackwellPlans: boolean; limitsEvolution: LimitsEvolution; linodeCloneFirewall: boolean; linodeDiskEncryption: boolean; diff --git a/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlanContainer.tsx b/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlanContainer.tsx index 70a72e40eed..95e03014172 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlanContainer.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlanContainer.tsx @@ -3,7 +3,6 @@ import { Hidden } from '@linode/ui'; import Grid from '@mui/material/Grid'; import * as React from 'react'; -import { useFlags } from 'src/hooks/useFlags'; import { PLAN_SELECTION_NO_REGION_SELECTED_MESSAGE } from 'src/utilities/pricing/constants'; import { KubernetesPlanSelection } from './KubernetesPlanSelection'; @@ -50,7 +49,6 @@ export const KubernetesPlanContainer = ( updatePlanCount, wholePanelIsDisabled, } = props; - const flags = useFlags(); const shouldDisplayNoRegionSelectedMessage = !selectedRegionId; /** @@ -59,9 +57,13 @@ export const KubernetesPlanContainer = ( */ const planSelectionDividers: PlanSelectionDividers[] = [ { - flag: Boolean(flags.gpuv2?.planDivider), planType: 'gpu', tables: [ + { + header: 'NVIDIA RTX PRO 6000 Blackwell Server Edition', + planFilter: (plan: PlanWithAvailability) => + plan.label.includes('Blackwell'), + }, { header: 'NVIDIA RTX 4000 Ada', planFilter: (plan: PlanWithAvailability) => @@ -70,7 +72,7 @@ export const KubernetesPlanContainer = ( { header: 'NVIDIA Quadro RTX 6000', planFilter: (plan: PlanWithAvailability) => - !plan.label.includes('Ada'), + !plan.label.includes('Ada') && !plan.label.includes('Blackwell'), }, ], }, @@ -130,8 +132,7 @@ export const KubernetesPlanContainer = ( /> ) : ( planSelectionDividers.map((planSelectionDivider) => - planType === planSelectionDivider.planType && - planSelectionDivider.flag + planType === planSelectionDivider.planType ? planSelectionDivider.tables.map((table) => { const filteredPlans = table.planFilter ? plans.filter(table.planFilter) @@ -159,8 +160,7 @@ export const KubernetesPlanContainer = ( }} > {planSelectionDividers.map((planSelectionDivider) => - planType === planSelectionDivider.planType && - planSelectionDivider.flag ? ( + planType === planSelectionDivider.planType ? ( planSelectionDivider.tables.map((table, idx) => { const filteredPlans = table.planFilter ? plans.filter(table.planFilter) diff --git a/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlansPanel.tsx b/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlansPanel.tsx index 2918b3f3abc..493d3b2b559 100644 --- a/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlansPanel.tsx +++ b/packages/manager/src/features/Kubernetes/KubernetesPlansPanel/KubernetesPlansPanel.tsx @@ -96,7 +96,9 @@ export const KubernetesPlansPanel = (props: Props) => { !type.id.includes('nanode-edge') && // Filter out GPU types for enterprise; otherwise, return the rest of the types. // TODO: remove this once GPU plans are supported in LKE-E (Q3 2025) - (selectedTier === 'enterprise' ? !type.id.includes('gpu') : true) + (selectedTier === 'enterprise' ? !type.id.includes('gpu') : true) && + // Filter out Blackwell plans for kubernetes (for now) + !(type.id.includes('blackwell') && !flags.kubernetesBlackwellPlans) ); }); diff --git a/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx b/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx index 04f7d0fc66e..edbd3a85639 100644 --- a/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlanContainer.tsx @@ -21,7 +21,6 @@ export interface PlanSelectionFilterOptionsTable { } export interface PlanSelectionDividers { - flag: boolean; planType: LinodeTypeClass; tables: PlanSelectionFilterOptionsTable[]; } @@ -87,9 +86,13 @@ export const PlanContainer = (props: PlanContainerProps) => { */ const planSelectionDividers: PlanSelectionDividers[] = [ { - flag: Boolean(flags.gpuv2?.planDivider), planType: 'gpu', tables: [ + { + header: 'NVIDIA RTX PRO 6000 Blackwell Server Edition', + planFilter: (plan: PlanWithAvailability) => + plan.label.includes('Blackwell'), + }, { header: 'NVIDIA RTX 4000 Ada', planFilter: (plan: PlanWithAvailability) => @@ -98,7 +101,7 @@ export const PlanContainer = (props: PlanContainerProps) => { { header: 'NVIDIA Quadro RTX 6000', planFilter: (plan: PlanWithAvailability) => - !plan.label.includes('Ada'), + !plan.label.includes('Ada') && !plan.label.includes('Blackwell'), }, ], }, @@ -170,8 +173,7 @@ export const PlanContainer = (props: PlanContainerProps) => { /> ) : ( planSelectionDividers.map((planSelectionDivider) => - planType === planSelectionDivider.planType && - planSelectionDivider.flag + planType === planSelectionDivider.planType ? planSelectionDivider.tables.map((table) => { const filteredPlans = table.planFilter ? plans.filter(table.planFilter) @@ -194,8 +196,7 @@ export const PlanContainer = (props: PlanContainerProps) => { {planSelectionDividers.map((planSelectionDivider) => - planType === planSelectionDivider.planType && - planSelectionDivider.flag ? ( + planType === planSelectionDivider.planType ? ( planSelectionDivider.tables.map((table, idx) => { const filteredPlans = table.planFilter ? plans.filter(table.planFilter) diff --git a/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx b/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx index 531c5d9838f..7db5f54f2d5 100644 --- a/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx +++ b/packages/manager/src/features/components/PlansPanel/PlanSelectionTable.tsx @@ -63,9 +63,10 @@ export const PlanSelectionTable = (props: PlanSelectionTableProps) => { (cellName: string) => plans?.some((plan) => { const showTooltipForGPUPlans = - flags.gpuv2?.transferBanner && - plan.class === 'gpu' && - filterOptions?.header?.includes('Ada'); + (flags.gpuv2?.transferBanner && + plan.class === 'gpu' && + filterOptions?.header?.includes('Ada')) || + filterOptions?.header?.includes('Blackwell'); return ( (showTooltipForGPUPlans || plan.class === 'accelerated') && cellName === 'Transfer'