refactor(ui): trivial code cleanups
[e-mobility-charging-stations-simulator.git] / ui / web / src / views / ChargingStationsView.vue
1 <template>
2 <Container id="charging-stations-container">
3 <Container
4 v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
5 id="ui-server-container"
6 >
7 <select
8 id="ui-server-selector"
9 v-model="state.uiServerIndex"
10 @change="
11 () => {
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)
23 $router.currentRoute.value.name !== 'charging-stations' &&
24 $router.push({ name: 'charging-stations' })
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 )
41 }
42 }
43 "
44 >
45 <option
46 v-for="uiServerConfiguration in uiServerConfigurations"
47 :value="uiServerConfiguration.index"
48 >
49 {{ uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host }}
50 </option>
51 </select>
52 </Container>
53 <Container id="buttons-container">
54 <Button @click="startSimulator()">Start Simulator</Button>
55 <Button @click="stopSimulator()">Stop Simulator</Button>
56 <ToggleButton
57 :id="'add-charging-stations'"
58 :key="state.renderAddChargingStations"
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 >
71 Add Charging Stations
72 </ToggleButton>
73 <ReloadButton
74 id="reload-button"
75 :loading="state.loading"
76 @click="loadChargingStations(() => (state.renderChargingStations = randomUUID()))"
77 />
78 </Container>
79 <CSTable
80 v-show="
81 Array.isArray(app?.appContext.config.globalProperties.$chargingStations) &&
82 app.appContext.config.globalProperties.$chargingStations.length > 0
83 "
84 :key="state.renderChargingStations"
85 :charging-stations="app?.appContext.config.globalProperties.$chargingStations"
86 />
87 </Container>
88 </template>
89
90 <script setup lang="ts">
91 import { getCurrentInstance, onMounted, ref } from 'vue'
92 import { useToast } from 'vue-toast-notification'
93 import CSTable from '@/components/charging-stations/CSTable.vue'
94 import type { ResponsePayload, UIServerConfigurationSection } from '@/types'
95 import Container from '@/components/Container.vue'
96 import ReloadButton from '@/components/buttons/ReloadButton.vue'
97 import Button from '@/components/buttons/Button.vue'
98 import {
99 getFromLocalStorage,
100 getLocalStorage,
101 randomUUID,
102 removeFromLocalStorage,
103 setToLocalStorage
104 } from '@/composables'
105 import ToggleButton from '@/components/buttons/ToggleButton.vue'
106
107 const app = getCurrentInstance()
108
109 const clearToggleButtons = (): void => {
110 for (const key in getLocalStorage()) {
111 if (key.includes('toggle-button')) {
112 removeFromLocalStorage(key)
113 }
114 }
115 }
116
117 const clearChargingStations = (): void => {
118 clearToggleButtons()
119 app!.appContext.config.globalProperties.$chargingStations = []
120 state.value.renderAddChargingStations = randomUUID()
121 state.value.renderChargingStations = randomUUID()
122 }
123
124 const initializeWSEventListeners = () => {
125 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('open', () => {
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 })
140 loadChargingStations(() => {
141 state.value.renderAddChargingStations = randomUUID()
142 state.value.renderChargingStations = randomUUID()
143 })
144 })
145 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
146 'error',
147 clearChargingStations
148 )
149 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
150 'close',
151 clearChargingStations
152 )
153 }
154
155 onMounted(() => {
156 initializeWSEventListeners()
157 })
158
159 const state = ref({
160 renderAddChargingStations: randomUUID(),
161 renderChargingStations: randomUUID(),
162 loading: false,
163 uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
164 })
165
166 const uiClient = app?.appContext.config.globalProperties.$uiClient
167 const uiServerConfigurations: { configuration: UIServerConfigurationSection; index: number }[] =
168 app?.appContext.config.globalProperties.$configuration.uiServer.map(
169 (configuration: UIServerConfigurationSection, index: number) => ({
170 configuration,
171 index
172 })
173 )
174
175 const $toast = useToast()
176
177 const loadChargingStations = (renderCallback?: () => void): void => {
178 if (state.value.loading === false) {
179 state.value.loading = true
180 uiClient
181 .listChargingStations()
182 .then((response: ResponsePayload) => {
183 if (app != null) {
184 app.appContext.config.globalProperties.$chargingStations = response.chargingStations
185 }
186 })
187 .catch((error: Error) => {
188 if (app != null) {
189 app.appContext.config.globalProperties.$chargingStations = []
190 }
191 $toast.error('Error at fetching charging stations')
192 console.error('Error at fetching charging stations:', error)
193 })
194 .finally(() => {
195 if (renderCallback != null) {
196 renderCallback()
197 }
198 state.value.loading = false
199 })
200 }
201 }
202
203 const startSimulator = (): void => {
204 uiClient
205 .startSimulator()
206 .then(() => {
207 $toast.success('Simulator successfully started')
208 })
209 .catch((error: Error) => {
210 $toast.error('Error at starting simulator')
211 console.error('Error at starting simulator:', error)
212 })
213 }
214 const stopSimulator = (): void => {
215 uiClient
216 .stopSimulator()
217 .then(() => {
218 if (app != null) {
219 app.appContext.config.globalProperties.$chargingStations = []
220 }
221 $toast.success('Simulator successfully stopped')
222 })
223 .catch((error: Error) => {
224 $toast.error('Error at stopping simulator')
225 console.error('Error at stopping simulator:', error)
226 })
227 }
228 </script>
229
230 <style>
231 #charging-stations-container {
232 height: fit-content;
233 width: 100%;
234 display: flex;
235 flex-direction: column;
236 }
237
238 #ui-server-container {
239 display: flex;
240 flex-direction: row;
241 }
242
243 #ui-server-selector {
244 width: 100%;
245 text-align: center;
246 }
247
248 #buttons-container {
249 display: flex;
250 flex-direction: row;
251 }
252
253 #action-button {
254 flex: none;
255 }
256
257 #reload-button {
258 flex: auto;
259 color: white;
260 background-color: blue;
261 font-size: 1.5rem;
262 font-weight: bold;
263 align-items: center;
264 justify-content: center;
265 }
266
267 #reload-button:hover {
268 background-color: rgb(0, 0, 225);
269 }
270
271 #reload-button:active {
272 background-color: red;
273 }
274
275 #action {
276 color: white;
277 background-color: black;
278 padding: 1%;
279 }
280 </style>