From 4135ee5f4a1e33d4c47dbcd09f6f12d2148ccc6e Mon Sep 17 00:00:00 2001 From: Dorian Date: Tue, 14 Jul 2026 03:39:56 +0100 Subject: [PATCH] fix(demo-ui): demoable apps launch in-frame; 'Not available in demo' label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Register the 8 new placeholder apps in DEMO_MOCK_UI so they're launchable and installable in the demo. - Demo bypasses the new-tab/tab-launch lists for demoable apps — they're served same-origin by the mock backend with no framing headers, so they render in the in-app session instead of opening broken localhost tabs. - Non-demoable apps now say 'Not available in demo' instead of 'No demo'. Co-Authored-By: Claude Fable 5 --- neode-ui/src/composables/useDemoIntro.ts | 9 +++++++++ neode-ui/src/views/Apps.vue | 5 ++++- neode-ui/src/views/MarketplaceAppDetails.vue | 6 +++--- neode-ui/src/views/discover/AppGrid.vue | 2 +- neode-ui/src/views/discover/FeaturedApps.vue | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/neode-ui/src/composables/useDemoIntro.ts b/neode-ui/src/composables/useDemoIntro.ts index 38fee9a4..8b683868 100644 --- a/neode-ui/src/composables/useDemoIntro.ts +++ b/neode-ui/src/composables/useDemoIntro.ts @@ -75,6 +75,15 @@ const DEMO_MOCK_UI: Record = { fedimint: '/app/fedimint/', fedimintd: '/app/fedimint/', filebrowser: '/app/filebrowser/', + // Static placeholder dashboards served by the mock backend (DEMO_APP_PAGES). + 'btcpay-server': '/app/btcpay-server/', + grafana: '/app/grafana/', + nextcloud: '/app/nextcloud/', + jellyfin: '/app/jellyfin/', + vaultwarden: '/app/vaultwarden/', + 'nostr-rs-relay': '/app/nostr-rs-relay/', + searxng: '/app/searxng/', + 'uptime-kuma': '/app/uptime-kuma/', } /** diff --git a/neode-ui/src/views/Apps.vue b/neode-ui/src/views/Apps.vue index 636dc9b3..af0884eb 100644 --- a/neode-ui/src/views/Apps.vue +++ b/neode-ui/src/views/Apps.vue @@ -404,6 +404,7 @@ import { buildServiceCategories, useServiceCategories, } from './apps/appsConfig' import { getCuratedAppList, INSTALLED_ALIASES, type MarketplaceApp } from './marketplace/marketplaceData' +import { IS_DEMO, isDemoApp } from '@/composables/useDemoIntro' const { t } = useI18n() const router = useRouter() @@ -633,7 +634,9 @@ function launchAppNow(id: string) { } return } - if (!isMobile && pkg && opensInTab(id)) { + // Demo: demoable apps are served same-origin by the mock backend, so the + // tab-launch list (real apps with framing headers) doesn't apply. + if (!isMobile && pkg && opensInTab(id) && !(IS_DEMO && isDemoApp(id))) { const url = resolveRuntimeLaunchUrl(pkg) if (url) { window.open(url, '_blank', 'noopener,noreferrer') diff --git a/neode-ui/src/views/MarketplaceAppDetails.vue b/neode-ui/src/views/MarketplaceAppDetails.vue index 373e88d9..26dcd97d 100644 --- a/neode-ui/src/views/MarketplaceAppDetails.vue +++ b/neode-ui/src/views/MarketplaceAppDetails.vue @@ -85,7 +85,7 @@ - {{ demoNoInstall ? 'No demo' : installBlockedReason ? 'Bitcoin Pruned' : installing ? t('common.installing') : t('common.install') }} + {{ demoNoInstall ? 'Not available in demo' : installBlockedReason ? 'Bitcoin Pruned' : installing ? t('common.installing') : t('common.install') }} @@ -164,7 +164,7 @@ - {{ demoNoInstall ? 'No demo' : installBlockedReason ? 'Bitcoin Pruned' : installing ? t('common.installing') : t('common.install') }} + {{ demoNoInstall ? 'Not available in demo' : installBlockedReason ? 'Bitcoin Pruned' : installing ? t('common.installing') : t('common.install') }} @@ -517,7 +517,7 @@ const installBlockedReason = computed(() => { return electrumxArchiveWarning }) -// Demo: only demoable apps can be installed; the rest show "No demo". +// Demo: only demoable apps can be installed; the rest show "Not available in demo". const demoNoInstall = computed(() => IS_DEMO && !!app.value?.id && !isDemoApp(app.value.id)) let pendingRedirect: ReturnType | null = null diff --git a/neode-ui/src/views/discover/AppGrid.vue b/neode-ui/src/views/discover/AppGrid.vue index 032c528d..e2a9ea56 100644 --- a/neode-ui/src/views/discover/AppGrid.vue +++ b/neode-ui/src/views/discover/AppGrid.vue @@ -121,7 +121,7 @@ v-else-if="IS_DEMO && !isInstalled(app.id) && !isDemoApp(app.id)" disabled class="flex-1 px-4 py-2 bg-white/10 rounded-lg text-white/40 text-sm font-medium cursor-not-allowed" - >No demo + >Not available in demo + >Not available in demo