feat: add api endpoint and UI to transfer a board to a different user

Signed-off-by: Luka Trovic <luka@nextcloud.com>
This commit is contained in:
Luka Trovic
2022-03-14 22:42:34 +01:00
committed by Julius Härtl
parent 3a4ec07103
commit bf9a51d167
5 changed files with 63 additions and 2 deletions

View File

@@ -39,6 +39,7 @@ return [
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'], ['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'], ['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
['name' => 'board#clone', 'url' => '/boards/{boardId}/clone', 'verb' => 'POST'], ['name' => 'board#clone', 'url' => '/boards/{boardId}/clone', 'verb' => 'POST'],
['name' => 'board#transferOwner', 'url' => '/boards/{boardId}/transferOwner', 'verb' => 'PUT'],
// stacks // stacks
['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'], ['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'],

View File

@@ -155,4 +155,15 @@ class BoardController extends ApiController {
public function clone($boardId) { public function clone($boardId) {
return $this->boardService->clone($boardId, $this->userId); 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);
}
} }

View File

@@ -746,6 +746,12 @@ class BoardService {
$this->boardsCache = null; $this->boardsCache = null;
} }
private function getBoardOwner($boardId) {
$board = $this->boardMapper->find($boardId);
return $board->getOwner();
}
/** /**
* Clean a given board data from the Cache * Clean a given board data from the Cache
*/ */

View File

@@ -53,6 +53,9 @@
<ActionCheckbox v-if="canManage" :checked="acl.permissionManage" @change="clickManageAcl(acl)"> <ActionCheckbox v-if="canManage" :checked="acl.permissionManage" @change="clickManageAcl(acl)">
{{ t('deck', 'Can manage') }} {{ t('deck', 'Can manage') }}
</ActionCheckbox> </ActionCheckbox>
<ActionCheckbox v-if="canManage" :checked="acl.owner" @change="clickTranserOwner(acl.participant.uid)">
{{ t('deck', 'Owner') }}
</ActionCheckbox>
<ActionButton v-if="canManage" icon="icon-delete" @click="clickDeleteAcl(acl)"> <ActionButton v-if="canManage" icon="icon-delete" @click="clickDeleteAcl(acl)">
{{ t('deck', 'Delete') }} {{ t('deck', 'Delete') }}
</ActionButton> </ActionButton>
@@ -72,7 +75,7 @@ import { Avatar, Multiselect, Actions, ActionButton, ActionCheckbox } from '@nex
import { CollectionList } from 'nextcloud-vue-collections' import { CollectionList } from 'nextcloud-vue-collections'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import { showError } from '@nextcloud/dialogs' import { showError, showSuccess } from '@nextcloud/dialogs'
import debounce from 'lodash/debounce' import debounce from 'lodash/debounce'
export default { export default {
@@ -97,6 +100,7 @@ export default {
isSearching: false, isSearching: false,
addAcl: null, addAcl: null,
addAclForAPI: null, addAclForAPI: null,
newOwner: null,
} }
}, },
computed: { computed: {
@@ -194,6 +198,39 @@ export default {
clickDeleteAcl(acl) { clickDeleteAcl(acl) {
this.$store.dispatch('deleteAclFromCurrentBoard', 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
)
},
}, },
} }
</script> </script>

View File

@@ -26,7 +26,7 @@ import { loadState } from '@nextcloud/initial-state'
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router' import { generateOcsUrl, generateUrl } from '@nextcloud/router'
import { BoardApi } from '../services/BoardApi' import { BoardApi } from '../services/BoardApi'
import actions from './actions' import actions from './actions'
import stack from './stack' import stack from './stack'
@@ -486,5 +486,11 @@ export default new Vuex.Store({
dispatch('loadBoardById', acl.boardId) dispatch('loadBoardById', acl.boardId)
}) })
}, },
async transferOwnership({ commit }, { boardId, owner, newOwner }) {
await axios.put(generateUrl(`apps/deck/boards/${boardId}/transferOwner`), {
owner,
newOwner,
})
},
}, },
}) })