refactor(ui): cleanup UI client instance getter
[e-mobility-charging-stations-simulator.git] / ui / web / src / components / charging-stations / CSData.vue
index da25b46b10c8ee0fadce37fbb547d87899137068..0da66895834c8296b982b7f2444b149d0ea516ab 100644 (file)
 <template>
-  <tr v-for="(connector, index) in getConnectors()" class="cs-table__row">
-    <CSConnector
-      :hash-id="getHashId()"
-      :connector="connector"
-      :connector-id="index + 1"
-      :transaction-id="connector.transactionId"
-      :id-tag="props.idTag"
-    />
-    <td class="cs-table__name-col">{{ getId() }}</td>
-    <td class="cs-table__started-col">{{ getStarted() }}</td>
-    <td class="cs-table__wsState-col">{{ getWsState() }}</td>
-    <td class="cs-table__registration-status-col">{{ getRegistrationStatus() }}</td>
-    <td class="cs-table__vendor-col">{{ getVendor() }}</td>
-    <td class="cs-table__model-col">{{ getModel() }}</td>
-    <td class="cs-table__firmware-col">{{ getFirmwareVersion() }}</td>
+  <tr class="cs-table__row">
+    <td class="cs-table__column">
+      {{ chargingStation.stationInfo.chargingStationId }}
+    </td>
+    <td class="cs-table__column">{{ chargingStation.started === true ? 'Yes' : 'No' }}</td>
+    <td class="cs-table__column">
+      {{ getSupervisionUrl() }}
+    </td>
+    <td class="cs-table__column">{{ getWSState() }}</td>
+    <td class="cs-table__column">
+      {{ chargingStation.bootNotificationResponse?.status ?? 'Ø' }}
+    </td>
+    <td class="cs-table__column">
+      {{ chargingStation.stationInfo.templateName }}
+    </td>
+    <td class="cs-table__column">{{ chargingStation.stationInfo.chargePointVendor }}</td>
+    <td class="cs-table__column">{{ chargingStation.stationInfo.chargePointModel }}</td>
+    <td class="cs-table__column">
+      {{ chargingStation.stationInfo.firmwareVersion ?? 'Ø' }}
+    </td>
+    <td class="cs-table__column">
+      <Button @click="startChargingStation()">Start Charging Station</Button>
+      <Button @click="stopChargingStation()">Stop Charging Station</Button>
+      <ToggleButton
+        :id="`${chargingStation.stationInfo.hashId}-set-supervision-url`"
+        :shared="true"
+        :on="
+          () => {
+            $router.push({
+              name: 'set-supervision-url',
+              params: {
+                hashId: chargingStation.stationInfo.hashId,
+                chargingStationId: chargingStation.stationInfo.chargingStationId
+              }
+            })
+          }
+        "
+        :off="
+          () => {
+            $router.push({ name: 'charging-stations' })
+          }
+        "
+        @clicked="
+          () => {
+            $emit('need-refresh')
+          }
+        "
+      >
+        Set Supervision Url
+      </ToggleButton>
+      <Button @click="openConnection()">Open Connection</Button>
+      <Button @click="closeConnection()">Close Connection</Button>
+      <Button @click="deleteChargingStation()">Delete Charging Station</Button>
+    </td>
+    <td class="cs-table__connectors-column">
+      <table id="connectors-table">
+        <caption></caption>
+        <thead id="connectors-table__head">
+          <tr class="connectors-table__row">
+            <th scope="col" class="connectors-table__column">Identifier</th>
+            <th scope="col" class="connectors-table__column">Status</th>
+            <th scope="col" class="connectors-table__column">Transaction</th>
+            <th scope="col" class="connectors-table__column">ATG Started</th>
+            <th scope="col" class="connectors-table__column">Actions</th>
+          </tr>
+        </thead>
+        <tbody id="connectors-table__body">
+          <!-- eslint-disable-next-line vue/valid-v-for -->
+          <CSConnector
+            v-for="(connector, index) in getConnectorStatuses()"
+            :hash-id="chargingStation.stationInfo.hashId"
+            :charging-station-id="chargingStation.stationInfo.chargingStationId"
+            :connector-id="index + 1"
+            :connector="connector"
+            :atg-status="getATGStatus(index + 1)"
+            @need-refresh="$emit('need-refresh')"
+          />
+        </tbody>
+      </table>
+    </td>
   </tr>
 </template>
 
 <script setup lang="ts">
-// import { reactive } from 'vue';
-import CSConnector from './CSConnector.vue';
-import type {
-  ChargingStationData,
-  ChargingStationInfo,
-  ConnectorStatus,
-} from '@/types/ChargingStationType';
-import Utils from '@/composables/Utils';
+import { useToast } from 'vue-toast-notification'
+import CSConnector from '@/components/charging-stations/CSConnector.vue'
+import Button from '@/components/buttons/Button.vue'
+import type { ChargingStationData, ConnectorStatus, Status } from '@/types'
+import ToggleButton from '@/components/buttons/ToggleButton.vue'
+import { useUIClient } from '@/composables'
 
 const props = defineProps<{
-  chargingStation: ChargingStationData;
-  idTag: string;
-}>();
+  chargingStation: ChargingStationData
+}>()
 
