]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
refactor(ui-web): reorganize composables into core/ infrastructure and shared/composa...
authorJérôme Benoit <jerome.benoit@sap.com>
Thu, 30 Apr 2026 07:35:59 +0000 (09:35 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Thu, 30 Apr 2026 07:35:59 +0000 (09:35 +0200)
52 files changed:
ui/web/src/composables/Utils.ts [deleted file]
ui/web/src/core/Constants.ts [moved from ui/web/src/composables/Constants.ts with 100% similarity]
ui/web/src/core/UIClient.ts [moved from ui/web/src/composables/UIClient.ts with 100% similarity]
ui/web/src/core/index.ts [moved from ui/web/src/composables/index.ts with 90% similarity]
ui/web/src/core/providers.ts [new file with mode: 0644]
ui/web/src/core/storage.ts [new file with mode: 0644]
ui/web/src/main.ts
ui/web/src/router/index.ts
ui/web/src/shared/components/SkinLoadError.vue
ui/web/src/shared/composables/index.ts
ui/web/src/shared/composables/useAddStationsForm.ts
ui/web/src/shared/composables/useConnectorActions.ts
ui/web/src/shared/composables/useFetchData.ts [new file with mode: 0644]
ui/web/src/shared/composables/useLayoutData.ts
ui/web/src/shared/composables/useSetUrlForm.ts
ui/web/src/shared/composables/useSimulatorControl.ts
ui/web/src/shared/composables/useSkin.ts
ui/web/src/shared/composables/useStartTxForm.ts
ui/web/src/shared/composables/useStationActions.ts
ui/web/src/shared/composables/useTheme.ts
ui/web/src/shared/utils/formatSupervisionUrl.ts
ui/web/src/skins/classic/ClassicLayout.vue
ui/web/src/skins/classic/components/actions/AddChargingStations.vue
ui/web/src/skins/classic/components/actions/SetSupervisionUrl.vue
ui/web/src/skins/classic/components/actions/StartTransaction.vue
ui/web/src/skins/classic/components/buttons/ToggleButton.vue
ui/web/src/skins/classic/components/charging-stations/CSConnector.vue
ui/web/src/skins/classic/components/charging-stations/CSData.vue
ui/web/src/skins/modern/ModernLayout.vue
ui/web/src/skins/modern/components/StationCard.vue
ui/web/src/skins/modern/components/dialogs/AuthorizeDialog.vue
ui/web/src/skins/modern/components/dialogs/SetSupervisionUrlDialog.vue
ui/web/tests/unit/UIClient.test.ts
ui/web/tests/unit/Utils.test.ts
ui/web/tests/unit/router.test.ts
ui/web/tests/unit/shared/composables/useAddStationsForm.test.ts
ui/web/tests/unit/shared/composables/useConnectorActions.test.ts
ui/web/tests/unit/shared/composables/useLayoutData.test.ts
ui/web/tests/unit/shared/composables/useSetUrlForm.test.ts
ui/web/tests/unit/shared/composables/useSimulatorControl.test.ts
ui/web/tests/unit/shared/composables/useStartTxForm.test.ts
ui/web/tests/unit/shared/composables/useStationActions.test.ts
ui/web/tests/unit/skins/classic/Actions.test.ts
ui/web/tests/unit/skins/classic/CSConnector.test.ts
ui/web/tests/unit/skins/classic/CSData.test.ts
ui/web/tests/unit/skins/classic/CSTable.test.ts
ui/web/tests/unit/skins/classic/ClassicComponents.test.ts
ui/web/tests/unit/skins/classic/ClassicLayout.test.ts
ui/web/tests/unit/skins/modern/ConnectorRow.test.ts
ui/web/tests/unit/skins/modern/Dialogs.test.ts
ui/web/tests/unit/skins/modern/ModernLayout.test.ts
ui/web/tests/unit/skins/modern/StationCard.test.ts

diff --git a/ui/web/src/composables/Utils.ts b/ui/web/src/composables/Utils.ts
deleted file mode 100644 (file)
index 1917a85..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-import type { ChargingStationData, ConfigurationData, ResponsePayload } from 'ui-common'
-import type { InjectionKey, Ref } from 'vue'
-
-import { inject, ref as vueRef } from 'vue'
-import { useToast } from 'vue-toast-notification'
-
-import { SHARED_TOGGLE_BUTTON_KEY_PREFIX, TOGGLE_BUTTON_KEY_PREFIX } from './Constants.js'
-import { UIClient } from './UIClient.js'
-
-export const configurationKey: InjectionKey<Ref<ConfigurationData>> = Symbol('configuration')
-export const chargingStationsKey: InjectionKey<Ref<ChargingStationData[]>> =
-  Symbol('chargingStations')
-export const templatesKey: InjectionKey<Ref<string[]>> = Symbol('templates')
-export const uiClientKey: InjectionKey<UIClient> = Symbol('uiClient')
-
-export const getFromLocalStorage = <T>(key: string, defaultValue: T): T => {
-  try {
-    const item = localStorage.getItem(key)
-    return item != null ? (JSON.parse(item) as T) : defaultValue
-  } catch {
-    if (import.meta.env.DEV) {
-      console.debug(`[localStorage] Failed to read key '${key}', using default`)
-    }
-    return defaultValue
-  }
-}
-
-// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
-export const setToLocalStorage = <T>(key: string, value: T): void => {
-  try {
-    localStorage.setItem(key, JSON.stringify(value))
-  } catch {
-    // localStorage.setItem() can throw:
-    // - QuotaExceededError when the origin's storage quota is genuinely exceeded
-    // - SecurityError when storage is blocked by user settings or browser policies
-    //   (e.g., "Block All Cookies" in Safari, third-party iframe in Chrome, file: URLs)
-    if (import.meta.env.DEV) {
-      console.debug(`[localStorage] Failed to write key '${key}'`)
-    }
-  }
-}
-
-export const deleteFromLocalStorage = (key: string): void => {
-  try {
-    localStorage.removeItem(key)
-  } catch {
-    if (import.meta.env.DEV) {
-      console.debug(`[localStorage] Failed to delete key '${key}'`)
-    }
-  }
-}
-
-export const getLocalStorage = (): Storage => {
-  try {
-    return localStorage
-  } catch {
-    throw new Error('localStorage is not available')
-  }
-}
-
-/**
- * Deletes all localStorage entries whose key includes the given pattern.
- * @param pattern - Substring to match against localStorage keys
- */
-export const deleteLocalStorageByKeyPattern = (pattern: string): void => {
-  try {
-    const keysToDelete = Object.keys(localStorage).filter(key => key.includes(pattern))
-    for (const key of keysToDelete) {
-      deleteFromLocalStorage(key)
-    }
-  } catch {
-    if (import.meta.env.DEV) {
-      console.debug(`[localStorage] Failed to delete keys matching '${pattern}'`)
-    }
-  }
-}
-
-/**
- * Resets the state of a toggle button by removing its entry from localStorage.
- * @param id - The identifier of the toggle button
- * @param shared - Whether the toggle button is shared
- */
-export const resetToggleButtonState = (id: string, shared = false): void => {
-  const key = shared
-    ? `${SHARED_TOGGLE_BUTTON_KEY_PREFIX}${id}`
-    : `${TOGGLE_BUTTON_KEY_PREFIX}${id}`
-  deleteFromLocalStorage(key)
-}
-
-export const useUIClient = (): UIClient => {
-  const injected = inject(uiClientKey, undefined)
-  if (injected != null) return injected
-  if (import.meta.env.DEV) {
-    console.debug('[useUIClient] Accessed outside provide scope — using singleton fallback')
-  }
-  return UIClient.getInstance()
-}
-
-export const useConfiguration = (): Ref<ConfigurationData> => {
-  const injected = inject(configurationKey, undefined)
-  if (injected != null) return injected
-  throw new Error('configuration not provided')
-}
-
-export const useChargingStations = (): Ref<ChargingStationData[]> => {
-  const injected = inject(chargingStationsKey, undefined)
-  if (injected != null) return injected
-  throw new Error('chargingStations not provided')
-}
-
-export const useTemplates = (): Ref<string[]> => {
-  const injected = inject(templatesKey, undefined)
-  if (injected != null) return injected
-  throw new Error('templates not provided')
-}
-
-export const useFetchData = (
-  clientFn: () => Promise<ResponsePayload>,
-  onSuccess: (response: ResponsePayload) => void,
-  errorMsg: string,
-  onError?: () => void
-): { fetch: () => void; fetching: Ref<boolean> } => {
-  const fetching = vueRef(false)
-  const $toast = useToast()
-  const fetch = (): void => {
-    if (!fetching.value) {
-      fetching.value = true
-      clientFn()
-        .then((response: ResponsePayload) => {
-          onSuccess(response)
-          return undefined
-        })
-        .finally(() => {
-          fetching.value = false
-        })
-        .catch((error: unknown) => {
-          try {
-            onError?.()
-          } catch (callbackError: unknown) {
-            console.error('Error in onError callback:', callbackError)
-          }
-          $toast.error(errorMsg)
-          console.error(`${errorMsg}:`, error)
-        })
-    }
-  }
-  return { fetch, fetching }
-}
similarity index 90%
rename from ui/web/src/composables/index.ts
rename to ui/web/src/core/index.ts
index 7086a0a9dcea7f5caa450ce2bbb9b1f6603a4a34..1b6e7b98eada2e939c32b42f1fb7d86c56174191 100644 (file)
@@ -6,21 +6,22 @@ export {
   TOGGLE_BUTTON_KEY_PREFIX,
   UI_SERVER_CONFIGURATION_INDEX_KEY,
 } from './Constants.js'
-export { UIClient } from './UIClient.js'
 export {
   chargingStationsKey,
   configurationKey,
-  deleteFromLocalStorage,
-  deleteLocalStorageByKeyPattern,
-  getFromLocalStorage,
-  getLocalStorage,
-  resetToggleButtonState,
-  setToLocalStorage,
   templatesKey,
   uiClientKey,
   useChargingStations,
   useConfiguration,
-  useFetchData,
   useTemplates,
   useUIClient,
-} from './Utils.js'
+} from './providers.js'
+export {
+  deleteFromLocalStorage,
+  deleteLocalStorageByKeyPattern,
+  getFromLocalStorage,
+  getLocalStorage,
+  resetToggleButtonState,
+  setToLocalStorage,
+} from './storage.js'
+export { UIClient } from './UIClient.js'
diff --git a/ui/web/src/core/providers.ts b/ui/web/src/core/providers.ts
new file mode 100644 (file)
index 0000000..b28c53b
--- /dev/null
@@ -0,0 +1,39 @@
+import type { ChargingStationData, ConfigurationData } from 'ui-common'
+import type { InjectionKey, Ref } from 'vue'
+
+import { inject } from 'vue'
+
+import { UIClient } from './UIClient.js'
+
+export const configurationKey: InjectionKey<Ref<ConfigurationData>> = Symbol('configuration')
+export const chargingStationsKey: InjectionKey<Ref<ChargingStationData[]>> =
+  Symbol('chargingStations')
+export const templatesKey: InjectionKey<Ref<string[]>> = Symbol('templates')
+export const uiClientKey: InjectionKey<UIClient> = Symbol('uiClient')
+
+export const useUIClient = (): UIClient => {
+  const injected = inject(uiClientKey, undefined)
+  if (injected != null) return injected
+  if (import.meta.env.DEV) {
+    console.debug('[useUIClient] Accessed outside provide scope — using singleton fallback')
+  }
+  return UIClient.getInstance()
+}
+
+export const useConfiguration = (): Ref<ConfigurationData> => {
+  const injected = inject(configurationKey, undefined)
+  if (injected != null) return injected
+  throw new Error('configuration not provided')
+}
+
+export const useChargingStations = (): Ref<ChargingStationData[]> => {
+  const injected = inject(chargingStationsKey, undefined)
+  if (injected != null) return injected
+  throw new Error('chargingStations not provided')
+}
+
+export const useTemplates = (): Ref<string[]> => {
+  const injected = inject(templatesKey, undefined)
+  if (injected != null) return injected
+  throw new Error('templates not provided')
+}
diff --git a/ui/web/src/core/storage.ts b/ui/web/src/core/storage.ts
new file mode 100644 (file)
index 0000000..bd4893a
--- /dev/null
@@ -0,0 +1,75 @@
+import { SHARED_TOGGLE_BUTTON_KEY_PREFIX, TOGGLE_BUTTON_KEY_PREFIX } from './Constants.js'
+
+export const getFromLocalStorage = <T>(key: string, defaultValue: T): T => {
+  try {
+    const item = localStorage.getItem(key)
+    return item != null ? (JSON.parse(item) as T) : defaultValue
+  } catch {
+    if (import.meta.env.DEV) {
+      console.debug(`[localStorage] Failed to read key '${key}', using default`)
+    }
+    return defaultValue
+  }
+}
+
+// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
+export const setToLocalStorage = <T>(key: string, value: T): void => {
+  try {
+    localStorage.setItem(key, JSON.stringify(value))
+  } catch {
+    // localStorage.setItem() can throw:
+    // - QuotaExceededError when the origin's storage quota is genuinely exceeded
+    // - SecurityError when storage is blocked by user settings or browser policies
+    //   (e.g., "Block All Cookies" in Safari, third-party iframe in Chrome, file: URLs)
+    if (import.meta.env.DEV) {
+      console.debug(`[localStorage] Failed to write key '${key}'`)
+    }
+  }
+}
+
+export const deleteFromLocalStorage = (key: string): void => {
+  try {
+    localStorage.removeItem(key)
+  } catch {
+    if (import.meta.env.DEV) {
+      console.debug(`[localStorage] Failed to delete key '${key}'`)
+    }
+  }
+}
+
+export const getLocalStorage = (): Storage => {
+  try {
+    return localStorage
+  } catch {
+    throw new Error('localStorage is not available')
+  }
+}
+
+/**
+ * Deletes all localStorage entries whose key includes the given pattern.
+ * @param pattern - Substring to match against localStorage keys
+ */
+export const deleteLocalStorageByKeyPattern = (pattern: string): void => {
+  try {
+    const keysToDelete = Object.keys(localStorage).filter(key => key.includes(pattern))
+    for (const key of keysToDelete) {
+      deleteFromLocalStorage(key)
+    }
+  } catch {
+    if (import.meta.env.DEV) {
+      console.debug(`[localStorage] Failed to delete keys matching '${pattern}'`)
+    }
+  }
+}
+
+/**
+ * Resets the state of a toggle button by removing its entry from localStorage.
+ * @param id - The identifier of the toggle button
+ * @param shared - Whether the toggle button is shared
+ */
+export const resetToggleButtonState = (id: string, shared = false): void => {
+  const key = shared
+    ? `${SHARED_TOGGLE_BUTTON_KEY_PREFIX}${id}`
+    : `${TOGGLE_BUTTON_KEY_PREFIX}${id}`
+  deleteFromLocalStorage(key)
+}
index a574a7763615f17ffe1a2ada6601bf49a21a206b..48c8db14ac3883841041f2f2f24a379465b09857 100644 (file)
@@ -18,7 +18,7 @@ import {
   UI_SERVER_CONFIGURATION_INDEX_KEY,
   UIClient,
   uiClientKey,
-} from '@/composables/index.js'
+} from '@/core/index.js'
 import { router } from '@/router'
 import { SKIN_STORAGE_KEY, useSkin } from '@/shared/composables/useSkin.js'
 import { DEFAULT_THEME, THEME_STORAGE_KEY, useTheme } from '@/shared/composables/useTheme.js'
