refactor(ui): put all main actions to the same bar
[e-mobility-charging-stations-simulator.git] / ui / web / src / views / ChargingStationsView.vue
index a19c14c32283c7d35591552b9486c6a8f048b85a..094988b101d4f9df3184437e6609f022e046b994 100644 (file)
 <template>
   <Container id="charging-stations-container">
-    <Container
-      v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
-      id="ui-server-container"
-    >
-      <select
-        id="ui-server-selector"
-        v-model="state.uiServerIndex"
-        @change="
-          () => {
-            if (
-              getFromLocalStorage<number>('uiServerConfigurationIndex', 0) !== state.uiServerIndex
-            ) {
-              app?.appContext.config.globalProperties.$uiClient.setConfiguration(
-                app?.appContext.config.globalProperties.$configuration.uiServer[state.uiServerIndex]
-              )
-              initializeWSEventListeners()
-              app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
-                'open',
-                () => {
-                  setToLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
-                  $router.currentRoute.value.name !== 'charging-stations' &&
-                    $router.push({ name: 'charging-stations' })
-                },
-                { once: true }
-              )
-              app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
-                'error',
-                () => {
-                  state.uiServerIndex = getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
-                  app?.appContext.config.globalProperties.$uiClient.setConfiguration(
-                    app?.appContext.config.globalProperties.$configuration.uiServer[
-                      getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
-                    ]
-                  )
-                  initializeWSEventListeners()
-                },
-                { once: true }
-              )
+    <Container id="buttons-container">
+      <Container
+        v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
+        id="ui-server-container"
+      >
+        <select
+          id="ui-server-selector"
+          v-model="state.uiServerIndex"
+          @change="
+            () => {
+              if (
+                getFromLocalStorage<number>('uiServerConfigurationIndex', 0) !== state.uiServerIndex
+              ) {
+                app?.appContext.config.globalProperties.$uiClient.setConfiguration(
+                  app?.appContext.config.globalProperties.$configuration.uiServer[
+                    state.uiServerIndex
+                  ]
+                )
+                initializeWSEventListeners()
+                app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
+                  'open',
+                  () => {
+                    setToLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
+                    clearToggleButtons()
+                    $router.currentRoute.value.name !== 'charging-stations' &&
+                      $router.push({ name: 'charging-stations' })
+                  },
+                  { once: true }
+                )
+                app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
+                  'error',
+                  () => {
+                    state.uiServerIndex = getFromLocalStorage<number>(
+                      'uiServerConfigurationIndex',
+                      0
+                    )
+                    app?.appContext.config.globalProperties.$uiClient.setConfiguration(
+                      app?.appContext.config.globalProperties.$configuration.uiServer[
+                        getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
+                      ]
+                    )
+                    initializeWSEventListeners()
+                  },
+                  { once: true }
+                )
+              }
             }
+          "
+        >
+          <option
+            v-for="uiServerConfiguration in uiServerConfigurations"
+            :value="uiServerConfiguration.index"
+          >
+            {{
+              uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host
+            }}
+          </option>
+        </select>
+      </Container>
+      <ToggleButton
+        :id="'simulator'"
+        :key="state.renderSimulator"
+        :status="state.simulatorState?.started"
+        :on="() => startSimulator()"
+        :off="() => stopSimulator()"
+        :class="
+          state.simulatorState?.started === true
+            ? 'simulator-stop-button'
+            : 'simulator-start-button'
+        "
+      >
+        {{ state.simulatorState?.started === true ? 'Stop' : 'Start' }} Simulator
+      </ToggleButton>
+      <ToggleButton
+        :id="'add-charging-stations'"
+        :key="state.renderAddChargingStations"
+        :shared="true"
+        :on="
+          () => {
+            $router.push({ name: 'add-charging-stations' })
+          }
+        "
+        :off="
+          () => {
+            $router.push({ name: 'charging-stations' })
+          }
+        "
+        @clicked="
+          () => {
+            state.renderChargingStations = randomUUID()
           }
         "
       >
-        <option
-          v-for="uiServerConfiguration in uiServerConfigurations"
-          :value="uiServerConfiguration.index"
-        >
-          {{ uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host }}
-        </option>
-      </select>
-    </Container>
-    <Container id="buttons-container">
-      <Button @click="startSimulator()">Start Simulator</Button>
-      <Button @click="stopSimulator()">Stop Simulator</Button>
-      <Button @click="$router.push({ name: 'add-charging-stations' })">
         Add Charging Stations
-      </Button>
+      </ToggleButton>
       <ReloadButton
         id="reload-button"
         :loading="state.loading"
-        @click="loadChargingStations(() => (state.renderChargingStationsList = randomUUID()))"
+        @click="loadChargingStations(() => (state.renderChargingStations = randomUUID()))"
       />
     </Container>
     <CSTable
       v-show="
         Array.isArray(app?.appContext.config.globalProperties.$chargingStations) &&
-        app?.appContext.config.globalProperties.$chargingStations.length > 0
+        app.appContext.config.globalProperties.$chargingStations.length > 0
       "
-      :key="state.renderChargingStationsList"
+      :key="state.renderChargingStations"
       :charging-stations="app?.appContext.config.globalProperties.$chargingStations"
+      @need-refresh="
+        () => {
+          state.renderAddChargingStations = randomUUID()
+          state.renderChargingStations = randomUUID()
+        }
+      "
     />
   </Container>
 </template>
