fix(ui): refresh add charging stations button on UI server switch
[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)
a4edfbb3 23 $router.currentRoute.value.name !== 'charging-stations' &&
de3e2a49 24 $router.push({ name: 'charging-stations' })
916fe456
JB
25 },
26 { once: true }
27 )
28 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
29 'error',
30 () => {
31 state.uiServerIndex = getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
32 app?.appContext.config.globalProperties.$uiClient.setConfiguration(
33 app?.appContext.config.globalProperties.$configuration.uiServer[
34 getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
35 ]
36 )
37 initializeWSEventListeners()
38 },
39 { once: true }
40 )
0344ad2b
JB
41 }
42 }
43 "
44 >
45 <option
46 v-for="uiServerConfiguration in uiServerConfigurations"
47 :value="uiServerConfiguration.index"
48 >
258666f9 49 {{ uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host }}
0344ad2b
JB
50 </option>
51 </select>
52 </Container>
13c19b7b 53 <Container id="buttons-container">
14ee627a
JB
54 <Button @click="startSimulator()">Start Simulator</Button>
55 <Button @click="stopSimulator()">Stop Simulator</Button>
2610da71
JB
56 <ToggleButton
57 :id="'add-charging-stations'"
d64ea57b 58 :key="state.renderAddChargingStations"
2610da71
JB
59 :shared="true"
60 :on="
61 () => {
62 $router.push({ name: 'add-charging-stations' })
63 }
64 "
65 :off="
66 () => {
67 $router.push({ name: 'charging-stations' })
68 }
69 "
70 >
1eb5f592 71 Add Charging Stations
2610da71 72 </ToggleButton>
b9d447d2
JB
73 <ReloadButton
74 id="reload-button"
a4868fd7 75 :loading="state.loading"
86545028 76 @click="loadChargingStations(() => (state.renderChargingStationsList = randomUUID()))"
b9d447d2 77 />
13c19b7b 78 </Container>
5c0e9352 79 <CSTable
7378b34a 80 v-show="
5c0e9352
JB
81 Array.isArray(app?.appContext.config.globalProperties.$chargingStations) &&
82 app?.appContext.config.globalProperties.$chargingStations.length > 0
83 "
86545028 84 :key="state.renderChargingStationsList"
5c0e9352
JB
85 :charging-stations="app?.appContext.config.globalProperties.$chargingStations"
86 />
32de5a57
LM
87 </Container>
88</template>
89
90<script setup lang="ts">
3b0c6e17 91import { getCurrentInstance, onMounted, ref } from 'vue'
cea23fa0 92import { useToast } from 'vue-toast-notification'
66a7748d 93import CSTable from '@/components/charging-stations/CSTable.vue'
0344ad2b 94import type { ResponsePayload, UIServerConfigurationSection } from '@/types'
66a7748d
JB
95import Container from '@/components/Container.vue'
96import ReloadButton from '@/components/buttons/ReloadButton.vue'
13c19b7b 97import Button from '@/components/buttons/Button.vue'
2610da71
JB
98import {
99 getFromLocalStorage,
100 getLocalStorage,
101 randomUUID,
102 removeFromLocalStorage,
103 setToLocalStorage
104} from '@/composables'
105import ToggleButton from '@/components/buttons/ToggleButton.vue'
a4868fd7 106
916fe456
JB
107const app = getCurrentInstance()
108
d64ea57b
JB
109const clearToggleButtons = (): void => {
110 for (const key in getLocalStorage()) {
111 if (key.includes('toggle-button')) {
112 removeFromLocalStorage(key)
113 }
114 }
115}
116
117const clearChargingStations = (): void => {
118 clearToggleButtons()
119 app!.appContext.config.globalProperties.$chargingStations = []
120 state.value.renderAddChargingStations = randomUUID()
121 state.value.renderChargingStationsList = randomUUID()
122}
123
916fe456
JB
124const initializeWSEventListeners = () => {
125 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('open', () => {
3b0c6e17
JB
126 uiClient
127 .listTemplates()
128 .then((response: ResponsePayload) => {
129 if (app != null) {
130 app.appContext.config.globalProperties.$templates = response.templates
131 }
132 })
133 .catch((error: Error) => {
134 if (app != null) {
135 app.appContext.config.globalProperties.$templates = []
136 }
137 $toast.error('Error at fetching charging station templates')
138 console.error('Error at fetching charging station templates:', error)
139 })
d64ea57b
JB
140 clearToggleButtons()
141 loadChargingStations(() => {
142 state.value.renderAddChargingStations = randomUUID()
143 state.value.renderChargingStationsList = randomUUID()
144 })
916fe456 145 })
d64ea57b
JB
146 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
147 'error',
148 clearChargingStations
149 )
150 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
151 'close',
152 clearChargingStations
153 )
916fe456
JB
154}
155
156onMounted(() => {
157 initializeWSEventListeners()
158})
159
3b0c6e17 160const state = ref({
d64ea57b 161 renderAddChargingStations: randomUUID(),
86545028 162 renderChargingStationsList: randomUUID(),
a4868fd7 163 loading: false,
0344ad2b 164 uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
66a7748d 165})
32de5a57 166
57c0ba05 167const uiClient = app?.appContext.config.globalProperties.$uiClient
0344ad2b
JB
168const uiServerConfigurations: { configuration: UIServerConfigurationSection; index: number }[] =
169 app?.appContext.config.globalProperties.$configuration.uiServer.map(
170 (configuration: UIServerConfigurationSection, index: number) => ({
171 configuration,
172 index
173 })
174 )
57c0ba05 175
cea23fa0
JB
176const $toast = useToast()
177
86545028 178const loadChargingStations = (renderCallback?: () => void): void => {
3b0c6e17
JB
179 if (state.value.loading === false) {
180 state.value.loading = true
57c0ba05
JB
181 uiClient
182 .listChargingStations()
183 .then((response: ResponsePayload) => {
184 if (app != null) {
185 app.appContext.config.globalProperties.$chargingStations = response.chargingStations
186 }
187 })
188 .catch((error: Error) => {
916fe456
JB
189 if (app != null) {
190 app.appContext.config.globalProperties.$chargingStations = []
191 }
cea23fa0 192 $toast.error('Error at fetching charging stations')
57c0ba05
JB
193 console.error('Error at fetching charging stations:', error)
194 })
195 .finally(() => {
86545028
JB
196 if (renderCallback != null) {
197 renderCallback()
b9d447d2 198 }
3b0c6e17 199 state.value.loading = false
57c0ba05 200 })
2113b3c6 201 }
32de5a57 202}
5a010bf0 203
fa5d129a 204const startSimulator = (): void => {
cea23fa0
JB
205 uiClient
206 .startSimulator()
207 .then(() => {
208 $toast.success('Simulator successfully started')
209 })
210 .catch((error: Error) => {
211 $toast.error('Error at starting simulator')
212 console.error('Error at starting simulator:', error)
213 })
5a010bf0 214}
fa5d129a 215const stopSimulator = (): void => {
cea23fa0
JB
216 uiClient
217 .stopSimulator()
218 .then(() => {
5c0e9352
JB
219 if (app != null) {
220 app.appContext.config.globalProperties.$chargingStations = []
221 }
cea23fa0
JB
222 $toast.success('Simulator successfully stopped')
223 })
224 .catch((error: Error) => {
225 $toast.error('Error at stopping simulator')
226 console.error('Error at stopping simulator:', error)
227 })
5a010bf0 228}
32de5a57
LM
229</script>
230
231<style>
ca1e5439 232#charging-stations-container {
1d41bc6b 233 height: fit-content;
32de5a57 234 width: 100%;
5a010bf0 235 display: flex;
32de5a57 236 flex-direction: column;
5a010bf0
JB
237}
238
0344ad2b
JB
239#ui-server-container {
240 display: flex;
241 flex-direction: row;
242}
243
244#ui-server-selector {
245 width: 100%;
246 text-align: center;
247}
248
13c19b7b
JB
249#buttons-container {
250 display: flex;
251 flex-direction: row;
252}
253
14ee627a
JB
254#action-button {
255 flex: none;
878855a2
JB
256}
257
32de5a57 258#reload-button {
5a010bf0 259 flex: auto;
32de5a57 260 color: white;
9dc8b66f 261 background-color: blue;
13c19b7b 262 font-size: 1.5rem;
32de5a57 263 font-weight: bold;
aee67dee
JB
264 align-items: center;
265 justify-content: center;
32de5a57
LM
266}
267
268#reload-button:hover {
9dc8b66f 269 background-color: rgb(0, 0, 225);
32de5a57
LM
270}
271
272#reload-button:active {
9dc8b66f 273 background-color: red;
32de5a57 274}
229d8c34
JB
275
276#action {
277 color: white;
278 background-color: black;
279 padding: 1%;
280}
32de5a57 281</style>