feat(ui): introduce toggle button and use it for actions
[e-mobility-charging-stations-simulator.git] / ui / web / src / components / charging-stations / CSData.vue
1 <template>
2 <tr class="cs-table__row">
3 <td class="cs-table__column">
4 {{ chargingStation.stationInfo.chargingStationId }}
5 </td>
6 <td class="cs-table__column">{{ chargingStation.started === true ? 'Yes' : 'No' }}</td>
7 <td class="cs-table__column">
8 {{ getSupervisionUrl() }}
9 </td>
10 <td class="cs-table__column">{{ getWSState() }}</td>
11 <td class="cs-table__column">
12 {{ chargingStation?.bootNotificationResponse?.status ?? 'Ø' }}
13 </td>
14 <td class="cs-table__column">
15 {{ chargingStation.stationInfo.templateName }}
16 </td>
17 <td class="cs-table__column">{{ chargingStation.stationInfo.chargePointVendor }}</td>
18 <td class="cs-table__column">{{ chargingStation.stationInfo.chargePointModel }}</td>
19 <td class="cs-table__column">
20 {{ chargingStation.stationInfo.firmwareVersion ?? 'Ø' }}
21 </td>
22 <td class="cs-table__column">
23 <Button @click="startChargingStation()">Start Charging Station</Button>
24 <Button @click="stopChargingStation()">Stop Charging Station</Button>
25 <ToggleButton
26 :id="`${chargingStation.stationInfo.hashId}-set-supervision-url`"
27 :shared="true"
28 :on="
29 () => {
30 $router.push({
31 name: 'set-supervision-url',
32 params: {
33 hashId: chargingStation.stationInfo.hashId,
34 chargingStationId: chargingStation.stationInfo.chargingStationId
35 }
36 })
37 }
38 "
39 :off="
40 () => {
41 $router.push({ name: 'charging-stations' })
42 }
43 "
44 >
45 Set Supervision Url
46 </ToggleButton>
47 <Button @click="openConnection()">Open Connection</Button>
48 <Button @click="closeConnection()">Close Connection</Button>
49 <Button @click="deleteChargingStation()">Delete Charging Station</Button>
50 </td>
51 <td class="cs-table__connectors-column">
52 <table id="connectors-table">
53 <caption></caption>
54 <thead id="connectors-table__head">
55 <tr class="connectors-table__row">
56 <th scope="col" class="connectors-table__column">Identifier</th>
57 <th scope="col" class="connectors-table__column">Status</th>
58 <th scope="col" class="connectors-table__column">Transaction</th>
59 <th scope="col" class="connectors-table__column">ATG Started</th>
60 <th scope="col" class="connectors-table__column">Actions</th>
61 </tr>
62 </thead>
63 <tbody id="connectors-table__body">
64 <!-- eslint-disable-next-line vue/valid-v-for -->
65 <CSConnector
66 v-for="(connector, index) in getConnectorStatuses()"
67 :hash-id="chargingStation.stationInfo.hashId"
68 :charging-station-id="chargingStation.stationInfo.chargingStationId"
69 :connector-id="index + 1"
70 :connector="connector"
71 :atg-status="getATGStatus(index + 1)"
72 />
73 </tbody>
74 </table>
75 </td>
76 </tr>
77 </template>
78
79 <script setup lang="ts">
80 import { getCurrentInstance } from 'vue'
81 import { useToast } from 'vue-toast-notification'
82 import CSConnector from '@/components/charging-stations/CSConnector.vue'
83 import Button from '@/components/buttons/Button.vue'
84 import type { ChargingStationData, ConnectorStatus, Status } from '@/types'
85 import ToggleButton from '@/components/buttons/ToggleButton.vue'
86
87 const props = defineProps<{
88 chargingStation: ChargingStationData
89 }>()
90
91 const getConnectorStatuses = (): ConnectorStatus[] => {
92 if (Array.isArray(props.chargingStation.evses) && props.chargingStation.evses.length > 0) {
93 const connectorStatuses: ConnectorStatus[] = []
94 for (const [evseId, evseStatus] of props.chargingStation.evses.entries()) {
95 if (evseId > 0 && Array.isArray(evseStatus.connectors) && evseStatus.connectors.length > 0) {
96 for (const connectorStatus of evseStatus.connectors) {
97 connectorStatuses.push(connectorStatus)
98 }
99 }
100 }
101 return connectorStatuses
102 }
103 return props.chargingStation.connectors?.slice(1)
104 }
105 const getATGStatus = (connectorId: number): Status | undefined => {
106 return props.chargingStation.automaticTransactionGenerator
107 ?.automaticTransactionGeneratorStatuses?.[connectorId - 1]
108 }
109 const getSupervisionUrl = (): string => {
110 const supervisionUrl = new URL(props.chargingStation.supervisionUrl)
111 return `${supervisionUrl.protocol}//${supervisionUrl.host.split('.').join('.\u200b')}`
112 }
113 const getWSState = (): string => {
114 switch (props.chargingStation?.wsState) {
115 case WebSocket.CONNECTING:
116 return 'Connecting'
117 case WebSocket.OPEN:
118 return 'Open'
119 case WebSocket.CLOSING:
120 return 'Closing'
121 case WebSocket.CLOSED:
122 return 'Closed'
123 default:
124 return 'Ø'
125 }
126 }
127
128 const uiClient = getCurrentInstance()?.appContext.config.globalProperties.$uiClient
129
130 const $toast = useToast()
131
132 const startChargingStation = (): void => {
133 uiClient
134 .startChargingStation(props.chargingStation.stationInfo.hashId)
135 .then(() => {
136 $toast.success('Charging station successfully started')
137 })
138 .catch((error: Error) => {
139 $toast.error('Error at starting charging station')
140 console.error('Error at starting charging station', error)
141 })
142 }
143 const stopChargingStation = (): void => {
144 uiClient
145 .stopChargingStation(props.chargingStation.stationInfo.hashId)
146 .then(() => {
147 $toast.success('Charging station successfully stopped')
148 })
149 .catch((error: Error) => {
150 $toast.error('Error at stopping charging station')
151 console.error('Error at stopping charging station', error)
152 })
153 }
154 const openConnection = (): void => {
155 uiClient
156 .openConnection(props.chargingStation.stationInfo.hashId)
157 .then(() => {
158 $toast.success('Connection successfully opened')
159 })
160 .catch((error: Error) => {
161 $toast.error('Error at opening connection')
162 console.error('Error at opening connection', error)
163 })
164 }
165 const closeConnection = (): void => {
166 uiClient
167 .closeConnection(props.chargingStation.stationInfo.hashId)
168 .then(() => {
169 $toast.success('Connection successfully closed')
170 })
171 .catch((error: Error) => {
172 $toast.error('Error at closing connection')
173 console.error('Error at closing connection', error)
174 })
175 }
176 const deleteChargingStation = (): void => {
177 uiClient
178 .deleteChargingStation(props.chargingStation.stationInfo.hashId)
179 .then(() => {
180 $toast.success('Charging station successfully deleted')
181 })
182 .catch((error: Error) => {
183 $toast.error('Error at deleting charging station')
184 console.error('Error at deleting charging station', error)
185 })
186 }
187 </script>
188
189 <style>
190 #connectors-table {
191 display: flex;
192 flex-direction: column;
193 background-color: white;
194 overflow: auto hidden;
195 border-collapse: collapse;
196 empty-cells: show;
197 }
198
199 #connectors-table__body {
200 display: flex;
201 flex-direction: column;
202 }
203
204 .connectors-table__row {
205 display: flex;
206 flex-direction: row;
207 justify-content: center;
208 align-items: center;
209 border: solid 0.25px black;
210 }
211
212 .connectors-table__row:nth-of-type(even) {
213 background-color: whitesmoke;
214 }
215
216 #connectors-table__head .connectors-table__row {
217 background-color: lightgrey;
218 }
219
220 .connectors-table__column {
221 width: calc(100% / 5);
222 text-align: center;
223 }
224 </style>