2019-01-21 14:08:22 +00:00
< template >
2019-10-01 18:10:53 +00:00
< section >
< div class = "container" >
< h1 class = "title" v-if ="isUpdate === false" >
{ { $t ( 'Create a new event' ) } }
< / h1 >
< h1 class = "title" v-else >
{ { $t ( 'Update event {name}' , { name : event . title } ) } }
< / h1 >
2019-12-20 12:04:34 +00:00
< form ref = "form" >
2020-02-18 07:47:41 +00:00
< subtitle >
2019-12-20 12:04:34 +00:00
{ { $t ( 'General information' ) } }
2020-02-18 07:47:41 +00:00
< / subtitle >
2019-12-20 12:04:34 +00:00
< picture -upload v -model = " pictureFile " : textFallback = "$t('Headline picture')" / >
< b -field :label ="$t('Title')" :type ="checkTitleLength[0]" :message ="checkTitleLength[1]" >
< b -input size = "is-large" aria -required = " true " required v -model = " event.title " / >
< / b - f i e l d >
2019-07-26 09:30:28 +00:00
2019-12-20 12:04:34 +00:00
< tag -input v -model = " event.tags " :data ="tags" path = "title" / >
2019-01-21 14:08:22 +00:00
2019-12-20 12:04:34 +00:00
< date -time -picker v -model = " event.beginsOn " : label = "$t('Starts on…')" / >
< date -time -picker :min-datetime ="event.beginsOn" v -model = " event.endsOn " : label = "$t('Ends on…')" / >
2019-10-14 17:29:18 +00:00
<!-- < b -switch v-model ="endsOnNull" > {{ $ t ( ' No end date ' ) }} < / b -switch > -- >
2019-12-20 12:04:34 +00:00
< b -button type = "is-text" @ click = "dateSettingsIsOpen = true" > { { $t ( 'Date parameters' ) } } < / b - b u t t o n >
2019-09-11 07:59:01 +00:00
2019-12-20 12:04:34 +00:00
< address -auto -complete v -model = " event.physicalAddress " / >
2019-09-11 07:59:01 +00:00
2019-12-20 12:04:34 +00:00
< div class = "field" >
< label class = "label" > { { $t ( 'Description' ) } } < / label >
< editor v -model = " event.description " / >
< / div >
2019-10-01 18:10:53 +00:00
2019-12-20 12:04:34 +00:00
< b -field : label = "$t('Website / URL')" >
< b -input icon = "link" type = "url" v -model = " event.onlineAddress " placeholder = "URL" / >
< / b - f i e l d >
2020-04-14 15:41:50 +00:00
< subtitle >
{ { $t ( 'Organizers' ) } }
< / subtitle >
< div class = "columns" >
< div class = "column" >
< b -field :label ="$t('Organizer')" >
< identity -picker -wrapper v -model = " event.organizerActor " :masked ="event.options.hideOrganizerWhenGroupEvent" @input ="resetAttributedToOnOrganizerChange" / >
< / b - f i e l d >
< / div >
< div class = "column" >
< b -field :label ="$t('Group')" v-if ="event.organizerActor" >
< group -picker -wrapper v -model = " event.attributedTo " :identity ="event.organizerActor" / >
< / b - f i e l d >
< / div >
< / div >
<!-- < div class = "field" v-if ="event.attributedTo.id" > - - >
<!-- < label class = "label" > { { $t ( 'Hide the organizer' ) } } < / label > -- >
<!-- < b -switch v-model ="event.options.hideOrganizerWhenGroupEvent" > - - >
<!-- { { $t ( "Don't show @{organizer} as event host alongside @{group}" , { organizer : event . organizerActor . preferredUsername , group : event . attributedTo . preferredUsername } ) } } -- >
<!-- < small > -- >
<!-- < br > -- >
<!-- { { $t ( 'All group members and other eventual server admins will still be able to view this information.' ) } } -- >
<!-- < / small > -- >
<!-- < / b - s w i t c h > - - >
<!-- < / div > -- >
2019-12-20 12:04:34 +00:00
<!-- < b -field :label ="$t('Category')" >
< b -select placeholder = "Select a category" v-model ="event.category" >
< option
v - for = "category in categories"
: value = "category"
: key = "category"
> { { $t ( category ) } } < / option >
< / b - s e l e c t >
< / b - f i e l d > - - >
2020-02-18 07:47:41 +00:00
< subtitle >
2019-12-20 12:04:34 +00:00
{ { $t ( 'Who can view this event and participate' ) } }
2020-02-18 07:47:41 +00:00
< / subtitle >
2019-12-20 12:04:34 +00:00
< div class = "field" >
2019-09-20 17:43:29 +00:00
< b -radio v -model = " event.visibility "
name = "eventVisibility"
2019-12-20 12:04:34 +00:00
: native - value = "EventVisibility.PUBLIC" >
{ { $t ( 'Visible everywhere on the web (public)' ) } }
2019-07-30 14:40:59 +00:00
< / b - r a d i o >
2019-10-01 18:10:53 +00:00
< / div >
< div class = "field" >
2019-12-20 12:04:34 +00:00
< b -radio v -model = " event.visibility "
name = "eventVisibility"
: native - value = "EventVisibility.UNLISTED" >
{ { $t ( 'Only accessible through link and search (private)' ) } }
< / b - r a d i o >
2019-10-01 18:10:53 +00:00
< / div >
2019-12-20 12:04:34 +00:00
<!-- < div class = "field" >
< b -radio v -model = " event.visibility "
name = "eventVisibility"
: native - value = "EventVisibility.PRIVATE" >
{ { $t ( 'Page limited to my group (asks for auth)' ) } }
< / b - r a d i o >
< / div > -- >
< div class = "field" v-if ="config && config.anonymous.participation.allowed" >
< label class = "label" > { { $t ( 'Anonymous participations' ) } } < / label >
< b -switch v-model ="event.options.anonymousParticipation" >
{ { $t ( 'I want to allow people to participate without an account.' ) } }
< small v-if ="config.anonymous.participation.validation.email.confirmationRequired" >
< br >
{ { $t ( 'Anonymous participants will be asked to confirm their participation through e-mail.' ) } }
< / small >
< / b - s w i t c h >
< / div >
2019-08-28 09:28:27 +00:00
2019-12-20 12:04:34 +00:00
< div class = "field" >
< label class = "label" > { { $t ( 'Participation approval' ) } } < / label >
< b -switch v-model ="needsApproval" >
{ { $t ( 'I want to approve every participation request' ) } }
< / b - s w i t c h >
< / div >
< div class = "field" >
< label class = "label" > { { $t ( 'Number of places' ) } } < / label >
< b -switch v-model ="limitedPlaces" >
{ { $t ( 'Limited number of places' ) } }
< / b - s w i t c h >
< / div >
< div class = "box" v-if ="limitedPlaces" >
< b -field : label = "$t('Number of places')" >
< b -numberinput controls -position = " compact " min = "1" v -model = " event.options.maximumAttendeeCapacity " / >
< / b - f i e l d >
2019-11-15 17:36:47 +00:00
<!--
2019-12-20 12:04:34 +00:00
< b -field >
< b -switch v-model ="event.options.showRemainingAttendeeCapacity" >
{ { $t ( 'Show remaining number of places' ) } }
< / b - s w i t c h >
< / b - f i e l d >
2019-10-01 18:10:53 +00:00
2019-12-20 12:04:34 +00:00
< b -field >
< b -switch v-model ="event.options.showParticipationPrice" >
{ { $t ( 'Display participation price' ) } }
< / b - s w i t c h >
< / b - f i e l d > - - >
< / div >
2019-08-28 09:28:27 +00:00
2020-02-18 07:47:41 +00:00
< subtitle >
2019-12-20 12:04:34 +00:00
{ { $t ( 'Public comment moderation' ) } }
2020-02-18 07:47:41 +00:00
< / subtitle >
2019-07-30 14:40:59 +00:00
2019-12-20 12:04:34 +00:00
< div class = "field" >
< b -radio v -model = " event.options.commentModeration "
name = "commentModeration"
: native - value = "CommentModeration.ALLOW_ALL" >
{ { $t ( 'Allow all comments' ) } }
< / b - r a d i o >
< / div >
2019-08-28 09:28:27 +00:00
2019-11-15 17:36:47 +00:00
<!-- < div class = "field" > -- >
<!-- < b -radio v -model = " event.options.commentModeration " - - >
<!-- name = "commentModeration" -- >
<!-- : native - value = "CommentModeration.MODERATED" > -- >
<!-- { { $t ( 'Moderated comments (shown after approval)' ) } } -- >
<!-- < / b - r a d i o > - - >
<!-- < / div > -- >
2019-08-28 09:28:27 +00:00
2019-12-20 12:04:34 +00:00
< div class = "field" >
< b -radio v -model = " event.options.commentModeration "
name = "commentModeration"
: native - value = "CommentModeration.CLOSED" >
{ { $t ( 'Close comments for all (except for admins)' ) } }
< / b - r a d i o >
< / div >
2019-08-28 09:28:27 +00:00
2020-02-18 07:47:41 +00:00
< subtitle >
2019-12-20 12:04:34 +00:00
{ { $t ( 'Status' ) } }
2020-02-18 07:47:41 +00:00
< / subtitle >
2019-12-20 12:04:34 +00:00
< b -field >
< b -radio -button v -model = " event.status "
name = "status"
type = "is-warning"
: native - value = "EventStatus.TENTATIVE" >
< b -icon icon = "calendar-question" / >
{ { $t ( 'Tentative: Will be confirmed later' ) } }
< / b - r a d i o - b u t t o n >
< b -radio -button v -model = " event.status "
name = "status"
type = "is-success"
: native - value = "EventStatus.CONFIRMED" >
< b -icon icon = "calendar-check" / >
{ { $t ( 'Confirmed: Will happen' ) } }
< / b - r a d i o - b u t t o n >
< b -radio -button v -model = " event.status "
name = "status"
type = "is-danger"
: native - value = "EventStatus.CANCELLED" >
< b -icon icon = "calendar-remove" / >
{ { $t ( "Cancelled: Won't happen" ) } }
< / b - r a d i o - b u t t o n >
< / b - f i e l d >
< / form >
2019-01-21 14:08:22 +00:00
< / div >
2019-10-14 17:29:18 +00:00
< b -modal :active.sync ="dateSettingsIsOpen" has -modal -card trap -focus >
< form action = "" >
< div class = "modal-card" style = "width: auto" >
< header class = "modal-card-head" >
< p class = "modal-card-title" > { { $t ( 'Date and time settings' ) } } < / p >
< / header >
< section class = "modal-card-body" >
< b -field : label = "$t('Event page settings')" >
< b -switch v-model ="event.options.showStartTime" >
{ { $t ( 'Show the time when the event begins' ) } }
< / b - s w i t c h >
< / b - f i e l d >
< b -field >
< b -switch v-model ="event.options.showEndTime" >
{ { $t ( 'Show the time when the event ends' ) } }
< / b - s w i t c h >
< / b - f i e l d >
< / section >
< footer class = "modal-card-foot" >
< button class = "button" type = "button" @ click = "dateSettingsIsOpen = false" > { { $t ( 'OK' ) } } < / button >
< / footer >
< / div >
< / form >
< / b - m o d a l >
2019-12-03 10:29:51 +00:00
< span ref = "bottomObserver" / >
2019-10-01 18:10:53 +00:00
< nav role = "navigation" aria -label = " main navigation " class = "navbar" : class = "{'is-fixed-bottom': showFixedNavbar }" >
< div class = "container" >
< div class = "navbar-menu" >
< div class = "navbar-start" >
2019-10-03 09:37:34 +00:00
< span class = "navbar-item" v-if ="isEventModified" > {{ $ t ( ' Unsaved changes ' ) }} < / span >
2019-10-01 18:10:53 +00:00
< / div >
< div class = "navbar-end" >
< span class = "navbar-item" >
< b -button type = "is-text" @click ="confirmGoBack" >
{ { $t ( 'Cancel' ) } }
< / b - b u t t o n >
< / span >
2019-10-02 15:59:07 +00:00
<!-- If an event has been published we can ' t make it draft anymore -- >
< span class = "navbar-item" v-if ="event.draft === true" >
< b -button type = "is-primary" outlined @click ="createOrUpdateDraft" >
2019-10-01 18:10:53 +00:00
{ { $t ( 'Save draft' ) } }
< / b - b u t t o n >
< / span >
< span class = "navbar-item" >
2019-10-02 15:59:07 +00:00
< b -button type = "is-primary" @click ="createOrUpdatePublish" @keyup.enter ="createOrUpdatePublish" >
2019-10-01 18:10:53 +00:00
< span v-if ="isUpdate === false" > {{ $ t ( ' Create my event ' ) }} < / span >
2019-10-02 15:59:07 +00:00
< span v -else -if = " event.draft = = = true " > { { $t ( 'Publish' ) } } < / span >
2019-10-01 18:10:53 +00:00
< span v-else > {{ $ t ( ' Update my event ' ) }} < / span >
< / b - b u t t o n >
< / span >
< / div >
< / div >
< / div >
< / nav >
2019-01-21 14:08:22 +00:00
< / section >
< / template >
2019-10-01 18:10:53 +00:00
< style lang = "scss" scoped >
2019-09-09 09:21:42 +00:00
@ import "@/variables.scss" ;
2019-12-20 12:04:34 +00:00
main section > . container {
background : $white ;
}
2019-09-09 09:21:42 +00:00
h2 . subtitle {
margin : 10 px 0 ;
span {
padding : 5 px 7 px ;
display : inline ;
background : $secondary ;
}
}
2019-10-01 18:10:53 +00:00
section {
& > . container {
2019-12-20 12:04:34 +00:00
padding : 2 rem 1.5 rem ;
2019-10-01 18:10:53 +00:00
}
nav . navbar {
min - height : 2 rem ! important ;
background : lighten ( $secondary , 10 % ) ;
. container {
min - height : 2 rem ;
. navbar - menu , . navbar - end {
display : flex ! important ;
background : lighten ( $secondary , 10 % ) ;
}
. navbar - end {
justify - content : flex - end ;
margin - left : auto ;
}
}
}
}
2019-09-09 09:21:42 +00:00
< / style >
2019-01-21 14:08:22 +00:00
< script lang = "ts" >
2019-10-04 16:28:25 +00:00
import { CREATE _EVENT , EDIT _EVENT , EVENT _PERSON _PARTICIPATION , FETCH _EVENT } from '@/graphql/event' ;
2019-09-02 12:35:50 +00:00
import { Component , Prop , Vue , Watch } from 'vue-property-decorator' ;
2019-09-20 16:22:03 +00:00
import {
2019-10-03 14:54:56 +00:00
CommentModeration ,
EventJoinOptions ,
EventModel ,
EventStatus ,
EventVisibility ,
IEvent , ParticipantRole ,
} from '@/types/event.model' ;
2019-10-17 09:04:07 +00:00
import { CURRENT _ACTOR _CLIENT , LOGGED _USER _DRAFTS , LOGGED _USER _PARTICIPATIONS } from '@/graphql/actor' ;
2020-05-08 20:48:41 +00:00
import { Group , IPerson , Person } from '@/types/actor' ;
2019-05-22 12:12:11 +00:00
import PictureUpload from '@/components/PictureUpload.vue' ;
2019-10-10 08:25:33 +00:00
import EditorComponent from '@/components/Editor.vue' ;
2019-06-07 15:19:30 +00:00
import DateTimePicker from '@/components/Event/DateTimePicker.vue' ;
2019-07-26 09:30:28 +00:00
import TagInput from '@/components/Event/TagInput.vue' ;
import { TAGS } from '@/graphql/tags' ;
import { ITag } from '@/types/tag.model' ;
2019-07-30 08:35:29 +00:00
import AddressAutoComplete from '@/components/Event/AddressAutoComplete.vue' ;
2019-10-14 09:41:57 +00:00
import { buildFileFromIPicture , buildFileVariable , readFileAsync } from '@/utils/image' ;
2019-09-26 14:38:58 +00:00
import IdentityPickerWrapper from '@/views/Account/IdentityPickerWrapper.vue' ;
2019-10-09 17:41:17 +00:00
import { RouteName } from '@/router' ;
2019-10-17 09:04:07 +00:00
import 'intersection-observer' ;
2019-12-20 12:04:34 +00:00
import { CONFIG } from '@/graphql/config' ;
import { IConfig } from '@/types/config.model' ;
2020-02-18 07:47:41 +00:00
import Subtitle from '@/components/Utils/Subtitle.vue' ;
2020-04-14 15:41:50 +00:00
import GroupPickerWrapper from '@/components/Group/GroupPickerWrapper.vue' ;
2019-01-21 14:08:22 +00:00
2019-12-15 21:42:38 +00:00
const DEFAULT _LIMIT _NUMBER _OF _PLACES = 10 ;
2019-03-05 11:07:58 +00:00
@ Component ( {
2020-04-14 15:41:50 +00:00
components : {
GroupPickerWrapper ,
Subtitle ,
IdentityPickerWrapper ,
AddressAutoComplete ,
TagInput ,
DateTimePicker ,
PictureUpload ,
Editor : EditorComponent ,
} ,
2019-03-05 11:07:58 +00:00
apollo : {
2019-12-20 12:04:34 +00:00
currentActor : CURRENT _ACTOR _CLIENT ,
tags : TAGS ,
config : CONFIG ,
2020-04-14 15:41:50 +00:00
event : {
query : FETCH _EVENT ,
variables ( ) {
return {
2020-05-08 20:48:41 +00:00
uuid : this . eventId ,
} ;
2020-04-14 15:41:50 +00:00
} ,
update ( data ) {
return new EventModel ( data . event ) ;
} ,
skip ( ) {
return ! this . eventId ;
2020-05-08 20:48:41 +00:00
} ,
} ,
2019-03-22 09:57:14 +00:00
} ,
2019-10-10 14:47:38 +00:00
metaInfo ( ) {
return {
// if no subcomponents specify a metaInfo.title, this title will be used
2020-05-10 15:37:58 +00:00
// @ts-ignore
2020-04-14 15:41:50 +00:00
title : ( this . isUpdate ? this . $t ( 'Event edition' ) : this . $t ( 'Event creation' ) ) as string ,
2019-10-10 14:47:38 +00:00
// all titles will be injected into this template
titleTemplate : '%s | Mobilizon' ,
} ;
} ,
2019-03-05 11:07:58 +00:00
} )
2019-09-02 12:35:50 +00:00
export default class EditEvent extends Vue {
2020-04-14 15:41:50 +00:00
@ Prop ( { required : false , type : String } ) eventId : undefined | string ;
2019-09-02 12:35:50 +00:00
2019-09-11 07:59:01 +00:00
currentActor = new Person ( ) ;
2019-09-04 16:24:31 +00:00
tags : ITag [ ] = [ ] ;
2019-10-01 18:10:53 +00:00
event : IEvent = new EventModel ( ) ;
2019-12-20 12:04:34 +00:00
config ! : IConfig ;
2019-10-01 18:10:53 +00:00
unmodifiedEvent ! : IEvent ;
2019-07-23 15:14:03 +00:00
pictureFile : File | null = null ;
2019-09-02 12:35:50 +00:00
2019-08-28 09:28:27 +00:00
EventStatus = EventStatus ;
2019-09-20 17:43:29 +00:00
EventVisibility = EventVisibility ;
2019-08-28 09:28:27 +00:00
needsApproval : boolean = false ;
canPromote : boolean = true ;
limitedPlaces : boolean = false ;
CommentModeration = CommentModeration ;
2019-10-01 18:10:53 +00:00
showFixedNavbar : boolean = true ;
observer ! : IntersectionObserver ;
2019-10-14 17:29:18 +00:00
dateSettingsIsOpen : boolean = false ;
endsOnNull : boolean = false ;
2019-01-21 14:08:22 +00:00
2019-06-07 15:19:30 +00:00
created ( ) {
2019-10-03 09:37:34 +00:00
this . initializeEvent ( ) ;
this . unmodifiedEvent = JSON . parse ( JSON . stringify ( this . event . toEditJSON ( ) ) ) ;
}
2020-04-14 15:41:50 +00:00
get isUpdate ( ) : boolean {
return this . eventId !== undefined ;
}
@ Watch ( 'eventId' , { immediate : true } )
resetFormForCreation ( eventId ) {
2020-05-11 07:20:55 +00:00
if ( eventId === undefined ) {
2020-04-14 15:41:50 +00:00
this . event = new EventModel ( ) ;
}
}
2019-10-03 09:37:34 +00:00
private initializeEvent ( ) {
const roundUpTo = roundTo => x => new Date ( Math . ceil ( x / roundTo ) * roundTo ) ;
const roundUpTo15Minutes = roundUpTo ( 1000 * 60 * 15 ) ;
const now = roundUpTo15Minutes ( new Date ( ) ) ;
const end = roundUpTo15Minutes ( new Date ( ) ) ;
2019-06-07 15:19:30 +00:00
end . setUTCHours ( now . getUTCHours ( ) + 3 ) ;
2019-09-02 12:35:50 +00:00
2019-06-07 15:19:30 +00:00
this . event . beginsOn = now ;
this . event . endsOn = end ;
2019-09-11 07:59:01 +00:00
this . event . organizerActor = this . event . organizerActor || this . currentActor ;
2019-06-07 15:19:30 +00:00
}
2020-04-14 15:41:50 +00:00
async mounted ( ) {
2019-10-03 09:37:34 +00:00
this . observer = new IntersectionObserver ( ( entries ) => {
2019-10-01 18:10:53 +00:00
for ( const entry of entries ) {
if ( entry ) {
this . showFixedNavbar = ! entry . isIntersecting ;
}
}
} , {
rootMargin : '-50px 0px -50px' ,
} ) ;
this . observer . observe ( this . $refs . bottomObserver as Element ) ;
2020-04-14 15:41:50 +00:00
this . unmodifiedEvent = JSON . parse ( JSON . stringify ( this . event . toEditJSON ( ) ) ) ;
this . pictureFile = await buildFileFromIPicture ( this . event . picture ) ;
this . limitedPlaces = this . event . options . maximumAttendeeCapacity > 0 ;
2019-10-01 18:10:53 +00:00
}
2019-10-02 15:59:07 +00:00
createOrUpdateDraft ( e : Event ) {
2019-01-21 14:08:22 +00:00
e . preventDefault ( ) ;
2019-10-02 15:59:07 +00:00
if ( this . validateForm ( ) ) {
if ( this . eventId ) return this . updateEvent ( ) ;
2019-07-23 15:14:03 +00:00
2019-10-02 15:59:07 +00:00
return this . createEvent ( ) ;
}
}
2019-09-02 12:35:50 +00:00
2019-10-02 15:59:07 +00:00
createOrUpdatePublish ( e : Event ) {
if ( this . validateForm ( ) ) {
this . event . draft = false ;
this . createOrUpdateDraft ( e ) ;
}
}
2019-12-03 10:29:51 +00:00
@ Watch ( 'currentActor' )
setCurrentActor ( ) {
this . event . organizerActor = this . currentActor ;
}
2020-04-14 15:41:50 +00:00
resetAttributedToOnOrganizerChange ( ) {
this . event . attributedTo = new Group ( ) ;
}
// @Watch('event.attributedTo', { deep: true })
// updateHideOrganizerWhenGroupEventOption(attributedTo) {
// if (!attributedTo.preferredUsername) {
// this.event.options.hideOrganizerWhenGroupEvent = false;
// }
// }
2019-10-02 15:59:07 +00:00
private validateForm ( ) {
const form = this . $refs . form as HTMLFormElement ;
if ( form . checkValidity ( ) ) {
return true ;
}
form . reportValidity ( ) ;
return false ;
2019-09-02 12:35:50 +00:00
}
async createEvent ( ) {
2019-10-14 09:41:57 +00:00
const variables = await this . buildVariables ( ) ;
2019-10-09 12:55:45 +00:00
try {
const { data } = await this . $apollo . mutate ( {
mutation : CREATE _EVENT ,
2019-10-14 09:41:57 +00:00
variables ,
2019-10-09 12:55:45 +00:00
update : ( store , { data : { createEvent } } ) => this . postCreateOrUpdate ( store , createEvent ) ,
refetchQueries : ( { data : { createEvent } } ) => this . postRefetchQueries ( createEvent ) ,
} ) ;
2019-10-13 11:56:24 +00:00
this . $buefy . notification . open ( {
message : ( this . event . draft ?
this . $i18n . t ( 'The event has been created as a draft' ) :
this . $i18n . t ( 'The event has been published' ) ) as string ,
type : 'is-success' ,
position : 'is-bottom-right' ,
duration : 5000 ,
} ) ;
2019-10-09 12:55:45 +00:00
await this . $router . push ( {
name : 'Event' ,
params : { uuid : data . createEvent . uuid } ,
} ) ;
} catch ( err ) {
console . error ( err ) ;
}
2019-09-02 12:35:50 +00:00
}
async updateEvent ( ) {
2019-10-14 09:41:57 +00:00
const variables = await this . buildVariables ( ) ;
2019-09-02 12:35:50 +00:00
try {
await this . $apollo . mutate ( {
mutation : EDIT _EVENT ,
2019-10-14 09:41:57 +00:00
variables ,
2019-10-04 16:28:25 +00:00
update : ( store , { data : { updateEvent } } ) => this . postCreateOrUpdate ( store , updateEvent ) ,
refetchQueries : ( { data : { updateEvent } } ) => this . postRefetchQueries ( updateEvent ) ,
2019-09-02 12:35:50 +00:00
} ) ;
2019-10-13 11:56:24 +00:00
this . $buefy . notification . open ( {
message : this . updateEventMessage ,
type : 'is-success' ,
position : 'is-bottom-right' ,
duration : 5000 ,
} ) ;
2019-09-04 16:24:31 +00:00
await this . $router . push ( {
2019-09-02 12:35:50 +00:00
name : 'Event' ,
params : { uuid : this . eventId as string } ,
} ) ;
} catch ( err ) {
console . error ( err ) ;
2019-01-21 14:08:22 +00:00
}
}
2019-10-13 11:56:24 +00:00
get updateEventMessage ( ) : string {
if ( this . unmodifiedEvent . draft && ! this . event . draft ) return this . $i18n . t ( 'The event has been updated and published' ) as string ;
return ( this . event . draft ? this . $i18n . t ( 'The draft event has been updated' ) : this . $i18n . t ( 'The event has been updated' ) ) as string ;
}
2019-10-04 16:28:25 +00:00
/ * *
* Put in cache the updated or created event .
* If the event is not a draft anymore , also put in cache the participation
* /
private postCreateOrUpdate ( store , updateEvent ) {
const resultEvent : IEvent = Object . assign ( { } , updateEvent ) ;
const organizerActor : IPerson = this . event . organizerActor as Person ;
resultEvent . organizerActor = organizerActor ;
resultEvent . relatedEvents = [ ] ;
store . writeQuery ( { query : FETCH _EVENT , variables : { uuid : updateEvent . uuid } , data : { event : resultEvent } } ) ;
if ( ! updateEvent . draft ) {
store . writeQuery ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : updateEvent . id , name : organizerActor . preferredUsername } ,
data : {
person : {
_ _typename : 'Person' ,
id : organizerActor . id ,
participations : [ {
_ _typename : 'Participant' ,
id : 'unknown' ,
role : ParticipantRole . CREATOR ,
actor : {
_ _typename : 'Actor' ,
id : organizerActor . id ,
} ,
event : {
_ _typename : 'Event' ,
id : updateEvent . id ,
} ,
} ] ,
} ,
} ,
} ) ;
}
}
/ * *
* Refresh drafts or participation cache depending if the event is still draft or not
* /
private postRefetchQueries ( updateEvent ) {
if ( updateEvent . draft ) {
return [ {
query : LOGGED _USER _DRAFTS ,
} ] ;
}
return [ {
query : LOGGED _USER _PARTICIPATIONS ,
variables : {
afterDateTime : new Date ( ) ,
} ,
} ] ;
}
2019-07-23 15:14:03 +00:00
/ * *
* Build variables for Event GraphQL creation query
* /
2019-10-14 09:41:57 +00:00
private async buildVariables ( ) {
2019-09-11 07:59:01 +00:00
let res = this . event . toEditJSON ( ) ;
if ( this . event . organizerActor ) {
res = Object . assign ( res , { organizerActorId : this . event . organizerActor . id } ) ;
}
2020-04-14 15:41:50 +00:00
if ( this . event . attributedTo ) {
res = Object . assign ( res , { attributedToId : this . event . attributedTo . id } ) ;
}
2019-07-30 08:35:29 +00:00
2019-09-04 16:24:31 +00:00
delete this . event . options [ '__typename' ] ;
2019-07-30 08:35:29 +00:00
if ( this . event . physicalAddress ) {
delete this . event . physicalAddress [ '__typename' ] ;
}
2019-07-23 15:14:03 +00:00
2019-10-14 17:29:18 +00:00
if ( this . endsOnNull ) {
res . endsOn = null ;
}
2019-09-02 12:35:50 +00:00
const pictureObj = buildFileVariable ( this . pictureFile , 'picture' ) ;
2019-10-14 09:41:57 +00:00
res = Object . assign ( { } , res , pictureObj ) ;
2019-11-15 17:36:47 +00:00
try {
if ( this . event . picture ) {
const oldPictureFile = await buildFileFromIPicture ( this . event . picture ) as File ;
const oldPictureFileContent = await readFileAsync ( oldPictureFile ) ;
const newPictureFileContent = await readFileAsync ( this . pictureFile as File ) ;
if ( oldPictureFileContent === newPictureFileContent ) {
res . picture = { pictureId : this . event . picture . id } ;
}
2019-10-14 09:41:57 +00:00
}
2019-11-15 17:36:47 +00:00
} catch ( e ) {
console . error ( e ) ;
2019-10-14 09:41:57 +00:00
}
return res ;
2019-05-22 12:12:11 +00:00
}
2019-09-02 12:35:50 +00:00
private async getEvent ( ) {
const result = await this . $apollo . query ( {
query : FETCH _EVENT ,
variables : {
uuid : this . eventId ,
} ,
} ) ;
2019-10-14 17:29:18 +00:00
if ( result . data . event . endsOn === null ) {
this . endsOnNull = true ;
}
2019-09-02 12:35:50 +00:00
return new EventModel ( result . data . event ) ;
}
2019-12-10 21:40:33 +00:00
@ Watch ( 'limitedPlaces' )
updatedEventCapacityOptions ( limitedPlaces : boolean ) {
2019-12-15 21:42:38 +00:00
if ( ! limitedPlaces ) {
this . event . options . maximumAttendeeCapacity = 0 ;
this . event . options . remainingAttendeeCapacity = 0 ;
this . event . options . showRemainingAttendeeCapacity = false ;
} else {
this . event . options . maximumAttendeeCapacity = this . event . options . maximumAttendeeCapacity || DEFAULT _LIMIT _NUMBER _OF _PLACES ;
2019-12-10 21:40:33 +00:00
}
}
2019-09-20 16:22:03 +00:00
@ Watch ( 'needsApproval' )
updateEventJoinOptions ( needsApproval ) {
if ( needsApproval === true ) {
this . event . joinOptions = EventJoinOptions . RESTRICTED ;
} else {
this . event . joinOptions = EventJoinOptions . FREE ;
}
}
2019-09-23 09:51:59 +00:00
get checkTitleLength ( ) {
return this . event . title . length > 80 ? [ 'is-info' , this . $t ( 'The event title will be ellipsed.' ) ] : [ undefined , undefined ] ;
}
2019-10-01 18:10:53 +00:00
/ * *
* Confirm cancel
* /
2019-10-09 15:18:27 +00:00
confirmGoElsewhere ( callback ) {
2019-10-02 15:59:07 +00:00
if ( ! this . isEventModified ) {
2019-10-09 15:18:27 +00:00
return callback ( ) ;
2019-10-02 15:59:07 +00:00
}
2019-10-01 18:10:53 +00:00
const title : string = this . isUpdate ?
this . $t ( 'Cancel edition' ) as string :
this . $t ( 'Cancel creation' ) as string ;
const message : string = this . isUpdate ?
2019-10-02 15:59:07 +00:00
this . $t ( "Are you sure you want to cancel the event edition? You'll lose all modifications." ,
2019-10-01 18:10:53 +00:00
{ title : this . event . title } ) as string :
2019-10-02 15:59:07 +00:00
this . $t ( "Are you sure you want to cancel the event creation? You'll lose all modifications." ,
2019-10-01 18:10:53 +00:00
{ title : this . event . title } ) as string ;
this . $buefy . dialog . confirm ( {
title ,
message ,
2019-10-09 17:41:17 +00:00
confirmText : this . $t ( 'Abandon edition' ) as string ,
2019-10-01 18:10:53 +00:00
cancelText : this . $t ( 'Continue editing' ) as string ,
type : 'is-warning' ,
hasIcon : true ,
2019-10-09 15:18:27 +00:00
onConfirm : callback ,
2019-10-01 18:10:53 +00:00
} ) ;
}
2019-10-09 15:18:27 +00:00
/ * *
* Confirm cancel
* /
confirmGoBack ( ) {
this . confirmGoElsewhere ( ( ) => this . $router . go ( - 1 ) ) ;
}
2019-10-09 15:54:35 +00:00
beforeRouteLeave ( to , from , next ) {
2019-10-09 17:41:17 +00:00
if ( to . name === RouteName . EVENT ) return next ( ) ;
2019-10-09 15:54:35 +00:00
this . confirmGoElsewhere ( ( ) => next ( ) ) ;
}
2019-10-01 18:10:53 +00:00
get isEventModified ( ) : boolean {
2019-10-03 09:37:34 +00:00
return JSON . stringify ( this . event . toEditJSON ( ) ) !== JSON . stringify ( this . unmodifiedEvent ) ;
2019-10-01 18:10:53 +00:00
}
2019-12-09 23:10:12 +00:00
get beginsOn ( ) : Date { return this . event . beginsOn ; }
2019-10-09 10:54:09 +00:00
2019-10-14 17:29:18 +00:00
@ Watch ( 'beginsOn' , { deep : true } )
2019-10-09 10:54:09 +00:00
onBeginsOnChanged ( beginsOn ) {
if ( ! this . event . endsOn ) return ;
const dateBeginsOn = new Date ( beginsOn ) ;
const dateEndsOn = new Date ( this . event . endsOn ) ;
if ( dateEndsOn < dateBeginsOn ) {
this . event . endsOn = dateBeginsOn ;
2019-12-09 23:10:12 +00:00
this . event . endsOn . setHours ( dateBeginsOn . getHours ( ) + 1 ) ;
2019-10-09 10:54:09 +00:00
}
if ( dateEndsOn === dateBeginsOn ) {
2019-10-14 17:29:18 +00:00
this . event . endsOn . setHours ( dateEndsOn . getHours ( ) + 1 ) ;
2019-10-09 10:54:09 +00:00
}
}
2019-10-11 16:41:29 +00:00
/ * *
* In event endsOn datepicker , we lock starting with the day before the beginsOn date
* /
get minDateForEndsOn ( ) : Date {
const minDate = new Date ( this . event . beginsOn ) ;
minDate . setDate ( minDate . getDate ( ) - 1 ) ;
return minDate ;
}
2019-01-21 14:08:22 +00:00
}
2019-09-02 12:35:50 +00:00
< / script >
2019-08-28 09:28:27 +00:00