diff --git a/nextcloud_backup/frontend/package.json b/nextcloud_backup/frontend/package.json index 5d313d0..8ebaf4e 100644 --- a/nextcloud_backup/frontend/package.json +++ b/nextcloud_backup/frontend/package.json @@ -22,7 +22,7 @@ "roboto-fontface": "*", "uuid": "^9.0.0", "vue": "^3.2.45", - "vuetify": "3.1.1", + "vuetify": "3.1.3", "webfontloader": "^1.6.28" }, "devDependencies": { diff --git a/nextcloud_backup/frontend/pnpm-lock.yaml b/nextcloud_backup/frontend/pnpm-lock.yaml index e6d930d..f0faad2 100644 --- a/nextcloud_backup/frontend/pnpm-lock.yaml +++ b/nextcloud_backup/frontend/pnpm-lock.yaml @@ -27,7 +27,7 @@ specifiers: vite-plugin-vuetify: ^1.0.1 vue: ^3.2.45 vue-tsc: 1.0.7 - vuetify: 3.1.1 + vuetify: 3.1.3 webfontloader: ^1.6.28 dependencies: @@ -42,7 +42,7 @@ dependencies: roboto-fontface: 0.10.0 uuid: 9.0.0 vue: 3.2.45 - vuetify: 3.1.1_ihnv4ujwy6q3qcyepcitbzrajy + vuetify: 3.1.3_ihnv4ujwy6q3qcyepcitbzrajy webfontloader: 1.6.28 devDependencies: @@ -59,7 +59,7 @@ devDependencies: prettier: 2.8.2 typescript: 4.7.4 vite: 3.2.5_@types+node@16.18.11 - vite-plugin-vuetify: 1.0.1_mc6ujyzexjrcgjeph6am73m5wu + vite-plugin-vuetify: 1.0.1_bps52lyiebopdablgncd5xv5m4 vue-tsc: 1.0.7_typescript@4.7.4 packages: @@ -497,7 +497,7 @@ packages: '@types/node': 16.18.11 dev: true - /@vuetify/loader-shared/1.7.0_vue@3.2.45+vuetify@3.1.1: + /@vuetify/loader-shared/1.7.0_vue@3.2.45+vuetify@3.1.3: resolution: {integrity: sha512-Db4K67wMhduDsbvdRBYkrYuomti+j0E/1vlz1lnDng5F9LYYBcXa60qypIazVGI6GX/CuY1vshN6XGtGQI4FKg==} peerDependencies: vue: ^3.0.0 @@ -506,7 +506,7 @@ packages: find-cache-dir: 3.3.2 upath: 2.0.1 vue: 3.2.45 - vuetify: 3.1.1_ihnv4ujwy6q3qcyepcitbzrajy + vuetify: 3.1.3_ihnv4ujwy6q3qcyepcitbzrajy /acorn-jsx/5.3.2_acorn@8.8.1: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -2260,18 +2260,18 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-plugin-vuetify/1.0.1_mc6ujyzexjrcgjeph6am73m5wu: + /vite-plugin-vuetify/1.0.1_bps52lyiebopdablgncd5xv5m4: resolution: {integrity: sha512-/xHsIDuHxq7f6fDqCBYxNascLhDi+X8dV3RzTwmo4mGPrSnGq9pHv8wJsXBIQIT3nY8s16V0lmd6sXMjm0F8wg==} engines: {node: '>=12'} peerDependencies: vite: ^2.7.0 || ^3.0.0 || ^4.0.0 vuetify: ^3.0.0-beta.4 dependencies: - '@vuetify/loader-shared': 1.7.0_vue@3.2.45+vuetify@3.1.1 + '@vuetify/loader-shared': 1.7.0_vue@3.2.45+vuetify@3.1.3 debug: 4.3.4 upath: 2.0.1 vite: 3.2.5_@types+node@16.18.11 - vuetify: 3.1.1_ihnv4ujwy6q3qcyepcitbzrajy + vuetify: 3.1.3_ihnv4ujwy6q3qcyepcitbzrajy transitivePeerDependencies: - supports-color - vue @@ -2369,8 +2369,8 @@ packages: '@vue/server-renderer': 3.2.45_vue@3.2.45 '@vue/shared': 3.2.45 - /vuetify/3.1.1_ihnv4ujwy6q3qcyepcitbzrajy: - resolution: {integrity: sha512-BkfRQZ406xQORpgrcUjuPaT/woO96ef/+2zHCfL3an+CrUhjG/sIAptEybHruq3xwFM0uJibDFqGiridsXc99w==} + /vuetify/3.1.3_ihnv4ujwy6q3qcyepcitbzrajy: + resolution: {integrity: sha512-QE/yXvHKDnlK9sjjMoZy9cAovNabpI97xg9RD+mAEDgSUaZNCX/jy7Qn0bP1DjJNeAsR2oAlcO0C2WhrsYe9kw==} engines: {node: ^12.20 || >=14.13} peerDependencies: vite-plugin-vuetify: ^1.0.0-alpha.12 @@ -2385,7 +2385,7 @@ packages: webpack-plugin-vuetify: optional: true dependencies: - vite-plugin-vuetify: 1.0.1_mc6ujyzexjrcgjeph6am73m5wu + vite-plugin-vuetify: 1.0.1_bps52lyiebopdablgncd5xv5m4 vue: 3.2.45 /webfontloader/1.6.28: diff --git a/nextcloud_backup/frontend/src/App.vue b/nextcloud_backup/frontend/src/App.vue index 08c03a3..3350235 100644 --- a/nextcloud_backup/frontend/src/App.vue +++ b/nextcloud_backup/frontend/src/App.vue @@ -3,7 +3,8 @@ - + + @@ -15,11 +16,12 @@ diff --git a/nextcloud_backup/frontend/src/components/AlertManager.vue b/nextcloud_backup/frontend/src/components/AlertManager.vue new file mode 100644 index 0000000..264bf4a --- /dev/null +++ b/nextcloud_backup/frontend/src/components/AlertManager.vue @@ -0,0 +1,56 @@ + + + diff --git a/nextcloud_backup/frontend/src/components/settings/BackupConfigMenu.vue b/nextcloud_backup/frontend/src/components/settings/BackupConfigMenu.vue index df6fdb2..7d7030e 100644 --- a/nextcloud_backup/frontend/src/components/settings/BackupConfigMenu.vue +++ b/nextcloud_backup/frontend/src/components/settings/BackupConfigMenu.vue @@ -12,7 +12,7 @@ | null>(null); @@ -55,8 +58,14 @@ function save() { form.value?.save(); } -function saved() { - dialogStatusStore.webdav = false; +function fail() { saving.value = false; + alertStore.add("error", "Fail to save backup settings !"); +} + +function saved() { + dialogStatusStore.backup = false; + saving.value = false; + alertStore.add("success", "Backup settings saved !"); } diff --git a/nextcloud_backup/frontend/src/components/settings/WebdavConfigMenu.vue b/nextcloud_backup/frontend/src/components/settings/WebdavConfigMenu.vue index efedae4..7005b55 100644 --- a/nextcloud_backup/frontend/src/components/settings/WebdavConfigMenu.vue +++ b/nextcloud_backup/frontend/src/components/settings/WebdavConfigMenu.vue @@ -12,7 +12,7 @@ import { useMenuSize } from "@/composable/menuSize"; +import { useAlertStore } from "@/stores/alert"; import { useDialogStatusStore } from "@/stores/dialogStatus"; import { computed, ref } from "vue"; import WebdavSettingsForm from "./WebdavConfigForm.vue"; +const alertStore = useAlertStore(); + const dialogStatusStore = useDialogStatusStore(); const form = ref | null>(null); const { width, isFullScreen } = useMenuSize(); @@ -55,8 +58,14 @@ function save() { form.value?.save(); } +function fail() { + saving.value = false; + alertStore.add("error", "Fail to save cloud settings !"); +} + function saved() { dialogStatusStore.webdav = false; saving.value = false; + alertStore.add("success", "Cloud settings saved !"); } diff --git a/nextcloud_backup/frontend/src/stores/alert.ts b/nextcloud_backup/frontend/src/stores/alert.ts new file mode 100644 index 0000000..fb62eec --- /dev/null +++ b/nextcloud_backup/frontend/src/stores/alert.ts @@ -0,0 +1,42 @@ +import type { Alert } from "@/types/alert"; +import { defineStore } from "pinia"; +import { ref, type Ref } from "vue"; +import { v4 as uuidv4 } from "uuid"; + +export const useAlertStore = defineStore("alert", () => { + const alertList = ref([]) as Ref; + const timeOutValue = ref(100); + + function add( + type: "error" | "success" | "warning" | "info", + message: string + ) { + const alert: Alert = { + id: uuidv4(), + timeOut: ref(timeOutValue.value), + interval: setInterval(() => { + timeout(alert); + }, 50), + type: type, + message: message, + }; + alertList.value.push(alert); + } + + function timeout(alert: Alert) { + if (alert.timeOut.value <= 0) { + remove(alert.id!); + } else { + alert.timeOut.value--; + } + } + + function remove(id: string) { + const alertToRemove = alertList.value.find((value) => value.id == id); + if (alertToRemove) { + clearInterval(alertToRemove.interval); + } + alertList.value = alertList.value.filter((value) => value.id != id); + } + return { alertList, timeOutValue, add, remove }; +}); diff --git a/nextcloud_backup/frontend/src/types/alert.ts b/nextcloud_backup/frontend/src/types/alert.ts new file mode 100644 index 0000000..e9c8a26 --- /dev/null +++ b/nextcloud_backup/frontend/src/types/alert.ts @@ -0,0 +1,9 @@ +import type { Ref } from "vue"; + +export interface Alert { + id: string; + type: "error" | "success" | "warning" | "info"; + message: string; + timeOut: Ref; + interval: number; +}