-// type State = {
-//   isTagModalVisible: boolean;
-//   idTag: string;
-// };
+const $emit = defineEmits(['need-refresh'])
 
-// const state: State = reactive({
-//   isTagModalVisible: false,
-//   idTag: '',
-// });
-
-function getConnectors(): ConnectorStatus[] {
-  return props.chargingStation.connectors?.slice(1);
-}
-function getInfo(): ChargingStationInfo {
-  return props.chargingStation.stationInfo;
-}
-function getHashId(): string {
-  return getInfo().hashId;
-}
-function getId(): string {
-  return Utils.ifUndefined<string>(getInfo().chargingStationId, 'Ø');
-}
-function getModel(): string {
-  return getInfo().chargePointModel;
-}
-function getVendor(): string {
-  return getInfo().chargePointVendor;
+const getConnectorStatuses = (): ConnectorStatus[] => {
+  if (Array.isArray(props.chargingStation.evses) && props.chargingStation.evses.length > 0) {
+    const connectorStatuses: ConnectorStatus[] = []
+    for (const [evseId, evseStatus] of props.chargingStation.evses.entries()) {
+      if (evseId > 0 && Array.isArray(evseStatus.connectors) && evseStatus.connectors.length > 0) {
+        for (const connectorStatus of evseStatus.connectors) {
+          connectorStatuses.push(connectorStatus)
+        }
+      }
+    }
+    return connectorStatuses
+  }
+  return props.chargingStation.connectors?.slice(1)
 }
-function getFirmwareVersion(): string {
-  return Utils.ifUndefined<string>(getInfo().firmwareVersion, 'Ø');
+const getATGStatus = (connectorId: number): Status | undefined => {
+  return props.chargingStation.automaticTransactionGenerator
+    ?.automaticTransactionGeneratorStatuses?.[connectorId - 1]
 }
-function getStarted(): string {
-  return props.chargingStation.started === true ? 'Yes' : 'No';
+const getSupervisionUrl = (): string => {
+  const supervisionUrl = new URL(props.chargingStation.supervisionUrl)
+  return `${supervisionUrl.protocol}//${supervisionUrl.host.split('.').join('.\u200b')}`
 }
-function getWsState(): string {
+const getWSState = (): string => {
   switch (props.chargingStation?.wsState) {
     case WebSocket.CONNECTING:
-      return 'Connecting';
+      return 'Connecting'
     case WebSocket.OPEN:
-      return 'Open';
+      return 'Open'
     case WebSocket.CLOSING:
-      return 'Closing';
+      return 'Closing'
     case WebSocket.CLOSED:
-      return 'Closed';
+      return 'Closed'
     default:
-      return 'Ø';
+      return 'Ø'
   }
 }
-function getRegistrationStatus(): string {
-  return props.chargingStation?.bootNotificationResponse?.status ?? 'Ø';
+
+const uiClient = useUIClient()
+
+const $toast = useToast()
+
+const startChargingStation = (): void => {
+  uiClient
+    .startChargingStation(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Charging station successfully started')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at starting charging station')
+      console.error('Error at starting charging station', error)
+    })
+}
+const stopChargingStation = (): void => {
+  uiClient
+    .stopChargingStation(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Charging station successfully stopped')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at stopping charging station')
+      console.error('Error at stopping charging station', error)
+    })
+}
+const openConnection = (): void => {
+  uiClient
+    .openConnection(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Connection successfully opened')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at opening connection')
+      console.error('Error at opening connection', error)
+    })
+}
+const closeConnection = (): void => {
+  uiClient
+    .closeConnection(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Connection successfully closed')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at closing connection')
+      console.error('Error at closing connection', error)
+    })
+}
+const deleteChargingStation = (): void => {
+  uiClient
+    .deleteChargingStation(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Charging station successfully deleted')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at deleting charging station')
+      console.error('Error at deleting charging station', error)
+    })
 }
-// function showTagModal(): void {
-//   state.isTagModalVisible = true;
-// }
-// function hideTagModal(): void {
-//   state.isTagModalVisible = false;
-// }
 </script>
+
+<style>
+#connectors-table {
+  display: flex;
+  flex-direction: column;
+  background-color: white;
+  overflow: auto hidden;
+  border-collapse: collapse;
+  empty-cells: show;
+}
+
+#connectors-table__body {
+  display: flex;
+  flex-direction: column;
+}
+
+.connectors-table__row {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+  border: solid 0.25px black;
+}
+
+.connectors-table__row:nth-of-type(even) {
+  background-color: whitesmoke;
+}
+
+#connectors-table__head .connectors-table__row {
+  background-color: lightgrey;
+}
+
+.connectors-table__column {
+  width: calc(100% / 5);
+  display: flex;
+  flex-direction: column;
+  text-align: center;
+}
+</style>