index 13b35cc69c0bcf3cdacf3984d22f4752a73a28e6..b1685a20da7f2bc8df850c0b823426f2d0fbbcd4 100644 (file)
@@ -3,7 +3,7 @@ import { h } from 'vue'
 import { createRouter, createWebHistory, type RouteLocationNormalized } from 'vue-router'
 import { useToast } from 'vue-toast-notification'
 
-import { ROUTE_NAMES } from '@/composables/index.js'
+import { ROUTE_NAMES } from '@/core/index.js'
 import { useSkin } from '@/shared/composables/useSkin.js'
 import { DEFAULT_SKIN } from '@/skins/registry.js'
 
index 0c995522e2c792ffedd4598e554e8becf182032e..60dfeea5c3098ccaa2955ee72764287624f7064e 100644 (file)
@@ -11,7 +11,7 @@
 </template>
 
 <script setup lang="ts">
-import { setToLocalStorage } from '@/composables/Utils.js'
+import { setToLocalStorage } from '@/core/index.js'
 import { SKIN_STORAGE_KEY } from '@/shared/composables/useSkin.js'
 import { DEFAULT_SKIN, skins } from '@/skins/registry.js'
 
index 74132e0c6f6bce76bb8ca19f3287eee07e6211ca..85572fa0474286161e7370d56a7eee2575c2bb4c 100644 (file)
@@ -1,6 +1,7 @@
 export { useAddStationsForm } from './useAddStationsForm.js'
 export { useAsyncAction } from './useAsyncAction.js'
 export { useConnectorActions } from './useConnectorActions.js'
+export { useFetchData } from './useFetchData.js'
 export { useLayoutData } from './useLayoutData.js'
 export { useSetUrlForm } from './useSetUrlForm.js'
 export { useSimulatorControl } from './useSimulatorControl.js'
index bc1a00354a676ea101b76b55d093776e3bbc0006..f6a2057d6e0b4b522b0fe446a9dfca1e5a814c24 100644 (file)
@@ -2,7 +2,7 @@ import { randomUUID, type UUIDv4 } from 'ui-common'
 import { type DeepReadonly, readonly, ref, type Ref, watch } from 'vue'
 import { useToast } from 'vue-toast-notification'
 
-import { useTemplates, useUIClient } from '@/composables/Utils.js'
+import { useTemplates, useUIClient } from '@/core/index.js'
 
 export interface AddStationsFormState {
   autoStart: boolean
index 01b719c7869e03f40306497ad3fa7f62284e04cd..ccf8ffce35a3678274099553d34edff8157232bf 100644 (file)
@@ -7,7 +7,7 @@ import type { OCPPVersion } from 'ui-common'
 import { computed, type MaybeRefOrGetter, readonly, toValue } from 'vue'
 import { useToast } from 'vue-toast-notification'
 
-import { useUIClient } from '@/composables/Utils.js'
+import { useUIClient } from '@/core/index.js'
 import { useAsyncAction } from '@/shared/composables/useAsyncAction.js'
 
 interface ConnectorActionsDeps {
diff --git a/ui/web/src/shared/composables/useFetchData.ts b/ui/web/src/shared/composables/useFetchData.ts
new file mode 100644 (file)
index 0000000..118a632
--- /dev/null
@@ -0,0 +1,38 @@
+import type { ResponsePayload } from 'ui-common'
+import type { Ref } from 'vue'
+
+import { ref as vueRef } from 'vue'
+import { useToast } from 'vue-toast-notification'
+
+export const useFetchData = (
+  clientFn: () => Promise<ResponsePayload>,
+  onSuccess: (response: ResponsePayload) => void,
+  errorMsg: string,
+  onError?: () => void
+): { fetch: () => void; fetching: Ref<boolean> } => {
+  const fetching = vueRef(false)
+  const $toast = useToast()
+  const fetch = (): void => {
+    if (!fetching.value) {
+      fetching.value = true
+      clientFn()
+        .then((response: ResponsePayload) => {
+          onSuccess(response)
+          return undefined
+        })
+        .finally(() => {
+          fetching.value = false
+        })
+        .catch((error: unknown) => {
+          try {
+            onError?.()
+          } catch (callbackError: unknown) {
+            console.error('Error in onError callback:', callbackError)
+          }
+          $toast.error(errorMsg)
+          console.error(`${errorMsg}:`, error)
+        })
+    }
+  }
+  return { fetch, fetching }
+}
index 73fa19029c9d31c7e6d93ec1a301218730144f14..f2df9c70d29667dad81fd856c22508b11b0c2a35 100644 (file)
@@ -10,13 +10,9 @@ import {
   shallowRef,
 } from 'vue'
 
-import {
-  useChargingStations,
-  useConfiguration,
-  useFetchData,
-  useTemplates,
-  useUIClient,
-} from '@/composables/index.js'
+import { useChargingStations, useConfiguration, useTemplates, useUIClient } from '@/core/index.js'
+
+import { useFetchData } from './useFetchData.js'
 
 export interface LayoutData {
   /** Fetches only the charging stations list. */
index 37d9fa22a2cd101d69315c98660f71573268356d..8d9e7c056436368a7ba32a8b0bf1a5ad5120d914 100644 (file)
@@ -1,7 +1,7 @@
 import { readonly, ref, type Ref } from 'vue'
 import { useToast } from 'vue-toast-notification'
 
-import { useUIClient } from '@/composables/Utils.js'
+import { useUIClient } from '@/core/index.js'
 
 export interface SetUrlFormState {
   supervisionPassword: string
index 3ba7599897d4f5962e462c3b8d0814001f065516..ef30d32c5e91297686de00f0f9d9ee5119c6cede 100644 (file)
@@ -10,7 +10,7 @@ import {
   useChargingStations,
   useConfiguration,
   useUIClient,
-} from '@/composables/index.js'
+} from '@/core/index.js'
 import { useAsyncAction } from '@/shared/composables/useAsyncAction.js'
 import { type LayoutData } from '@/shared/composables/useLayoutData.js'
 
index d8b2060920059bd882604fd4ac56a245501b3c18..f5bc2463c085d6ee500bcc35365a8fca9d543171 100644 (file)
@@ -1,7 +1,7 @@
 import { type SKIN_IDS } from 'ui-common'
 import { readonly, ref, type Ref } from 'vue'
 
-import { getFromLocalStorage, setToLocalStorage } from '@/composables/Utils.js'
+import { getFromLocalStorage, setToLocalStorage } from '@/core/index.js'
 import { validateTokenContract } from '@/shared/tokens/contract.js'
 // Intentional: registry.ts is pure metadata (ids, labels, loaders) — no behavioral coupling.
 import { DEFAULT_SKIN, type SkinDefinition, skins } from '@/skins/registry.js'
index 0ba825793ce4a58a5b2ec2e4e05397ba1d9f2224..c487117e86526f07769f25e8a2164e1fd90a433c 100644 (file)
@@ -2,7 +2,7 @@ import { convertToInt, type OCPPVersion } from 'ui-common'
 import { readonly, ref, type Ref } from 'vue'
 import { useToast } from 'vue-toast-notification'
 
-import { useUIClient } from '@/composables/Utils.js'
+import { useUIClient } from '@/core/index.js'
 
 export interface StartTxFormConfig {
   connectorId: string
index ea0c152d04c1a6861082a8aca75a9062acc772c8..5a0c391721ba16fad25417d18ad4207efa6b06ee 100644 (file)
@@ -4,7 +4,7 @@
  */
 import { readonly } from 'vue'
 
-import { useUIClient } from '@/composables/Utils.js'
+import { useUIClient } from '@/core/index.js'
 import { useAsyncAction } from '@/shared/composables/useAsyncAction.js'
 
 /**
index 57e5faf9b3c0cf66c9595a9d41b1a6b7ac107d67..9f399956824668401582b3325199c69c6a6d7583 100644 (file)
@@ -1,7 +1,7 @@
 import { THEME_IDS } from 'ui-common'
 import { readonly, ref, type Ref } from 'vue'
 
-import { getFromLocalStorage, setToLocalStorage } from '@/composables/Utils.js'
+import { getFromLocalStorage, setToLocalStorage } from '@/core/index.js'
 import { validateTokenContract } from '@/shared/tokens/contract.js'
 
 export const AVAILABLE_THEMES = THEME_IDS
index da394a42854696b3c0fd45ff6964ce60e88e7782..0c9d6b99d283b357e9893b9be291dbd1804ef20c 100644 (file)
@@ -1,4 +1,4 @@
-import { EMPTY_VALUE_PLACEHOLDER } from '@/composables/Constants.js'
+import { EMPTY_VALUE_PLACEHOLDER } from '@/core/Constants.js'
 
 export interface FormatSupervisionUrlOptions {
   /** Insert zero-width-space after dots for word-break in table cells. */
index c57ab1cc6a222b574d4d7f46ff32d893375ffc56..ae91b53ef62d3a0d63b3a69915534f9a6558bb85 100644 (file)
@@ -110,7 +110,7 @@ import {
   TOGGLE_BUTTON_KEY_PREFIX,
   UI_SERVER_CONFIGURATION_INDEX_KEY,
   useChargingStations,
-} from '@/composables'
+} from '@/core'
 import { useLayoutData } from '@/shared/composables/useLayoutData.js'
 import { useSimulatorControl } from '@/shared/composables/useSimulatorControl.js'
 import { useSkin } from '@/shared/composables/useSkin.js'
index 6699651ef60a16b8c42a555d51d547402cb5675c..1da70e47e52f9b8b974b1c3ad66443272a589b4b 100644 (file)
 <script setup lang="ts">
 import { useRouter } from 'vue-router'
 
-import { resetToggleButtonState, ROUTE_NAMES } from '@/composables'
+import { resetToggleButtonState, ROUTE_NAMES } from '@/core'
 import { useAddStationsForm } from '@/shared/composables/useAddStationsForm.js'
 
 import Button from '../buttons/ClassicButton.vue'
index 3689712cce80bf6a92bd437ee58c0d82aa380c56..d4f7d3d5cdf0f432738aaff41724c88d63b704a2 100644 (file)
@@ -44,7 +44,7 @@
 <script setup lang="ts">
 import { useRouter } from 'vue-router'
 
-import { resetToggleButtonState, ROUTE_NAMES } from '@/composables'
+import { resetToggleButtonState, ROUTE_NAMES } from '@/core'
 import { useSetUrlForm } from '@/shared/composables/useSetUrlForm.js'
 
 import Button from '../buttons/ClassicButton.vue'
index 33e82d650f2fbc891c6b01d41e41b6c7b7447e36..762d39dd2ce5109adecbf3fb0989129f0e963c49 100644 (file)
@@ -42,7 +42,7 @@ import type { OCPPVersion } from 'ui-common'
 import { computed } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 
-import { resetToggleButtonState, ROUTE_NAMES } from '@/composables'
+import { resetToggleButtonState, ROUTE_NAMES } from '@/core'
 import { useStartTxForm } from '@/shared/composables/useStartTxForm.js'
 
 import Button from '../buttons/ClassicButton.vue'
index d8a946f2016fe5fa51211f9e657d6a9b9c0d91d9..ecc38b1c6f7bc537e72cdc53e7af0f146acf74a4 100644 (file)
@@ -16,7 +16,7 @@ import {
   setToLocalStorage,
   SHARED_TOGGLE_BUTTON_KEY_PREFIX,
   TOGGLE_BUTTON_KEY_PREFIX,
-} from '@/composables'
+} from '@/core'
 
 import Button from './ClassicButton.vue'
 
index 7f121e4d0137878eb04e766be36f5e5720667ee6..7f33f735c1a7b15ccaffd62b56a54eba57e8d3d1 100644 (file)
@@ -71,7 +71,7 @@ import type { ConnectorStatus, OCPPVersion, Status } from 'ui-common'
 import { computed } from 'vue'
 import { useRouter } from 'vue-router'
 
-import { EMPTY_VALUE_PLACEHOLDER, ROUTE_NAMES } from '@/composables'
+import { EMPTY_VALUE_PLACEHOLDER, ROUTE_NAMES } from '@/core'
 import { useConnectorActions } from '@/shared/composables/useConnectorActions.js'
 
 import Button from '../buttons/ClassicButton.vue'
index a87233c9ecc793d0b18e4d3b4ab4033c24d45eb7..0eea87c56473659491df0334cd7a3e25b4029cfd 100644 (file)
@@ -125,7 +125,7 @@ import {
 } from 'ui-common'
 import { computed } from 'vue'
 
-import { deleteLocalStorageByKeyPattern, EMPTY_VALUE_PLACEHOLDER, ROUTE_NAMES } from '@/composables'
+import { deleteLocalStorageByKeyPattern, EMPTY_VALUE_PLACEHOLDER, ROUTE_NAMES } from '@/core'
 import { useStationActions } from '@/shared/composables/useStationActions.js'
 import { formatSupervisionUrl } from '@/shared/utils/formatSupervisionUrl.js'
 import { getATGStatus, getConnectorEntries } from '@/shared/utils/stationStatus.js'
index fe9ce54eb902485cad7fe932752ddfdb07d463dc..fc7f2b3b0bbc72d48b1627d5aa1801a9e6fac50d 100644 (file)
 import { type OCPPVersion } from 'ui-common'
 import { defineAsyncComponent, ref } from 'vue'
 
-import {
-  getFromLocalStorage,
-  UI_SERVER_CONFIGURATION_INDEX_KEY,
-  useChargingStations,
-} from '@/composables'
+import { getFromLocalStorage, UI_SERVER_CONFIGURATION_INDEX_KEY, useChargingStations } from '@/core'
 import SkinLoadError from '@/shared/components/SkinLoadError.vue'
 import SkinLoading from '@/shared/components/SkinLoading.vue'
 import { useLayoutData } from '@/shared/composables/useLayoutData.js'
index cc415717c5403e1282d92e09d2bc60f8654a849d..fe0665e3103a6978c99e5134e67b19fa971d5865 100644 (file)
@@ -168,7 +168,7 @@ import {
 } from 'ui-common'
 import { computed, ref } from 'vue'
 
-import { deleteLocalStorageByKeyPattern, EMPTY_VALUE_PLACEHOLDER as EMPTY } from '@/composables'
+import { deleteLocalStorageByKeyPattern, EMPTY_VALUE_PLACEHOLDER as EMPTY } from '@/core'
 import { useStationActions } from '@/shared/composables/useStationActions.js'
 import { formatSupervisionUrl } from '@/shared/utils/formatSupervisionUrl.js'
 import {
index 701b33be6614e57c4b2e090a5864b16dd2878148..aa8ae6bac224fadd25b42b84745cf4ab7f4e0545 100644 (file)
@@ -63,7 +63,7 @@
 import { computed, ref } from 'vue'
 import { useToast } from 'vue-toast-notification'
 
-import { useUIClient } from '@/composables'
+import { useUIClient } from '@/core'
 
 import { type FailureInfo, getFailureInfo } from '../../utils/errors.js'
 import ActionButton from '../ActionButton.vue'
index 7c515e4e174b71e0d8dd52cf1d07f1ffef0ba009..0689f786024c47675efae00364b77a19074b5a20 100644 (file)
@@ -83,7 +83,7 @@
 <script setup lang="ts">
 import { computed, ref, watch } from 'vue'
 
-import { useChargingStations, useUIClient } from '@/composables'
+import { useChargingStations, useUIClient } from '@/core'
 import { useSetUrlForm } from '@/shared/composables/useSetUrlForm.js'
 import { stripStationId } from '@/shared/utils/stripStationId.js'
 
index 138ffe9fd9843b8f14cef3ffc0efdcf0cb07af9b..b2b7d4ef9472d6bf0423c9846bbfe7fe3670fe4b 100644 (file)
@@ -14,7 +14,7 @@ import {
 } from 'ui-common'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 
-import { UIClient } from '@/composables'
+import { UIClient } from '@/core'
 
 import { toastMock } from '../setup'
 import { createUIServerConfig, TEST_HASH_ID, TEST_ID_TAG } from './constants'
index fe124dd74103a6d80d75b9407a60ed4ca13b1c01..566a3bc02783aeb2690fd9f901cfcead6f7188c4 100644 (file)
@@ -14,9 +14,9 @@ import {
   setToLocalStorage,
   useChargingStations,
   useConfiguration,
-  useFetchData,
   useTemplates,
-} from '@/composables'
+} from '@/core'
+import { useFetchData } from '@/shared/composables/useFetchData.js'
 
 import { toastMock } from '../setup'
 
index 76e9b860ff5ce0038d71708388dc0f07d21f77a5..52a440a6f1a3ce3f08a3ce21909f2a8d6a55f97e 100644 (file)
@@ -4,7 +4,7 @@
  */
 import { describe, expect, it, vi } from 'vitest'
 
-import { ROUTE_NAMES } from '@/composables'
+import { ROUTE_NAMES } from '@/core'
 import { router } from '@/router/index.js'
 
 vi.mock('@/shared/composables/useSkin.js', async importOriginal => {
index b1edacdd488831f8222013bbb78a5e7cc28abd6c..c14d00e8a52eae0d8866b87e4fe60483c90792f8 100644 (file)
@@ -10,7 +10,7 @@ import { toastMock } from '../../../setup.js'
 const mockAddChargingStations = vi.fn().mockResolvedValue({ status: 'success' })
 const mockTemplates = ref(['template1.json', 'template2.json'])
 
-vi.mock('@/composables/Utils.js', () => ({
+vi.mock('@/core/index.js', () => ({
   resetToggleButtonState: vi.fn(),
   useTemplates: () => mockTemplates,
   useUIClient: () => ({
index 7eafc4cdf11c25cac905debc47affdbf38c75c23..a28a6211d81cdb66df3b38f69d05e9a5a50fb2e9 100644 (file)
@@ -12,7 +12,7 @@ import { createMockUIClient, type MockUIClient, withSetup } from '../../helpers.
 
 let mockClient: MockUIClient
 
-vi.mock('@/composables/Utils.js', () => ({
+vi.mock('@/core/index.js', () => ({
   useUIClient: () => mockClient,
 }))
 
index 3a7ee8e676e12fd0b950654027563ee55564837f..688bf39b4d32ce0fe7e0823217148c2546a240ea 100644 (file)
@@ -8,9 +8,9 @@ import { flushPromises } from '@vue/test-utils'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 import { type Ref, ref } from 'vue'
 
-import { useChargingStations, useConfiguration, useTemplates, useUIClient } from '@/composables'
+import { useChargingStations, useConfiguration, useTemplates, useUIClient } from '@/core'
 
-vi.mock('@/composables', async importOriginal => {
+vi.mock('@/core', async importOriginal => {
   const actual = await importOriginal()
   return {
     ...(actual as Record<string, unknown>),
index 3ea701eecd077604d331d4bf0aa5fe41320cc8ed..ac2218823926f14403288a6f2eff9c4414d6ffc4 100644 (file)
@@ -8,7 +8,7 @@ import { toastMock } from '../../../setup.js'
 
 const mockSetSupervisionUrl = vi.fn().mockResolvedValue({ status: 'success' })
 
-vi.mock('@/composables/Utils.js', () => ({
+vi.mock('@/core/index.js', () => ({
   useUIClient: () => ({
     setSupervisionUrl: mockSetSupervisionUrl,
   }),
index d0909db5eec321b885b07c05fc7b27b6649083e2..c408263b086f8f6937cb19309bf654f3120f8673 100644 (file)
@@ -15,13 +15,13 @@ import {
   useChargingStations,
   useConfiguration,
   useUIClient,
-} from '@/composables'
+} from '@/core'
 
 import { toastMock } from '../../../setup.js'
 import { createUIServerConfig } from '../../constants'
 import { createMockUIClient, type MockUIClient, withSetup } from '../../helpers.js'
 
-vi.mock('@/composables', async importOriginal => {
+vi.mock('@/core', async importOriginal => {
   const actual = await importOriginal()
   return {
     ...(actual as Record<string, unknown>),
index d0a5c0ee002a49befdb22db4b17bfc22619d9514..d653ee0ecf455ddf281d2bb548a9356471e0abe0 100644 (file)
@@ -9,7 +9,7 @@ import { toastMock } from '../../../setup.js'
 const mockAuthorize = vi.fn().mockResolvedValue({ status: 'success' })
 const mockStartTransaction = vi.fn().mockResolvedValue({ status: 'success' })
 
-vi.mock('@/composables/Utils.js', () => ({
+vi.mock('@/core/index.js', () => ({
   useUIClient: () => ({
     authorize: mockAuthorize,
     startTransaction: mockStartTransaction,
index 12785f6fec2ec5c457109817957ee31dd3333dcc..a32ae6b0e49ad0c3a34a78de5409949a0482f486 100644 (file)
@@ -11,7 +11,7 @@ import { createMockUIClient, type MockUIClient, withSetup } from '../../helpers.
 
 let mockUIClient: MockUIClient
 
-vi.mock('@/composables/Utils.js', () => ({
+vi.mock('@/core/index.js', () => ({
   useUIClient: () => mockUIClient,
 }))
 
index 0fb2f0b2f0dbe58cb5a075dfbb511f5740250ff8..883f9da4d9cb3e0a7521fb5d099d0183f87e7c8c 100644 (file)
@@ -6,7 +6,7 @@ import { flushPromises, mount } from '@vue/test-utils'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 import { ref, shallowRef } from 'vue'
 
-import { chargingStationsKey, configurationKey, templatesKey, uiClientKey } from '@/composables'
+import { chargingStationsKey, configurationKey, templatesKey, uiClientKey } from '@/core'
 import AddChargingStations from '@/skins/classic/components/actions/AddChargingStations.vue'
 import SetSupervisionUrl from '@/skins/classic/components/actions/SetSupervisionUrl.vue'
 import StartTransaction from '@/skins/classic/components/actions/StartTransaction.vue'
index 7c02c5af1cf5ee4ea85a79b22e9ef795bf0e8f9f..a2efabf5054a3b76075050171284e4a10d76affc 100644 (file)
@@ -6,7 +6,7 @@ import { flushPromises, mount } from '@vue/test-utils'
 import { type ConnectorStatus, OCPP16ChargePointStatus, OCPPVersion } from 'ui-common'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 
-import { uiClientKey } from '@/composables'
+import { uiClientKey } from '@/core'
 import CSConnector from '@/skins/classic/components/charging-stations/CSConnector.vue'
 
 import { toastMock } from '../../../setup.js'
index 4683b8dc6586f422668b6b5cc72b9d38361f062a..4de141ee6b2814793783d51b2ff0249edd6d4104 100644 (file)
@@ -6,7 +6,7 @@ import { flushPromises, mount } from '@vue/test-utils'
 import { type ChargingStationData, OCPP16AvailabilityType, OCPPVersion } from 'ui-common'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 
-import { uiClientKey } from '@/composables'
+import { uiClientKey } from '@/core'
 import CSData from '@/skins/classic/components/charging-stations/CSData.vue'
 
 import { toastMock } from '../../../setup.js'
index f9cb273608c01addeabf8b64dc09c4e250ee63db..1dfe9346f7c024ac04eddcb89821e317f61ce5ff 100644 (file)
@@ -5,7 +5,7 @@
 import { shallowMount } from '@vue/test-utils'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 
-import { uiClientKey } from '@/composables'
+import { uiClientKey } from '@/core'
 import CSTable from '@/skins/classic/components/charging-stations/CSTable.vue'
 
 import { createChargingStationData } from '../../constants.js'
index f9285e2ad32a3b16d76c667ae82211a2eb0128ee..1f1649432a524b829e86a16e0a7087b5e7e75134 100644 (file)
@@ -8,7 +8,7 @@ import { flushPromises, mount } from '@vue/test-utils'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 import { defineComponent, shallowRef } from 'vue'
 
-import { chargingStationsKey, configurationKey, templatesKey, uiClientKey } from '@/composables'
+import { chargingStationsKey, configurationKey, templatesKey, uiClientKey } from '@/core'
 import ToggleButton from '@/skins/classic/components/buttons/ToggleButton.vue'
 import CSTable from '@/skins/classic/components/charging-stations/CSTable.vue'
 
index bd56723faab000daca93a7d63e5c2c388d81ffc5..b745e6dc329f8ebc10dc4f169e18bbf50344ee9b 100644 (file)
@@ -6,7 +6,7 @@ import { flushPromises, mount } from '@vue/test-utils'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 import { ref } from 'vue'
 
-import { chargingStationsKey, configurationKey, templatesKey, uiClientKey } from '@/composables'
+import { chargingStationsKey, configurationKey, templatesKey, uiClientKey } from '@/core'
 import ClassicLayout from '@/skins/classic/ClassicLayout.vue'
 
 import { createUIServerConfig } from '../../constants'
index 87735225b8fdade2098d480b30ba80e8e2febfdc..93f5e267d4eb3cd733cdbef72d04250eb41a81cd 100644 (file)
@@ -11,7 +11,7 @@ import {
 } from 'ui-common'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 
-import { uiClientKey } from '@/composables'
+import { uiClientKey } from '@/core'
 import ConnectorRow from '@/skins/modern/components/ConnectorRow.vue'
 
 import { toastMock } from '../../../setup.js'
index c8cefa37ca0da545138333913731fc0953800778..9d8d00be0405ddf1ebddc5e93dcc277586df13cb 100644 (file)
@@ -8,7 +8,7 @@ import { ResponseStatus, ServerFailureError } from 'ui-common'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 import { defineComponent, ref } from 'vue'
 
-import { chargingStationsKey, templatesKey, uiClientKey } from '@/composables'
+import { chargingStationsKey, templatesKey, uiClientKey } from '@/core'
 
 // Mock Modal to render slots inline (no Teleport), so `wrapper.find()` works.
 vi.mock('@/skins/modern/components/ModernModal.vue', () => ({
index 76645574305bacbc5c5b93e90fe58e9bb5da8fb0..015fa0726e9820ac0a7cbca9aa10137ef0f8db2c 100644 (file)
@@ -14,14 +14,14 @@ import {
   UI_SERVER_CONFIGURATION_INDEX_KEY,
   uiClientKey,
   useUIClient,
-} from '@/composables'
+} from '@/core'
 import ModernLayout from '@/skins/modern/ModernLayout.vue'
 
 import { toastMock } from '../../../setup.js'
 import { createChargingStationData, createUIServerConfig } from '../../constants'
 import { createMockUIClient, type MockUIClient } from '../../helpers.js'
 
-vi.mock('@/composables', async importOriginal => {
+vi.mock('@/core', async importOriginal => {
   const actual = await importOriginal()
   return { ...(actual as Record<string, unknown>), useUIClient: vi.fn() }
 })
index cb9679f7be9199cc96ca51069361422e200c91d0..de7a083dc66c27c30e7dc1573acae0fffbd04cbb 100644 (file)
@@ -6,7 +6,7 @@ import { flushPromises, mount } from '@vue/test-utils'
 import { type ChargingStationData, OCPP16AvailabilityType } from 'ui-common'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 
-import { uiClientKey } from '@/composables'
+import { uiClientKey } from '@/core'
 import StationCard from '@/skins/modern/components/StationCard.vue'
 
 import { toastMock } from '../../../setup.js'