@@ -80,17 +125,65 @@ import CSTable from '@/components/charging-stations/CSTable.vue'
 import type { ResponsePayload, UIServerConfigurationSection } from '@/types'
 import Container from '@/components/Container.vue'
 import ReloadButton from '@/components/buttons/ReloadButton.vue'
-import Button from '@/components/buttons/Button.vue'
-import { getFromLocalStorage, setToLocalStorage } from '@/composables'
+import {
+  deleteFromLocalStorage,
+  getFromLocalStorage,
+  getLocalStorage,
+  randomUUID,
+  setToLocalStorage
+} from '@/composables'
+import ToggleButton from '@/components/buttons/ToggleButton.vue'
 
-const randomUUID = (): `${string}-${string}-${string}-${string}-${string}` => {
-  return crypto.randomUUID()
-}
+const state = ref<{
+  renderSimulator: `${string}-${string}-${string}-${string}-${string}`
+  renderAddChargingStations: `${string}-${string}-${string}-${string}-${string}`
+  renderChargingStations: `${string}-${string}-${string}-${string}-${string}`
+  loading: boolean
+  simulatorState?: { started: boolean }
+  uiServerIndex: number
+}>({
+  renderSimulator: randomUUID(),
+  renderAddChargingStations: randomUUID(),
+  renderChargingStations: randomUUID(),
+  loading: false,
+  uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
+})
 
 const app = getCurrentInstance()
 
+const clearToggleButtons = (): void => {
+  for (const key in getLocalStorage()) {
+    if (key.includes('toggle-button')) {
+      deleteFromLocalStorage(key)
+    }
+  }
+}
+
+const clearChargingStations = (): void => {
+  app!.appContext.config.globalProperties.$chargingStations = []
+  state.value.renderChargingStations = randomUUID()
+}
+
+const uiClient = app?.appContext.config.globalProperties.$uiClient
+
+const getSimulatorState = (): void => {
+  uiClient
+    .simulatorState()
+    .then((response: ResponsePayload) => {
+      state.value.simulatorState = response.state as { started: boolean }
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at fetching simulator state')
+      console.error('Error at fetching simulator state:', error)
+    })
+    .finally(() => {
+      state.value.renderSimulator = randomUUID()
+    })
+}
+
 const initializeWSEventListeners = () => {
   app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('open', () => {
+    getSimulatorState()
     uiClient
       .listTemplates()
       .then((response: ResponsePayload) => {
@@ -105,29 +198,27 @@ const initializeWSEventListeners = () => {
         $toast.error('Error at fetching charging station templates')
         console.error('Error at fetching charging station templates:', error)
       })
-    loadChargingStations(() => (state.value.renderChargingStationsList = randomUUID()))
-  })
-  app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('error', () => {
-    app.appContext.config.globalProperties.$chargingStations = []
-    state.value.renderChargingStationsList = randomUUID()
-  })
-  app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('close', () => {
-    app.appContext.config.globalProperties.$chargingStations = []
-    state.value.renderChargingStationsList = randomUUID()
+      .finally(() => {
+        state.value.renderAddChargingStations = randomUUID()
+      })
+    loadChargingStations(() => {
+      state.value.renderChargingStations = randomUUID()
+    })
   })
+  app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
+    'error',
+    clearChargingStations
+  )
+  app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
+    'close',
+    clearChargingStations
+  )
 }
 
 onMounted(() => {
   initializeWSEventListeners()
 })
 
-const state = ref({
-  renderChargingStationsList: randomUUID(),
-  loading: false,
-  uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
-})
-
-const uiClient = app?.appContext.config.globalProperties.$uiClient
 const uiServerConfigurations: { configuration: UIServerConfigurationSection; index: number }[] =
   app?.appContext.config.globalProperties.$configuration.uiServer.map(
     (configuration: UIServerConfigurationSection, index: number) => ({
@@ -174,6 +265,9 @@ const startSimulator = (): void => {
       $toast.error('Error at starting simulator')
       console.error('Error at starting simulator:', error)
     })
+    .finally(() => {
+      getSimulatorState()
+    })
 }
 const stopSimulator = (): void => {
   uiClient
@@ -188,6 +282,9 @@ const stopSimulator = (): void => {
       $toast.error('Error at stopping simulator')
       console.error('Error at stopping simulator:', error)
     })
+    .finally(() => {
+      getSimulatorState()
+    })
 }
 </script>
 
@@ -201,31 +298,43 @@ const stopSimulator = (): void => {
 
 #ui-server-container {
   display: flex;
-  flex-direction: row;
+  justify-content: center;
 }
 
 #ui-server-selector {
   width: 100%;
+  background-color: rgb(239, 239, 239);
   text-align: center;
 }
 
+#ui-server-selector:hover {
+  background-color: lightgrey;
+}
+
 #buttons-container {
   display: flex;
   flex-direction: row;
 }
 
+.simulator-start-button {
+  color: ivory;
+  background-color: green;
+}
+
+.simulator-stop-button {
+  color: ivory;
+  background-color: red;
+}
+
 #action-button {
   flex: none;
 }
 
 #reload-button {
-  flex: auto;
-  color: white;
+  color: ivory;
   background-color: blue;
   font-size: 1.5rem;
   font-weight: bold;
-  align-items: center;
-  justify-content: center;
 }
 
 #reload-button:hover {
@@ -233,11 +342,11 @@ const stopSimulator = (): void => {
 }
 
 #reload-button:active {
-  background-color: red;
+  background-color: darkblue;
 }
 
 #action {
-  color: white;
+  color: ivory;
   background-color: black;
   padding: 1%;
 }