feat(web): add windowed Settings app, separate from initial Config screen
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled

The taskbar's gear icon reopened the full-page "Connect to Oikos" screen
even once already connected. Split that: Config.svelte stays as the
first-run/unconfigured screen; a new Settings app (windowed, like Tasks or
Operations) now handles in-session changes, with a section list (Connection,
Appearance) built to grow — future settings are one more entry, not a new
screen.

- pages/Settings.svelte: Connection (server URL/token/Authentik, reusing
  config.ts + oidc.ts) and Appearance (Terracotta/Carbon picker) sections.
- apps.ts: registered as a normal desktop app.
- Taskbar's gear button now opens the Settings window; removed the
  onOpenConnection prop threaded through App -> Desktop -> Taskbar, since
  Settings' "Forget saved connection" (clear config + reload) replaces it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 11:00:57 +02:00
parent 58a11ca872
commit aee458ce83
5 changed files with 210 additions and 9 deletions

View File

@@ -15,12 +15,14 @@ import Ops from '../pages/Ops.svelte'
import Signals from '../pages/Signals.svelte'
import Knowledge from '../pages/Knowledge.svelte'
import Learning from '../pages/Learning.svelte'
import Settings from '../pages/Settings.svelte'
import ListTodoIcon from '@lucide/svelte/icons/list-todo'
import DatabaseIcon from '@lucide/svelte/icons/database'
import ShieldCheckIcon from '@lucide/svelte/icons/shield-check'
import SirenIcon from '@lucide/svelte/icons/siren'
import SearchIcon from '@lucide/svelte/icons/search'
import TrendingUpIcon from '@lucide/svelte/icons/trending-up'
import SettingsIcon from '@lucide/svelte/icons/settings'
export interface AppDef {
id: string
@@ -99,6 +101,16 @@ export const APPS: AppDef[] = [
height: 600,
minWidth: 440,
minHeight: 340
},
{
id: 'settings',
title: 'Settings',
icon: SettingsIcon,
component: Settings,
width: 640,
height: 480,
minWidth: 480,
minHeight: 360
}
]

View File

@@ -21,8 +21,6 @@
import Undo2Icon from '@lucide/svelte/icons/undo-2'
import Redo2Icon from '@lucide/svelte/icons/redo-2'
let { onOpenConnection }: { onOpenConnection: () => void } = $props()
// Clicking the bare desktop (not an icon, not a window) blurs the focused
// window — the familiar "click empty desktop to deselect" affordance.
function onSurfaceClick(e: MouseEvent) {
@@ -104,7 +102,7 @@
<WindowLayer />
</div>
<Taskbar {onOpenConnection} />
<Taskbar />
</div>
{#if menuPos}

View File

@@ -6,7 +6,7 @@
// to the old MinimizedWindowsBar, which only ever showed minimized windows
// and gave no way to see/switch between windows that were merely
// unfocused), plus a system tray for theme/connection/version.
import { wm, wmState, toggleShowDesktop } from '$lib/stores/windows'
import { wm, wmState, toggleShowDesktop, openAppWindow } from '$lib/stores/windows'
import { appById, appIdFromWindowId } from '$lib/apps'
import { summary } from '$lib/stores/context'
import { truncateMiddle } from '$lib/utils'
@@ -19,8 +19,6 @@
import LayoutGridIcon from '@lucide/svelte/icons/layout-grid'
import XIcon from '@lucide/svelte/icons/x'
let { onOpenConnection }: { onOpenConnection: () => void } = $props()
const SESSION_PREFIX = 'session:'
const buttons = $derived(
@@ -121,8 +119,8 @@
<button
type="button"
class="flex items-center justify-center rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground"
onclick={onOpenConnection}
title="Server connection settings"
onclick={() => openAppWindow('settings')}
title="Settings"
>
<SettingsIcon class="size-4" />
</button>