Merge pull request #410 from nextcloud/sharing
Implement sharing calendars / task lists
This commit is contained in:
commit
5648b2fd7f
9 changed files with 608 additions and 43 deletions
64
css/src/Calendars/Calendar.scss
Normal file
64
css/src/Calendars/Calendar.scss
Normal file
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
* @author Team Popcorn <teampopcornberlin@gmail.com>
|
||||
* @author Raimund Schlüßler <raimund.schluessler@mailbox.org>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
.calendar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
> a:first-of-type {
|
||||
// put actions at the end
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&__name {
|
||||
display: block;
|
||||
flex: 0 1 auto;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
&__share,
|
||||
&__menu .icon-more {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
opacity: .5;
|
||||
cursor: pointer;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
opacity: .7;
|
||||
}
|
||||
}
|
||||
&__share {
|
||||
&--shared {
|
||||
opacity: .7;
|
||||
}
|
||||
}
|
||||
&--disabled &__name {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
85
css/src/Calendars/CalendarSharee.scss
Normal file
85
css/src/Calendars/CalendarSharee.scss
Normal file
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
* @author Team Popcorn <teampopcornberlin@gmail.com>
|
||||
* @author Raimund Schlüßler <raimund.schluessler@mailbox.org>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
.calendar-sharee {
|
||||
padding: 0 5px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.icon {
|
||||
margin-right: 5px;
|
||||
opacity: 0.2;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
margin-bottom: 2px;
|
||||
&.icon-loading-small {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__identifier {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
&__utils {
|
||||
padding: 0 !important;
|
||||
float: right;
|
||||
position: relative !important;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
height: 20px;
|
||||
|
||||
.icon-delete {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.4;
|
||||
margin-bottom: 2px;
|
||||
margin-left: 4px;
|
||||
&:hover {
|
||||
box-shadow: unset !important;
|
||||
}
|
||||
}
|
||||
|
||||
// loading state
|
||||
&--disabled {
|
||||
opacity: .2 !important;
|
||||
}
|
||||
.checkbox + label {
|
||||
padding: 0 !important;
|
||||
}
|
||||
label {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
62
css/src/Calendars/CalendarShares.scss
Normal file
62
css/src/Calendars/CalendarShares.scss
Normal file
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
* @author Team Popcorn <teampopcornberlin@gmail.com>
|
||||
* @author Raimund Schlüßler <raimund.schluessler@mailbox.org>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
.calendar-shares {
|
||||
width: calc(100% - 6px);
|
||||
margin: 6px;
|
||||
&__list {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__shareematch--bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icon-loading::after {
|
||||
top: 70%;
|
||||
left: 95%;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
width: inherit;
|
||||
margin: 0;
|
||||
.multiselect__tags:focus-within,
|
||||
.multiselect__tags:hover {
|
||||
border-color: var(--color-primary-element);
|
||||
}
|
||||
|
||||
&:not(.showContent) .multiselect__content-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.multiselect__content-wrapper {
|
||||
z-index: 101 !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,8 +47,11 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
&.list:not(.active) .app-navigation-entry-utils-menu-button {
|
||||
display: none;
|
||||
&.list:not(.active) {
|
||||
.app-navigation-entry-utils-menu-button,
|
||||
.calendar__share {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.app-navigation-entry-edit {
|
||||
|
|
|
@ -24,3 +24,7 @@
|
|||
@import './src/sprites-bw';
|
||||
@import './src/style';
|
||||
@import './src/markdown';
|
||||
|
||||
@import './src/Calendars/Calendar.scss';
|
||||
@import './src/Calendars/CalendarShares.scss';
|
||||
@import './src/Calendars/CalendarSharee.scss';
|
||||
|
|
140
src/components/CalendarShare.vue
Normal file
140
src/components/CalendarShare.vue
Normal file
|
@ -0,0 +1,140 @@
|
|||
<!--
|
||||
@copyright Copyright (c) 2018 Team Popcorn <teampopcornberlin@gmail.com>
|
||||
|
||||
@author Team Popcorn <teampopcornberlin@gmail.com>
|
||||
@author Raimund Schlüßler <raimund.schluessler@mailbox.org>
|
||||
|
||||
@license GNU AGPL version 3 or any later version
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="calendar-shares">
|
||||
<multiselect
|
||||
id="users-groups-search"
|
||||
:options="usersOrGroups"
|
||||
:searchable="true"
|
||||
:internal-search="false"
|
||||
:max-height="600"
|
||||
:show-no-results="true"
|
||||
:placeholder="placeholder"
|
||||
:class="{ 'showContent': inputGiven, 'icon-loading': isLoading }"
|
||||
:user-select="true"
|
||||
open-direction="bottom"
|
||||
track-by="user"
|
||||
label="user"
|
||||
@search-change="findSharee"
|
||||
@input="shareCalendar"
|
||||
/>
|
||||
<!-- list of user or groups calendar is shared with -->
|
||||
<ul v-if="calendar.shares.length > 0" class="calendar-shares__list">
|
||||
<calendar-sharee v-for="sharee in calendar.shares" :key="sharee.uri"
|
||||
:sharee="sharee" :calendar="calendar"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import client from '../services/cdav'
|
||||
import { Multiselect } from 'nextcloud-vue'
|
||||
|
||||
import calendarSharee from './CalendarSharee'
|
||||
// import debounce from 'debounce'
|
||||
|
||||
export default {
|
||||
name: 'ShareCalendar',
|
||||
components: {
|
||||
calendarSharee,
|
||||
Multiselect
|
||||
},
|
||||
props: {
|
||||
calendar: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
inputGiven: false,
|
||||
usersOrGroups: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
placeholder() {
|
||||
return t('tasks', 'Share with users or groups')
|
||||
},
|
||||
noResult() {
|
||||
return t('tasks', 'No users or groups')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// This ensures that the multiselect input is in focus as soon as the user clicks share
|
||||
document.getElementById('users-groups-search').focus()
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Share calendar
|
||||
*
|
||||
* @param {Object} data destructuring object
|
||||
* @param {string} data.user the userId
|
||||
* @param {string} data.displayName the displayName
|
||||
* @param {string} data.uri the sharing principalScheme uri
|
||||
* @param {boolean} data.isGroup is this a group ?
|
||||
*/
|
||||
shareCalendar({ user, displayName, uri, isGroup }) {
|
||||
let calendar = this.calendar
|
||||
uri = decodeURI(uri)
|
||||
user = decodeURI(user)
|
||||
this.$store.dispatch('shareCalendar', { calendar, user, displayName, uri, isGroup })
|
||||
},
|
||||
|
||||
/**
|
||||
* Use the cdav client call to find matches to the query from the existing Users & Groups
|
||||
*
|
||||
* @param {string} query The query string
|
||||
*/
|
||||
findSharee: async function(query) {
|
||||
this.isLoading = true
|
||||
this.usersOrGroups = []
|
||||
if (query.length > 0) {
|
||||
const results = await client.principalPropertySearchByDisplayname(query)
|
||||
this.usersOrGroups = results.reduce((list, result) => {
|
||||
if (['GROUP', 'INDIVIDUAL'].indexOf(result.calendarUserType) > -1) {
|
||||
const isGroup = result.calendarUserType === 'GROUP'
|
||||
list.push({
|
||||
user: result[isGroup ? 'groupId' : 'userId'],
|
||||
displayName: result.displayname,
|
||||
icon: isGroup ? 'icon-group' : 'icon-user',
|
||||
uri: result.principalScheme,
|
||||
isGroup
|
||||
})
|
||||
}
|
||||
return list
|
||||
}, [])
|
||||
this.isLoading = false
|
||||
this.inputGiven = true
|
||||
} else {
|
||||
this.inputGiven = false
|
||||
this.isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
129
src/components/CalendarSharee.vue
Normal file
129
src/components/CalendarSharee.vue
Normal file
|
@ -0,0 +1,129 @@
|
|||
<!--
|
||||
@copyright Copyright (c) 2018 Team Popcorn <teampopcornberlin@gmail.com>
|
||||
|
||||
@author Team Popcorn <teampopcornberlin@gmail.com>
|
||||
@author Raimund Schlüßler <raimund.schluessler@mailbox.org>
|
||||
|
||||
@license GNU AGPL version 3 or any later version
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<template>
|
||||
<li class="calendar-sharee">
|
||||
<span :class="{
|
||||
'icon-loading-small': loading,
|
||||
'icon-group': sharee.isGroup && !loading,
|
||||
'icon-user': !sharee.isGroup && !loading
|
||||
}" class="icon"
|
||||
/>
|
||||
<span class="calendar-sharee__identifier">
|
||||
{{ sharee.displayName }}
|
||||
</span>
|
||||
<span class="calendar-sharee__utils">
|
||||
<input
|
||||
:id="uid"
|
||||
:checked="writeable"
|
||||
:disabled="loading"
|
||||
class="checkbox"
|
||||
name="editable"
|
||||
type="checkbox"
|
||||
@change="editSharee"
|
||||
>
|
||||
<label :for="uid">
|
||||
{{ t('tasks', 'can edit') }}
|
||||
</label>
|
||||
<a :class="{'calendar-sharee__utils--disabled': loading}" href="#"
|
||||
title="Delete"
|
||||
class="icon-delete"
|
||||
@click="deleteSharee"
|
||||
/>
|
||||
</span>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'ShareSharee',
|
||||
|
||||
props: {
|
||||
calendar: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
sharee: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
writeable() {
|
||||
return this.sharee.writeable
|
||||
},
|
||||
// generated id for this sharee
|
||||
uid() {
|
||||
return this.sharee.id + this.calendar.id + Math.floor(Math.random() * 1000)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async deleteSharee() {
|
||||
if (this.loading) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
try {
|
||||
await this.$store.dispatch('removeSharee', {
|
||||
calendar: this.calendar,
|
||||
uri: this.sharee.uri
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
OC.Notification.showTemporary(t('tasks', 'Unable to delete the share.'))
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async editSharee() {
|
||||
if (this.loading) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
try {
|
||||
await this.$store.dispatch('toggleShareeWritable', {
|
||||
calendar: this.calendar,
|
||||
uri: this.sharee.uri,
|
||||
writeable: !this.sharee.writeable
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
OC.Notification.showTemporary(t('tasks', 'Unable to change permissions.'))
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -65,11 +65,19 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
{{ calendar.displayName }}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter">
|
||||
{{ calendarCount(calendar.id) | counterFormatter }}
|
||||
</li>
|
||||
|
||||
<!-- sharing button -->
|
||||
<li v-if="!calendar.readOnly" v-tooltip.top="sharedWithTooltip(calendar)"
|
||||
:class="{'calendar__share--shared': hasShares(calendar)}"
|
||||
:title="sharedWithTooltip(calendar)" href="#"
|
||||
class="calendar__share icon-shared reactive" @click="toggleShare(calendar)"
|
||||
/>
|
||||
<Popover tag="li" class="app-navigation-entry-utils-menu-button reactive">
|
||||
<ul>
|
||||
<li v-if="!calendar.readOnly">
|
||||
|
@ -101,6 +109,10 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
</Popover>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- sharing input -->
|
||||
<ShareCalendar v-if="shareOpen == calendar.id && !calendar.readOnly" :calendar="calendar" />
|
||||
|
||||
<div :class="{error: nameError}" class="app-navigation-entry-edit name">
|
||||
<form>
|
||||
<input v-model="newCalendarName"
|
||||
|
@ -175,6 +187,7 @@ import { mapState, mapGetters, mapActions } from 'vuex'
|
|||
import Colorpicker from './Colorpicker'
|
||||
import PopoverMenu from './PopoverMenu'
|
||||
import Confirmation from './Confirmation'
|
||||
import ShareCalendar from './CalendarShare'
|
||||
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
|
||||
|
@ -182,7 +195,8 @@ export default {
|
|||
components: {
|
||||
'Colorpicker': Colorpicker,
|
||||
'Popover': PopoverMenu,
|
||||
'Confirmation': Confirmation
|
||||
'Confirmation': Confirmation,
|
||||
ShareCalendar
|
||||
},
|
||||
directives: {
|
||||
ClickOutside
|
||||
|
@ -202,6 +216,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
editing: '',
|
||||
shareOpen: '',
|
||||
copySuccess: false,
|
||||
copied: false,
|
||||
creating: false,
|
||||
|
@ -253,10 +268,34 @@ export default {
|
|||
() => document.querySelector('#list_' + calendar.id + ' input.edit').focus()
|
||||
)
|
||||
},
|
||||
toggleShare: function(calendar) {
|
||||
if (this.shareOpen === calendar.id) {
|
||||
this.shareOpen = ''
|
||||
} else {
|
||||
this.shareOpen = calendar.id
|
||||
}
|
||||
},
|
||||
hasShares: function(calendar) {
|
||||
return calendar.shares.length > 0
|
||||
},
|
||||
// info tooltip about number of shares
|
||||
sharedWithTooltip: function(calendar) {
|
||||
return this.hasShares(calendar)
|
||||
? n('tasks',
|
||||
'Shared with {num} entity',
|
||||
'Shared with {num} entities',
|
||||
calendar.shares.length, {
|
||||
num: calendar.shares.length
|
||||
})
|
||||
: '' // disable the tooltip
|
||||
},
|
||||
resetView: function(calendar) {
|
||||
if (this.editing === calendar.id) {
|
||||
this.editing = ''
|
||||
}
|
||||
if (this.shareOpen === calendar.id) {
|
||||
this.shareOpen = ''
|
||||
}
|
||||
this.tooltipTarget = ''
|
||||
},
|
||||
copyCalDAVUrl(event, calendar) {
|
||||
|
|
|
@ -75,11 +75,32 @@ export function mapDavCollectionToCalendar(calendar) {
|
|||
tasks: {},
|
||||
url: calendar.url,
|
||||
dav: calendar,
|
||||
shares: calendar.shares.map(sharee => Object.assign({}, mapDavShareeToSharee(sharee))),
|
||||
supportsTasks: calendar.components.includes('VTODO'),
|
||||
loadedCompleted: false,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a dav collection to the sharee array
|
||||
*
|
||||
* @param {Object} sharee The sharee object from the cdav library shares
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function mapDavShareeToSharee(sharee) {
|
||||
const id = sharee.href.split('/').slice(-1)[0]
|
||||
const name = sharee['common-name']
|
||||
? sharee['common-name']
|
||||
: id
|
||||
return {
|
||||
displayName: name,
|
||||
id: id,
|
||||
writeable: sharee.access[0].endsWith('read-write'),
|
||||
isGroup: sharee.href.startsWith('principal:principals/groups/'),
|
||||
uri: sharee.href
|
||||
}
|
||||
}
|
||||
|
||||
const getters = {
|
||||
|
||||
/**
|
||||
|
@ -309,16 +330,19 @@ const mutations = {
|
|||
* @param {Object} state The store data
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Calendar} data.calendar The calendar
|
||||
* @param {String} data.sharee The sharee
|
||||
* @param {String} data.id The id
|
||||
* @param {Boolean} data.group The group
|
||||
* @param {String} data.user The userId
|
||||
* @param {String} data.displayName The displayName
|
||||
* @param {String} data.uri The sharing principalScheme uri
|
||||
* @param {Boolean} data.isGroup Is this a group ?
|
||||
*/
|
||||
shareCalendar(state, { calendar, sharee, id, group }) {
|
||||
let newSharee = {
|
||||
displayname: sharee,
|
||||
id,
|
||||
shareCalendar(state, { calendar, user, displayName, uri, isGroup }) {
|
||||
calendar = state.calendars.find(search => search.id === calendar.id)
|
||||
const newSharee = {
|
||||
displayName,
|
||||
id: user,
|
||||
writeable: false,
|
||||
group
|
||||
isGroup,
|
||||
uri
|
||||
}
|
||||
calendar.shares.push(newSharee)
|
||||
},
|
||||
|
@ -327,34 +351,27 @@ const mutations = {
|
|||
* Removes a sharee from calendar shares list
|
||||
*
|
||||
* @param {Object} state The store data
|
||||
* @param {Object} sharee The sharee
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Calendar} data.calendar The calendar
|
||||
* @param {String} data.uri The sharee uri
|
||||
*/
|
||||
removeSharee(state, sharee) {
|
||||
let calendar = state.calendars.find(search => {
|
||||
for (let i in search.shares) {
|
||||
if (search.shares[i] === sharee) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
calendar.shares.splice(calendar.shares.indexOf(sharee), 1)
|
||||
removeSharee(state, { calendar, uri }) {
|
||||
calendar = state.calendars.find(search => search.id === calendar.id)
|
||||
let shareIndex = calendar.shares.findIndex(sharee => sharee.uri === uri)
|
||||
calendar.shares.splice(shareIndex, 1)
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles sharee's writable permission
|
||||
*
|
||||
* @param {Object} state The store data
|
||||
* @param {Object} sharee The sharee
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Object} data.calendar The calendar
|
||||
* @param {String} data.uri The sharee uri
|
||||
*/
|
||||
updateShareeWritable(state, sharee) {
|
||||
let calendar = state.calendars.find(search => {
|
||||
for (let i in search.shares) {
|
||||
if (search.shares[i] === sharee) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
sharee = calendar.shares.find(search => search === sharee)
|
||||
updateShareeWritable(state, { calendar, uri }) {
|
||||
calendar = state.calendars.find(search => search.id === calendar.id)
|
||||
let sharee = calendar.shares.find(sharee => sharee.uri === uri)
|
||||
sharee.writeable = !sharee.writeable
|
||||
}
|
||||
}
|
||||
|
@ -567,20 +584,36 @@ const actions = {
|
|||
* Removes a sharee from a calendar
|
||||
*
|
||||
* @param {Object} context The store mutations Current context
|
||||
* @param {Object} sharee Calendar sharee object
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Object} data.calendar The calendar
|
||||
* @param {String} data.uri The sharee uri
|
||||
*/
|
||||
removeSharee(context, sharee) {
|
||||
context.commit('removeSharee', sharee)
|
||||
async removeSharee(context, { calendar, uri }) {
|
||||
try {
|
||||
await calendar.dav.unshare(uri)
|
||||
context.commit('removeSharee', { calendar, uri })
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles permissions of calendar sharees writeable rights
|
||||
*
|
||||
* @param {Object} context The store mutations Current context
|
||||
* @param {Object} sharee Calendar sharee object
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Object} data.calendar The calendar
|
||||
* @param {String} data.uri The sharee uri
|
||||
* @param {Boolean} data.writeable The sharee permission
|
||||
*/
|
||||
toggleShareeWritable(context, sharee) {
|
||||
context.commit('updateShareeWritable', sharee)
|
||||
async toggleShareeWritable(context, { calendar, uri, writeable }) {
|
||||
try {
|
||||
await calendar.dav.share(uri, writeable)
|
||||
context.commit('updateShareeWritable', { calendar, uri, writeable })
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -588,13 +621,19 @@ const actions = {
|
|||
*
|
||||
* @param {Object} context The store mutations Current context
|
||||
* @param {Calendar} data.calendar The calendar
|
||||
* @param {String} data.sharee The sharee
|
||||
* @param {Boolean} data.id The id
|
||||
* @param {Boolean} data.group The group
|
||||
* @param {String} data.user The userId
|
||||
* @param {String} data.displayName The displayName
|
||||
* @param {String} data.uri The sharing principalScheme uri
|
||||
* @param {Boolean} data.isGroup Is this a group ?
|
||||
*/
|
||||
shareCalendar(context, { calendar, sharee, id, group }) {
|
||||
// Share a calendar with the entered group or user
|
||||
context.commit('shareCalendar', { calendar, sharee, id, group })
|
||||
async shareCalendar(context, { calendar, user, displayName, uri, isGroup }) {
|
||||
// Share calendar with entered group or user
|
||||
try {
|
||||
await calendar.dav.share(uri)
|
||||
context.commit('shareCalendar', { calendar, user, displayName, uri, isGroup })
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue