fix(theme): Farben erben wieder den Standard statt ihn einzufrieren
Fuenf Farbspalten trugen einen fest eingebauten Vorgabewert — primary_color #4285f4, accent_color #ea4335, today_color #4285f4, month_divider_color und month_label_color #7090c0. Damit hatte *jeder* Nutzer immer eine eigene Farbe, und der Fallback settings.X || baseColor(X) kam nie zum Zug. Das Admin-Versprechen "Gilt fuer alle Nutzer ohne eigene Farbe" war fuer diese fuenf unerfuellbar, und die Werte widersprachen DEFAULT_COLORS im Frontend, das laut Kommentar die einzige Quelle sein soll. Das betraf nicht nur Altbestand: UserSettings wird ohne Farbwerte angelegt, also bekam auch jeder heute neu angelegte Nutzer das Blau. - models.py: die fuenf Spalten sind nullable, NULL heisst "erbt". - settings_router: NULL wird ausgeliefert statt durch einen Standard ersetzt, und ein explizites null wird gespeichert (NULLABLE_OVERRIDES). - main.py: einmalige Migration setzt genau die alten Vorgabewerte auf NULL. Bewusst gewaehlte Farben bleiben unangetastet. - calendar.js: eine erbende Zeile merkt sich das und sendet beim Speichern null. "Zurueck" heisst wieder erben, statt den aktuellen Standard in die Nutzerzeile zu kopieren — sonst erreichen spaetere Aenderungen des Standards den Nutzer nie mehr. Verifiziert: frische Installation liefert --primary #58B900 statt #4285f4; zurueckgeschriebenes Alt-Blau wird beim Neustart geleert; eine eigene Farbe (#FF00AA) ueberlebt die Migration. Suite 129 gruen, davon 5 neue. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
aaecfc435d
commit
8bc32faa7f
+15
-5
@@ -3761,8 +3761,13 @@ function settingRowHtml(def) {
|
||||
valueHtml = `<button type="button" class="sync-toggle ${val ? 'on' : ''}" data-vtoggle="${def.key}" role="switch" aria-checked="${!!val}"></button>`;
|
||||
} else if (def.type === 'color') {
|
||||
const hex = normalizeHex(val, baseColor(def.key));
|
||||
// No own value means the row inherits the admin instance default. The
|
||||
// field still shows that colour, but saving must send null — writing the
|
||||
// hex back would freeze today's admin default into the user's row and
|
||||
// later admin changes would stop reaching them.
|
||||
const inherits = val == null ? ' data-inherit="1"' : '';
|
||||
valueHtml = `<div class="settings-color-ctl">
|
||||
<input type="text" class="ev-color-hex" data-shex="${def.key}" maxlength="7" spellcheck="false" value="${hex}" />
|
||||
<input type="text" class="ev-color-hex" data-shex="${def.key}" maxlength="7" spellcheck="false" value="${hex}"${inherits} />
|
||||
<div class="ev-color-preview" data-sprev="${def.key}" style="background:${hex}" title="${escHtml(t('color_pick'))}"></div>
|
||||
<button type="button" class="icon-btn ev-color-reset" data-sreset="${def.key}" title="${escHtml(t('reset'))}">${RESET_ICON_SVG}</button>
|
||||
</div>`;
|
||||
@@ -3817,20 +3822,23 @@ function wireSettingRow(def) {
|
||||
state.settings[def.key] = color;
|
||||
applyTheme(state.settings);
|
||||
};
|
||||
const own = () => { delete hex.dataset.inherit; };
|
||||
prev.addEventListener('click', async () => {
|
||||
const picked = await openColorPicker(prev, hex.value || baseColor(def.key));
|
||||
if (picked) { hex.value = picked.toUpperCase(); apply(picked); }
|
||||
if (picked) { hex.value = picked.toUpperCase(); own(); apply(picked); }
|
||||
});
|
||||
hex.addEventListener('input', () => {
|
||||
const norm = normalizeHex(hex.value, null);
|
||||
if (norm) apply(norm);
|
||||
if (norm) { own(); apply(norm); }
|
||||
});
|
||||
hex.addEventListener('change', () => {
|
||||
const norm = normalizeHex(hex.value, baseColor(def.key));
|
||||
hex.value = norm; apply(norm);
|
||||
hex.value = norm; own(); apply(norm);
|
||||
});
|
||||
reset.addEventListener('click', () => {
|
||||
// Back to inheriting, not "copy the current admin default in".
|
||||
const d = baseColor(def.key);
|
||||
hex.dataset.inherit = '1';
|
||||
hex.value = d; apply(d);
|
||||
});
|
||||
} else if (def.type === 'icon') {
|
||||
@@ -3860,7 +3868,9 @@ function readAppearanceTable() {
|
||||
out[def.key] = el ? el.classList.contains('on') : !!state.settings[def.key];
|
||||
} else if (def.type === 'color') {
|
||||
const el = document.querySelector(`[data-shex="${def.key}"]`);
|
||||
out[def.key] = normalizeHex(el && el.value, baseColor(def.key));
|
||||
out[def.key] = (el && el.dataset.inherit === '1')
|
||||
? null // inherit the admin default
|
||||
: normalizeHex(el && el.value, baseColor(def.key));
|
||||
} else if (def.type === 'icon') {
|
||||
const on = document.querySelector(`[data-sicon="${def.key}"] .group-icon-opt.on`);
|
||||
out[def.key] = on ? on.dataset.shareIcon : (state.settings[def.key] || 'share');
|
||||
|
||||
Reference in New Issue
Block a user