fix(ui): ensure the charging stations list re-rendered after UI server
[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 () => {
12 try {
13 if (
14 getFromLocalStorage<number>('uiServerConfigurationIndex', 0) !== state.uiServerIndex
15 ) {
16 setToLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
7e2e8c9b
JB
17 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
18 'close',
19 () => {
20 app!.appContext.config.globalProperties.$chargingStations = []
21 },
22 { once: true }
23 )
24 app?.appContext.config.globalProperties.$uiClient.setConfiguration(
0344ad2b
JB
25 app?.appContext.config.globalProperties.$configuration.uiServer[
26 getFromLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
27 ]
28 )
7e2e8c9b
JB
29 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
30 'open',
31 () => {
32 loadChargingStations(() => (state.renderChargingStationsList = randomUUID()))
33 },
34 { once: true }
35 )
0344ad2b
JB
36 }
37 } catch (error) {
38 $toast.error('Error at changing UI server configuration')
39 console.error('Error at changing UI server configuration:', error)
40 }
41 }
42 "
43 >
44 <option
45 v-for="uiServerConfiguration in uiServerConfigurations"
46 :value="uiServerConfiguration.index"
47 >
48 {{ uiServerConfiguration.configuration.host }}
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">
57c0ba05 76import { getCurrentInstance, 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
57c0ba05 89const state = reactive({
86545028 90 renderChargingStationsList: randomUUID(),
a4868fd7 91 loading: false,
0344ad2b 92 uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
66a7748d 93})
32de5a57 94
57c0ba05
JB
95const app = getCurrentInstance()
96const uiClient = app?.appContext.config.globalProperties.$uiClient
0344ad2b
JB
97const uiServerConfigurations: { configuration: UIServerConfigurationSection; index: number }[] =
98 app?.appContext.config.globalProperties.$configuration.uiServer.map(
99 (configuration: UIServerConfigurationSection, index: number) => ({
100 configuration,
101 index
102 })
103 )
57c0ba05 104
cea23fa0
JB
105const $toast = useToast()
106
86545028 107const loadChargingStations = (renderCallback?: () => void): void => {
a4868fd7
JB
108 if (state.loading === false) {
109 state.loading = true
57c0ba05
JB
110 uiClient
111 .listChargingStations()
112 .then((response: ResponsePayload) => {
113 if (app != null) {
114 app.appContext.config.globalProperties.$chargingStations = response.chargingStations
115 }
116 })
117 .catch((error: Error) => {
cea23fa0 118 $toast.error('Error at fetching charging stations')
57c0ba05
JB
119 console.error('Error at fetching charging stations:', error)
120 })
121 .finally(() => {
86545028
JB
122 if (renderCallback != null) {
123 renderCallback()
b9d447d2 124 }
a4868fd7 125 state.loading = false
57c0ba05 126 })
2113b3c6 127 }
32de5a57 128}
5a010bf0 129
fa5d129a 130const startSimulator = (): void => {
cea23fa0
JB
131 uiClient
132 .startSimulator()
133 .then(() => {
134 $toast.success('Simulator successfully started')
135 })
136 .catch((error: Error) => {
137 $toast.error('Error at starting simulator')
138 console.error('Error at starting simulator:', error)
139 })
5a010bf0 140}
fa5d129a 141const stopSimulator = (): void => {
cea23fa0
JB
142 uiClient
143 .stopSimulator()
144 .then(() => {
5c0e9352
JB
145 if (app != null) {
146 app.appContext.config.globalProperties.$chargingStations = []
147 }
cea23fa0
JB
148 $toast.success('Simulator successfully stopped')
149 })
150 .catch((error: Error) => {
151 $toast.error('Error at stopping simulator')
152 console.error('Error at stopping simulator:', error)
153 })
5a010bf0 154}
32de5a57
LM
155</script>
156
157<style>
ca1e5439 158#charging-stations-container {
1d41bc6b 159 height: fit-content;
32de5a57 160 width: 100%;
5a010bf0 161 display: flex;
32de5a57 162 flex-direction: column;
5a010bf0
JB
163}
164
0344ad2b
JB
165#ui-server-container {
166 display: flex;
167 flex-direction: row;
168}
169
170#ui-server-selector {
171 width: 100%;
172 text-align: center;
173}
174
13c19b7b
JB
175#buttons-container {
176 display: flex;
177 flex-direction: row;
178}
179
14ee627a
JB
180#action-button {
181 flex: none;
878855a2
JB
182}
183
32de5a57 184#reload-button {
5a010bf0 185 flex: auto;
32de5a57 186 color: white;
9dc8b66f 187 background-color: blue;
13c19b7b 188 font-size: 1.5rem;
32de5a57 189 font-weight: bold;
aee67dee
JB
190 align-items: center;
191 justify-content: center;
32de5a57
LM
192}
193
194#reload-button:hover {
9dc8b66f 195 background-color: rgb(0, 0, 225);
32de5a57
LM
196}
197
198#reload-button:active {
9dc8b66f 199 background-color: red;
32de5a57 200}
229d8c34
JB
201
202#action {
203 color: white;
204 background-color: black;
205 padding: 1%;
206}
32de5a57 207</style>