Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Changed
---

Update Generational Plans default sort to show newest (G8) -> oldest (G6) ([#13234](https://github.com/linode/manager/pull/13234))
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
filterPlansByGpuType,
filterPlansByType,
getAvailableTypes,
getGenerationRank,
supportsTypeFiltering,
} from './planFilters';

Expand Down Expand Up @@ -240,4 +241,32 @@ describe('planFilters utilities', () => {
expect(result).toEqual(gpuPlans);
});
});

describe('getGenerationRank', () => {
it('returns higher rank for newer generations', () => {
expect(getGenerationRank('g8-dedicated-4-2')).toBeGreaterThan(
getGenerationRank('g7-dedicated-4-2')
);
expect(getGenerationRank('g7-dedicated-4-2')).toBeGreaterThan(
getGenerationRank('g6-dedicated-2')
);
});

it('handles multi-digit generations correctly', () => {
expect(getGenerationRank('g10-dedicated-2')).toBeGreaterThan(
getGenerationRank('g8-dedicated-4-2')
);
expect(getGenerationRank('g11-dedicated-2')).toBeGreaterThan(
getGenerationRank('g10-dedicated-2')
);
});

it('returns 0 for unknown generations', () => {
expect(getGenerationRank('legacy-plan')).toBe(0);
expect(getGenerationRank('gg-xyz')).toBe(0);
expect(getGenerationRank('g-pqr')).toBe(0);
expect(getGenerationRank('x123')).toBe(0);
expect(getGenerationRank('')).toBe(0);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ export const filterPlansByGeneration = (
// Type Filtering
// ============================================================================

/**
* Returns the numeric generation of a plan based on its ID.
* Higher generation number = newer plan (shown first).
*
* Example:
* - "g8-dedicated-4-2" -> 8
* - "g1-accelerated-netint-vpu" -> 1
* - "legacy-plan" -> 0
*/
export const getGenerationRank = (planId: string): number => {
const generation = planId.split('-')[0]; // eg., "g8" or "legacy"

// Safe fallback: must start with "g"
if (!generation.startsWith('g')) return 0;

const num = Number(generation.slice(1));

return Number.isFinite(num) ? num : 0;
};

/**
* Filter plans by type within a generation
*
Expand All @@ -88,9 +108,11 @@ export const filterPlansByType = (
generation: PlanFilterGeneration,
type: PlanFilterType
): PlanWithAvailability[] => {
// "All" returns all plans unchanged
// "All" returns all plans, sorted from newest to oldest generations
if (type === PLAN_FILTER_ALL) {
return plans;
return [...plans].sort(
(a, b) => getGenerationRank(b.id) - getGenerationRank(a.id)
);
}

// G7, G6, and "All" generation only have "All" option (no sub-types)
Expand Down