mirror of https://github.com/nextcloud/calendar
Add basic components, fc, router & store
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
8fa7f4aa8a
commit
c4559d047c
|
@ -58,3 +58,11 @@
|
|||
#fullcalendar td.fc-day.fc-sun {
|
||||
background-color: var(--color-background-darker);
|
||||
}
|
||||
|
||||
@import 'calendarlist.scss';
|
||||
@import 'confirmation.scss';
|
||||
@import 'datepicker.scss';
|
||||
@import 'eventdialog.scss';
|
||||
@import 'globals.scss';
|
||||
@import 'print.scss';
|
||||
@import 'settings.scss';
|
||||
|
|
|
@ -2591,13 +2591,8 @@
|
|||
"requires": {
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"compare-urls": "^2.0.0",
|
||||
"davclient.js": "git+https://github.com/owncloud/davclient.js.git#0e5ef1af5d174d9ec10dbe889a415b8f481d5094",
|
||||
"normalize-url": "^3.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"davclient.js": {
|
||||
"version": "git+https://github.com/owncloud/davclient.js.git#0e5ef1af5d174d9ec10dbe889a415b8f481d5094",
|
||||
"from": "git+https://github.com/owncloud/davclient.js.git#0e5ef1af5d174d9ec10dbe889a415b8f481d5094"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
|
@ -3561,6 +3556,10 @@
|
|||
"integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
|
||||
"dev": true
|
||||
},
|
||||
"davclient.js": {
|
||||
"version": "git+https://github.com/owncloud/davclient.js.git#0e5ef1af5d174d9ec10dbe889a415b8f481d5094",
|
||||
"from": "git+https://github.com/owncloud/davclient.js.git"
|
||||
},
|
||||
"de-indent": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
|
||||
|
|
76
src/App.vue
76
src/App.vue
|
@ -21,11 +21,83 @@
|
|||
-->
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
<div class="app">
|
||||
<app-navigation menu="menu">
|
||||
<settings-section v-if="!loading" slot="settings-content" />
|
||||
</app-navigation>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { AppNavigation } from 'nextcloud-vue'
|
||||
import client from './services/cdav.js'
|
||||
|
||||
export default {
|
||||
name: 'App'
|
||||
name: 'App',
|
||||
components: {
|
||||
AppNavigation,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// store getters
|
||||
calendars() {
|
||||
return this.$store.getters.getCalendars
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
// get calendars then get events
|
||||
client.connect({ enableCalDAV: true }).then(() => {
|
||||
console.debug('Connected to dav!', client)
|
||||
this.$store.dispatch('getCalendars')
|
||||
.then((calendars) => {
|
||||
|
||||
// No calendars? Create a new one!
|
||||
if (calendars.length === 0) {
|
||||
this.$store.dispatch('appendCalendar', { displayName: t('calendars', 'Calendars') })
|
||||
.then(() => {
|
||||
this.fetchEvents()
|
||||
})
|
||||
// else, let's get those events!
|
||||
} else {
|
||||
this.fetchEvents()
|
||||
}
|
||||
})
|
||||
// check local storage for orderKey
|
||||
// if (localStorage.getItem('orderKey')) {
|
||||
// // run setOrder mutation with local storage key
|
||||
// this.$store.commit('setOrder', localStorage.getItem('orderKey'))
|
||||
// }
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
menu() {
|
||||
return {
|
||||
menu: {
|
||||
id: 'navigation',
|
||||
items: [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Fetch the events of each calendar
|
||||
*/
|
||||
fetchEvents() {
|
||||
// wait for all calendars to have fetch their events
|
||||
Promise.all(this.calendars.map(calendar => this.$store.dispatch('getEventsFromCalendar', { calendar })))
|
||||
.then(results => {
|
||||
this.loading = false
|
||||
// eslint-disable-next-line
|
||||
console.log(results)
|
||||
})
|
||||
// no need for a catch, the action does not throw
|
||||
// and the error is handled there
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<div class="editor">
|
||||
<!-- title -->
|
||||
<!-- timepicker -->
|
||||
<!-- details -->
|
||||
<!-- invitees-list -->
|
||||
<!-- invitees-list-new -->
|
||||
<!-- invitees-list-item -->
|
||||
<!-- alarm-list -->
|
||||
<!-- alarm-list-new -->
|
||||
<!-- alarm-list-item -->
|
||||
<!-- repeat -->
|
||||
<!-- eventual other apps modules -->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'Edit',
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div class="sidebar">
|
||||
<!-- Datepicker -->
|
||||
<!-- View buttons -->
|
||||
<!-- Today button -->
|
||||
<!-- Calendar list -->
|
||||
<!-- calendar-list-new -->
|
||||
<!-- calendar-list-item -->
|
||||
<!-- colorpicker -->
|
||||
<!-- subscription-list -->
|
||||
<!-- subscription-list-new -->
|
||||
<!-- subscription-list-item -->
|
||||
<!-- colorpicker -->
|
||||
<!-- Settings -->
|
||||
<!-- import-progressbar (similar to contacts) -->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'Sidebar',
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<template>
|
||||
<div class="view">
|
||||
<!-- Full calendar -->
|
||||
<div ref="fullcalendar" class="fullcalendar-wrapper" />
|
||||
<!-- Edit modal -->
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { Calendar } from 'fullcalendar'
|
||||
import '../../node_modules/fullcalendar/dist/fullcalendar.css'
|
||||
|
||||
export default {
|
||||
name: 'View',
|
||||
// props: {
|
||||
// view: {
|
||||
// type: String,
|
||||
// required: true,
|
||||
// },
|
||||
// firstday: {
|
||||
// type: String,
|
||||
// required: true,
|
||||
// }
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
calendar: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.calendar = new Calendar(this.$refs.fullcalendar)
|
||||
this.calendar.render()
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -23,8 +23,8 @@ import '@babel/polyfill'
|
|||
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
// import router from './router'
|
||||
// import store from './store'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
// import { sync } from 'vuex-router-sync'
|
||||
|
||||
// CSP config for webpack dynamic chunk loading
|
||||
|
@ -47,7 +47,7 @@ Vue.prototype.OCA = OCA
|
|||
|
||||
export default new Vue({
|
||||
el: '#content',
|
||||
// router,
|
||||
// store,
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
})
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export default class {
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import View from './components/View'
|
||||
import Edit from './components/Edit'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
const router = new Router({
|
||||
mode: 'history',
|
||||
base: OC.generateUrl('/apps/calendar'),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Root',
|
||||
component: View,
|
||||
// redirect: {
|
||||
// name: 'View',
|
||||
// params: {
|
||||
// view: 'now',
|
||||
// firstday: 'now'
|
||||
// },
|
||||
// }
|
||||
},
|
||||
{
|
||||
path: '/{view}/{firstday}',
|
||||
props: true,
|
||||
children: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'View',
|
||||
component: View,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/edit/{mode}/{object}/{recurrence}',
|
||||
name: 'Edit',
|
||||
component: Edit,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/new/{mode}/{recurrence}',
|
||||
name: 'Edit',
|
||||
component: Edit,
|
||||
props: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
export default router
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import DavClient from 'cdav-library'
|
||||
|
||||
function xhrProvider() {
|
||||
var headers = {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'requesttoken': OC.requestToken
|
||||
}
|
||||
var xhr = new XMLHttpRequest()
|
||||
var oldOpen = xhr.open
|
||||
|
||||
// override open() method to add headers
|
||||
xhr.open = function() {
|
||||
var result = oldOpen.apply(this, arguments)
|
||||
for (let name in headers) {
|
||||
xhr.setRequestHeader(name, headers[name])
|
||||
}
|
||||
return result
|
||||
}
|
||||
OC.registerXHRForErrorProcessing(xhr)
|
||||
return xhr
|
||||
}
|
||||
|
||||
export default new DavClient({
|
||||
rootUrl: OC.linkToRemote('dav')
|
||||
}, xhrProvider)
|
|
@ -0,0 +1,3 @@
|
|||
export default function(ics, calendar) {
|
||||
|
||||
}
|
|
@ -0,0 +1,420 @@
|
|||
import Vue from 'vue'
|
||||
import ICAL from 'ical.js'
|
||||
import parseIcs from '../services/parseIcs'
|
||||
import client from '../services/cdav'
|
||||
import Event from '../models/event'
|
||||
import pLimit from 'p-limit'
|
||||
|
||||
const calendarModel = {
|
||||
id: '',
|
||||
displayName: '',
|
||||
enabled: true,
|
||||
owner: '',
|
||||
shares: [],
|
||||
events: {},
|
||||
url: '',
|
||||
readOnly: false,
|
||||
dav: false
|
||||
}
|
||||
|
||||
const state = {
|
||||
calendars: []
|
||||
}
|
||||
|
||||
/**
|
||||
* map a dav collection to our calendar object model
|
||||
*
|
||||
* @param {Object} calendar the calendar object from the cdav library
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function mapDavCollectionToCalendar(calendar) {
|
||||
return {
|
||||
// get last part of url
|
||||
id: calendar.url.split('/').slice(-2, -1)[0],
|
||||
displayName: calendar.displayname,
|
||||
enabled: calendar.enabled !== false,
|
||||
owner: calendar.owner,
|
||||
readOnly: calendar.readOnly !== false,
|
||||
url: calendar.url,
|
||||
dav: calendar
|
||||
}
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
|
||||
/**
|
||||
* Add calendar into state
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Object} calendar the calendar to add
|
||||
*/
|
||||
addCalendar(state, calendar) {
|
||||
// extend the calendar to the default model
|
||||
state.calendars.push(Object.assign({}, calendarModel, calendar))
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete calendar
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Object} calendar the calendar to delete
|
||||
*/
|
||||
deleteCalendar(state, calendar) {
|
||||
state.calendars.splice(state.calendars.indexOf(calendar), 1)
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle whether a calendar is Enabled
|
||||
* @param {Object} context the store mutations
|
||||
* @param {Object} calendar the calendar to toggle
|
||||
*/
|
||||
toggleCalendarEnabled(context, calendar) {
|
||||
calendar = state.calendars.find(search => search.id === calendar.id)
|
||||
calendar.enabled = !calendar.enabled
|
||||
},
|
||||
|
||||
/**
|
||||
* Rename a calendar
|
||||
* @param {Object} context the store mutations
|
||||
* @param {Object} data destructuring object
|
||||
* @param {Object} data.calendar the calendar to rename
|
||||
* @param {String} data.newName the new name of the calendar
|
||||
*/
|
||||
renameCalendar(context, { calendar, newName }) {
|
||||
calendar = state.calendars.find(search => search.id === calendar.id)
|
||||
calendar.displayName = newName
|
||||
},
|
||||
|
||||
/**
|
||||
* Append a list of events to an calendar
|
||||
* and remove duplicates
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Object} data destructuring object
|
||||
* @param {Object} data.calendar the calendar to add the event to
|
||||
* @param {Event[]} data.events array of events to append
|
||||
*/
|
||||
appendEventsToCalendar(state, { calendar, events }) {
|
||||
calendar = state.calendars.find(search => search === calendar)
|
||||
|
||||
// convert list into an array and remove duplicate
|
||||
calendar.events = events.reduce((list, event) => {
|
||||
if (list[event.uid]) {
|
||||
console.debug('Duplicate event overrided', list[event.uid], event)
|
||||
}
|
||||
Vue.set(list, event.uid, event)
|
||||
return list
|
||||
}, calendar.events)
|
||||
},
|
||||
|
||||
/**
|
||||
* Add an event to an calendar and overwrite if duplicate uid
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Event} event the event to add
|
||||
*/
|
||||
addEventToCalendar(state, event) {
|
||||
let calendar = state.calendars.find(search => search.id === event.calendar.id)
|
||||
Vue.set(calendar.events, event.uid, event)
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete an event in a specified calendar
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Event} event the event to delete
|
||||
*/
|
||||
deleteEventFromCalendar(state, event) {
|
||||
let calendar = state.calendars.find(search => search.id === event.calendar.id)
|
||||
Vue.delete(calendar, event.uid)
|
||||
},
|
||||
|
||||
/**
|
||||
* Share calendar with a user or group
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Object} data destructuring object
|
||||
* @param {Object} data.calendar the calendar
|
||||
* @param {string} data.sharee the sharee
|
||||
* @param {string} data.id id
|
||||
* @param {Boolean} data.group group
|
||||
*/
|
||||
shareCalendar(state, { calendar, sharee, id, group }) {
|
||||
calendar = state.calendars.find(search => search.id === calendar.id)
|
||||
let newSharee = {
|
||||
displayname: sharee,
|
||||
id,
|
||||
writeable: false,
|
||||
group
|
||||
}
|
||||
calendar.shares.push(newSharee)
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove Sharee from calendar shares list
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Object} sharee the sharee
|
||||
*/
|
||||
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)
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle sharee's writable permission
|
||||
*
|
||||
* @param {Object} state the store data
|
||||
* @param {Object} sharee the sharee
|
||||
*/
|
||||
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)
|
||||
sharee.writeable = !sharee.writeable
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const getters = {
|
||||
getCalendars: state => state.calendar
|
||||
}
|
||||
|
||||
const actions = {
|
||||
|
||||
/**
|
||||
* Retrieve and commit calendars
|
||||
*
|
||||
* @param {Object} context the store mutations
|
||||
* @returns {Promise<Array>} the calendars
|
||||
*/
|
||||
async getCalendars(context) {
|
||||
let calendars = await client.calendarHomes[0].findAllCalendars()
|
||||
.then(calendars => {
|
||||
return calendars.map(calendar => {
|
||||
return mapDavCollectionToCalendar(calendar)
|
||||
})
|
||||
})
|
||||
|
||||
calendars.forEach(calendar => {
|
||||
context.commit('addCalendar', calendar)
|
||||
})
|
||||
|
||||
return calendars
|
||||
},
|
||||
|
||||
/**
|
||||
* Append a new calendar to array of existing calendars
|
||||
*
|
||||
* @param {Object} context the store mutations
|
||||
* @param {Object} calendar The calendar to append
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async appendCalendar(context, calendar) {
|
||||
return client.calendarHomes[0].createCalendarCollection(calendar.displayName)
|
||||
.then((response) => {
|
||||
calendar = mapDavCollectionToCalendar(response)
|
||||
context.commit('addCalendar', calendar)
|
||||
})
|
||||
.catch((error) => { throw error })
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete calendar
|
||||
* @param {Object} context the store mutations Current context
|
||||
* @param {Object} calendar the calendar to delete
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async deleteCalendar(context, calendar) {
|
||||
return calendar.dav.delete()
|
||||
.then((response) => {
|
||||
// delete all the events from the store that belong to this calendar
|
||||
Object.values(calendar.events)
|
||||
.forEach(event => context.commit('deleteEvent', event))
|
||||
// then delete the calendar
|
||||
context.commit('deleteCalendar', calendar)
|
||||
})
|
||||
.catch((error) => { throw error })
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle whether a calendar is Enabled
|
||||
* @param {Object} context the store mutations Current context
|
||||
* @param {Object} calendar the calendar to toggle
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async toggleCalendarEnabled(context, calendar) {
|
||||
calendar.dav.enabled = !calendar.dav.enabled
|
||||
return calendar.dav.update()
|
||||
.then((response) => context.commit('toggleCalendarEnabled', calendar))
|
||||
.catch((error) => { throw error })
|
||||
},
|
||||
|
||||
/**
|
||||
* Rename a calendar
|
||||
* @param {Object} context the store mutations Current context
|
||||
* @param {Object} data.calendar the calendar to rename
|
||||
* @param {String} data.newName the new name of the calendar
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async renameCalendar(context, { calendar, newName }) {
|
||||
calendar.dav.displayname = newName
|
||||
return calendar.dav.update()
|
||||
.then((response) => context.commit('renameCalendar', { calendar, newName }))
|
||||
.catch((error) => { throw error })
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the events of the specified calendar
|
||||
* and commit the results
|
||||
*
|
||||
* @param {Object} context the store mutations
|
||||
* @param {Object} importDetails = { ics, calendar }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async getEventsFromCalendar(context, { calendar }) {
|
||||
return calendar.dav.findByType('VEVENT')
|
||||
.then((response) => {
|
||||
// We don't want to lose the url information
|
||||
// so we need to parse one by one
|
||||
const events = response.map(item => {
|
||||
let event = new Event(item.data, calendar)
|
||||
Vue.set(event, 'dav', item)
|
||||
return event
|
||||
})
|
||||
context.commit('appendEventsToCalendar', { calendar, events })
|
||||
context.commit('appendEvents', events)
|
||||
return events
|
||||
})
|
||||
.catch((error) => {
|
||||
// unrecoverable error, if no events were loaded,
|
||||
// remove the calendar
|
||||
// TODO: create a failed calendar state and show that there was an issue?
|
||||
context.commit('deleteCalendar', calendar)
|
||||
console.error(error)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} context the store mutations
|
||||
* @param {Object} importDetails = { ics, calendar }
|
||||
*/
|
||||
async importEventsIntoCalendar(context, { ics, calendar }) {
|
||||
const events = parseIcs(ics, calendar)
|
||||
context.commit('changeStage', 'importing')
|
||||
|
||||
// max simultaneous requests
|
||||
const limit = pLimit(3)
|
||||
const requests = []
|
||||
|
||||
// create the array of requests to send
|
||||
events.map(async event => {
|
||||
// Get vcard string
|
||||
try {
|
||||
let vData = ICAL.stringify(event.vCard.jCal)
|
||||
// push event to server and use limit
|
||||
requests.push(limit(() => event.calendar.dav.createVCard(vData)
|
||||
.then((response) => {
|
||||
// setting the event dav property
|
||||
Vue.set(event, 'dav', response)
|
||||
|
||||
// success, update store
|
||||
context.commit('addEvent', event)
|
||||
context.commit('addEventToCalendar', event)
|
||||
context.commit('incrementAccepted')
|
||||
})
|
||||
.catch((error) => {
|
||||
// error
|
||||
context.commit('incrementDenied')
|
||||
console.error(error)
|
||||
})
|
||||
))
|
||||
} catch (e) {
|
||||
context.commit('incrementDenied')
|
||||
}
|
||||
})
|
||||
|
||||
Promise.all(requests).then(() => {
|
||||
context.commit('changeStage', 'default')
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove sharee from calendar
|
||||
* @param {Object} context the store mutations Current context
|
||||
* @param {Object} sharee calendar sharee object
|
||||
*/
|
||||
removeSharee(context, sharee) {
|
||||
context.commit('removeSharee', sharee)
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle permissions of calendar Sharees writeable rights
|
||||
* @param {Object} context the store mutations Current context
|
||||
* @param {Object} sharee calendar sharee object
|
||||
*/
|
||||
toggleShareeWritable(context, sharee) {
|
||||
context.commit('updateShareeWritable', sharee)
|
||||
},
|
||||
|
||||
/**
|
||||
* Share calendar with User or Group
|
||||
* @param {Object} context the store mutations Current context
|
||||
* @param {Object} data.calendar the calendar
|
||||
* @param {String} data.sharee the sharee
|
||||
* @param {Boolean} data.id id
|
||||
* @param {Boolean} data.group group
|
||||
*/
|
||||
shareCalendar(context, { calendar, sharee, id, group }) {
|
||||
// Share calendar with entered group or user
|
||||
context.commit('shareCalendar', { calendar, sharee, id, group })
|
||||
},
|
||||
|
||||
/**
|
||||
* Move an event to the provided calendar
|
||||
*
|
||||
* @param {Object} context the store mutations
|
||||
* @param {Object} data destructuring object
|
||||
* @param {Event} data.event the event to move
|
||||
* @param {Object} data.calendar the calendar to move the event to
|
||||
*/
|
||||
async moveEventToCalendar(context, { event, calendar }) {
|
||||
// only local move if the event doesn't exists on the server
|
||||
if (event.dav) {
|
||||
// TODO: implement proper move
|
||||
// await events.dav.move(calendar.dav)
|
||||
// .catch((error) => {
|
||||
// console.error(error)
|
||||
// OC.Notification.showTemporary(t('calendars', 'An error occurred'))
|
||||
// })
|
||||
let vData = ICAL.stringify(event.vCard.jCal)
|
||||
let newDav
|
||||
await calendar.dav.createVCard(vData)
|
||||
.then((response) => { newDav = response })
|
||||
.catch((error) => { throw error })
|
||||
await event.dav.delete()
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
OC.Notification.showTemporary(t('calendars', 'An error occurred'))
|
||||
})
|
||||
await Vue.set(event, 'dav', newDav)
|
||||
}
|
||||
await context.commit('deleteEventFromCalendar', event)
|
||||
await context.commit('updateEventCalendar', { event, calendar })
|
||||
await context.commit('addEventToCalendar', event)
|
||||
}
|
||||
}
|
||||
|
||||
export default { state, mutations, getters, actions }
|
|
@ -0,0 +1,14 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import calendars from './calendars'
|
||||
Vue.use(Vuex)
|
||||
|
||||
const mutations = {}
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
calendars,
|
||||
},
|
||||
|
||||
mutations
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
<?php
|
||||
script('contacts', 'contacts');
|
||||
style('contacts', 'contacts');
|
||||
script('calendar', 'calendar');
|
||||
style('calendar', 'app/calendar');
|
||||
?>
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = {
|
|||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new StyleLintPlugin(),
|
||||
// new StyleLintPlugin(),
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
|
||||
],
|
||||
resolve: {
|
||||
|
|
Loading…
Reference in New Issue