Fix default surface resolution for type:full packages
resolveDefaultSurface was using ListEnabledByType("surface") which
missed extension packages with type "full". Switch to List() and
filter by source != core/builtin + type surface/full.
Also make welcome surface smarter: detect when extensions exist
but no default is set vs truly empty install, show appropriate
messaging and CTA (Set Default Surface vs Go to Packages).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -129,14 +129,17 @@ func (e *Engine) resolveDefaultSurface(ctx context.Context, userID string) strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. First enabled extension surface
|
// 3. First enabled extension surface (type "surface" or "full")
|
||||||
surfaces, err := e.stores.Packages.ListEnabledByType(ctx, "surface")
|
allPkgs, err := e.stores.Packages.List(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, s := range surfaces {
|
for _, s := range allPkgs {
|
||||||
if s.Source == "core" {
|
if s.Source == "core" || s.Source == "builtin" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if s.Enabled {
|
if !s.Enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s.Type == "surface" || s.Type == "full" {
|
||||||
return "/s/" + s.ID
|
return "/s/" + s.ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* WelcomeSurface — shown when no extension surfaces are installed.
|
* WelcomeSurface — fallback landing page.
|
||||||
* Renders Topbar + a getting-started card with link to admin.
|
* Shown when no default surface is configured or no extensions are installed.
|
||||||
|
* Checks for available extension surfaces and adjusts messaging.
|
||||||
*/
|
*/
|
||||||
const { html } = window;
|
const { html } = window;
|
||||||
|
const { useState, useEffect } = hooks;
|
||||||
const { render } = preact;
|
const { render } = preact;
|
||||||
|
|
||||||
import { Topbar } from '../../shell/topbar.js';
|
import { Topbar } from '../../shell/topbar.js';
|
||||||
@@ -10,27 +12,49 @@ import { Topbar } from '../../shell/topbar.js';
|
|||||||
function WelcomeSurface() {
|
function WelcomeSurface() {
|
||||||
const BASE = window.__BASE__ || '';
|
const BASE = window.__BASE__ || '';
|
||||||
const isAdmin = sw.can?.('surface.admin.access');
|
const isAdmin = sw.can?.('surface.admin.access');
|
||||||
|
const [surfaces, setSurfaces] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
sw.api.get('/api/v1/surfaces').then(list => {
|
||||||
|
setSurfaces((list || []).filter(s => s.source !== 'core'));
|
||||||
|
}).catch(() => {});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const hasSurfaces = surfaces.length > 0;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<${Topbar} title="Switchboard" />
|
<${Topbar} title="Switchboard" />
|
||||||
<div style="flex:1;display:flex;align-items:center;justify-content:center;padding:24px;">
|
<div style="flex:1;display:flex;align-items:center;justify-content:center;padding:24px;">
|
||||||
<div style="max-width:420px;width:100%;background:var(--bg-surface);border:1px solid var(--border);border-radius:12px;padding:32px;text-align:center;">
|
<div style="max-width:420px;width:100%;background:var(--bg-surface);border:1px solid var(--border);border-radius:12px;padding:32px;text-align:center;">
|
||||||
<div style="font-size:36px;margin-bottom:16px;">📦</div>
|
<div style="font-size:36px;margin-bottom:16px;">${hasSurfaces ? '🏠' : '📦'}</div>
|
||||||
<h2 style="font-size:20px;font-weight:600;margin:0 0 8px;">Welcome to Switchboard</h2>
|
<h2 style="font-size:20px;font-weight:600;margin:0 0 8px;">Welcome to Switchboard</h2>
|
||||||
<p style="font-size:14px;color:var(--text-2);margin:0 0 24px;line-height:1.5;">
|
${hasSurfaces ? html`
|
||||||
No surfaces are installed yet. Install an extension surface
|
<p style="font-size:14px;color:var(--text-2);margin:0 0 24px;line-height:1.5;">
|
||||||
to get started.
|
No default surface is configured. Choose a surface from
|
||||||
</p>
|
the menu, or ${isAdmin ? 'set a default in admin settings.' : 'ask your administrator to set a default.'}
|
||||||
${isAdmin && html`
|
|
||||||
<a href="${BASE}/admin/packages"
|
|
||||||
style="display:inline-flex;align-items:center;gap:8px;padding:10px 24px;background:var(--accent);color:#fff;border-radius:8px;text-decoration:none;font-weight:600;font-size:14px;">
|
|
||||||
Go to Packages
|
|
||||||
</a>
|
|
||||||
`}
|
|
||||||
${!isAdmin && html`
|
|
||||||
<p style="font-size:13px;color:var(--text-3);">
|
|
||||||
Ask your administrator to install a surface package.
|
|
||||||
</p>
|
</p>
|
||||||
|
${isAdmin && html`
|
||||||
|
<a href="${BASE}/admin/settings"
|
||||||
|
style="display:inline-flex;align-items:center;gap:8px;padding:10px 24px;background:var(--accent);color:#fff;border-radius:8px;text-decoration:none;font-weight:600;font-size:14px;">
|
||||||
|
Set Default Surface
|
||||||
|
</a>
|
||||||
|
`}
|
||||||
|
` : html`
|
||||||
|
<p style="font-size:14px;color:var(--text-2);margin:0 0 24px;line-height:1.5;">
|
||||||
|
No surfaces are installed yet. Install an extension surface
|
||||||
|
to get started.
|
||||||
|
</p>
|
||||||
|
${isAdmin && html`
|
||||||
|
<a href="${BASE}/admin/packages"
|
||||||
|
style="display:inline-flex;align-items:center;gap:8px;padding:10px 24px;background:var(--accent);color:#fff;border-radius:8px;text-decoration:none;font-weight:600;font-size:14px;">
|
||||||
|
Go to Packages
|
||||||
|
</a>
|
||||||
|
`}
|
||||||
|
${!isAdmin && html`
|
||||||
|
<p style="font-size:13px;color:var(--text-3);">
|
||||||
|
Ask your administrator to install a surface package.
|
||||||
|
</p>
|
||||||
|
`}
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user