diff --git a/src/components/SettingsConnectedService.vue b/src/components/SettingsConnectedService.vue
index 638893c..0dbe3a8 100644
--- a/src/components/SettingsConnectedService.vue
+++ b/src/components/SettingsConnectedService.vue
@@ -26,6 +26,7 @@ interface SystemConfiguration {
const props = defineProps<{
service: Service
+ busy: boolean
systemConfiguration: SystemConfiguration
contactsRemoteSupported: boolean
contactsRemoteCollections: Collection[]
@@ -230,19 +231,19 @@ function establishedEventCorrelationHarmonized(ccid: string | null): number {
-
+
{{ t('integration_davc', 'Save') }}
-
+
{{ t('integration_davc', 'Harmonize') }}
-
+
diff --git a/src/views/UserSettings.vue b/src/views/UserSettings.vue
index 5e8e1d7..81f8b0a 100644
--- a/src/views/UserSettings.vue
+++ b/src/views/UserSettings.vue
@@ -14,11 +14,9 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { onMounted, reactive, ref } from 'vue'
import NcButton from '@nextcloud/vue/components/NcButton'
-import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
import NcSelect from '@nextcloud/vue/components/NcSelect'
import AccountRemoveIcon from 'vue-material-design-icons/AccountMinus.vue'
import AccountAddIcon from 'vue-material-design-icons/AccountPlus.vue'
-import CheckIcon from 'vue-material-design-icons/Check.vue'
import SettingsConnectedService from '../components/SettingsConnectedService.vue'
import SettingsEmptyState from '../components/SettingsEmptyState.vue'
import SettingsFreshService from '../components/SettingsFreshService.vue'
@@ -39,6 +37,22 @@ const systemConfiguration = reactive(loadState('integration
const configuredServices = ref([])
const selectedService = ref(null)
+// Whether an action (save/harmonize/disconnect) is currently in progress
+const busy = ref(false)
+
+// Runs an action while preventing any other action from starting until it completes
+async function runExclusive(action: () => void | Promise): Promise {
+ if (busy.value) {
+ return
+ }
+ busy.value = true
+ try {
+ await action()
+ } finally {
+ busy.value = false
+ }
+}
+
// Contacts
const contactsRemoteSupported = ref(false)
const contactsRemoteCollections = ref([])
@@ -124,8 +138,8 @@ async function disconnectService(): Promise {
}
}
-function modifyService(): void {
- localCollectionsDeposit()
+function modifyService(): Promise {
+ return localCollectionsDeposit()
}
async function harmonizeService(): Promise {
@@ -156,13 +170,25 @@ async function serviceList(): Promise {
}
}
-function serviceSelect(option: Service | null): void {
+async function serviceSelect(option: Service | null): Promise {
if (!option) {
return
}
selectedService.value = option
- remoteCollectionsFetch()
- localCollectionsFetch()
+ // reset collections state
+ contactsRemoteSupported.value = false
+ contactsRemoteCollections.value = []
+ contactsLocalCollections.value = []
+ eventsRemoteSupported.value = false
+ eventsRemoteCollections.value = []
+ eventsLocalCollections.value = []
+
+ busy.value = true
+ try {
+ await Promise.all([remoteCollectionsFetch(), localCollectionsFetch()])
+ } finally {
+ busy.value = false
+ }
}
async function remoteCollectionsFetch(): Promise {
const uri = generateUrl('/apps/integration_davc/remote/collections/fetch')
@@ -310,6 +336,7 @@ function changeEventCorrelation(rcid: string | null, e: boolean): void {
+ @save="runExclusive(modifyService)"
+ @harmonize="runExclusive(harmonizeService)"
+ @disconnect="runExclusive(disconnectService)" />