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