From d006d2a90c7c9081888801a731cfe7205b38e1e0 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 13 Jul 2026 22:56:44 +0400 Subject: [PATCH] Hide unavailable low-tier build specs --- src/lib/helpers/specifications.test.ts | 61 +++++++++++++++++++ src/lib/helpers/specifications.ts | 15 +++++ .../functions/+layout.ts | 3 +- .../sites/site-[site]/settings/+page.ts | 3 +- 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/lib/helpers/specifications.test.ts create mode 100644 src/lib/helpers/specifications.ts diff --git a/src/lib/helpers/specifications.test.ts b/src/lib/helpers/specifications.test.ts new file mode 100644 index 0000000000..4fb7ba0a07 --- /dev/null +++ b/src/lib/helpers/specifications.test.ts @@ -0,0 +1,61 @@ +import { trimLeadingDisabledSpecifications } from '$lib/helpers/specifications'; +import type { Models } from '@appwrite.io/console'; +import { describe, expect, it } from 'vitest'; + +const specification = (slug: string, enabled: boolean): Models.Specification => ({ + slug, + enabled, + cpus: 1, + memory: 512 +}); + +describe('trimLeadingDisabledSpecifications', () => { + it('hides disabled specifications before the first enabled specification', () => { + const list = { + total: 4, + specifications: [ + specification('disabled-small', false), + specification('enabled-small', true), + specification('enabled-large', true), + specification('disabled-large', false) + ] + }; + + expect(trimLeadingDisabledSpecifications(list)).toEqual({ + total: 3, + specifications: list.specifications.slice(1) + }); + expect(list.specifications).toHaveLength(4); + }); + + it('keeps the list unchanged when the first specification is enabled', () => { + const list = { + total: 2, + specifications: [specification('enabled', true), specification('disabled', false)] + }; + + expect(trimLeadingDisabledSpecifications(list)).toEqual(list); + }); + + it('returns an empty list when no specification is enabled', () => { + const list = { + total: 2, + specifications: [ + specification('disabled-small', false), + specification('disabled-large', false) + ] + }; + + expect(trimLeadingDisabledSpecifications(list)).toEqual({ + total: 0, + specifications: [] + }); + }); + + it('keeps an empty list empty', () => { + expect(trimLeadingDisabledSpecifications({ total: 0, specifications: [] })).toEqual({ + total: 0, + specifications: [] + }); + }); +}); diff --git a/src/lib/helpers/specifications.ts b/src/lib/helpers/specifications.ts new file mode 100644 index 0000000000..f33914c91f --- /dev/null +++ b/src/lib/helpers/specifications.ts @@ -0,0 +1,15 @@ +import type { Models } from '@appwrite.io/console'; + +export function trimLeadingDisabledSpecifications( + list: Models.SpecificationList +): Models.SpecificationList { + const firstEnabledIndex = list.specifications.findIndex(({ enabled }) => enabled); + const specifications = + firstEnabledIndex === -1 ? [] : list.specifications.slice(firstEnabledIndex); + + return { + ...list, + total: specifications.length, + specifications + }; +} diff --git a/src/routes/(console)/project-[region]-[project]/functions/+layout.ts b/src/routes/(console)/project-[region]-[project]/functions/+layout.ts index 0d691eceb0..f2442d6bf0 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/+layout.ts +++ b/src/routes/(console)/project-[region]-[project]/functions/+layout.ts @@ -4,6 +4,7 @@ import { sdk } from '$lib/stores/sdk'; import { Query } from '@appwrite.io/console'; import { Dependencies } from '$lib/constants'; import { isCloud } from '$lib/system'; +import { trimLeadingDisabledSpecifications } from '$lib/helpers/specifications'; import type { LayoutLoad } from './$types'; export const load: LayoutLoad = async ({ depends, params }) => { @@ -32,7 +33,7 @@ export const load: LayoutLoad = async ({ depends, params }) => { breadcrumbs: Breadcrumbs, runtimesList, installations, - specificationsList: buildSpecificationsList, + specificationsList: trimLeadingDisabledSpecifications(buildSpecificationsList), runtimeSpecificationsList }; }; diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts index 74d2d64800..fb958d60a5 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/settings/+page.ts @@ -2,6 +2,7 @@ import { sdk } from '$lib/stores/sdk'; import { Dependencies, PAGE_LIMIT } from '$lib/constants'; import { isCloud } from '$lib/system'; import { Query } from '@appwrite.io/console'; +import { trimLeadingDisabledSpecifications } from '$lib/helpers/specifications'; const VARIABLES_LIMIT = 100; @@ -82,7 +83,7 @@ export const load = async ({ params, depends, parent }) => { limit, variablesOffset, installations, - buildSpecificationsList, + buildSpecificationsList: trimLeadingDisabledSpecifications(buildSpecificationsList), runtimeSpecificationsList }; };