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