fix(demo-ui): demoable apps launch in-frame; 'Not available in demo' label
- 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 <noreply@anthropic.com>
This commit is contained in:
parent
7d7a7d08af
commit
4135ee5f4a
@ -75,6 +75,15 @@ const DEMO_MOCK_UI: Record<string, string> = {
|
|||||||
fedimint: '/app/fedimint/',
|
fedimint: '/app/fedimint/',
|
||||||
fedimintd: '/app/fedimint/',
|
fedimintd: '/app/fedimint/',
|
||||||
filebrowser: '/app/filebrowser/',
|
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/',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -404,6 +404,7 @@ import {
|
|||||||
buildServiceCategories, useServiceCategories,
|
buildServiceCategories, useServiceCategories,
|
||||||
} from './apps/appsConfig'
|
} from './apps/appsConfig'
|
||||||
import { getCuratedAppList, INSTALLED_ALIASES, type MarketplaceApp } from './marketplace/marketplaceData'
|
import { getCuratedAppList, INSTALLED_ALIASES, type MarketplaceApp } from './marketplace/marketplaceData'
|
||||||
|
import { IS_DEMO, isDemoApp } from '@/composables/useDemoIntro'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -633,7 +634,9 @@ function launchAppNow(id: string) {
|
|||||||
}
|
}
|
||||||
return
|
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)
|
const url = resolveRuntimeLaunchUrl(pkg)
|
||||||
if (url) {
|
if (url) {
|
||||||
window.open(url, '_blank', 'noopener,noreferrer')
|
window.open(url, '_blank', 'noopener,noreferrer')
|
||||||
|
|||||||
@ -85,7 +85,7 @@
|
|||||||
<svg v-else class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg v-else class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||||
</svg>
|
</svg>
|
||||||
{{ 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') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -164,7 +164,7 @@
|
|||||||
<svg v-else class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg v-else class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||||
</svg>
|
</svg>
|
||||||
{{ 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') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -517,7 +517,7 @@ const installBlockedReason = computed(() => {
|
|||||||
return electrumxArchiveWarning
|
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))
|
const demoNoInstall = computed(() => IS_DEMO && !!app.value?.id && !isDemoApp(app.value.id))
|
||||||
|
|
||||||
let pendingRedirect: ReturnType<typeof setTimeout> | null = null
|
let pendingRedirect: ReturnType<typeof setTimeout> | null = null
|
||||||
|
|||||||
@ -121,7 +121,7 @@
|
|||||||
v-else-if="IS_DEMO && !isInstalled(app.id) && !isDemoApp(app.id)"
|
v-else-if="IS_DEMO && !isInstalled(app.id) && !isDemoApp(app.id)"
|
||||||
disabled
|
disabled
|
||||||
class="flex-1 px-4 py-2 bg-white/10 rounded-lg text-white/40 text-sm font-medium cursor-not-allowed"
|
class="flex-1 px-4 py-2 bg-white/10 rounded-lg text-white/40 text-sm font-medium cursor-not-allowed"
|
||||||
>No demo</button>
|
>Not available in demo</button>
|
||||||
<!-- Install button -->
|
<!-- Install button -->
|
||||||
<button
|
<button
|
||||||
v-else-if="!isInstalled(app.id) && (app.source === 'local' || app.dockerImage)"
|
v-else-if="!isInstalled(app.id) && (app.source === 'local' || app.dockerImage)"
|
||||||
|
|||||||
@ -78,7 +78,7 @@
|
|||||||
v-else-if="IS_DEMO && !isInstalled(app.id) && !isDemoApp(app.id)"
|
v-else-if="IS_DEMO && !isInstalled(app.id) && !isDemoApp(app.id)"
|
||||||
disabled
|
disabled
|
||||||
class="glass-button glass-button-sm rounded-lg text-sm font-medium opacity-50 cursor-not-allowed"
|
class="glass-button glass-button-sm rounded-lg text-sm font-medium opacity-50 cursor-not-allowed"
|
||||||
>No demo</button>
|
>Not available in demo</button>
|
||||||
<button
|
<button
|
||||||
v-else-if="!isInstalled(app.id) && app.dockerImage"
|
v-else-if="!isInstalled(app.id) && app.dockerImage"
|
||||||
data-controller-install-btn
|
data-controller-install-btn
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user