diff --git a/frontend/src/pages/Settings.jsx b/frontend/src/pages/Settings.jsx index a2eb56e..37d782a 100644 --- a/frontend/src/pages/Settings.jsx +++ b/frontend/src/pages/Settings.jsx @@ -9,7 +9,7 @@ import { IconSearch, IconSystem as IconTune, } from '../icons.jsx'; import { moduleIcon } from '../module-icons.jsx'; -import { findSettings } from '../setting-index.js'; +import { findSettings, SETTING_INDEX } from '../setting-index.js'; import { Markdown } from '../markdown.jsx'; const API_SCOPES = [ @@ -348,6 +348,16 @@ export default function Settings({ me }) { // … und zusätzlich auf einzelne Einstellungen, mit Sprung aufs Feld const foundSettings = query ? findSettings(query, canTab) : []; + /** + * Zum Feld einer Einstellung springen — der Bereich kommt aus dem Register, + * damit „Einrichten" nicht im falschen Tab landet (das Gitea-Token steht + * z. B. bei Brand, nicht bei System). + */ + function jumpToMissing(fehlt, fallbackTab) { + const bekannt = SETTING_INDEX.find((s) => s.id === fehlt.setting); + jumpToSetting(bekannt ?? { id: fehlt.setting, tab: fallbackTab }); + } + /** Bereich wechseln, zum Feld scrollen und es kurz hervorheben */ function jumpToSetting(entry) { setTab(entry.tab); @@ -1155,11 +1165,13 @@ export default function Settings({ me }) { : `${x.create.rolle ? 'Rolle' : 'Kanal'} anlegen`} ))} - {m.tab && ( - - )} + ))} @@ -1244,7 +1256,7 @@ export default function Settings({ me }) { setForm({ ...form, discord_guild_id: e.target.value })} /> -
+
setGiteaToken(e.target.value)} />
@@ -2400,7 +2412,12 @@ export default function Settings({ me }) { )} {!m.enabled && Ausgeschaltet} {m.tab && ( - )} diff --git a/frontend/src/setting-index.js b/frontend/src/setting-index.js index 61a86fc..8e24c1e 100644 --- a/frontend/src/setting-index.js +++ b/frontend/src/setting-index.js @@ -83,6 +83,7 @@ export const SETTING_INDEX = [ { id: 'cookie_domain', tab: 'system', label: 'Cookie-Domain', find: 'login beide domains' }, { id: 'gitea_url', tab: 'system', label: 'Gitea-Adresse', find: 'git server url' }, { id: 'discord_guild_id', tab: 'brand', label: 'Server-ID', find: 'guild id discord' }, + { id: 'gitea_api_token', tab: 'brand', label: 'Gitea-API-Token', find: 'token bug issue schluessel' }, { id: 'legal_name', tab: 'system', label: 'Impressum: Name', find: 'betreiber rechtstext' }, { id: 'legal_address', tab: 'system', label: 'Impressum: Anschrift', find: 'adresse rechtstext' }, { id: 'legal_email', tab: 'system', label: 'Impressum: E-Mail', find: 'kontakt rechtstext' }, diff --git a/src/modules.js b/src/modules.js index 424dd9d..23f59bd 100644 --- a/src/modules.js +++ b/src/modules.js @@ -9,6 +9,7 @@ // arbeiten kann. Fehlt etwas, zeigt das Panel „noch nicht einsatzbereit" // statt das Modul stillschweigend nichts tun zu lassen. import { getSetting, setSetting } from './db.js'; +import { effectiveSetting } from './runtime-settings.js'; export const MODULE_GROUPS = [ { id: 'inhalte', label: 'Inhalte & Feeds' }, @@ -162,7 +163,9 @@ export const MODULES = [ { id: 'bug_reports', group: 'moderation', name: 'Fehlermeldungen', desc: 'Meldungen werden zu Issues im Repository, mit Rückmeldung beim Schließen.', - tab: 'system', default: true, + // Der Token steht im Brand-Bereich („Aus der Env verlagert"), nicht im + // System-Bereich — sonst landet „Einrichten" an der falschen Stelle. + tab: 'brand', default: true, requires: [{ setting: 'gitea_api_token', label: 'Gitea-Token' }], }, @@ -251,7 +254,9 @@ export function setModuleEnabled(id, on) { */ export function moduleMissing(mod) { return (mod.requires ?? []) - .filter((r) => !String(getSetting(r.setting) ?? '').trim()) + // Effektiver Wert, nicht nur die Einstellung: was über die Umgebung + // gesetzt ist, fehlt nicht. + .filter((r) => !effectiveSetting(r.setting)) .map((r) => ({ setting: r.setting, label: r.label, create: r.create ?? null })); } diff --git a/src/runtime-settings.js b/src/runtime-settings.js index c774de9..fabc248 100644 --- a/src/runtime-settings.js +++ b/src/runtime-settings.js @@ -229,6 +229,29 @@ export function welcomeChannelId() { return getSetting('welcome_channel_id') || null; } +/** + * Wert einer Einstellung so, wie er tatsächlich wirkt — also inklusive der + * Env-Fallbacks aus config.js. + * + * Ohne das meldet die Config Sachen als „fehlt", die über die Umgebung längst + * gesetzt sind: Wer sein Gitea-Token per GITEA_API_TOKEN übergibt, sieht in + * der Liste „Fehlermeldungen — Gitea-Token", obwohl /bug einwandfrei läuft. + * + * @param {string} key + * @returns {string} + */ +export function effectiveSetting(key) { + const gesetzt = String(getSetting(key) ?? '').trim(); + if (gesetzt) return gesetzt; + const ausDerEnv = { + devlog_channel_id: config.devlogChannelId, + commit_channel_id: config.commitChannelId, + gitea_api_token: config.giteaApiToken, + discord_guild_id: config.discordGuildId, + }[key]; + return String(ausDerEnv ?? '').trim(); +} + /** * Aussehen der Willkommens-Karte. Die Standardwerte sind der Marken-Look; * die Marken-Farben ziehen automatisch nach, solange nichts eigenes gesetzt ist.