diff --git a/appinfo/routes.php b/appinfo/routes.php
index 0f553333a..8e43b417f 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -39,6 +39,7 @@ return [
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
['name' => 'board#clone', 'url' => '/boards/{boardId}/clone', 'verb' => 'POST'],
+ ['name' => 'board#transferOwner', 'url' => '/boards/{boardId}/transferOwner', 'verb' => 'PUT'],
// stacks
['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'],
diff --git a/lib/Controller/BoardController.php b/lib/Controller/BoardController.php
index 9d0b9fcaf..086cf8a59 100644
--- a/lib/Controller/BoardController.php
+++ b/lib/Controller/BoardController.php
@@ -155,4 +155,15 @@ class BoardController extends ApiController {
public function clone($boardId) {
return $this->boardService->clone($boardId, $this->userId);
}
+
+ /**
+ * @NoAdminRequired
+ * @param $boardId
+ * @param $owner
+ * @param $newOwner
+ * * @return null|void
+ */
+ public function transferOwner($boardId, $owner, $newOwner) {
+ return $this->boardService->transferOwnership($owner, $newOwner);
+ }
}
diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php
index 556408551..9f47afba7 100644
--- a/lib/Service/BoardService.php
+++ b/lib/Service/BoardService.php
@@ -746,6 +746,12 @@ class BoardService {
$this->boardsCache = null;
}
+ private function getBoardOwner($boardId) {
+ $board = $this->boardMapper->find($boardId);
+
+ return $board->getOwner();
+ }
+
/**
* Clean a given board data from the Cache
*/
diff --git a/src/components/board/SharingTabSidebar.vue b/src/components/board/SharingTabSidebar.vue
index b1f84bf91..d09c99afd 100644
--- a/src/components/board/SharingTabSidebar.vue
+++ b/src/components/board/SharingTabSidebar.vue
@@ -53,6 +53,9 @@
{{ t('deck', 'Can manage') }}
+
+ {{ t('deck', 'Owner') }}
+
{{ t('deck', 'Delete') }}
@@ -72,7 +75,7 @@ import { Avatar, Multiselect, Actions, ActionButton, ActionCheckbox } from '@nex
import { CollectionList } from 'nextcloud-vue-collections'
import { mapGetters, mapState } from 'vuex'
import { getCurrentUser } from '@nextcloud/auth'
-import { showError } from '@nextcloud/dialogs'
+import { showError, showSuccess } from '@nextcloud/dialogs'
import debounce from 'lodash/debounce'
export default {
@@ -97,6 +100,7 @@ export default {
isSearching: false,
addAcl: null,
addAclForAPI: null,
+ newOwner: null,
}
},
computed: {
@@ -194,6 +198,39 @@ export default {
clickDeleteAcl(acl) {
this.$store.dispatch('deleteAclFromCurrentBoard', acl)
},
+ clickTranserOwner(newOwner) {
+ OC.dialogs.confirmDestructive(
+ t('deck', 'Are you sure you want to transfer the board {title} for {user} ?', { title: this.board.title, user: newOwner }),
+ t('deck', 'Transfer the board.'),
+ {
+ type: OC.dialogs.YES_NO_BUTTONS,
+ confirm: t('deck', 'Transfer'),
+ confirmClasses: 'error',
+ cancel: t('deck', 'Cancel'),
+ },
+ async (result) => {
+ if (result) {
+ try {
+ this.isLoading = true
+ await this.$store.dispatch('transferOwnership', {
+ boardId: this.board.id,
+ newOwner,
+ owner: this.board.owner.uid,
+ })
+ const successMessage = t('deck', 'Transfer the board for {user} successfully', { user: newOwner })
+ showSuccess(successMessage)
+ this.$router.push({ name: 'main' })
+ } catch (e) {
+ const errorMessage = t('deck', 'Failed to transfer the board for {user}', { user: newOwner.user })
+ showError(errorMessage)
+ } finally {
+ this.isLoading = false
+ }
+ }
+ },
+ true
+ )
+ },
},
}
diff --git a/src/store/main.js b/src/store/main.js
index c157423bf..d0e63cf0e 100644
--- a/src/store/main.js
+++ b/src/store/main.js
@@ -26,7 +26,7 @@ import { loadState } from '@nextcloud/initial-state'
import Vue from 'vue'
import Vuex from 'vuex'
import axios from '@nextcloud/axios'
-import { generateOcsUrl } from '@nextcloud/router'
+import { generateOcsUrl, generateUrl } from '@nextcloud/router'
import { BoardApi } from '../services/BoardApi'
import actions from './actions'
import stack from './stack'
@@ -497,5 +497,11 @@ export default new Vuex.Store({
dispatch('loadBoardById', acl.boardId)
})
},
+ async transferOwnership({ commit }, { boardId, owner, newOwner }) {
+ await axios.put(generateUrl(`apps/deck/boards/${boardId}/transferOwner`), {
+ owner,
+ newOwner,
+ })
+ },
},
})