mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-17 12:31:20 +00:00
- Replace the two-step settings nav with a sticky accordion that tracks active sections - Restyle the settings rail with opacity-based active state and hash-aware opening - Reinitialize and clean up API example Ace editors across modal reopen cycles - Preserve modal html classes and center settings loading/error states across the full modal body
161 lines
6.5 KiB
HTML
161 lines
6.5 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">
|
|
<template x-for="item in $store.settings.navItems" :key="item.id">
|
|
<div class="settings-nav-group"
|
|
:class="{'settings-nav-group-active': $store.settings.activeTab === item.id}">
|
|
<button type="button"
|
|
class="settings-tab settings-parent-tab"
|
|
role="tab"
|
|
:aria-selected="$store.settings.activeTab === item.id"
|
|
:aria-expanded="$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-tab-meta">
|
|
<span class="settings-attention-dot"
|
|
x-show="$store.settings.navItemHasAttention(item)"
|
|
aria-hidden="true"></span>
|
|
<span class="material-symbols-outlined settings-tab-chevron"
|
|
aria-hidden="true">expand_more</span>
|
|
</span>
|
|
</button>
|
|
|
|
<div class="settings-section-list"
|
|
x-show="$store.settings.activeTab === item.id"
|
|
x-transition.opacity.duration.120ms>
|
|
<template x-for="section in item.sections" :key="section.id">
|
|
<a class="settings-section-link"
|
|
:class="{
|
|
'active': $store.settings.activeSection === section.id,
|
|
'settings-tab-attention': $store.settings.sectionItemHasAttention(section)
|
|
}"
|
|
:aria-current="$store.settings.activeSection === section.id ? 'true' : null"
|
|
:href="`#${section.id}`"
|
|
@click="$store.settings.scrollToSection(section.id, $event)">
|
|
<span class="material-symbols-outlined" aria-hidden="true" x-text="section.icon"></span>
|
|
<span class="settings-tab-label" x-text="section.label"></span>
|
|
<span class="settings-attention-dot"
|
|
x-show="$store.settings.sectionItemHasAttention(section)"
|
|
aria-hidden="true"></span>
|
|
</a>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</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;
|
|
flex: 1 1 auto;
|
|
align-items: center;
|
|
justify-content: center;
|
|
align-self: stretch;
|
|
gap: 0.75rem;
|
|
width: 100%;
|
|
min-height: 0;
|
|
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>
|