feat(ui): add action success/failure notifications
authorJérôme Benoit <jerome.benoit@sap.com>
Sun, 18 Feb 2024 13:15:56 +0000 (14:15 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sun, 18 Feb 2024 13:15:56 +0000 (14:15 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
ui/web/package.json
ui/web/pnpm-lock.yaml
ui/web/src/components/actions/AddChargingStations.vue
ui/web/src/components/actions/SetSupervisionUrl.vue
ui/web/src/components/actions/StartTransaction.vue
ui/web/src/components/charging-stations/CSConnector.vue
ui/web/src/components/charging-stations/CSData.vue
ui/web/src/main.ts
ui/web/src/views/ChargingStationsView.vue

index db4c7b4c75aa5bcc4e49fead4a5d0a2f259a413f..caa425a1bb5f769b1baf33618a2ff949a590c8bd 100644 (file)
@@ -35,7 +35,8 @@
     "finalhandler": "^1.2.0",
     "serve-static": "^1.15.0",
     "vue": "^3.4.19",
-    "vue-router": "^4.2.5"
+    "vue-router": "^4.2.5",
+    "vue-toast-notification": "^3.1.2"
   },
   "devDependencies": {
     "@rushstack/eslint-patch": "^1.7.2",
index 050f7de36ac54e8e597e3837e54a0b1ef119b7de..60741f5be6e263e27031c77863796b6a8654398d 100644 (file)
@@ -20,6 +20,9 @@ dependencies:
   vue-router:
     specifier: ^4.2.5
     version: 4.2.5(vue@3.4.19)
+  vue-toast-notification:
+    specifier: ^3.1.2
+    version: 3.1.2(vue@3.4.19)
 
 devDependencies:
   '@rushstack/eslint-patch':
@@ -4219,6 +4222,15 @@ packages:
       vue: 3.4.19(typescript@5.3.3)
     dev: false
 
+  /vue-toast-notification@3.1.2(vue@3.4.19):
+    resolution: {integrity: sha512-oNRL/W9aaHoeScp+iTIW7k09vM16/+8aptp2maa+7qTB43JuxmAgKdXKFYtf+uvSNOYYq2BIWgLCeJ61pwom/A==}
+    engines: {node: '>=12.15.0'}
+    peerDependencies:
+      vue: ^3.0
+    dependencies:
+      vue: 3.4.19(typescript@5.3.3)
+    dev: false
+
   /vue@3.4.19(typescript@5.3.3):
     resolution: {integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==}
     peerDependencies:
index 387d8a1a7110860e55a954878bc6b874403e21ed..7a2f8a59ef86cc8c727a5f587c7cbd5e55558557 100644 (file)
       () => {
         uiClient
           .addChargingStations(state.template, state.numberOfStations)
+          .then(() => {
+            $toast.success('Charging stations successfully added')
+          })
           .catch((error: Error) => {
-            // TODO: add code for UI notifications or other error handling logic
+            $toast.error('Error at adding charging stations')
             console.error('Error at adding charging stations:', error)
           })
           .finally(() => {
@@ -36,6 +39,7 @@
 
 <script setup lang="ts">
 import { getCurrentInstance, onMounted, reactive } from 'vue'
+import { useToast } from 'vue-toast-notification'
 import Button from '@/components/buttons/Button.vue'
 import type { ResponsePayload } from '@/types'
 
@@ -48,6 +52,8 @@ const state = reactive({
 const app = getCurrentInstance()
 const uiClient = app?.appContext.config.globalProperties.$uiClient
 
+const $toast = useToast()
+
 onMounted(() => {
   uiClient
     .listTemplates()
@@ -57,7 +63,7 @@ onMounted(() => {
       }
     })
     .catch((error: Error) => {
-      // TODO: add code for UI notifications or other error handling logic
+      $toast.error('Error at fetching charging station templates')
       console.error('Error at fetching charging station templates:', error)
     })
     .finally(() => {
index 00f4ef3d4ebcf40d1d23ecabf9db18aceacb168b..0dfc282cfd88f24d0018af7c26b08539c23d29db 100644 (file)
       () => {
         uiClient
           .setSupervisionUrl(props.hashId, state.supervisionUrl)
+          .then(() => {
+            $toast.success('Supervision url successfully set')
+          })
           .catch((error: Error) => {
-            // TODO: add code for UI notifications or other error handling logic
+            $toast.error('Error at setting supervision url')
             console.error('Error at setting supervision url:', error)
           })
           .finally(() => {
index 62fe31f1ceac25c92d341cd8bc86385ac84712d1..6a96e34df4dccf80efe23ad024612d56ea957131 100644 (file)
@@ -9,8 +9,11 @@
       () => {
         uiClient
           .startTransaction(props.hashId, parseInt(props.connectorId), state.idTag)
+          .then(() => {
+            $toast.success('Transaction successfully started')
+          })
           .catch((error: Error) => {
-            // TODO: add code for UI notifications or other error handling logic
+            $toast.error('Error at starting transaction')
             console.error('Error at starting transaction:', error)
           })
           .finally(() => {
index c9e53696cde361b52feecbb020ec22200c21c6b8..8b577f580661d2eb6dd171f1973f76b7eea30bba 100644 (file)
@@ -27,6 +27,7 @@
 
 <script setup lang="ts">
 import { getCurrentInstance } from 'vue'
+import { useToast } from 'vue-toast-notification'
 import Button from '@/components/buttons/Button.vue'
 import type { ConnectorStatus, Status } from '@/types'
 
@@ -40,13 +41,39 @@ const props = defineProps<{
 
 const uiClient = getCurrentInstance()?.appContext.config.globalProperties.$uiClient
 
+const $toast = useToast()
+
 function stopTransaction(): void {
-  uiClient.stopTransaction(props.hashId, props.connector.transactionId)
+  uiClient
+    .stopTransaction(props.hashId, props.connector.transactionId)
+    .then(() => {
+      $toast.success('Transaction successfully stopped')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at stopping transaction')
+      console.error('Error at stopping transaction:', error)
+    })
 }
 function startAutomaticTransactionGenerator(): void {
-  uiClient.startAutomaticTransactionGenerator(props.hashId, props.connectorId)
+  uiClient
+    .startAutomaticTransactionGenerator(props.hashId, props.connectorId)
+    .then(() => {
+      $toast.success('Automatic transaction generator successfully started')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at starting automatic transaction generator')
+      console.error('Error at starting automatic transaction generator:', error)
+    })
 }
 function stopAutomaticTransactionGenerator(): void {
-  uiClient.stopAutomaticTransactionGenerator(props.hashId, props.connectorId)
+  uiClient
+    .stopAutomaticTransactionGenerator(props.hashId, props.connectorId)
+    .then(() => {
+      $toast.success('Automatic transaction generator successfully stopped')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at stopping automatic transaction generator')
+      console.error('Error at stopping automatic transaction generator:', error)
+    })
 }
 </script>
index 4502f53cb300f48178119e3462382d2c4e7f7628..423014bdae8b9e27ae6c92e3a4d93f8da468fcfb 100644 (file)
@@ -67,6 +67,7 @@
 
 <script setup lang="ts">
 import { getCurrentInstance } from 'vue'
+import { useToast } from 'vue-toast-notification'
 import CSConnector from '@/components/charging-stations/CSConnector.vue'
 import Button from '@/components/buttons/Button.vue'
 import type { ChargingStationData, ConnectorStatus, Status } from '@/types'
@@ -114,20 +115,62 @@ function getWsState(): string {
 
 const uiClient = getCurrentInstance()?.appContext.config.globalProperties.$uiClient
 
+const $toast = useToast()
+
 function startChargingStation(): void {
-  uiClient.startChargingStation(props.chargingStation.stationInfo.hashId)
+  uiClient
+    .startChargingStation(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Charging station successfully started')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at starting charging station')
+      console.error('Error at starting charging station', error)
+    })
 }
 function stopChargingStation(): void {
-  uiClient.stopChargingStation(props.chargingStation.stationInfo.hashId)
+  uiClient
+    .stopChargingStation(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Charging station successfully stopped')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at stopping charging station')
+      console.error('Error at stopping charging station', error)
+    })
 }
 function openConnection(): void {
-  uiClient.openConnection(props.chargingStation.stationInfo.hashId)
+  uiClient
+    .openConnection(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Connection successfully opened')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at opening connection')
+      console.error('Error at opening connection', error)
+    })
 }
 function closeConnection(): void {
-  uiClient.closeConnection(props.chargingStation.stationInfo.hashId)
+  uiClient
+    .closeConnection(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Connection successfully closed')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at closing connection')
+      console.error('Error at closing connection', error)
+    })
 }
 function deleteChargingStation(): void {
-  uiClient.deleteChargingStation(props.chargingStation.stationInfo.hashId)
+  uiClient
+    .deleteChargingStation(props.chargingStation.stationInfo.hashId)
+    .then(() => {
+      $toast.success('Charging station successfully deleted')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at deleting charging station')
+      console.error('Error at deleting charging station', error)
+    })
 }
 </script>
 
index 18186e16cf91ac208dd2d205df4700b84961c2bd..bb42f57690273dd5c88115fd1f6228520f549725 100644 (file)
@@ -1,8 +1,10 @@
 import { createApp } from 'vue'
+import ToastPlugin from 'vue-toast-notification'
 import type { ConfigurationData, ResponsePayload } from './types'
 import { router } from '@/router'
 import { UIClient } from '@/composables'
 import App from '@/App.vue'
+import 'vue-toast-notification/dist/theme-default.css'
 
 const initializeApp = (config: ConfigurationData) => {
   const app = createApp(App)
@@ -25,7 +27,7 @@ const initializeApp = (config: ConfigurationData) => {
         throw error
       })
       .finally(() => {
-        app.use(router).mount('#app')
+        app.use(router).use(ToastPlugin).mount('#app')
       })
   })
 }
index d0acc4e3562c9e3a1b5ffb9f531cb5adc82ec614..b8a719b75ecaacd5fc49e660e7d9abb0acb4bcff 100644 (file)
@@ -18,6 +18,7 @@
 
 <script setup lang="ts">
 import { getCurrentInstance, reactive } from 'vue'
+import { useToast } from 'vue-toast-notification'
 import CSTable from '@/components/charging-stations/CSTable.vue'
 import type { ResponsePayload } from '@/types'
 import Container from '@/components/Container.vue'
@@ -31,6 +32,8 @@ const state = reactive({
 const app = getCurrentInstance()
 const uiClient = app?.appContext.config.globalProperties.$uiClient
 
+const $toast = useToast()
+
 function loadChargingStations(reloadCallback?: () => void): void {
   if (state.isLoading === false) {
     state.isLoading = true
@@ -42,7 +45,7 @@ function loadChargingStations(reloadCallback?: () => void): void {
         }
       })
       .catch((error: Error) => {
-        // TODO: add code for UI notifications or other error handling logic
+        $toast.error('Error at fetching charging stations')
         console.error('Error at fetching charging stations:', error)
       })
       .finally(() => {
@@ -55,10 +58,26 @@ function loadChargingStations(reloadCallback?: () => void): void {
 }
 
 function startSimulator(): void {
-  uiClient.startSimulator()
+  uiClient
+    .startSimulator()
+    .then(() => {
+      $toast.success('Simulator successfully started')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at starting simulator')
+      console.error('Error at starting simulator:', error)
+    })
 }
 function stopSimulator(): void {
-  uiClient.stopSimulator()
+  uiClient
+    .stopSimulator()
+    .then(() => {
+      $toast.success('Simulator successfully stopped')
+    })
+    .catch((error: Error) => {
+      $toast.error('Error at stopping simulator')
+      console.error('Error at stopping simulator:', error)
+    })
 }
 </script>