From 02402251652add4654f65b68f6257dc4031138f5 Mon Sep 17 00:00:00 2001 From: D4rkst3r Date: Fri, 31 Jul 2026 18:22:35 +0200 Subject: [PATCH] Config-Suche findet einzelne Einstellungen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Seitenleisten-Suche kannte nur Bereiche: „starboard" führte zu Community, aber nicht zum Schwellwert-Feld. Bei rund 60 Einstellungen heißt das raten, in welchem Bereich etwas liegt. setting-index.js hält jetzt fest, wo jede Einstellung wohnt, mit Suchwörtern und Synonymen. Die Suche zeigt Treffer als eigene Gruppe unter den Bereichen; ein Klick wechselt den Bereich, scrollt zum Feld und hebt es kurz hervor. Enter nimmt den ersten Treffer, wobei Einstellungen Vorrang vor Bereichen haben — wer „schwellwert" tippt, will das Feld. Die Felder tragen dafür data-setting=""; das Attribut wurde skriptgesteuert ergänzt, ohne die Struktur anzufassen. Fünf Einstellungen teilen sich ein Feld mit einer anderen (etwa die beiden Markenfarben) — die zeigen über `target` auf den Nachbarn. Textfelder werden beim Sprung fokussiert, Kanal-Auswahlen bewusst nicht: deren Fokus klappt die Liste auf und verdeckt alles darunter. Co-Authored-By: Claude Fable 5 --- README.md | 10 +- frontend/src/pages/Settings.jsx | 162 ++++++++++++++++++++------------ frontend/src/setting-index.js | 103 ++++++++++++++++++++ frontend/src/style.css | 28 ++++++ 4 files changed, 241 insertions(+), 62 deletions(-) create mode 100644 frontend/src/setting-index.js diff --git a/README.md b/README.md index 116e940..e51b81c 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,14 @@ Code, die Datenbank enthält nur echte Abweichungen. | Technik | Server · System | | Zugang | API · Team | -Das Suchfeld über der Leiste findet Bereiche auch über Stichwörter — „geburtstag" -führt zu Community, „willkommen" zu Support. Enter springt zum ersten Treffer. +Das Suchfeld über der Leiste findet **Bereiche und einzelne Einstellungen**: +„geburtstag" führt zu Community, „schwellwert" direkt aufs Starboard-Feld, das +kurz hervorgehoben wird. Enter nimmt den ersten Treffer. Welche Einstellung wo +liegt, steht in [`frontend/src/setting-index.js`](frontend/src/setting-index.js). + +Sobald sich etwas vom gespeicherten Stand unterscheidet, erscheint unten eine +Leiste mit Anzahl, *Verwerfen* und *Speichern*; beim Verlassen mit offenen +Änderungen fragt der Browser nach. Der aktive Bereich steht in der Adresse (`/settings#texte`), Links und Neuladen landen also wieder dort. diff --git a/frontend/src/pages/Settings.jsx b/frontend/src/pages/Settings.jsx index dd45c37..18010c4 100644 --- a/frontend/src/pages/Settings.jsx +++ b/frontend/src/pages/Settings.jsx @@ -9,6 +9,7 @@ import { IconSearch, IconSystem as IconTune, } from '../icons.jsx'; import { moduleIcon } from '../module-icons.jsx'; +import { findSettings } from '../setting-index.js'; import { Markdown } from '../markdown.jsx'; const API_SCOPES = [ @@ -339,6 +340,27 @@ export default function Settings({ me }) { const foundTabs = query ? visibleTabs.filter((t) => `${t.label} ${t.find}`.toLowerCase().includes(query)) : visibleTabs; + // … und zusätzlich auf einzelne Einstellungen, mit Sprung aufs Feld + const foundSettings = query ? findSettings(query, canTab) : []; + + /** Bereich wechseln, zum Feld scrollen und es kurz hervorheben */ + function jumpToSetting(entry) { + setTab(entry.tab); + setTabSearch(''); + const key = entry.target ?? entry.id; + // Zwei Bilder warten, bis der neue Bereich wirklich im Dokument steht + requestAnimationFrame(() => requestAnimationFrame(() => { + const el = document.querySelector(`[data-setting="${key}"]`); + if (!el) return; + el.scrollIntoView({ behavior: 'smooth', block: 'center' }); + el.classList.add('field-found'); + setTimeout(() => el.classList.remove('field-found'), 2200); + // Nur Textfelder fokussieren: bei der Kanal-Auswahl würde der Fokus + // die Liste aufklappen und alles darunter verdecken. + const feld = el.querySelector('input, textarea'); + if (feld && !feld.closest('.picksel')) feld.focus({ preventScroll: true }); + })); + } // Tags + geplante Posts const [tags, setTags] = useState([]); const [tagDraft, setTagDraft] = useState({ name: '', content: '' }); @@ -1039,7 +1061,7 @@ export default function Settings({ me }) {
-
+
setBotName(e.target.value)} />
@@ -1047,7 +1069,7 @@ export default function Settings({ me }) {