]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
feat(ui): add configurable theme support
authorJérôme Benoit <jerome.benoit@sap.com>
Wed, 18 Mar 2026 23:23:29 +0000 (00:23 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Wed, 18 Mar 2026 23:23:29 +0000 (00:23 +0100)
Add theme field to ConfigurationData. Theme CSS files are loaded
dynamically from assets/themes/ at startup. Falls back to
tokyo-night-storm when not configured or theme not found.

Move theme.css to assets/themes/tokyo-night-storm.css.

ui/web/src/assets/config-template.json
ui/web/src/assets/themes/tokyo-night-storm.css [moved from ui/web/src/assets/theme.css with 100% similarity]
ui/web/src/main.ts
ui/web/src/types/ConfigurationType.ts

index 1542583a2b0f9f96784e5fcadc20d53378235f38..2fc411e102baed4e89815f2f5718bad503ca054d 100644 (file)
@@ -1,4 +1,5 @@
 {
+  "theme": "tokyo-night-storm",
   "uiServer": {
     "host": "localhost",
     "port": 8080,
index d40f9a250580e9d40bf8ab15a8893bd260b14c32..6a22da453d997e5444b0dcbcb214d277fe58276e 100644 (file)
@@ -9,11 +9,21 @@ import { router } from '@/router'
 
 import 'vue-toast-notification/dist/theme-bootstrap.css'
 
-import '@/assets/theme.css'
+const DEFAULT_THEME = 'tokyo-night-storm'
+
+const loadTheme = async (theme: string): Promise<void> => {
+  try {
+    await import(`./assets/themes/${theme}.css`)
+  } catch {
+    console.error(`Theme '${theme}' not found, falling back to '${DEFAULT_THEME}'`)
+    await import(`./assets/themes/${DEFAULT_THEME}.css`)
+  }
+}
 
 const app = createApp(App as Component)
 
-const initializeApp = (app: AppType, config: ConfigurationData) => {
+const initializeApp = async (app: AppType, config: ConfigurationData): Promise<void> => {
+  await loadTheme(config.theme ?? DEFAULT_THEME)
   app.config.errorHandler = (error, instance, info) => {
     console.error('Error:', error)
     console.info('Vue instance:', instance)
@@ -57,8 +67,8 @@ fetch('/config.json')
     response
       .json()
       // eslint-disable-next-line promise/no-nesting
-      .then(config => {
-        initializeApp(app, config as ConfigurationData)
+      .then(async config => {
+        await initializeApp(app, config as ConfigurationData)
         return undefined
       })
       // eslint-disable-next-line promise/no-nesting
index 40586918aeb13483e7bb002e9a9e7014aae27480..b76fc240a48e836a2fe47e9665286ea9f4129e9f 100644 (file)
@@ -1,6 +1,7 @@
 import type { AuthenticationType, Protocol, ProtocolVersion } from './UIProtocol'
 
 export interface ConfigurationData {
+  theme?: string
   uiServer: UIServerConfigurationSection | UIServerConfigurationSection[]
 }