refactor(ui): cleanup eslint configuration
[e-mobility-charging-stations-simulator.git] / ui / web / src / views / ChargingStationsView.vue
1 <template>
2 <Container id="charging-stations-container">
3 <Container id="buttons-container">
4 <Container
5 v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
6 id="ui-server-container"
7 >
8 <select
9 id="ui-server-selector"
10 v-model="state.uiServerIndex"
11 @change="
12 () => {
13 if (
14 getFromLocalStorage<number>('uiServerConfigurationIndex', 0) !== state.uiServerIndex
15 ) {
16 $uiClient.setConfiguration(
17 ($configuration.value.uiServer as UIServerConfigurationSection[])[
18 state.uiServerIndex
19 ]
20 )
21 registerWSEventListeners()
22 $uiClient.registerWSEventListener(
23 'open',
24 () => {
25 setToLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
26 clearToggleButtons()
27 $route.name !== 'charging-stations' &&
28 $router.push({ name: 'charging-stations' })
29 },
30 { once: true }
31 )
32 $uiClient.registerWSEventListener(
33 'error',
34 () => {
35 state.uiServerIndex = getFromLocalStorage<number>(
36 'uiServerConfigurationIndex',
37 0
38 )
39 $uiClient.setConfiguration(
40 ($configuration.value.uiServer as UIServerConfigurationSection[])[
41 getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
42 ]
43 )
44 registerWSEventListeners()
45 },
46 { once: true }
47 )
48 }
49 }
50 "
51 >
52 <option
53 v-for="uiServerConfiguration in uiServerConfigurations"
54 :key="uiServerConfiguration.index"
55 :value="uiServerConfiguration.index"
56 >
57 {{
58 uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host
59 }}
60 </option>
61 </select>
62 </Container>
63 <ToggleButton
64 :id="'simulator'"
65 :key="state.renderSimulator"
66 :status="simulatorState?.started"
67 :on="() => startSimulator()"
68 :off="() => stopSimulator()"
69 :class="simulatorButtonClass"
70 >
71 {{ simulatorButtonMessage }}
72 </ToggleButton>
73 <ToggleButton
74 :id="'add-charging-stations'"
75 :key="state.renderAddChargingStations"
76 :shared="true"
77 :on="
78 () => {
79 $router.push({ name: 'add-charging-stations' })
80 }
81 "
82 :off="
83 () => {
84 $router.push({ name: 'charging-stations' })
85 }
86 "
87 @clicked="
88 () => {
89 state.renderChargingStations = randomUUID()
90 }
91 "
92 >
93 Add Charging Stations
94 </ToggleButton>
95 <ReloadButton
96 id="reload-button"
97 :loading="state.gettingChargingStations"
98 @click="getChargingStations()"
99 />
100 </Container>
101 <CSTable
102 v-show="Array.isArray($chargingStations.value) && $chargingStations.value.length > 0"
103 :key="state.renderChargingStations"
104 :charging-stations="$chargingStations.value"
105 @need-refresh="
106 () => {
107 state.renderAddChargingStations = randomUUID()
108 state.renderChargingStations = randomUUID()
109 }
110 "
111 />
112 </Container>
113 </template>
114
115 <script setup lang="ts">
116 import { computed, getCurrentInstance, onMounted, onUnmounted, ref, watch } from 'vue'
117 import { useToast } from 'vue-toast-notification'
118
119 import ReloadButton from '@/components/buttons/ReloadButton.vue'
120 import ToggleButton from '@/components/buttons/ToggleButton.vue'
121 import CSTable from '@/components/charging-stations/CSTable.vue'
122 import Container from '@/components/Container.vue'
123 import {
124 deleteFromLocalStorage,
125 getFromLocalStorage,
126 getLocalStorage,
127 randomUUID,
128 setToLocalStorage,
129 useUIClient
130 } from '@/composables'
131 import type {
132 ChargingStationData,
133 ResponsePayload,
134 SimulatorState,
135 UIServerConfigurationSection
136 } from '@/types'
137
138 const simulatorState = ref<SimulatorState | undefined>(undefined)
139
140 const simulatorButtonClass = computed<string>(() =>
141 simulatorState.value?.started === true ? 'simulator-stop-button' : 'simulator-start-button'
142 )
143 const simulatorButtonMessage = computed<string>(
144 () =>
145 `${simulatorState.value?.started === true ? 'Stop' : 'Start'} Simulator${simulatorState.value?.version != null ? ` (${simulatorState.value.version})` : ''}`
146 )
147
148 const state = ref<{
149 renderSimulator: `${string}-${string}-${string}-${string}-${string}`
150 renderAddChargingStations: `${string}-${string}-${string}-${string}-${string}`
151 renderChargingStations: `${string}-${string}-${string}-${string}-${string}`
152 gettingSimulatorState: boolean
153 gettingTemplates: boolean
154 gettingChargingStations: boolean
155 uiServerIndex: number
156 }>({
157 renderSimulator: randomUUID(),
158 renderAddChargingStations: randomUUID(),
159 renderChargingStations: randomUUID(),
160 gettingSimulatorState: false,
161 gettingTemplates: false,
162 gettingChargingStations: false,
163 uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
164 })
165
166 const clearToggleButtons = (): void => {
167 for (const key in getLocalStorage()) {
168 if (key.includes('toggle-button')) {
169 deleteFromLocalStorage(key)
170 }
171 }
172 state.value.renderChargingStations = randomUUID()
173 state.value.renderAddChargingStations = randomUUID()
174 }
175
176 const app = getCurrentInstance()
177
178 watch(app!.appContext.config.globalProperties.$chargingStations, () => {
179 state.value.renderChargingStations = randomUUID()
180 })
181
182 watch(simulatorState, () => {
183 state.value.renderSimulator = randomUUID()
184 })
185
186 const clearTemplates = (): void => {
187 if (app != null) {
188 app.appContext.config.globalProperties.$templates.value = []
189 }
190 }
191
192 const clearChargingStations = (): void => {
193 if (app != null) {
194 app.appContext.config.globalProperties.$chargingStations.value = []
195 }
196 }
197
198 const uiClient = useUIClient()
199
200 const $toast = useToast()
201
202 const getSimulatorState = (): void => {
203 if (state.value.gettingSimulatorState === false) {
204 state.value.gettingSimulatorState = true
205 uiClient
206 .simulatorState()
207 .then((response: ResponsePayload) => {
208 simulatorState.value = response.state as SimulatorState
209 })
210 .catch((error: Error) => {
211 $toast.error('Error at fetching simulator state')
212 console.error('Error at fetching simulator state:', error)
213 })
214 .finally(() => {
215 state.value.gettingSimulatorState = false
216 })
217 }
218 }
219
220 const getTemplates = (): void => {
221 if (state.value.gettingTemplates === false) {
222 state.value.gettingTemplates = true
223 uiClient
224 .listTemplates()
225 .then((response: ResponsePayload) => {
226 if (app != null) {
227 app.appContext.config.globalProperties.$templates.value = response.templates as string[]
228 }
229 })
230 .catch((error: Error) => {
231 clearTemplates()
232 $toast.error('Error at fetching charging station templates')
233 console.error('Error at fetching charging station templates:', error)
234 })
235 .finally(() => {
236 state.value.gettingTemplates = false
237 })
238 }
239 }
240
241 const getChargingStations = (): void => {
242 if (state.value.gettingChargingStations === false) {
243 state.value.gettingChargingStations = true
244 uiClient
245 .listChargingStations()
246 .then((response: ResponsePayload) => {
247 if (app != null) {
248 app.appContext.config.globalProperties.$chargingStations.value =
249 response.chargingStations as ChargingStationData[]
250 }
251 })
252 .catch((error: Error) => {
253 clearChargingStations()
254 $toast.error('Error at fetching charging stations')
255 console.error('Error at fetching charging stations:', error)
256 })
257 .finally(() => {
258 state.value.gettingChargingStations = false
259 })
260 }
261 }
262
263 const getData = (): void => {
264 getSimulatorState()
265 getTemplates()
266 getChargingStations()
267 }
268
269 const registerWSEventListeners = () => {
270 uiClient.registerWSEventListener('open', getData)
271 uiClient.registerWSEventListener('error', clearChargingStations)
272 uiClient.registerWSEventListener('close', clearChargingStations)
273 }
274
275 const unregisterWSEventListeners = () => {
276 uiClient.unregisterWSEventListener('open', getData)
277 uiClient.unregisterWSEventListener('error', clearChargingStations)
278 uiClient.unregisterWSEventListener('close', clearChargingStations)
279 }
280
281 onMounted(() => {
282 registerWSEventListeners()
283 })
284
285 onUnmounted(() => {
286 unregisterWSEventListeners()
287 })
288
289 const uiServerConfigurations: { index: number; configuration: UIServerConfigurationSection }[] = (
290 app?.appContext.config.globalProperties.$configuration.value
291 .uiServer as UIServerConfigurationSection[]
292 ).map((configuration: UIServerConfigurationSection, index: number) => ({
293 index,
294 configuration
295 }))
296
297 const startSimulator = (): void => {
298 uiClient
299 .startSimulator()
300 .then(() => {
301 $toast.success('Simulator successfully started')
302 })
303 .catch((error: Error) => {
304 $toast.error('Error at starting simulator')
305 console.error('Error at starting simulator:', error)
306 })
307 .finally(() => {
308 getSimulatorState()
309 })
310 }
311 const stopSimulator = (): void => {
312 uiClient
313 .stopSimulator()
314 .then(() => {
315 clearChargingStations()
316 $toast.success('Simulator successfully stopped')
317 })
318 .catch((error: Error) => {
319 $toast.error('Error at stopping simulator')
320 console.error('Error at stopping simulator:', error)
321 })
322 .finally(() => {
323 getSimulatorState()
324 })
325 }
326 </script>
327
328 <style>
329 #charging-stations-container {
330 height: fit-content;
331 width: 100%;
332 display: flex;
333 flex-direction: column;
334 }
335
336 #ui-server-container {
337 display: flex;
338 justify-content: center;
339 border-style: outset;
340 }
341
342 #ui-server-selector {
343 width: 100%;
344 background-color: rgb(239, 239, 239);
345 font: small-caption;
346 text-align: center;
347 }
348
349 #ui-server-selector:hover {
350 background-color: rgb(229, 229, 229);
351 }
352
353 #buttons-container {
354 display: flex;
355 flex-direction: row;
356 }
357
358 .simulator-start-button {
359 color: ivory;
360 background-color: green;
361 }
362
363 .simulator-start-button:hover {
364 background-color: rgb(0, 98, 0);
365 }
366
367 .simulator-stop-button {
368 color: ivory;
369 background-color: red;
370 }
371
372 .simulator-stop-button:hover {
373 background-color: rgb(225, 0, 0);
374 }
375
376 #action-button {
377 flex: none;
378 }
379
380 #reload-button {
381 color: ivory;
382 background-color: blue;
383 font-size: 2rem;
384 }
385
386 #reload-button:hover {
387 background-color: rgb(0, 0, 225);
388 }
389
390 #reload-button:active {
391 background-color: darkblue;
392 }
393
394 #action {
395 min-width: max-content;
396 color: ivory;
397 background-color: black;
398 padding: 0.8%;
399 }
400 </style>