agent-zero/webui/components/settings/settings.html
Alessandro a1c12e9247 Refine settings and remote access UX
Restyle Settings and standard modals around a streamlined left-rail layout, clearer section hierarchy, advanced settings disclosures, and stronger update states.

Add persistent update visibility with quieter once-daily update notifications, plus Remote Link and Space Agent actions in the canvas rail. Refresh the tunnel experience as a normal Remote Link modal with clearer copy, QR/mobile affordances, and safer state handling.
2026-04-27 02:48:23 +02:00

150 lines
6 KiB
HTML

<html class="settings-modal">
<head>
<title>Settings</title>
</head>
<body>
<script type="module">
import { store as settingsStore } from "/components/settings/settings-store.js";
</script>
<div x-data>
<template x-if="$store.settings">
<div x-init="$store.settings.onOpen()" x-destroy="$store.settings.cleanup()">
<!-- Loading state -->
<div x-show="$store.settings.isLoading && !$store.settings.settings" class="settings-loading">
<span class="material-symbols-outlined spinning">progress_activity</span>
<span>Loading settings...</span>
</div>
<!-- Error state -->
<div x-show="$store.settings.error && !$store.settings.settings" class="settings-error">
<span class="material-symbols-outlined">error</span>
<span x-text="$store.settings.error"></span>
<button class="btn btn-retry" @click="$store.settings.onOpen()">Retry</button>
</div>
<!-- Settings content -->
<div x-show="$store.settings.settings" class="settings-content">
<!-- Tab Navigation -->
<aside class="settings-tabs-container" aria-label="Settings categories">
<div class="settings-tabs no-scrollbar" role="tablist" aria-orientation="vertical" x-show="$store.settings.navMode === 'categories'">
<template x-for="item in $store.settings.navItems" :key="item.id">
<button type="button"
class="settings-tab"
role="tab"
:aria-selected="$store.settings.activeTab === item.id"
:class="{
'active': $store.settings.activeTab === item.id,
'settings-tab-attention': $store.settings.navItemHasAttention(item)
}"
@click="$store.settings.enterTab(item.id)">
<span class="material-symbols-outlined" aria-hidden="true" x-text="item.icon"></span>
<span class="settings-tab-label" x-text="item.label"></span>
<span class="settings-attention-dot"
x-show="$store.settings.navItemHasAttention(item)"
aria-hidden="true"></span>
</button>
</template>
</div>
<div class="settings-tabs no-scrollbar settings-section-tabs" x-show="$store.settings.navMode === 'sections'" style="display: none;">
<button type="button"
class="settings-tab settings-back-tab"
@click="$store.settings.backToCategories()">
<span class="material-symbols-outlined" aria-hidden="true">arrow_back</span>
<span class="settings-tab-label">&lt; Back</span>
</button>
<div class="settings-tabs-heading" x-text="$store.settings.activeTabItem?.label || 'Settings'"></div>
<template x-for="item in $store.settings.sectionItems" :key="item.id">
<a class="settings-tab settings-section-link"
:class="{'settings-tab-attention': $store.settings.sectionItemHasAttention(item)}"
:href="`#${item.id}`"
@click="$store.settings.scrollToSection(item.id, $event)">
<span class="material-symbols-outlined" aria-hidden="true" x-text="item.icon"></span>
<span class="settings-tab-label" x-text="item.label"></span>
<span class="settings-attention-dot"
x-show="$store.settings.sectionItemHasAttention(item)"
aria-hidden="true"></span>
</a>
</template>
</div>
</aside>
<!-- Settings sections for agent, external, developer, mcp, backup tabs -->
<main id="settings-sections" class="settings-pane">
<div class="settings-tab-panel" data-settings-tab="agent" x-show="$store.settings.activeTab === 'agent'">
<x-component path="settings/agent/agent-settings.html"></x-component>
</div>
<div class="settings-tab-panel" data-settings-tab="external" x-show="$store.settings.activeTab === 'external'">
<x-component path="settings/external/external-settings.html"></x-component>
</div>
<div class="settings-tab-panel" data-settings-tab="mcp" x-show="$store.settings.activeTab === 'mcp'">
<x-component path="settings/mcp/mcp-settings.html"></x-component>
</div>
<div class="settings-tab-panel" data-settings-tab="developer" x-show="$store.settings.activeTab === 'developer'">
<x-component path="settings/developer/developer-settings.html"></x-component>
</div>
<div class="settings-tab-panel" data-settings-tab="backup" x-show="$store.settings.activeTab === 'backup'">
<x-component path="settings/backup/backup-settings.html"></x-component>
</div>
<div class="settings-tab-panel" data-settings-tab="skills" x-show="$store.settings.activeTab === 'skills'">
<x-component path="settings/skills/skills-settings.html"></x-component>
</div>
</main>
</div>
<!-- Footer -->
<div class="modal-footer" data-modal-footer x-show="$store.settings.settings">
<button class="btn btn-ok"
@click="$store.settings.saveAndClose()"
:disabled="$store.settings?.isLoading">
Save
</button>
<button class="btn btn-cancel"
@click="$store.settings.closeSettings()">
Cancel
</button>
</div>
</div>
</template>
</div>
</body>
</html>
<style>
.settings-loading,
.settings-error {
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
padding: 2rem;
color: var(--color-text-secondary, #999);
font-size: 1rem;
}
.settings-error {
flex-direction: column;
color: var(--color-error, #e74c3c);
}
.settings-error .material-symbols-outlined {
font-size: 2rem;
}
.settings-error .btn-retry {
margin-top: 1rem;
}
.spinning {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>