fix(themes): style admin health alerts

Add custom-theme styles for the admin configuration alerts and bump built-in theme asset versions so existing installations refresh stale theme CSS.
This commit is contained in:
3252a8
2026-06-10 14:25:24 +03:00
parent 217bed3c5d
commit fd931581f5
8 changed files with 145 additions and 10 deletions
+57 -2
View File
@@ -168,6 +168,7 @@
.theme-key-ascii .admin-toolbar-card,
.theme-key-ascii .admin-table-card,
.theme-key-ascii .admin-panel-dash-card,
.theme-key-ascii .admin-config-alerts,
.theme-key-ascii .admin-select-trigger,
.theme-key-ascii .admin-select-content,
.theme-key-ascii .admin-cn-card[data-slot="card"],
@@ -199,7 +200,8 @@
.theme-key-ascii .admin-tabs-trigger,
.theme-key-ascii .admin-revenue-period-btn,
.theme-key-ascii .admin-mobile-toggle,
.theme-key-ascii .admin-nav-item {
.theme-key-ascii .admin-nav-item,
.theme-key-ascii .admin-config-alert-link {
border: 1px solid #ffffff;
border-radius: 0;
background: #000000;
@@ -216,7 +218,8 @@
.theme-key-ascii .admin-nav-item:hover,
.theme-key-ascii .admin-tabs-trigger:hover,
.theme-key-ascii .admin-revenue-period-btn:hover,
.theme-key-ascii .bottom-nav button:hover {
.theme-key-ascii .bottom-nav button:hover,
.theme-key-ascii .admin-config-alert-link:hover {
background: #ffffff;
color: #000000;
}
@@ -393,6 +396,58 @@
color: #000000;
}
/* ---------- Admin health config alerts ---------- */
.theme-key-ascii .admin-config-alerts {
position: relative;
padding-left: 18px;
color: #ffffff;
}
.theme-key-ascii .admin-config-alerts::before {
content: "!";
position: absolute;
top: 11px;
left: 7px;
color: #ffffff;
font-family: var(--font-mono);
font-weight: 700;
}
.theme-key-ascii .admin-config-alerts-error {
border-color: #ff5555;
color: #ffaaaa;
}
.theme-key-ascii .admin-config-alerts-error::before {
color: #ff5555;
}
.theme-key-ascii .admin-config-alert-dot {
width: auto;
height: auto;
border-radius: 0;
background: transparent;
color: currentColor;
transform: none;
}
.theme-key-ascii .admin-config-alert-dot::before {
content: ">";
font-family: var(--font-mono);
}
.theme-key-ascii .admin-config-alert-error .admin-config-alert-dot {
background: transparent;
color: #ff5555;
}
.theme-key-ascii .admin-config-alert-link {
padding: 1px 7px;
font-family: var(--font-mono);
opacity: 1;
}
/* ---------- New webapp surfaces: support, purchase info, password login ---------- */
.theme-key-ascii .trial-offer-card,
+1 -1
View File
@@ -9,7 +9,7 @@
"use_primary_accent": false,
"use_in_admin": true,
"css_file": "style.css",
"assets_version": 6,
"assets_version": 7,
"tokens": {
"color_scheme": "dark",
"style_preset": "ascii"
@@ -252,6 +252,27 @@ body:has(.theme-key-light) .install-platform-item[data-selected] {
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}
/* Admin health config alerts */
.theme-key-light .admin-config-alerts {
border-color: color-mix(in srgb, var(--warning) 38%, var(--admin-border));
background: color-mix(in srgb, var(--warning) 9%, #ffffff);
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.06);
}
.theme-key-light .admin-config-alerts-error {
border-color: color-mix(in srgb, var(--danger) 38%, var(--admin-border));
background: color-mix(in srgb, var(--danger) 8%, #ffffff);
}
.theme-key-light .admin-config-alert-link {
background: rgba(255, 255, 255, 0.58);
}
.theme-key-light .admin-config-alert-link:hover {
background: #ffffff;
}
/* Telegram notifications banner: keep the warm warning tint but swap the
* dark-theme inset bevel for the soft drop shadow the other light cards use. */
.theme-key-light .telegram-notifications-card {
+1 -1
View File
@@ -9,7 +9,7 @@
"use_primary_accent": true,
"use_in_admin": true,
"css_file": "style.css",
"assets_version": 5,
"assets_version": 6,
"tokens": {
"color_scheme": "light"
}
@@ -1267,6 +1267,59 @@ body:has(.theme-key-windows95) .install-platform-item[data-selected] {
inset -1px -1px 0 #dfdfdf;
}
/* Admin health config alerts */
.theme-key-windows95 .admin-config-alerts {
border: 2px solid;
border-color: #ffffff #404040 #404040 #ffffff;
background: #ffffcc;
color: #000000;
box-shadow:
inset 1px 1px 0 #dfdfdf,
inset -1px -1px 0 #808080;
}
.theme-key-windows95 .admin-config-alerts-error {
border-color: #ffffff #404040 #404040 #ffffff;
background: #f7d6d6;
color: #000000;
}
.theme-key-windows95 .admin-config-alert-dot {
border-radius: 0;
background: #808000;
box-shadow:
1px 1px 0 #ffffff,
-1px -1px 0 #404040;
}
.theme-key-windows95 .admin-config-alert-error .admin-config-alert-dot {
background: #800000;
}
.theme-key-windows95 .admin-config-alert-link {
border: 2px solid;
border-color: #ffffff #404040 #404040 #ffffff;
border-radius: 0;
background: #c0c0c0;
color: #000000;
box-shadow:
inset 1px 1px 0 #dfdfdf,
inset -1px -1px 0 #808080;
opacity: 1;
}
.theme-key-windows95 .admin-config-alert-link:hover {
background: #dfdfdf;
}
.theme-key-windows95 .admin-config-alert-link:active {
border-color: #404040 #ffffff #ffffff #404040;
box-shadow:
inset 1px 1px 0 #808080,
inset -1px -1px 0 #dfdfdf;
}
.theme-key-windows95 input::placeholder,
.theme-key-windows95 textarea::placeholder,
.theme-key-windows95 .input::placeholder,
@@ -9,7 +9,7 @@
"use_primary_accent": false,
"use_in_admin": true,
"css_file": "style.css",
"assets_version": 13,
"assets_version": 14,
"tokens": {
"color_scheme": "light",
"style_preset": "win95"
+3
View File
@@ -372,6 +372,7 @@ def _builtin_theme_assets_need_refresh(key: str, target_dir: Path) -> bool:
or ".theme-key-light.app-shell" not in style
or "Install guide theme surfaces" not in style
or "Admin controls: range sliders and sortable rows" not in style
or "Admin health config alerts" not in style
)
if key == "ascii":
return (
@@ -383,6 +384,7 @@ def _builtin_theme_assets_need_refresh(key: str, target_dir: Path) -> bool:
or "New webapp surfaces: support, purchase info, password login" not in style
or "Install guide theme surfaces" not in style
or "Admin controls: range sliders and sortable rows" not in style
or "Admin health config alerts" not in style
)
if key != "windows95":
return False
@@ -407,6 +409,7 @@ def _builtin_theme_assets_need_refresh(key: str, target_dir: Path) -> bool:
or "New webapp surfaces: support, purchase info, password login" not in style
or "Install guide theme surfaces" not in style
or "Admin controls: range sliders and sortable rows" not in style
or "Admin health config alerts" not in style
or any(not (target_dir / "icons" / icon).exists() for icon in required_icons)
)
+8 -5
View File
@@ -34,14 +34,14 @@ class WebappThemesConfigTests(unittest.TestCase):
self.assertEqual(win95.tokens.style_preset, "win95")
self.assertFalse(win95.use_primary_accent)
self.assertTrue(win95.use_in_admin)
self.assertEqual(win95.assets_version, 13)
self.assertEqual(cfg.theme_by_key("light").assets_version, 5)
self.assertEqual(win95.assets_version, 14)
self.assertEqual(cfg.theme_by_key("light").assets_version, 6)
ascii_theme = cfg.theme_by_key("ascii")
self.assertIsNotNone(ascii_theme)
self.assertEqual(ascii_theme.css_file, "style.css")
self.assertFalse(ascii_theme.use_primary_accent)
self.assertTrue(ascii_theme.use_in_admin)
self.assertEqual(ascii_theme.assets_version, 6)
self.assertEqual(ascii_theme.assets_version, 7)
def test_env_override_default_theme(self):
cfg = builtin_webapp_themes_config("#00fe7a")
@@ -430,7 +430,7 @@ class WebappThemesConfigTests(unittest.TestCase):
descriptor["assets_version"],
cfg.theme_by_key("windows95").assets_version,
)
self.assertEqual(descriptor["assets_version"], 13)
self.assertEqual(descriptor["assets_version"], 14)
self.assertIn("lucide-house", css)
self.assertIn("lucide-earth", css)
self.assertIn("lucide-circle-check", css)
@@ -444,6 +444,7 @@ class WebappThemesConfigTests(unittest.TestCase):
self.assertIn("New webapp surfaces: support, purchase info, password login", css)
self.assertIn("Install guide theme surfaces", css)
self.assertIn("Admin controls: range sliders and sortable rows", css)
self.assertIn("Admin health config alerts", css)
self.assertIn(
(
".theme-key-windows95 .support-list-card {\n"
@@ -486,6 +487,7 @@ class WebappThemesConfigTests(unittest.TestCase):
self.assertIn(".theme-key-light.app-shell", css)
self.assertIn("Install guide theme surfaces", css)
self.assertIn("Admin controls: range sliders and sortable rows", css)
self.assertIn("Admin health config alerts", css)
def test_resolved_refreshes_stale_builtin_ascii_assets(self):
with tempfile.TemporaryDirectory() as tmp:
@@ -518,7 +520,8 @@ class WebappThemesConfigTests(unittest.TestCase):
descriptor = json.loads((stale_theme_dir / "theme.json").read_text(encoding="utf-8"))
css = (stale_theme_dir / "style.css").read_text(encoding="utf-8")
self.assertEqual(descriptor["assets_version"], cfg.theme_by_key("ascii").assets_version)
self.assertEqual(descriptor["assets_version"], 6)
self.assertEqual(descriptor["assets_version"], 7)
self.assertIn("Console-style tables", css)
self.assertIn("Install guide theme surfaces", css)
self.assertIn("Admin controls: range sliders and sortable rows", css)
self.assertIn("Admin health config alerts", css)