Make sure to respect board acls in the frontend all over the place
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
@@ -29,7 +29,10 @@
|
||||
<p />
|
||||
</div>
|
||||
<div v-else-if="board" class="board">
|
||||
<Container lock-axix="y" orientation="horizontal" @drop="onDropStack">
|
||||
<Container lock-axix="y"
|
||||
orientation="horizontal"
|
||||
:drag-handle-selector="dragHandleSelector"
|
||||
@drop="onDropStack">
|
||||
<Draggable v-for="stack in stacksByBoard" :key="stack.id">
|
||||
<Stack :stack="stack" />
|
||||
</Draggable>
|
||||
@@ -46,7 +49,7 @@
|
||||
<script>
|
||||
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { mapState } from 'vuex'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Controls from '../Controls'
|
||||
import Stack from './Stack'
|
||||
|
||||
@@ -77,9 +80,15 @@ export default {
|
||||
board: state => state.currentBoard,
|
||||
showArchived: state => state.showArchived,
|
||||
}),
|
||||
...mapGetters([
|
||||
'canEdit',
|
||||
]),
|
||||
stacksByBoard() {
|
||||
return this.$store.getters.stacksByBoard(this.board.id)
|
||||
},
|
||||
dragHandleSelector() {
|
||||
return this.canEdit ? null : '.no-drag'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
id: 'fetchData',
|
||||
|
||||
@@ -33,7 +33,10 @@
|
||||
<TagsTabSidebar :board="board" />
|
||||
</AppSidebarTab>
|
||||
|
||||
<AppSidebarTab :order="2" name="Deleted items" icon="icon-delete">
|
||||
<AppSidebarTab v-if="canEdit"
|
||||
:order="2"
|
||||
name="Deleted items"
|
||||
icon="icon-delete">
|
||||
<DeletedTabSidebar :board="board" />
|
||||
</AppSidebarTab>
|
||||
|
||||
@@ -44,7 +47,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import SharingTabSidebar from './SharingTabSidebar'
|
||||
import TagsTabSidebar from './TagsTabSidebar'
|
||||
import DeletedTabSidebar from './DeletedTabSidebar'
|
||||
@@ -73,6 +76,7 @@ export default {
|
||||
board: state => state.currentBoard,
|
||||
labels: state => state.labels,
|
||||
}),
|
||||
...mapGetters(['canEdit']),
|
||||
},
|
||||
methods: {
|
||||
closeSidebar() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<Multiselect
|
||||
v-if="canShare"
|
||||
v-model="addAcl"
|
||||
:placeholder="t('deck', 'Share board with a user, group or circle …')"
|
||||
:options="formatedSharees"
|
||||
@@ -17,6 +18,9 @@
|
||||
<Avatar :user="board.owner.uid" />
|
||||
<span class="has-tooltip username">
|
||||
{{ board.owner.displayname }}
|
||||
<span v-if="!isCurrentUser(board.owner.uid)" class="board-owner-label">
|
||||
{{ t('deck', 'Board owner') }}
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
<li v-for="acl in board.acl" :key="acl.participant.uid">
|
||||
@@ -29,17 +33,17 @@
|
||||
<span v-if="acl.type===7">{{ t('deck', '(Circle)') }}</span>
|
||||
</span>
|
||||
|
||||
<ActionCheckbox :checked="acl.permissionEdit" @change="clickEditAcl(acl)">
|
||||
<ActionCheckbox v-if="!isCurrentUser(acl.participant.uid) && (canManage || (canEdit && canShare))" :checked="acl.permissionEdit" @change="clickEditAcl(acl)">
|
||||
{{ t('deck', 'Can edit') }}
|
||||
</ActionCheckbox>
|
||||
<Actions>
|
||||
<ActionCheckbox :checked="acl.permissionShare" @change="clickShareAcl(acl)">
|
||||
<Actions v-if="!isCurrentUser(acl.participant.uid)" :force-menu="true">
|
||||
<ActionCheckbox v-if="canManage || canShare" :checked="acl.permissionShare" @change="clickShareAcl(acl)">
|
||||
{{ t('deck', 'Can share') }}
|
||||
</ActionCheckbox>
|
||||
<ActionCheckbox :checked="acl.permissionManage" @change="clickManageAcl(acl)">
|
||||
<ActionCheckbox v-if="canManage" :checked="acl.permissionManage" @change="clickManageAcl(acl)">
|
||||
{{ t('deck', 'Can manage') }}
|
||||
</ActionCheckbox>
|
||||
<ActionButton icon="icon-delete" @click="clickDeleteAcl(acl)">
|
||||
<ActionButton v-if="canManage" icon="icon-delete" @click="clickDeleteAcl(acl)">
|
||||
{{ t('deck', 'Delete') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
@@ -61,6 +65,7 @@ import { ActionButton } from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
import { ActionCheckbox } from '@nextcloud/vue/dist/Components/ActionCheckbox'
|
||||
import { CollectionList } from 'nextcloud-vue-collections'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
export default {
|
||||
name: 'SharingTabSidebar',
|
||||
@@ -86,9 +91,15 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
sharees: 'sharees',
|
||||
}),
|
||||
...mapGetters([
|
||||
'sharees',
|
||||
'canEdit',
|
||||
'canManage',
|
||||
'canShare',
|
||||
]),
|
||||
isCurrentUser() {
|
||||
return (uid) => uid === getCurrentUser().uid
|
||||
},
|
||||
formatedSharees() {
|
||||
return this.unallocatedSharees.map(item => {
|
||||
|
||||
@@ -173,6 +184,9 @@ export default {
|
||||
padding: 12px 9px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.board-owner-label {
|
||||
opacity: .7;
|
||||
}
|
||||
.avatarLabel {
|
||||
padding: 6px
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
<div class="stack">
|
||||
<div class="stack--header">
|
||||
<transition name="fade" mode="out-in">
|
||||
<h3 v-if="!editing" @click="startEditing(stack)">
|
||||
<h3 v-if="!canManage">
|
||||
{{ stack.title }}
|
||||
</h3>
|
||||
<h3 v-else-if="!editing" @click="startEditing(stack)">
|
||||
{{ stack.title }}
|
||||
</h3>
|
||||
<form v-else @submit.prevent="finishedEdit(stack)">
|
||||
@@ -36,12 +39,12 @@
|
||||
value="">
|
||||
</form>
|
||||
</transition>
|
||||
<Actions :force-menu="true">
|
||||
<Actions v-if="canManage" :force-menu="true">
|
||||
<ActionButton icon="icon-delete" @click="deleteStack(stack)">
|
||||
{{ t('deck', 'Delete stack') }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<Actions>
|
||||
<Actions v-if="canEdit">
|
||||
<ActionButton icon="icon-add" @click="showAddCard=true">
|
||||
{{ t('deck', 'Add card') }}
|
||||
</ActionButton>
|
||||
@@ -63,7 +66,11 @@
|
||||
value="">
|
||||
</form>
|
||||
|
||||
<Container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="($event) => onDropCard(stack.id, $event)">
|
||||
<Container :get-child-payload="payloadForCard(stack.id)"
|
||||
group-name="stack"
|
||||
:drag-handle-selector="dragHandleSelector"
|
||||
@should-accept-drop="canEdit"
|
||||
@drop="($event) => onDropCard(stack.id, $event)">
|
||||
<Draggable v-for="card in cardsByStack(stack.id)" :key="card.id">
|
||||
<CardItem v-if="card" :id="card.id" />
|
||||
</Draggable>
|
||||
@@ -73,6 +80,7 @@
|
||||
|
||||
<script>
|
||||
|
||||
import { mapGetters } from 'vuex'
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { Actions } from '@nextcloud/vue/dist/Components/Actions'
|
||||
import { ActionButton } from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
@@ -103,13 +111,19 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'canManage',
|
||||
'canEdit',
|
||||
]),
|
||||
cardsByStack() {
|
||||
return (id) => this.$store.getters.cardsByStack(id)
|
||||
},
|
||||
dragHandleSelector() {
|
||||
return this.canEdit ? null : '.no-drag'
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
onDropCard(stackId, event) {
|
||||
const { addedIndex, removedIndex, payload } = event
|
||||
const card = Object.assign({}, payload)
|
||||
|
||||
@@ -21,8 +21,14 @@
|
||||
<div :style="{ backgroundColor: `#${label.color}`, color:textColor(label.color) }" class="label-title">
|
||||
<span>{{ label.title }}</span>
|
||||
</div>
|
||||
<button v-tooltip="t('deck', 'Edit')" class="icon-rename" @click="clickEdit(label)" />
|
||||
<button v-tooltip="t('deck', 'Delete')" class="icon-delete" @click="deleteLabel(label.id)" />
|
||||
<button v-if="canManage"
|
||||
v-tooltip="t('deck', 'Edit')"
|
||||
class="icon-rename"
|
||||
@click="clickEdit(label)" />
|
||||
<button v-if="canManage"
|
||||
v-tooltip="t('deck', 'Delete')"
|
||||
class="icon-delete"
|
||||
@click="deleteLabel(label.id)" />
|
||||
</template>
|
||||
</li>
|
||||
|
||||
@@ -43,7 +49,7 @@
|
||||
<ColorPicker :value="'#' + addLabelObj.color" @input="updateColor" />
|
||||
</template>
|
||||
</li>
|
||||
<button @click="clickShowAddLabel()">
|
||||
<button v-if="canManage" @click="clickShowAddLabel()">
|
||||
<span class="icon-add" />{{ t('deck', 'Add a new label') }}
|
||||
</button>
|
||||
</ul>
|
||||
@@ -75,6 +81,7 @@ export default {
|
||||
computed: {
|
||||
...mapGetters({
|
||||
labels: 'currentBoardLabels',
|
||||
canManage: 'canManage',
|
||||
}),
|
||||
addLabelObjValidated() {
|
||||
if (this.addLabelObj.title === '') {
|
||||
|
||||
Reference in New Issue
Block a user