Settings: badge tab on unsaved changes, align toolbar to content width (#128)
* feat(settings): badge Settings tab while unsaved changes exist, align toolbar to content width (closes #125) * refactor(settings): drop toolbar wrapper div and dead sticky rule, remove comment noise (PR #128 review) * docs(settings): document unsaved-changes tab badge, recapture app-settings screenshots for new toolbar layout * docs(settings): recapture app-settings screenshots against a ready app, sidebar closed, default config (PR #128 review)
@@ -15,6 +15,7 @@
|
||||
- "Scene Browser Landing Page: The home screen was rebuilt into a full-page landing view, replacing the sidebar load panel. A file-tree Scene Library lists scene projects with cover thumbnails, save counts and per-save metadata, plus an asset and node-module summary row per expanded project; long save lists collapse behind a 'Show all' row and the list is filterable with click-to-load. Individual scene files and character cards can be deleted from the tree, and an entire scene project (saves, assets, nodes, history) can be deleted behind a type-the-project-name confirmation. Character cards display their card image and only actual card files are listed. Scene and character card import moved to a prominent drag-and-drop dropzone next to a Create-new-scene card, with the quick-load recent scene cards kept on top."
|
||||
improvements:
|
||||
- "Application Settings Redesign: The application settings moved out of their cramped modal into the main view as an always-available Settings tab, matching the World Editor and Templates. The nested tabs-within-tabs layout is replaced by a single sidebar navigation grouped by topic (Game, Appearance, Connections, Presets, Storytelling), with a settings search that finds any setting by name — including individual API-key providers — and jumps straight to it, highlighting the target. All API keys now live on one scrollable page instead of ten separate per-provider pages. Edits are tracked against the stored configuration: an Unsaved-changes indicator with Save and Discard appears in the toolbar, unsaved edits survive switching to other tabs, and configuration changed elsewhere (another window, the help agent) while you are editing is flagged instead of silently overwriting or being overwritten. Existing deep links — for example the 'Set API key' action on a misconfigured client — land on the correct page as before."
|
||||
- "Application Settings: The Settings tab in the top navigation now shows a warning badge with a tooltip while there are unsaved changes, so the state stays visible after switching away. The settings toolbar is also capped to the content width and groups Save / Discard next to the page title on the left instead of the far viewport edge."
|
||||
- "Help Agent: The documentation index is no longer embedded in the chat prompt - the prompt now carries only a compact section overview (~15k fewer tokens per message), and a new find_docs lookup locates the right documentation pages on demand, so the help chat works with small context windows typical of local models."
|
||||
- "Uniform Settings Framework: Agent settings and client settings now share one field-definition schema on the backend and one field renderer on the frontend. Client-specific settings gain the full widget set previously exclusive to agents (sliders, autocompletes, selects with rich choices, per-value notes) plus conditional visibility, and choice lists are delivered to the frontend in a single normalized shape."
|
||||
- "MistralAI Client: Added a Concurrent Inference toggle so batch operations can dispatch multiple requests in parallel. Off by default."
|
||||
|
||||
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 77 KiB |
BIN
docs/img/0.39.0/app-settings-unsaved-badge.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
@@ -2,7 +2,9 @@
|
||||
|
||||
Application settings open in the main view via the **:material-cog: Settings** tab in the top navigation (or the cogwheel icon on the right side of the top bar). Navigation lives in the left sidebar, grouped by topic, with a **search field** at the top that finds any setting by name and jumps straight to it.
|
||||
|
||||
Changes are collected as you edit — an **Unsaved changes** indicator with **Save** and **Discard** actions appears in the toolbar whenever your edits differ from the stored configuration. Nothing is applied until you save.
|
||||
Changes are collected as you edit — an **Unsaved changes** indicator with **Save** and **Discard** actions appears in the toolbar whenever your edits differ from the stored configuration. Nothing is applied until you save. While you have unsaved changes, the **Settings** tab in the top navigation also shows a warning badge, so the state stays visible even after you switch to another tab.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
<v-card variant="text" v-if="app_config !== null">
|
||||
<v-toolbar rounded="md" density="compact" color="grey-darken-4" class="pl-2 mb-1 app-settings-toolbar">
|
||||
<v-icon class="mr-2" color="primary">{{ currentPage?.icon || 'mdi-cog' }}</v-icon>
|
||||
<span class="text-subtitle-2">{{ currentPage?.group }} <span class="text-muted">/</span> {{ currentPage?.title }}</span>
|
||||
<v-spacer></v-spacer>
|
||||
<span class="text-subtitle-2 mr-4">{{ currentPage?.group }} <span class="text-muted">/</span> {{ currentPage?.title }}</span>
|
||||
<v-btn color="primary" variant="text" prepend-icon="mdi-check-circle-outline" :disabled="!dirty || embeddingsBusy" @click="saveConfig">Save</v-btn>
|
||||
<v-btn v-if="dirty" color="muted" variant="text" prepend-icon="mdi-undo" @click="discard">Discard</v-btn>
|
||||
<span v-if="dirty" class="text-muted text-caption mr-2">Unsaved changes.</span>
|
||||
<v-chip v-if="externalChange" size="small" label color="warning" variant="text" prepend-icon="mdi-alert-circle-outline" class="mr-2">
|
||||
Changed outside this view — saving overwrites
|
||||
<v-tooltip activator="parent" location="bottom" max-width="400">The configuration was changed elsewhere (another window or the help agent) while you have unsaved edits here. Discard to load the latest, or save to overwrite.</v-tooltip>
|
||||
</v-chip>
|
||||
<span v-if="dirty" class="text-muted text-caption mr-2">Unsaved changes.</span>
|
||||
<v-btn v-if="dirty" color="muted" variant="text" prepend-icon="mdi-undo" @click="discard">Discard</v-btn>
|
||||
<v-btn color="primary" variant="text" prepend-icon="mdi-check-circle-outline" :disabled="!dirty || embeddingsBusy" @click="saveConfig">Save</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
</v-toolbar>
|
||||
|
||||
<!-- surface-colored canvas: the reused editors were designed against the
|
||||
@@ -134,6 +134,7 @@ export default {
|
||||
'appearance-preview',
|
||||
'appearance-preview-clear',
|
||||
'page-changed',
|
||||
'dirty-changed',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
@@ -167,6 +168,9 @@ export default {
|
||||
page(newPage) {
|
||||
this.$emit('page-changed', newPage);
|
||||
},
|
||||
dirty(isDirty) {
|
||||
this.$emit('dirty-changed', isDirty);
|
||||
},
|
||||
visible(isVisible) {
|
||||
if (!isVisible) {
|
||||
// leaving the settings tab — the scene should show the saved
|
||||
@@ -373,12 +377,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-settings-toolbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.app-settings-toolbar,
|
||||
.app-settings-content {
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,10 @@
|
||||
<v-tab v-for="tab in availableTabs" :key="tab" :value="tab.value" @click.stop="tab.click">
|
||||
<v-icon class="mr-1">{{ tab.icon() }}</v-icon>
|
||||
{{ tab.title() }}
|
||||
<v-icon v-if="tab.alert && tab.alert()" size="x-small" color="warning" class="ml-1">mdi-alert</v-icon>
|
||||
<span v-if="tab.alert && tab.alert()" class="ml-1 d-inline-flex">
|
||||
<v-tooltip v-if="tab.alertTooltip" activator="parent" location="top">{{ tab.alertTooltip() }}</v-tooltip>
|
||||
<v-icon size="x-small" color="warning">mdi-alert</v-icon>
|
||||
</span>
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
@@ -372,7 +375,8 @@
|
||||
:visible="tab === 'settings'"
|
||||
@appearance-preview="onAppearancePreview"
|
||||
@appearance-preview-clear="onAppearancePreviewClear"
|
||||
@page-changed="(page) => appSettingsPage = page" />
|
||||
@page-changed="(page) => appSettingsPage = page"
|
||||
@dirty-changed="(dirty) => appSettingsDirty = dirty" />
|
||||
</v-tabs-window-item>
|
||||
|
||||
</v-tabs-window>
|
||||
@@ -574,6 +578,8 @@ export default {
|
||||
title: () => { return 'Settings' },
|
||||
condition: () => { return true },
|
||||
icon: () => { return 'mdi-cog' },
|
||||
alert: () => { return this.appSettingsDirty },
|
||||
alertTooltip: () => { return 'You have unsaved changes in Settings' },
|
||||
click: () => {
|
||||
// Settings tab clicked
|
||||
},
|
||||
@@ -654,6 +660,7 @@ export default {
|
||||
promptsMainTab: 'prompts',
|
||||
// Synced page state between AppSettingsMenu and AppSettings
|
||||
appSettingsPage: 'gameplay',
|
||||
appSettingsDirty: false,
|
||||
// Count of outdated prompt template overrides
|
||||
promptsOutdatedCount: 0,
|
||||
// Flag to ensure new-scene navigation only happens once per scene load
|
||||
|
||||