fix(ui): ensure the tool bar is sized at 100% width
[e-mobility-charging-stations-simulator.git] / ui / web / src / views / ChargingStationsView.vue
CommitLineData
32de5a57 1<template>
ca1e5439 2 <Container id="charging-stations-container">
239bd875
JB
3 <Container id="buttons-container">
4 <Container
5 v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
6 id="ui-server-container"
0344ad2b 7 >
239bd875
JB
8 <select
9 id="ui-server-selector"
10 v-model="state.uiServerIndex"
11 @change="
12 () => {
13 if (
14 getFromLocalStorage<number>('uiServerConfigurationIndex', 0) !== state.uiServerIndex
15 ) {
16 app?.appContext.config.globalProperties.$uiClient.setConfiguration(
17 app?.appContext.config.globalProperties.$configuration.uiServer[
18 state.uiServerIndex
19 ]
20 )
21 initializeWSEventListeners()
22 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
23 'open',
24 () => {
25 setToLocalStorage<number>('uiServerConfigurationIndex', state.uiServerIndex)
26 clearToggleButtons()
27 $router.currentRoute.value.name !== 'charging-stations' &&
28 $router.push({ name: 'charging-stations' })
29 },
30 { once: true }
31 )
32 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
33 'error',
34 () => {
35 state.uiServerIndex = getFromLocalStorage<number>(
36 'uiServerConfigurationIndex',
37 0
38 )
39 app?.appContext.config.globalProperties.$uiClient.setConfiguration(
40 app?.appContext.config.globalProperties.$configuration.uiServer[
41 getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
42 ]
43 )
44 initializeWSEventListeners()
45 },
46 { once: true }
47 )
48 }
49 }
50 "
0344ad2b 51 >
239bd875
JB
52 <option
53 v-for="uiServerConfiguration in uiServerConfigurations"
54 :value="uiServerConfiguration.index"
55 >
56 {{
57 uiServerConfiguration.configuration.name ?? uiServerConfiguration.configuration.host
58 }}
59 </option>
60 </select>
61 </Container>
240fa4da
JB
62 <ToggleButton
63 :id="'simulator'"
64 :key="state.renderSimulator"
65 :status="state.simulatorState?.started"
66 :on="() => startSimulator()"
67 :off="() => stopSimulator()"
3802683b
JB
68 :class="
69 state.simulatorState?.started === true
6027002f
JB
70 ? 'simulator-stop-button'
71 : 'simulator-start-button'
3802683b 72 "
240fa4da
JB
73 >
74 {{ state.simulatorState?.started === true ? 'Stop' : 'Start' }} Simulator
e8237645 75 {{ state.simulatorState?.version != null ? ` (${state.simulatorState?.version})` : '' }}
240fa4da 76 </ToggleButton>
2610da71
JB
77 <ToggleButton
78 :id="'add-charging-stations'"
d64ea57b 79 :key="state.renderAddChargingStations"
2610da71
JB
80 :shared="true"
81 :on="
82 () => {
83 $router.push({ name: 'add-charging-stations' })
84 }
85 "
86 :off="
87 () => {
88 $router.push({ name: 'charging-stations' })
89 }
90 "
83468764
JB
91 @clicked="
92 () => {
93 state.renderChargingStations = randomUUID()
94 }
95 "
2610da71 96 >
1eb5f592 97 Add Charging Stations
2610da71 98 </ToggleButton>
b9d447d2
JB
99 <ReloadButton
100 id="reload-button"
a4868fd7 101 :loading="state.loading"
3eea3ebc 102 @click="loadChargingStations(() => (state.renderChargingStations = randomUUID()))"
b9d447d2 103 />
13c19b7b 104 </Container>
5c0e9352 105 <CSTable
7378b34a 106 v-show="
5c0e9352 107 Array.isArray(app?.appContext.config.globalProperties.$chargingStations) &&
3eea3ebc 108 app.appContext.config.globalProperties.$chargingStations.length > 0
5c0e9352 109 "
3eea3ebc 110 :key="state.renderChargingStations"
5c0e9352 111 :charging-stations="app?.appContext.config.globalProperties.$chargingStations"
83468764
JB
112 @need-refresh="
113 () => {
114 state.renderAddChargingStations = randomUUID()
115 state.renderChargingStations = randomUUID()
116 }
117 "
5c0e9352 118 />
32de5a57
LM
119 </Container>
120</template>
121
122<script setup lang="ts">
3b0c6e17 123import { getCurrentInstance, onMounted, ref } from 'vue'
cea23fa0 124import { useToast } from 'vue-toast-notification'
66a7748d 125import CSTable from '@/components/charging-stations/CSTable.vue'
e8237645 126import type { ResponsePayload, SimulatorState, UIServerConfigurationSection } from '@/types'
66a7748d
JB
127import Container from '@/components/Container.vue'
128import ReloadButton from '@/components/buttons/ReloadButton.vue'
2610da71 129import {
b767fda7 130 deleteFromLocalStorage,
2610da71
JB
131 getFromLocalStorage,
132 getLocalStorage,
133 randomUUID,
2610da71
JB
134 setToLocalStorage
135} from '@/composables'
136import ToggleButton from '@/components/buttons/ToggleButton.vue'
a4868fd7 137
240fa4da
JB
138const state = ref<{
139 renderSimulator: `${string}-${string}-${string}-${string}-${string}`
140 renderAddChargingStations: `${string}-${string}-${string}-${string}-${string}`
141 renderChargingStations: `${string}-${string}-${string}-${string}-${string}`
142 loading: boolean
e8237645 143 simulatorState?: SimulatorState
240fa4da
JB
144 uiServerIndex: number
145}>({
146 renderSimulator: randomUUID(),
147 renderAddChargingStations: randomUUID(),
148 renderChargingStations: randomUUID(),
149 loading: false,
150 uiServerIndex: getFromLocalStorage<number>('uiServerConfigurationIndex', 0)
151})
152
916fe456
JB
153const app = getCurrentInstance()
154
d64ea57b
JB
155const clearToggleButtons = (): void => {
156 for (const key in getLocalStorage()) {
157 if (key.includes('toggle-button')) {
b767fda7 158 deleteFromLocalStorage(key)
d64ea57b
JB
159 }
160 }
161}
162
163const clearChargingStations = (): void => {
d64ea57b 164 app!.appContext.config.globalProperties.$chargingStations = []
3eea3ebc 165 state.value.renderChargingStations = randomUUID()
d64ea57b
JB
166}
167
240fa4da
JB
168const uiClient = app?.appContext.config.globalProperties.$uiClient
169
170const getSimulatorState = (): void => {
171 uiClient
172 .simulatorState()
173 .then((response: ResponsePayload) => {
e8237645 174 state.value.simulatorState = response.state as SimulatorState
240fa4da
JB
175 })
176 .catch((error: Error) => {
177 $toast.error('Error at fetching simulator state')
178 console.error('Error at fetching simulator state:', error)
179 })
180 .finally(() => {
181 state.value.renderSimulator = randomUUID()
182 })
183}
184
916fe456
JB
185const initializeWSEventListeners = () => {
186 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener('open', () => {
240fa4da 187 getSimulatorState()
3b0c6e17
JB
188 uiClient
189 .listTemplates()
190 .then((response: ResponsePayload) => {
191 if (app != null) {
192 app.appContext.config.globalProperties.$templates = response.templates
193 }
194 })
195 .catch((error: Error) => {
196 if (app != null) {
197 app.appContext.config.globalProperties.$templates = []
198 }
199 $toast.error('Error at fetching charging station templates')
200 console.error('Error at fetching charging station templates:', error)
201 })
240fa4da
JB
202 .finally(() => {
203 state.value.renderAddChargingStations = randomUUID()
204 })
d64ea57b 205 loadChargingStations(() => {
3eea3ebc 206 state.value.renderChargingStations = randomUUID()
d64ea57b 207 })
916fe456 208 })
d64ea57b
JB
209 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
210 'error',
211 clearChargingStations
212 )
213 app?.appContext.config.globalProperties.$uiClient.registerWSEventListener(
214 'close',
215 clearChargingStations
216 )
916fe456
JB
217}
218
219onMounted(() => {
220 initializeWSEventListeners()
221})
222
0344ad2b
JB
223const uiServerConfigurations: { configuration: UIServerConfigurationSection; index: number }[] =
224 app?.appContext.config.globalProperties.$configuration.uiServer.map(
225 (configuration: UIServerConfigurationSection, index: number) => ({
226 configuration,
227 index
228 })
229 )
57c0ba05 230
cea23fa0
JB
231const $toast = useToast()
232
86545028 233const loadChargingStations = (renderCallback?: () => void): void => {
3b0c6e17
JB
234 if (state.value.loading === false) {
235 state.value.loading = true
57c0ba05
JB
236 uiClient
237 .listChargingStations()
238 .then((response: ResponsePayload) => {
239 if (app != null) {
240 app.appContext.config.globalProperties.$chargingStations = response.chargingStations
241 }
242 })
243 .catch((error: Error) => {
916fe456
JB
244 if (app != null) {
245 app.appContext.config.globalProperties.$chargingStations = []
246 }
cea23fa0 247 $toast.error('Error at fetching charging stations')
57c0ba05
JB
248 console.error('Error at fetching charging stations:', error)
249 })
250 .finally(() => {
86545028
JB
251 if (renderCallback != null) {
252 renderCallback()
b9d447d2 253 }
3b0c6e17 254 state.value.loading = false
57c0ba05 255 })
2113b3c6 256 }
32de5a57 257}
5a010bf0 258
fa5d129a 259const startSimulator = (): void => {
cea23fa0
JB
260 uiClient
261 .startSimulator()
262 .then(() => {
263 $toast.success('Simulator successfully started')
264 })
265 .catch((error: Error) => {
266 $toast.error('Error at starting simulator')
267 console.error('Error at starting simulator:', error)
268 })
240fa4da
JB
269 .finally(() => {
270 getSimulatorState()
271 })
5a010bf0 272}
fa5d129a 273const stopSimulator = (): void => {
cea23fa0
JB
274 uiClient
275 .stopSimulator()
276 .then(() => {
5c0e9352
JB
277 if (app != null) {
278 app.appContext.config.globalProperties.$chargingStations = []
279 }
cea23fa0
JB
280 $toast.success('Simulator successfully stopped')
281 })
282 .catch((error: Error) => {
283 $toast.error('Error at stopping simulator')
284 console.error('Error at stopping simulator:', error)
285 })
240fa4da
JB
286 .finally(() => {
287 getSimulatorState()
288 })
5a010bf0 289}
32de5a57
LM
290</script>
291
292<style>
ca1e5439 293#charging-stations-container {
1d41bc6b 294 height: fit-content;
32de5a57 295 width: 100%;
5a010bf0 296 display: flex;
32de5a57 297 flex-direction: column;
5a010bf0
JB
298}
299
0344ad2b
JB
300#ui-server-container {
301 display: flex;
239bd875 302 justify-content: center;
0344ad2b
JB
303}
304
305#ui-server-selector {
306 width: 100%;
239bd875 307 background-color: rgb(239, 239, 239);
c6308554 308 font: small-caption;
0344ad2b
JB
309 text-align: center;
310}
311
239bd875 312#ui-server-selector:hover {
bad93db3 313 background-color: rgb(229, 229, 229);
239bd875
JB
314}
315
13c19b7b
JB
316#buttons-container {
317 display: flex;
318 flex-direction: row;
319}
320
6027002f 321.simulator-start-button {
3802683b
JB
322 color: ivory;
323 background-color: green;
324}
325
6027002f 326.simulator-stop-button {
3802683b
JB
327 color: ivory;
328 background-color: red;
329}
330
14ee627a
JB
331#action-button {
332 flex: none;
878855a2
JB
333}
334
32de5a57 335#reload-button {
3802683b 336 color: ivory;
9dc8b66f 337 background-color: blue;
c6308554 338 font-size: 2rem;
32de5a57
LM
339}
340
341#reload-button:hover {
9dc8b66f 342 background-color: rgb(0, 0, 225);
32de5a57
LM
343}
344
345#reload-button:active {
4b10e4f9 346 background-color: darkblue;
32de5a57 347}
229d8c34
JB
348
349#action {
3802683b 350 color: ivory;
229d8c34
JB
351 background-color: black;
352 padding: 1%;
353}
32de5a57 354</style>