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