From 0128b9f76865fc2e6f49e5b63d07e6d9693e73be Mon Sep 17 00:00:00 2001 From: Andrea Leardini Date: Thu, 5 Dec 2024 12:32:08 +0100 Subject: [PATCH] feat(ui): restore mail folder --- ui/package.json | 6 +- ui/public/i18n/en/translation.json | 34 +- .../mailboxes/BackupRepositorySelector.vue | 164 ++++++ .../mailboxes/BackupSnapshotSelector.vue | 147 +++++ .../components/mailboxes/PublicMailboxes.vue | 30 +- .../mailboxes/RestoreFolderModal.vue | 536 ++++++++++++++++++ ui/src/components/mailboxes/UserMailboxes.vue | 34 +- ui/src/main.js | 10 +- ui/yarn.lock | 28 +- 9 files changed, 972 insertions(+), 17 deletions(-) create mode 100644 ui/src/components/mailboxes/BackupRepositorySelector.vue create mode 100644 ui/src/components/mailboxes/BackupSnapshotSelector.vue create mode 100644 ui/src/components/mailboxes/RestoreFolderModal.vue diff --git a/ui/package.json b/ui/package.json index 186bac84..09718177 100644 --- a/ui/package.json +++ b/ui/package.json @@ -12,7 +12,7 @@ "dependencies": { "@carbon/icons-vue": "^10.37.0", "@carbon/vue": "^2.40.0", - "@nethserver/ns8-ui-lib": "^0.1.31", + "@nethserver/ns8-ui-lib": "^1.2.1", "await-to-js": "^3.0.0", "axios": "^0.21.2", "carbon-components": "^10.41.0", @@ -22,9 +22,10 @@ "vue": "^2.6.11", "vue-axios": "^3.2.4", "vue-date-fns": "^2.0.1", - "vue-debounce": "^4.0.0", "vue-i18n": "^8.24.4", + "vue-infinite-loading": "^2.4.5", "vue-router": "^3.2.0", + "vue2-debounce": "^1.0.1", "vuex": "^3.4.0" }, "devDependencies": { @@ -38,6 +39,7 @@ "eslint": "^6.7.2", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-vue": "^6.2.2", + "mark.js": "^8.11.1", "prettier": "^2.2.1", "sass-loader": "^10.1.1", "vue-template-compiler": "^2.6.11" diff --git a/ui/public/i18n/en/translation.json b/ui/public/i18n/en/translation.json index 3115f197..d50e06d7 100644 --- a/ui/public/i18n/en/translation.json +++ b/ui/public/i18n/en/translation.json @@ -19,7 +19,9 @@ "optional": "Optional", "mail_hostname": "Mail server hostname", "mail_hostname_tooltip": "Enter the MX record configured on your DNS service provider", - "rspamd_credentials_tooltip": "Use your login credentials to access Rspamd" + "rspamd_credentials_tooltip": "Use your login credentials to access Rspamd", + "next": "Next", + "previous": "Previous" }, "status": { "title": "Status", @@ -104,7 +106,10 @@ "flush-postfix-queue": "Flush Postfix queue", "get-queue-settings": "Get queue settings", "set-queue-settings": "Set queue settings", - "set-always-bcc": "Set always BCC" + "set-always-bcc": "Set always BCC", + "restore-backup-content": "Restore mail folder", + "seek-snapshot-contents": "Get snapshot folders", + "read-backup-snapshots": "Read backup snapshots" }, "error": { "error": "Error", @@ -274,7 +279,30 @@ "disable_mailbox": "Disable mailbox", "confirm_disable_mailbox": "Do you really want to disable mailbox {mailbox}?", "confirm_disable_mailbox_2": "It will stop receiving messages and you won't be able to select it as address destination", - "address_already_exists": "Address already exists" + "address_already_exists": "Address already exists", + "restore_folder_for_user_name": "Restore folder for user {name}", + "restore_public_mailbox_name": "Restore public mailbox {name}", + "restore_folder": "Restore folder", + "restore": "Restore", + "select_backup_destination": "Select backup destination", + "select_backup_snapshot": "Select backup snapshot", + "select_folder_to_restore": "Select folder to restore", + "no_backup_found": "No backup found", + "no_backup_found_description": "Ensure that a backup destination has been configured and that a backup has been performed for {module}", + "from_node_name_of_this_cluster": "From node {name} of this cluster", + "from_node_name_of_different_cluster": "From node {name} of a different cluster", + "from_this_cluster": "From this cluster", + "from_different_cluster": "From a different cluster", + "from_node_name": "From node {name}", + "most_recent": "Most recent", + "no_snapshot_to_restore": "No snapshots to restore", + "search_folder": "Search folder", + "restore_folder_info": "The selected mail folder will be restored to '{restoredFolder}'. If it exceeds the available space in the user's mailbox, the quota setting for that user will be changed to '@:settings_mailboxes.unlimited'.", + "restoring_mail_folder_for_user": "Restoring mail folder for {name}", + "restoring_public_mailbox_name": "Restoring public mailbox {name}", + "mailbox_quota_changed": "Mailbox quota changed", + "mailbox_quota_changed_description": "Mailbox quota for {user} has been set to '@:settings_mailboxes.unlimited' due to insufficient space encountered during folder restoration", + "go_to_mailboxes": "Go to Mailboxes" }, "filter": { "title": "Filter", diff --git a/ui/src/components/mailboxes/BackupRepositorySelector.vue b/ui/src/components/mailboxes/BackupRepositorySelector.vue new file mode 100644 index 00000000..ea0d13fe --- /dev/null +++ b/ui/src/components/mailboxes/BackupRepositorySelector.vue @@ -0,0 +1,164 @@ + + + + + + diff --git a/ui/src/components/mailboxes/BackupSnapshotSelector.vue b/ui/src/components/mailboxes/BackupSnapshotSelector.vue new file mode 100644 index 00000000..bdded13b --- /dev/null +++ b/ui/src/components/mailboxes/BackupSnapshotSelector.vue @@ -0,0 +1,147 @@ + + + + + + diff --git a/ui/src/components/mailboxes/PublicMailboxes.vue b/ui/src/components/mailboxes/PublicMailboxes.vue index b94d200b..e289722f 100644 --- a/ui/src/components/mailboxes/PublicMailboxes.vue +++ b/ui/src/components/mailboxes/PublicMailboxes.vue @@ -124,6 +124,16 @@ :label="core.$t('common.edit')" /> + + + + + @@ -195,10 +212,12 @@ import { } from "@nethserver/ns8-ui-lib"; import to from "await-to-js"; import CreateOrEditPublicMailboxModal from "./CreateOrEditPublicMailboxModal"; +import RecentlyViewed20 from "@carbon/icons-vue/es/recently-viewed/20"; +import RestoreFolderModal from "./RestoreFolderModal"; export default { name: "PublicMailboxes", - components: { CreateOrEditPublicMailboxModal }, + components: { CreateOrEditPublicMailboxModal, RestoreFolderModal }, mixins: [QueryParamService, UtilService, IconService, TaskService], data() { return { @@ -209,6 +228,8 @@ export default { mailboxes: [], isShownCreateOrEditPublicMailboxModal: false, isShownDeleteMailboxModal: false, + RecentlyViewed20, + isShownRestoreFolderModal: false, loading: { listPublicMailboxes: false, alterPublicMailbox: false, @@ -298,6 +319,13 @@ export default { hideDeleteMailboxModal() { this.isShownDeleteMailboxModal = false; }, + showRestoreFolderModal(mailbox) { + this.currentMailbox = mailbox; + this.isShownRestoreFolderModal = true; + }, + hideRestoreFolderModal() { + this.isShownRestoreFolderModal = false; + }, async removePublicMailbox() { this.loading.removePublicMailbox = true; this.error.removePublicMailbox = ""; diff --git a/ui/src/components/mailboxes/RestoreFolderModal.vue b/ui/src/components/mailboxes/RestoreFolderModal.vue new file mode 100644 index 00000000..8380bb95 --- /dev/null +++ b/ui/src/components/mailboxes/RestoreFolderModal.vue @@ -0,0 +1,536 @@ + + + + + + diff --git a/ui/src/components/mailboxes/UserMailboxes.vue b/ui/src/components/mailboxes/UserMailboxes.vue index b5b74b75..f920b561 100644 --- a/ui/src/components/mailboxes/UserMailboxes.vue +++ b/ui/src/components/mailboxes/UserMailboxes.vue @@ -163,6 +163,16 @@ :label="core.$t('common.edit')" /> + + + + + @@ -214,10 +231,16 @@ import { import to from "await-to-js"; import EditUserMailboxModal from "./EditUserMailboxModal"; import ConfirmDisableMailboxModal from "./ConfirmDisableMailboxModal"; +import RecentlyViewed20 from "@carbon/icons-vue/es/recently-viewed/20"; +import RestoreFolderModal from "./RestoreFolderModal"; export default { name: "UserMailboxes", - components: { EditUserMailboxModal, ConfirmDisableMailboxModal }, + components: { + EditUserMailboxModal, + ConfirmDisableMailboxModal, + RestoreFolderModal, + }, mixins: [QueryParamService, UtilService, IconService, TaskService], data() { return { @@ -228,6 +251,8 @@ export default { isShownEditUserMailboxModal: false, defaultSpamRetention: 0, isShownConfirmDisableMailbox: false, + RecentlyViewed20, + isShownRestoreFolderModal: false, loading: { listUserMailboxes: false, alterUserMailbox: false, @@ -307,6 +332,13 @@ export default { hideEditUserMailboxModal() { this.isShownEditUserMailboxModal = false; }, + showRestoreFolderModal(mailbox) { + this.currentMailbox = mailbox; + this.isShownRestoreFolderModal = true; + }, + hideRestoreFolderModal() { + this.isShownRestoreFolderModal = false; + }, toggleMailboxEnabled(mailbox) { this.currentMailbox = mailbox; diff --git a/ui/src/main.js b/ui/src/main.js index 64e3eaff..ce1faca1 100644 --- a/ui/src/main.js +++ b/ui/src/main.js @@ -28,7 +28,15 @@ Vue.use(VueDateFns); import LottieAnimation from "lottie-web-vue"; Vue.use(LottieAnimation); -import vueDebounce from "vue-debounce"; +import InfiniteLoading from "vue-infinite-loading"; +Vue.use(InfiniteLoading, { + slots: { + noResults: "", + noMore: "", + }, +}); + +import vueDebounce from "vue2-debounce"; Vue.use(vueDebounce); // filters diff --git a/ui/yarn.lock b/ui/yarn.lock index 6239cb60..89c78508 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1012,10 +1012,10 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@nethserver/ns8-ui-lib@^0.1.31": - version "0.1.31" - resolved "https://registry.yarnpkg.com/@nethserver/ns8-ui-lib/-/ns8-ui-lib-0.1.31.tgz#3dab2dde84441696e6a36b9e5d0e2dad913a691d" - integrity sha512-0r5Vcae6+rsOfOCYOgjCjr5JbIGZx4Qyq3biD3h66AoGBJSADfVDY3RWqlsu9yD0gHtC87Av0SJ18R9qq7ET0Q== +"@nethserver/ns8-ui-lib@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@nethserver/ns8-ui-lib/-/ns8-ui-lib-1.2.1.tgz#1c44f886af63cb8bfbd4fb07ef72163cb3ac5ecf" + integrity sha512-vcAFwsDHpTU2jE1Rc9avl22gE7rokGf1nIPzqAynywfuyaa6djzSnP61lJSDHTKQ3oFAd5bzi68McPntLQNAHQ== dependencies: "@rollup/plugin-json" "^4.1.0" core-js "^3.15.2" @@ -5741,6 +5741,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mark.js@^8.11.1: + version "8.11.1" + resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5" + integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.npmmirror.com/md5.js/download/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -8721,11 +8726,6 @@ vue-date-fns@^2.0.1: dependencies: date-fns "^2.0.0" -vue-debounce@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vue-debounce/-/vue-debounce-4.0.0.tgz#3f584dabc08a841a0182ab68d19f77f70a416fcc" - integrity sha512-+BrcKfLpyDpUJ58ZrAvI35irRCgYHFpnF3NJZwwaz8/kkKmEq6TWPXBIhLh2HQAsUZNwo52K/vQyiEFsJ/1RYA== - vue-eslint-parser@^7.0.0: version "7.8.0" resolved "https://registry.npmmirror.com/vue-eslint-parser/download/vue-eslint-parser-7.8.0.tgz#43850bf856c9a69d62c0e12769609c338423684b" @@ -8749,6 +8749,11 @@ vue-i18n@^8.24.4: resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.24.5.tgz#7127a666d5be2199be69be39e439a419a90ff931" integrity sha512-p8W5xOmniuZ8fj76VXe0vBL3bRWVU87jHuC/v8VwmhKVH2iMQsKnheB1U+umxDBqC/5g9K+NwzokepcLxnBAVQ== +vue-infinite-loading@^2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/vue-infinite-loading/-/vue-infinite-loading-2.4.5.tgz#cc20fd40af7f20188006443c99b60470cf1de1b3" + integrity sha512-xhq95Mxun060bRnsOoLE2Be6BR7jYwuC89kDe18+GmCLVrRA/dU0jrGb12Xu6NjmKs+iTW0AA6saSEmEW4cR7g== + "vue-loader-v16@npm:vue-loader@^16.1.0": version "16.3.0" resolved "https://registry.npmmirror.com/vue-loader/download/vue-loader-16.3.0.tgz?cache=0&sync_timestamp=1624994254628&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fvue-loader%2Fdownload%2Fvue-loader-16.3.0.tgz#2f195e4ba0fb0e263596d6830df17d1a36e8936c" @@ -8795,6 +8800,11 @@ vue-template-es2015-compiler@^1.9.0: resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" integrity sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU= +vue2-debounce@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vue2-debounce/-/vue2-debounce-1.0.1.tgz#2b4da2fe9d34f9c8be08ead9e8e68b988fd15f98" + integrity sha512-tZX6QltRUuGn9WUUVJDTWUmAqGugIUKcQN4praNAW4ZQPtBIyyZfvCLq7hKOOSdFhVRloXeFnCZvETibEgKNOw== + vue@^2.6.11, vue@^2.6.12: version "2.6.14" resolved "https://registry.npmmirror.com/vue/download/vue-2.6.14.tgz#e51aa5250250d569a3fbad3a8a5a687d6036e235"