diff --git a/src/components/CircleDetails.vue b/src/components/CircleDetails.vue
index c90865e0a..4ac773356 100644
--- a/src/components/CircleDetails.vue
+++ b/src/components/CircleDetails.vue
@@ -73,7 +73,11 @@
-
+
@@ -649,6 +653,10 @@ export default {
this.confirmDeleteCircle()
},
+ onCloseSettingsPopover() {
+ this.isSettingsPopoverShown = false
+ },
+
startEditing() {
this.originalDisplayName = this.circle.displayName
this.originalDescription = this.circle.description
diff --git a/src/components/CircleDetails/CircleSettings.vue b/src/components/CircleDetails/CircleSettings.vue
index 1e3e8286b..4fda50199 100644
--- a/src/components/CircleDetails/CircleSettings.vue
+++ b/src/components/CircleDetails/CircleSettings.vue
@@ -19,7 +19,7 @@
:loading="loading === config"
:disabled="loading !== false"
wrapper-element="li"
- @update:model-value="onChange(config, $event)">
+ @update:model-value="onChange(Number(config), $event)">
{{ label }}
@@ -63,7 +63,8 @@ import IconLogout from 'vue-material-design-icons/Logout.vue'
import IconDelete from 'vue-material-design-icons/TrashCanOutline.vue'
import CirclePasswordSettings from './CirclePasswordSettings.vue'
import ContentHeading from './ContentHeading.vue'
-import { PUBLIC_CIRCLE_CONFIG } from '../../models/constants.ts'
+import CircleActionsMixin from '../../mixins/CircleActionsMixin.js'
+import { CircleConfigs, PUBLIC_CIRCLE_CONFIG } from '../../models/constants.ts'
import { CircleEdit, editCircle } from '../../services/circles.ts'
export default defineComponent({
@@ -77,6 +78,8 @@ export default defineComponent({
NcCheckboxRadioSwitch,
},
+ mixins: [CircleActionsMixin],
+
props: {
circle: {
type: Object,
@@ -84,7 +87,7 @@ export default defineComponent({
},
},
- emits: ['leave', 'delete'],
+ emits: ['leave', 'delete', 'close-settings-popover'],
setup() {
return { t }
},
@@ -110,6 +113,14 @@ export default defineComponent({
async onChange(config: number, checked: boolean) {
this.logger.debug(`Circle config ${config} is set to ${checked}`)
+ if (checked && config === CircleConfigs.FEDERATED) {
+ this.$emit('close-settings-popover')
+ const confirmed = await this.confirmEnableFederationForCircle()
+ if (!confirmed) {
+ return
+ }
+ }
+
this.loading = config
const prevConfig = this.circle.config
if (checked) {
diff --git a/src/mixins/CircleActionsMixin.js b/src/mixins/CircleActionsMixin.js
index 20cbeab5f..d1cb14a4d 100644
--- a/src/mixins/CircleActionsMixin.js
+++ b/src/mixins/CircleActionsMixin.js
@@ -1,4 +1,4 @@
-import { showError } from '@nextcloud/dialogs'
+import { showConfirmation, showError, showSuccess } from '@nextcloud/dialogs'
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -134,6 +134,39 @@ export default {
}
},
+ async confirmEnableFederationForCircle() {
+ const confirmed = await showConfirmation({
+ name: t('contacts', 'Confirm enabling federation'),
+ text: t('contacts', 'Enabling this will remove {circle} from all the teams it belongs to.\nAre you sure?', {
+ circle: this.circle.displayName,
+ }),
+ labelConfirm: t('contacts', 'Enable federation'),
+ labelReject: t('contacts', 'Cancel'),
+ severity: 'warning',
+ })
+ if (!confirmed) {
+ this.logger.debug('Enable federation cancelled')
+ return false
+ }
+ return await this.removeCircleFromParentCircles()
+ },
+
+ async removeCircleFromParentCircles() {
+ this.loadingAction = true
+ try {
+ await this.$store.dispatch('removeCircleFromParentCircles', this.circle.id)
+ showSuccess(t('contacts', 'Federation enabled for {circle}', {
+ circle: this.circle.displayName,
+ }))
+ return true
+ } catch (error) {
+ showError(t('contacts', 'Unable to enable federation'))
+ return false
+ } finally {
+ this.loadingAction = false
+ }
+ },
+
/**
* Trigger the entity picker view
*/
diff --git a/src/services/circles.d.ts b/src/services/circles.d.ts
index c8a885973..548f5801d 100644
--- a/src/services/circles.d.ts
+++ b/src/services/circles.d.ts
@@ -47,6 +47,12 @@ export declare const createCircle: (name: string, personal: boolean, local: bool
* @return {object}
*/
export declare const deleteCircle: (circleId: string) => Promise
+/**
+ * Remove a circle from all parent circles it belongs to
+ *
+ * @param {string} circleId the circle id
+ */
+export declare const removeCircleFromParentCircles: (circleId: string) => Promise
/**
* Edit an existing circle
*
diff --git a/src/services/circles.ts b/src/services/circles.ts
index d833200f5..d5cedd758 100644
--- a/src/services/circles.ts
+++ b/src/services/circles.ts
@@ -75,6 +75,16 @@ export async function deleteCircle(circleId: string) {
return response.data.ocs.data
}
+/**
+ * Remove a circle from all parent circles it belongs to
+ *
+ * @param circleId the circle id
+ */
+export async function removeCircleFromParentCircles(circleId: string) {
+ const response = await axios.put(generateOcsUrl('apps/circles/circles/{circleId}/leave-parent-circles', { circleId }))
+ return response.data.ocs.data
+}
+
/**
* Edit an existing circle
*
diff --git a/src/store/circles.js b/src/store/circles.js
index fae56686e..4b1ed3799 100644
--- a/src/store/circles.js
+++ b/src/store/circles.js
@@ -17,6 +17,7 @@ import {
getCircleMembers,
getCircles,
leaveCircle,
+ removeCircleFromParentCircles,
} from '../services/circles.ts'
import logger from '../services/logger.js'
@@ -217,6 +218,23 @@ const actions = {
}
},
+ /**
+ * Remove circle from all parent circles it belongs to
+ *
+ * @param {object} context the store mutations Current context
+ * @param {string} circleId the circle id
+ */
+ async removeCircleFromParentCircles(context, circleId) {
+ try {
+ await removeCircleFromParentCircles(circleId)
+ logger.debug('Removed circle from parent circles', { circleId })
+ context.dispatch('updateCirclesPopulationCount')
+ } catch (error) {
+ console.error(error)
+ throw error
+ }
+ },
+
/**
* Update population count for all circles
*