From b7dd9e71ff4e0f5bc090cd9b31d04c2e9dd09aba Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 30 Apr 2026 10:46:15 +0200 Subject: [PATCH] =?utf8?q?refactor(ui-web):=20fix=20audit=20findings=20?= =?utf8?q?=E2=80=94=20dead=20code,=20layer=20violations,=20composable=20ex?= =?utf8?q?traction?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- ui/web/src/assets/themes/catppuccin-latte.css | 9 +- ui/web/src/assets/themes/sap-horizon.css | 9 +- ui/web/src/assets/themes/teal-dark.css | 9 +- ui/web/src/assets/themes/teal-light.css | 9 +- .../src/assets/themes/tokyo-night-storm.css | 9 +- ui/web/src/core/Constants.ts | 3 + ui/web/src/core/UIClient.ts | 2 +- ui/web/src/core/index.ts | 2 +- ui/web/src/main.ts | 2 +- ui/web/src/router/index.ts | 3 +- .../src/shared/components/SkinLoadError.vue | 9 +- ui/web/src/shared/components/SkinLoading.vue | 2 +- .../src/shared/composables/useServerSwitch.ts | 125 ++++++++++++++++++ .../shared/composables/useSimulatorControl.ts | 99 ++------------ ui/web/src/shared/composables/useSkin.ts | 4 +- ui/web/src/shared/types.ts | 5 - ui/web/src/shared/utils/index.ts | 2 +- ui/web/src/skins/modern/modern.css | 26 ++++ ui/web/src/skins/registry.ts | 2 - ui/web/tests/unit/App.test.ts | 1 - ui/web/tests/unit/UIClient.test.ts | 18 --- ui/web/tests/unit/Utils.test.ts | 2 +- .../unit/shared/composables/useSkin.test.ts | 4 +- ui/web/tests/unit/skins/registry.test.ts | 3 +- 24 files changed, 212 insertions(+), 147 deletions(-) create mode 100644 ui/web/src/shared/composables/useServerSwitch.ts delete mode 100644 ui/web/src/shared/types.ts diff --git a/ui/web/src/assets/themes/catppuccin-latte.css b/ui/web/src/assets/themes/catppuccin-latte.css index ae5cba6b..cc00f058 100644 --- a/ui/web/src/assets/themes/catppuccin-latte.css +++ b/ui/web/src/assets/themes/catppuccin-latte.css @@ -12,6 +12,9 @@ --ctp-overlay1: #8c8fa1; --ctp-blue: #1e66f5; --ctp-lavender: #7287fd; + --ctp-green: #2e7d32; + --ctp-orange: #ef6c00; + --ctp-red: #c62828; /* Semantic */ --color-bg: var(--ctp-base); @@ -38,9 +41,9 @@ --color-bg-sunken: var(--ctp-crust); /* State colors (Material 700 for light mode readability) */ - --color-state-ok: #2e7d32; - --color-state-warn: #ef6c00; - --color-state-err: #c62828; + --color-state-ok: var(--ctp-green); + --color-state-warn: var(--ctp-orange); + --color-state-err: var(--ctp-red); --color-state-idle: var(--ctp-overlay1); color-scheme: light; diff --git a/ui/web/src/assets/themes/sap-horizon.css b/ui/web/src/assets/themes/sap-horizon.css index c74975d3..07950e6d 100644 --- a/ui/web/src/assets/themes/sap-horizon.css +++ b/ui/web/src/assets/themes/sap-horizon.css @@ -17,6 +17,9 @@ --sap-button-border: #bcc3ca; --sap-button-text: #0064d9; --sap-button-emphasized-bg: #0070f2; + --sap-positive: #256f3a; + --sap-critical: #e76500; + --sap-negative: #aa0808; --sap-white: #fff; /* Semantic */ @@ -44,9 +47,9 @@ --color-bg-sunken: var(--sap-hover); /* State colors (SAP Horizon palette) */ - --color-state-ok: #256f3a; - --color-state-warn: #e76500; - --color-state-err: #aa0808; + --color-state-ok: var(--sap-positive); + --color-state-warn: var(--sap-critical); + --color-state-err: var(--sap-negative); --color-state-idle: var(--sap-label); color-scheme: light; diff --git a/ui/web/src/assets/themes/teal-dark.css b/ui/web/src/assets/themes/teal-dark.css index 898ad7d2..a0c75602 100644 --- a/ui/web/src/assets/themes/teal-dark.css +++ b/ui/web/src/assets/themes/teal-dark.css @@ -12,6 +12,9 @@ --td-fg-muted: #78909c; --td-teal: #26a69a; --td-teal-dim: #00897b; + --td-green: #66bb6a; + --td-amber: #ffb300; + --td-red: #ef5350; --td-white: #ffffff; /* Semantic */ @@ -39,9 +42,9 @@ --color-bg-sunken: var(--td-bg-dark); /* State colors */ - --color-state-ok: #66bb6a; - --color-state-warn: #ffb300; - --color-state-err: #ef5350; + --color-state-ok: var(--td-green); + --color-state-warn: var(--td-amber); + --color-state-err: var(--td-red); --color-state-idle: var(--td-fg-muted); color-scheme: dark; diff --git a/ui/web/src/assets/themes/teal-light.css b/ui/web/src/assets/themes/teal-light.css index f26c8c11..26101016 100644 --- a/ui/web/src/assets/themes/teal-light.css +++ b/ui/web/src/assets/themes/teal-light.css @@ -12,6 +12,9 @@ --tl-fg-muted: #697386; --tl-teal: #009688; --tl-teal-dim: #00796b; + --tl-green: #2e7d32; + --tl-orange: #ef6c00; + --tl-red: #c62828; --tl-white: #ffffff; /* Semantic */ @@ -39,9 +42,9 @@ --color-bg-sunken: var(--tl-bg-active); /* State colors */ - --color-state-ok: #2e7d32; - --color-state-warn: #ef6c00; - --color-state-err: #c62828; + --color-state-ok: var(--tl-green); + --color-state-warn: var(--tl-orange); + --color-state-err: var(--tl-red); --color-state-idle: var(--tl-fg-muted); color-scheme: light; diff --git a/ui/web/src/assets/themes/tokyo-night-storm.css b/ui/web/src/assets/themes/tokyo-night-storm.css index f05fe578..ce6999eb 100644 --- a/ui/web/src/assets/themes/tokyo-night-storm.css +++ b/ui/web/src/assets/themes/tokyo-night-storm.css @@ -12,6 +12,9 @@ --tn-fg-muted: #8089b3; --tn-blue: #7aa2f7; --tn-accent: #3d59a1; + --tn-green: #66bb6a; + --tn-amber: #ffb300; + --tn-red: #ef5350; --tn-white: #ffffff; /* Semantic */ @@ -39,9 +42,9 @@ --color-bg-sunken: var(--tn-bg-raised); /* State colors */ - --color-state-ok: #66bb6a; - --color-state-warn: #ffb300; - --color-state-err: #ef5350; + --color-state-ok: var(--tn-green); + --color-state-warn: var(--tn-amber); + --color-state-err: var(--tn-red); --color-state-idle: var(--tn-fg-muted); color-scheme: dark; diff --git a/ui/web/src/core/Constants.ts b/ui/web/src/core/Constants.ts index e92023c9..854f43c2 100644 --- a/ui/web/src/core/Constants.ts +++ b/ui/web/src/core/Constants.ts @@ -1,6 +1,9 @@ +import { type SKIN_IDS } from 'ui-common' + // Local UI project constants export const ASYNC_COMPONENT_DELAY_MS = 200 +export const DEFAULT_SKIN: (typeof SKIN_IDS)[number] = 'classic' export const ASYNC_COMPONENT_TIMEOUT_MS = 10_000 export const EMPTY_VALUE_PLACEHOLDER = 'Ø' export const MAX_SKIN_ERROR_RELOADS = 2 diff --git a/ui/web/src/core/UIClient.ts b/ui/web/src/core/UIClient.ts index c6a97d76..18ff2732 100644 --- a/ui/web/src/core/UIClient.ts +++ b/ui/web/src/core/UIClient.ts @@ -46,7 +46,7 @@ export class UIClient { return UIClient.instance } - public static isOCPP20x (version: OCPPVersion | undefined): boolean { + private static isOCPP20x (version: OCPPVersion | undefined): boolean { return version === OCPPVersion.VERSION_20 || version === OCPPVersion.VERSION_201 } diff --git a/ui/web/src/core/index.ts b/ui/web/src/core/index.ts index e730115f..231af0bf 100644 --- a/ui/web/src/core/index.ts +++ b/ui/web/src/core/index.ts @@ -1,6 +1,7 @@ export { ASYNC_COMPONENT_DELAY_MS, ASYNC_COMPONENT_TIMEOUT_MS, + DEFAULT_SKIN, EMPTY_VALUE_PLACEHOLDER, LEGACY_UI_SERVER_CONFIG_KEY, MAX_SKIN_ERROR_RELOADS, @@ -22,7 +23,6 @@ export { useUIClient, } from './providers.js' export { - deleteFromLocalStorage, deleteLocalStorageByKeyPattern, getFromLocalStorage, getLocalStorage, diff --git a/ui/web/src/main.ts b/ui/web/src/main.ts index 164b0be1..21dbacb9 100644 --- a/ui/web/src/main.ts +++ b/ui/web/src/main.ts @@ -11,6 +11,7 @@ import App from '@/App.vue' import { chargingStationsKey, configurationKey, + DEFAULT_SKIN, getFromLocalStorage, LEGACY_UI_SERVER_CONFIG_KEY, setToLocalStorage, @@ -22,7 +23,6 @@ import { import { router } from '@/router/index.js' import { SKIN_STORAGE_KEY, useSkin } from '@/shared/composables/useSkin.js' import { DEFAULT_THEME, THEME_STORAGE_KEY, useTheme } from '@/shared/composables/useTheme.js' -import { DEFAULT_SKIN } from '@/skins/registry.js' import 'vue-toast-notification/dist/theme-bootstrap.css' diff --git a/ui/web/src/router/index.ts b/ui/web/src/router/index.ts index b1685a20..bd4ff989 100644 --- a/ui/web/src/router/index.ts +++ b/ui/web/src/router/index.ts @@ -3,9 +3,8 @@ import { h } from 'vue' import { createRouter, createWebHistory, type RouteLocationNormalized } from 'vue-router' import { useToast } from 'vue-toast-notification' -import { ROUTE_NAMES } from '@/core/index.js' +import { DEFAULT_SKIN, ROUTE_NAMES } from '@/core/index.js' import { useSkin } from '@/shared/composables/useSkin.js' -import { DEFAULT_SKIN } from '@/skins/registry.js' declare module 'vue-router' { interface RouteMeta { diff --git a/ui/web/src/shared/components/SkinLoadError.vue b/ui/web/src/shared/components/SkinLoadError.vue index aad03282..a60ebf80 100644 --- a/ui/web/src/shared/components/SkinLoadError.vue +++ b/ui/web/src/shared/components/SkinLoadError.vue @@ -11,9 +11,10 @@