refactor(ui): cleanup helper namespace
[e-mobility-charging-stations-simulator.git] / ui / web / src / views / ChargingStationsView.vue
CommitLineData
32de5a57 1<template>
ca1e5439 2 <Container id="charging-stations-container">
47521384
JB
3 <Container
4 v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
5 id="ui-server-container"
6 >
0344ad2b 7 <select
0344ad2b
JB
8 id="ui-server-selector"
9 v-model="state.uiServerIndex"
10 @change="
11 () => {
916fe456
JB
12 if (
13 getFromLocalStorage<number>('uiServerConfigurationIndex', 0) !== state.uiServerIndex
14 ) {
15 app?.appContext.config.globalProperties.$uiClient.setConfiguration(
16 app?.appContext.config.globalProperties.$configuration.uiServer[state.uiServerIndex]
17 )
18 initializeWSEventListeners()
19 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
20 'open',
21 () => {
22 setToLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
240fa4da 23 clearToggleButtons()
a4edfbb3 24 $router.currentRoute.value.name !== 'charging-stations' &&
de3e2a49 25 $router.push({ name: 'charging-stations' })
916fe456
JB
26 },
27 { once: true }
28 )
29 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
30 'error',
31 () => {
32 state.uiServerIndex = getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
33 app?.appContext.config.globalProperties.$uiClient.setConfiguration(
34 app?.appContext.config.globalProperties.$configuration.uiServer[
35 getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
36 ]
37 )
38 initializeWSEventListeners()
39 },
40 { once: true }
41 )
0344ad2b
JB
42 }
43 }
44 "
45 >
46 <option
47 v-for="uiServerConfiguration in uiServerConfigurations"
48 :value="uiServerConfiguration.index"
49 >
258666f9 50 {{ uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host }}
0344ad2b
JB
51 </option>
52 </select>
53 </Container>
13c19b7b 54 <Container id="buttons-container">
240fa4da
JB
55 <ToggleButton
56 :id="'simulator'"
57 :key="state.renderSimulator"
58 :status="state.simulatorState?.started"
59 :on="() => startSimulator()"
60 :off="() => stopSimulator()"
3802683b
JB
61 :class="
62 state.simulatorState?.started === true
6027002f
JB
63 ? 'simulator-stop-button'
64 : 'simulator-start-button'
3802683b 65 "
240fa4da
JB
66 >
67 {{ state.simulatorState?.started === true ? 'Stop' : 'Start' }} Simulator
68 </ToggleButton>
2610da71
JB
69 <ToggleButton
70 :id="'add-charging-stations'"
d64ea57b 71 :key="state.renderAddChargingStations"
2610da71
JB
72 :shared="true"
73 :on="
74 () => {
75 $router.push({ name: 'add-charging-stations' })
76 }
77 "
78 :off="
79 () => {
80 $router.push({ name: 'charging-stations' })
81 }
82 "
83468764
JB
83 @clicked="
84 () => {
85 state.renderChargingStations = randomUUID()
86 }
87 "
2610da71 88 >
1eb5f592 89 Add Charging Stations
2610da71 90 </ToggleButton>
b9d447d2
JB
91 <ReloadButton
92 id="reload-button"
a4868fd7 93 :loading="state.loading"
3eea3ebc 94 @click="loadChargingStations(() => (state.renderChargingStations = randomUUID()))"
b9d447d2 95 />
13c19b7b 96 </Container>
5c0e9352 97 <CSTable
7378b34a 98 v-show="
5c0e9352 99 Array.isArray(app?.appContext.config.globalProperties.$chargingStations) &&
3eea3ebc 100 app.appContext.config.globalProperties.$chargingStations.length > 0
5c0e9352 101 "
3eea3ebc 102 :key="state.renderChargingStations"
5c0e9352 103 :charging-stations="app?.appContext.config.globalProperties.$chargingStations"
83468764
JB
104 @need-refresh="
105 () => {
106 state.renderAddChargingStations = randomUUID()
107 state.renderChargingStations = randomUUID()
108 }
109 "
5c0e9352 110 />
32de5a57
LM
111 </Container>
112</template>
113
114<script setup lang="ts">
3b0c6e17 115import { getCurrentInstance, onMounted, ref } from 'vue'
cea23fa0 116import { useToast } from 'vue-toast-notification'
66a7748d 117import CSTable from '@/components/charging-stations/CSTable.vue'
0344ad2b 118import type { ResponsePayload, UIServerConfigurationSection } from '@/types'
66a7748d
JB
119import Container from '@/components/Container.vue'
120import ReloadButton from '@/components/buttons/ReloadButton.vue'
2610da71 121import {
b767fda7 122 deleteFromLocalStorage,
2610da71
JB
123 getFromLocalStorage,
124 getLocalStorage,
125 randomUUID,
2610da71
JB
126 setToLocalStorage
127} from '@/composables'
128import ToggleButton from '@/components/buttons/ToggleButton.vue'
a4868fd7 129
240fa4da
JB
130const state = ref<{
131 renderSimulator: `${string}-${string}-${string}-${string}-${string}`
132 renderAddChargingStations: `${string}-${string}-${string}-${string}-${string}`
133 renderChargingStations: `${string}-${string}-${string}-${string}-${string}`
134 loading: boolean
135 simulatorState?: { started: boolean }
136 uiServerIndex: number
137}>({
138 renderSimulator: randomUUID(),
139 renderAddChargingStations: randomUUID(),
140 renderChargingStations: randomUUID(),
141 loading: false,
142 uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
143})
144
916fe456
JB
145const app = getCurrentInstance()
146
d64ea57b
JB
147const clearToggleButtons = (): void => {
148 for (const key in getLocalStorage()) {
149 if (key.includes('toggle-button')) {
b767fda7 150 deleteFromLocalStorage(key)
d64ea57b
JB
151 }
152 }
153}
154
155const clearChargingStations = (): void => {
d64ea57b 156 app!.appContext.config.globalProperties.$chargingStations = []
3eea3ebc 157 state.value.renderChargingStations = randomUUID()
d64ea57b
JB
158}
159
240fa4da
JB
160const uiClient = app?.appContext.config.globalProperties.$uiClient
161
162const getSimulatorState = (): void => {
163 uiClient
164 .simulatorState()
165 .then((response: ResponsePayload) => {
166 state.value.simulatorState = response.state as { started: boolean }
167 })
168 .catch((error: Error) => {
169 $toast.error('Error at fetching simulator state')
170 console.error('Error at fetching simulator state:', error)
171 })
172 .finally(() => {
173 state.value.renderSimulator = randomUUID()
174 })
175}
176
916fe456
JB
177const initializeWSEventListeners = () => {
178 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('open', () => {
240fa4da 179 getSimulatorState()
3b0c6e17
JB
180 uiClient
181 .listTemplates()
182 .then((response: ResponsePayload) => {
183 if (app != null) {
184 app.appContext.config.globalProperties.$templates = response.templates
185 }
186 })
187 .catch((error: Error) => {
188 if (app != null) {
189 app.appContext.config.globalProperties.$templates = []
190 }
191 $toast.error('Error at fetching charging station templates')
192 console.error('Error at fetching charging station templates:', error)
193 })
240fa4da
JB
194 .finally(() => {
195 state.value.renderAddChargingStations = randomUUID()
196 })
d64ea57b 197 loadChargingStations(() => {
3eea3ebc 198 state.value.renderChargingStations = randomUUID()
d64ea57b 199 })
916fe456 200 })
d64ea57b
JB
201 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
202 'error',
203 clearChargingStations
204 )
205 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
206 'close',
207 clearChargingStations
208 )
916fe456
JB
209}
210
211onMounted(() => {
212 initializeWSEventListeners()
213})
214
0344ad2b
JB
215const uiServerConfigurations: { configuration: UIServerConfigurationSection; index: number }[] =
216 app?.appContext.config.globalProperties.$configuration.uiServer.map(
217 (configuration: UIServerConfigurationSection, index: number) => ({
218 configuration,
219 index
220 })
221 )
57c0ba05 222
cea23fa0
JB
223const $toast = useToast()
224
86545028 225const loadChargingStations = (renderCallback?: () => void): void => {
3b0c6e17
JB
226 if (state.value.loading === false) {
227 state.value.loading = true
57c0ba05
JB
228 uiClient
229 .listChargingStations()
230 .then((response: ResponsePayload) => {
231 if (app != null) {
232 app.appContext.config.globalProperties.$chargingStations = response.chargingStations
233 }
234 })
235 .catch((error: Error) => {
916fe456
JB
236 if (app != null) {
237 app.appContext.config.globalProperties.$chargingStations = []
238 }
cea23fa0 239 $toast.error('Error at fetching charging stations')
57c0ba05
JB
240 console.error('Error at fetching charging stations:', error)
241 })
242 .finally(() => {
86545028
JB
243 if (renderCallback != null) {
244 renderCallback()
b9d447d2 245 }
3b0c6e17 246 state.value.loading = false
57c0ba05 247 })
2113b3c6 248 }
32de5a57 249}
5a010bf0 250
fa5d129a 251const startSimulator = (): void => {
cea23fa0
JB
252 uiClient
253 .startSimulator()
254 .then(() => {
255 $toast.success('Simulator successfully started')
256 })
257 .catch((error: Error) => {
258 $toast.error('Error at starting simulator')
259 console.error('Error at starting simulator:', error)
260 })
240fa4da
JB
261 .finally(() => {
262 getSimulatorState()
263 })
5a010bf0 264}
fa5d129a 265const stopSimulator = (): void => {
cea23fa0
JB
266 uiClient
267 .stopSimulator()
268 .then(() => {
5c0e9352
JB
269 if (app != null) {
270 app.appContext.config.globalProperties.$chargingStations = []
271 }
cea23fa0
JB
272 $toast.success('Simulator successfully stopped')
273 })
274 .catch((error: Error) => {
275 $toast.error('Error at stopping simulator')
276 console.error('Error at stopping simulator:', error)
277 })
240fa4da
JB
278 .finally(() => {
279 getSimulatorState()
280 })
5a010bf0 281}
32de5a57
LM
282</script>
283
284<style>
ca1e5439 285#charging-stations-container {
1d41bc6b 286 height: fit-content;
32de5a57 287 width: 100%;
5a010bf0 288 display: flex;
32de5a57 289 flex-direction: column;
5a010bf0
JB
290}
291
0344ad2b
JB
292#ui-server-container {
293 display: flex;
294 flex-direction: row;
295}
296
297#ui-server-selector {
298 width: 100%;
299 text-align: center;
300}
301
13c19b7b
JB
302#buttons-container {
303 display: flex;
304 flex-direction: row;
305}
306
6027002f 307.simulator-start-button {
3802683b
JB
308 color: ivory;
309 background-color: green;
310}
311
6027002f 312.simulator-stop-button {
3802683b
JB
313 color: ivory;
314 background-color: red;
315}
316
14ee627a
JB
317#action-button {
318 flex: none;
878855a2
JB
319}
320
32de5a57 321#reload-button {
3802683b 322 color: ivory;
9dc8b66f 323 background-color: blue;
13c19b7b 324 font-size: 1.5rem;
32de5a57
LM
325 font-weight: bold;
326}
327
328#reload-button:hover {
9dc8b66f 329 background-color: rgb(0, 0, 225);
32de5a57
LM
330}
331
332#reload-button:active {
4b10e4f9 333 background-color: darkblue;
32de5a57 334}
229d8c34
JB
335
336#action {
3802683b 337 color: ivory;
229d8c34
JB
338 background-color: black;
339 padding: 1%;
340}
32de5a57 341</style>