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 }) {