calendar/src/components/AppNavigation/CalendarListItem.vue

331 lines
9.2 KiB
Vue

<template>
<li v-click-outside="closeShareMenu" :class="{enabled: enabled, 'icon-loading-small': loading}" class="app-navigation-list-item">
<div :style="{ backgroundColor: calendarColor }" class="app-navigation-entry-bullet" />
<a :class="{selected: shareMenuOpen}" href="#" @click="toggleEnabled">{{ displayName }}</a>
<div class="app-navigation-entry-utils">
<ul>
<!-- share popovermenu -->
<li v-if="showSharingIcon" :class="{'owner-avatar': isSharedWithMe}" class="app-navigation-entry-utils-menu-button">
<button :class="{'icon-public': isPublished, 'icon-shared': !isPublished && isShared, 'icon-share': !isPublished && !isShared}" @click="toggleShareMenu" />
<!-- TODO this needs a tooltip saying "shared with you by .... " -->
<avatar v-if="isSharedWithMe && loadedOwnerPrincipal" :user="ownerUserId" :display-name="ownerDisplayname" />
<div v-if="isSharedWithMe && !loadedOwnerPrincipal" class="icon icon-loading" />
</li>
<!-- more popovermenu -->
<li v-click-outside="closeMoreMenu" class="app-navigation-entry-utils-menu-button">
<button class="icon-more" @click="toggleMoreMenu" />
</li>
</ul>
</div>
<calendar-list-item-sharing v-if="shareMenuOpen" :calendar="calendar" />
<div :class="{open: moreMenuOpen}" class="app-navigation-entry-menu popover-menu-container">
<popover-menu :menu="moreMenu" />
</div>
</li>
</template>
<script>
import { Avatar, PopoverMenu } from 'nextcloud-vue'
import ClickOutside from 'vue-click-outside'
import CalendarListItemSharing from './CalendarListItemSharing.vue'
export default {
name: 'CalendarListItem',
components: {
Avatar,
CalendarListItemSharing,
PopoverMenu
},
directives: {
ClickOutside
},
props: {
calendar: {
type: Object,
required: true
}
},
data: function() {
return {
shareMenuOpen: false,
moreMenuOpen: false,
// Edit button from menu
editingName: false,
savingName: false,
editingColor: false,
savingColor: false,
// Copy button from menu
copyLoading: false,
copied: false,
copySuccess: false,
// Delete button
deleteLoading: false
}
},
computed: {
displayName() {
return this.calendar.displayName
},
calendarColor() {
return this.enabled ? this.calendar.color : 'transparent'
},
enabled() {
return this.calendar.enabled
},
loading() {
return this.calendar.loading
},
showSharingIcon() {
return this.calendar.canBeShared || this.calendar.canBePublished
},
canBeShared() {
return this.calendar.canBeShared
},
isShared() {
return !!this.calendar.shares.length
},
canBePublished() {
return this.calendar.canBePublished
},
isPublished() {
return !!this.calendar.publishURL
},
isSharedWithMe() {
return this.calendar.isSharedWithMe
},
owner() {
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug('OWNER FOO BAR TRALAALALALALALALALALALA')
console.debug(this.calendar.owner)
console.debug(this.calendar)
if (this.calendar.owner.indexOf('principal:principals/users/') === '0') {
console.debug(this.calendar.owner.substr(27))
return this.calendar.owner.substr(27)
}
return ''
},
loadedOwnerPrincipal() {
console.debug(this.calendar.owner)
console.debug(this.$store.getters.getPrincipalByUrl(this.calendar.owner))
console.debug(this.$store.getters.getPrincipalByUrl(this.calendar.owner) !== undefined)
return this.$store.getters.getPrincipalByUrl(this.calendar.owner) !== undefined
},
ownerUserId() {
const principal = this.$store.getters.getPrincipalByUrl(this.calendar.owner)
if (principal) {
return principal.userId
}
return ''
},
ownerDisplayname() {
const principal = this.$store.getters.getPrincipalByUrl(this.calendar.owner)
if (principal) {
return principal.displayname
}
return ''
},
moreMenu() {
return [
{
text: this.savingName
? t('calendar', 'Saving name ...')
: t('calendar', 'Edit name'),
icon: this.savingName
? 'icon-loading-small'
: 'icon-rename',
input: this.editingName ? 'text' : false,
action: this.editingName ? this.saveNameInput : this.openNameInput,
value: this.calendar.displayName
},
{
text: this.savingColor
? t('calendar', 'Saving color ...')
: t('calendar', 'Edit color'),
icon: this.savingColor
? 'icon-loading-small'
: 'icon-edit', // TODO use color picker icon
input: this.editingColor ? 'text' : false,
action: this.editingColor ? this.saveColorInput : this.openColorInput,
value: this.calendar.color
},
{
href: this.calendar.url,
icon: this.copyLoading ? 'icon-loading-small' : 'icon-clippy',
text: !this.copied
? t('calendar', 'Copy private link')
: this.copySuccess
? t('calendar', 'Copied')
: t('calendar', 'Can not copy'),
action: this.copyLink
},
{
href: this.calendar.url + '?export',
icon: 'icon-download',
text: t('calendar', 'Download')
},
{
text: this.deleteLoading
? (this.calendar.isSharedWithMe ? t('calendar', 'Unsharing from me ...') : t('calendar', 'Deleting ...'))
: (this.calendar.isSharedWithMe ? t('calendar', 'Unshare from me') : t('calendar', 'Delete')),
icon: this.deleteLoading
? 'icon-loading-small'
: 'icon-delete',
action: this.deleteCalendar
}
]
}
},
methods: {
toggleEnabled() {
this.$store.dispatch('toggleCalendarEnabled', { calendar: this.calendar })
.catch((error) => {
console.error(error)
OC.Notification.showTemporary(t('calendar', 'An error occurred, unable to change visibility of the calendar.'))
})
},
deleteCalendar() {
this.deleteLoading = true
this.$store.dispatch('deleteCalendar', { calendar: this.calendar })
.then(() => {
this.deleteLoading = false
})
.catch((error) => {
console.error(error)
OC.Notification.showTemporary(t('calendar', 'An error occurred, unable to delete the calendar.'))
this.deleteLoading = false
})
},
closeShareMenu() {
this.shareMenuOpen = false
},
toggleShareMenu() {
this.shareMenuOpen = !this.shareMenuOpen
},
closeMoreMenu(event) {
if (this.$el.querySelector('.popover-menu-container').contains(event.target)) {
return
}
this.moreMenuOpen = false
this.editingName = false
this.editingColor = false
},
toggleMoreMenu() {
this.moreMenuOpen = !this.moreMenuOpen
if (!this.moreMenuOpen) {
this.editingName = false
this.editingColor = false
}
},
copyLink(event) {
// change to loading status
this.copyLoading = true
event.stopPropagation()
const rootURL = OC.linkToRemote('dav')
const url = new URL(this.calendar.url, rootURL)
// copy link for calendar to clipboard
this.$copyText(url)
.then(e => {
event.preventDefault()
this.copySuccess = true
this.copied = true
// Notify calendar url was copied
OC.Notification.showTemporary(t('calendar', 'Calendar link copied to clipboard'))
}, e => {
this.copySuccess = false
this.copied = true
OC.Notification.showTemporary(t('calendar', 'Calendar link was not copied to clipboard.'))
}).then(() => {
this.copyLoading = false
setTimeout(() => {
// stop loading status regardless of outcome
this.copied = false
}, 2000)
})
},
openNameInput() {
event.stopPropagation()
if (this.savingName) {
return
}
this.editingColor = false
this.editingName = true
},
saveNameInput(event) {
event.stopPropagation()
this.savingName = true
this.editingName = false
const value = event.target.querySelector('input[type=text]').value
this.$store.dispatch('renameCalendar', { calendar: this.calendar, newName: value })
.then(() => {
this.savingName = false
})
.catch((error) => {
console.error(error)
OC.Notification.showTemporary(t('calendar', 'An error occurred, unable to rename the calendar.'))
this.savingName = false
this.editingName = true
})
},
openColorInput() {
event.stopPropagation()
if (this.savingColor) {
return
}
this.editingName = false
this.editingColor = true
},
saveColorInput(event) {
event.stopPropagation()
this.savingColor = true
this.editingColor = false
const value = event.target.querySelector('input[type=text]').value
this.$store.dispatch('changeCalendarColor', { calendar: this.calendar, newColor: value })
.then(() => {
this.savingColor = false
})
.catch((error) => {
console.error(error)
OC.Notification.showTemporary(t('calendar', 'An error occurred, unable to change the calendar\'s color.'))
this.savingColor = false
this.editingColor = true
})
}
}
}
</script>