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