From 2d2a56301994be455e5f74cc6d3f66e81091ccff Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 31 Mar 2026 15:36:24 +1300 Subject: [PATCH] (fix): gate dedicated database features behind isCloud - Filter dedicateddb from databaseTypes for self-hosted instances - Hide dedicated DB cards in empty state when not cloud - Default create wizard to tablesdb for self-hosted - Disable dedicated-only header tabs for self-hosted - Fix null as DatabaseType cast and selectedEngine typing --- .../databases/create/+page.svelte | 38 ++++++++++--------- .../database-[database]/header.svelte | 6 +-- .../databases/empty.svelte | 17 +++++---- .../databases/store.ts | 8 +++- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte index f776ffb54..cdd618332 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte @@ -8,7 +8,7 @@ import { CustomId } from '$lib/components'; import { page } from '$app/state'; import { addNotification } from '$lib/stores/notifications'; - import { BackupServices, ID, type Models } from '@appwrite.io/console'; + import { BackupServices, Engine, ID, type Models } from '@appwrite.io/console'; import { type DatabaseType, type DedicatedDatabaseParams, @@ -40,7 +40,7 @@ let formComponent: Form; const params = page.url.searchParams; - const typeFromParams = params.get('type') ?? (null as DatabaseType); + const typeFromParams: DatabaseType | null = params.get('type') as DatabaseType | null; let showCreatePolicies = $state(false); let totalPolicies: UserBackupPolicy[] = $state([]); @@ -48,7 +48,7 @@ let showExitModal = $state(false); let isSubmitting = $state(writable(false)); let previousPage: string = $state(resolveRoute('/')); - let type = $state(typeFromParams ?? 'dedicateddb') as DatabaseType; + let type = $state(typeFromParams ?? (isCloud ? 'dedicateddb' : 'tablesdb')) as DatabaseType; const isDark = $derived($app.themeInUse === 'dark'); const backupsImg = $derived(isDark ? EmptyDarkMobile : EmptyLightMobile); @@ -81,7 +81,7 @@ })); // State for dedicated options (pre-populated from URL params) - let selectedEngine = $state(params.get('engine') ?? 'postgres'); + let selectedEngine = $state((params.get('engine') as Engine) ?? Engine.Postgres); let selectedRegion = $state(params.get('region') ?? null); let selectedTier = $state(params.get('tier') ?? 'free'); @@ -526,21 +526,23 @@ {/snippet} {#snippet selectDatabaseType(disabled = false)} - + {#each databaseTypes as databaseType} -
- - {databaseType.subtitle} - -
+ {#if databaseType.type !== 'dedicateddb' || isCloud} +
+ + {databaseType.subtitle} + +
+ {/if} {/each}
{/snippet} diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte index 11aabbd5d..ed66868e6 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte @@ -6,6 +6,7 @@ import { canWriteDatabases } from '$lib/stores/roles'; import { resolveRoute, withPath } from '$lib/stores/navigation'; import { useTerminology, type DatabaseType } from '$database/(entity)'; + import { isCloud } from '$lib/system'; import { isSmallViewport } from '$lib/stores/viewport'; const terminology = useTerminology(page); @@ -20,7 +21,6 @@ page.params ); - // Check if this is a dedicated database type const isDedicatedType = $derived((database?.type as DatabaseType) === 'dedicateddb'); const tabs = $derived( @@ -41,13 +41,13 @@ href: withPath(baseDatabasePath, '/auth'), title: 'Auth', event: 'auth', - disabled: !isDedicatedType + disabled: !isDedicatedType || !isCloud }, { href: withPath(baseDatabasePath, '/monitoring'), title: 'Monitoring', event: 'monitoring', - disabled: !isDedicatedType + disabled: !isDedicatedType || !isCloud }, { href: withPath(baseDatabasePath, '/usage'), diff --git a/src/routes/(console)/project-[region]-[project]/databases/empty.svelte b/src/routes/(console)/project-[region]-[project]/databases/empty.svelte index e95475bef..f60e9bdba 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/empty.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/empty.svelte @@ -17,6 +17,7 @@ import DedicatedDB from './(assets)/dedicated-db.svg'; import DedicatedDBDark from './(assets)/dark/dedicated-db.svg'; + import { isCloud } from '$lib/system'; import { isSmallViewport } from '$lib/stores/viewport'; import type { DatabaseType } from '$database/(entity)'; import { databaseTypes } from './store'; @@ -56,14 +57,16 @@ >Store, organize, and manage your app data - + {#each databaseTypes as db} - {@render databaseTypeCard({ - type: db.type, - title: db.title, - subtitle: db.subtitle, - image: images[db.type] - })} + {#if db.type !== 'dedicateddb' || isCloud} + {@render databaseTypeCard({ + type: db.type, + title: db.title, + subtitle: db.subtitle, + image: images[db.type] + })} + {/if} {/each} diff --git a/src/routes/(console)/project-[region]-[project]/databases/store.ts b/src/routes/(console)/project-[region]-[project]/databases/store.ts index 643c1931c..bf4658f4c 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/store.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/store.ts @@ -23,16 +23,18 @@ export const columns = writable( ] ); -export const databaseTypes: Array<{ +const allDatabaseTypes: Array<{ type: DatabaseType; title: string; subtitle: string; + cloudOnly?: boolean; }> = [ { type: 'dedicateddb', title: 'DedicatedDB', subtitle: - 'Always-on dedicated instances with high availability. Best for production workloads.' + 'Always-on dedicated instances with high availability. Best for production workloads.', + cloudOnly: true }, { type: 'tablesdb', @@ -54,6 +56,8 @@ export const databaseTypes: Array<{ } ]; +export const databaseTypes = allDatabaseTypes.filter((db) => !db.cloudOnly || isCloud); + export function getDatabaseTypeTitle(database: Models.Database & { engine?: string }) { switch (database.type as DatabaseType) { case 'dedicateddb': {