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)" />