From f46c31f1207815a9c5bcf7146daf332b1835da49 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Mon, 14 Mar 2022 22:42:34 +0100 Subject: [PATCH] feat: add api endpoint and UI to transfer a board to a different user Signed-off-by: Luka Trovic --- appinfo/routes.php | 1 + lib/Controller/BoardController.php | 11 ++++++ lib/Service/BoardService.php | 6 ++++ src/components/board/SharingTabSidebar.vue | 39 +++++++++++++++++++++- src/store/main.js | 8 ++++- 5 files changed, 63 insertions(+), 2 deletions(-) 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, + }) + }, }, })