2022-10-11 17:48:58 +02:00
< template >
< div class = "" >
< participation -section
2022-10-31 18:54:21 +01:00
v - if = "event && anonymousParticipationConfig"
2022-10-11 17:48:58 +02:00
: participation = "participations[0]"
: event = "event"
: anonymousParticipation = "anonymousParticipation"
: currentActor = "currentActor"
: identities = "identities"
: anonymousParticipationConfig = "anonymousParticipationConfig"
@ join - event = "joinEvent"
@ join - modal = "isJoinModalActive = true"
@ join - event - with - confirmation = "joinEventWithConfirmation"
@ confirm - leave = "confirmLeave"
@ cancel - anonymous - participation = "cancelAnonymousParticipation"
/ >
< div class = "flex flex-col" >
< p class = "inline-flex gap-1" >
< TicketConfirmationOutline / >
< router -link
class = "participations-link"
v - if = "canManageEvent && event?.draft === false"
: to = " {
name : RouteName . PARTICIPATIONS ,
params : { eventId : event . uuid } ,
} "
>
<!-- We retire one because of the event creator who is a
participant -- >
< span v-if ="maximumAttendeeCapacity" >
{ {
t (
"{available}/{capacity} available places" ,
{
available :
maximumAttendeeCapacity -
event . participantStats . participant ,
capacity : maximumAttendeeCapacity ,
} ,
maximumAttendeeCapacity - event . participantStats . participant
)
} }
< / span >
< span v-else >
{ {
t (
"No one is participating|One person participating|{going} people participating" ,
{
going : event . participantStats . participant ,
} ,
event . participantStats . participant
)
} }
< / span >
< / r o u t e r - l i n k >
< span v-else >
< span v-if ="maximumAttendeeCapacity" >
{ {
t (
"{available}/{capacity} available places" ,
{
available :
maximumAttendeeCapacity -
( event ? . participantStats . participant ? ? 0 ) ,
capacity : maximumAttendeeCapacity ,
} ,
maximumAttendeeCapacity -
( event ? . participantStats . participant ? ? 0 )
)
} }
< / span >
< span v-else >
{ {
t (
"No one is participating|One person participating|{going} people participating" ,
{
going : event ? . participantStats . participant ,
} ,
event ? . participantStats . participant ? ? 0
)
} }
< / span >
< / span >
< VTooltip v-if ="event?.local === false" >
< HelpCircleOutline :size ="16" / >
< template # popper >
{ {
t (
"The actual number of participants may differ, as this event is hosted on another instance."
)
} }
< / template >
< / VTooltip >
< / p >
< o -dropdown >
< template # trigger >
< o -button icon -right = " dots -horizontal " >
{ { t ( "Actions" ) } }
< / o - b u t t o n >
< / template >
< o -dropdown -item
aria - role = "listitem"
has - link
v - if = "canManageEvent || event?.draft"
>
< router -link
class = "flex gap-1"
: to = " {
name : RouteName . EDIT _EVENT ,
params : { eventId : event ? . uuid } ,
} "
>
< Pencil / >
{ { t ( "Edit" ) } }
< / r o u t e r - l i n k >
< / o - d r o p d o w n - i t e m >
< o -dropdown -item
aria - role = "listitem"
has - link
v - if = "canManageEvent || event?.draft"
>
< router -link
class = "flex gap-1"
: to = " {
name : RouteName . DUPLICATE _EVENT ,
params : { eventId : event ? . uuid } ,
} "
>
< ContentDuplicate / >
{ { t ( "Duplicate" ) } }
< / r o u t e r - l i n k >
< / o - d r o p d o w n - i t e m >
< o -dropdown -item
aria - role = "listitem"
v - if = "canManageEvent || event?.draft"
@ click = "openDeleteEventModal"
@ keyup . enter = "openDeleteEventModal"
> < span class = "flex gap-1" >
< Delete / >
{ { t ( "Delete" ) } }
< / span >
< / o - d r o p d o w n - i t e m >
< hr
role = "presentation"
class = "dropdown-divider"
aria - role = "o-dropdown-item"
v - if = "canManageEvent || event?.draft"
/ >
< o -dropdown -item
aria - role = "listitem"
v - if = "event?.draft === false"
@ click = "triggerShare()"
@ keyup . enter = "triggerShare()"
class = "p-1"
>
< span class = "flex gap-1" >
< Share / >
{ { t ( "Share this event" ) } }
< / span >
< / o - d r o p d o w n - i t e m >
< o -dropdown -item
aria - role = "listitem"
@ click = "downloadIcsEvent()"
@ keyup . enter = "downloadIcsEvent()"
v - if = "event?.draft === false"
>
< span class = "flex gap-1" >
< CalendarPlus / >
{ { t ( "Add to my calendar" ) } }
< / span >
< / o - d r o p d o w n - i t e m >
< o -dropdown -item
aria - role = "listitem"
v - if = "ableToReport"
@ click = "isReportModalActive = true"
@ keyup . enter = "isReportModalActive = true"
class = "p-1"
>
< span class = "flex gap-1" >
< Flag / >
{ { t ( "Report" ) } }
< / span >
< / o - d r o p d o w n - i t e m >
< / o - d r o p d o w n >
< / div >
< / div >
< o -modal
v - model : active = "isReportModalActive"
has - modal - card
ref = "reportModal"
: close - button - aria - label = "t('Close')"
>
< ReportModal
: on - confirm = "reportEvent"
: title = "t('Report this event')"
: outside - domain = "organizerDomain"
/ >
< / o - m o d a l >
< o -modal
: close - button - aria - label = "t('Close')"
v - model : active = "isShareModalActive"
has - modal - card
ref = "shareModal"
>
< share -event -modal
v - if = "event"
: event = "event"
: eventCapacityOK = "eventCapacityOK"
/ >
< / o - m o d a l >
< o -modal
v - model : active = "isJoinModalActive"
has - modal - card
ref = "participationModal"
: close - button - aria - label = "t('Close')"
>
< identity -picker v-if ="identity" v-model="identity" >
< template # footer >
< footer class = "flex gap-2" >
< o -button
outlined
ref = "cancelButton"
@ click = "isJoinModalActive = false"
@ keyup . enter = "isJoinModalActive = false"
>
{ { t ( "Cancel" ) } }
< / o - b u t t o n >
< o -button
v - if = "identity"
variant = "primary"
ref = "confirmButton"
@ click = "
event ? . joinOptions === EventJoinOptions . RESTRICTED
? joinEventWithConfirmation ( identity as IPerson )
: joinEvent ( identity as IPerson )
"
@ keyup . enter = "
event ? . joinOptions === EventJoinOptions . RESTRICTED
? joinEventWithConfirmation ( identity as IPerson )
: joinEvent ( identity as IPerson )
"
>
{ { t ( "Confirm my particpation" ) } }
< / o - b u t t o n >
< / footer >
< / template >
< / i d e n t i t y - p i c k e r >
< / o - m o d a l >
< o -modal
v - model : active = "isJoinConfirmationModalActive"
has - modal - card
ref = "joinConfirmationModal"
: close - button - aria - label = "t('Close')"
>
< div class = "modal-card" >
< header class = "modal-card-head" >
< p class = "modal-card-title" >
{ { t ( "Participation confirmation" ) } }
< / p >
< / header >
< section class = "modal-card-body" >
< p >
{ {
t (
"The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?"
)
} }
< / p >
< form
@ submit . prevent = "
joinEvent ( actorForConfirmation as IPerson , messageForConfirmation )
"
>
< o -field :label ="t('Message')" >
< o -input
type = "textarea"
size = "medium"
v - model = "messageForConfirmation"
minlength = "10"
> < / o - i n p u t >
< / o - f i e l d >
< div class = "buttons" >
< o -button
native - type = "button"
class = "button"
ref = "cancelButton"
@ click = "isJoinConfirmationModalActive = false"
@ keyup . enter = "isJoinConfirmationModalActive = false"
> { { t ( "Cancel" ) } }
< / o - b u t t o n >
< o -button variant = "primary" native -type = " submit " >
{ { t ( "Confirm my participation" ) } }
< / o - b u t t o n >
< / div >
< / form >
< / section >
< / div >
< / o - m o d a l >
< / template >
< script lang = "ts" setup >
import { IActor , IPerson } from "@/types/actor" ;
import { IEvent } from "@/types/event.model" ;
import ParticipationSection from "@/components/Participation/ParticipationSection.vue" ;
import ReportModal from "@/components/Report/ReportModal.vue" ;
import IdentityPicker from "@/views/Account/IdentityPicker.vue" ;
2022-10-31 18:05:59 +01:00
import { EventJoinOptions , ParticipantRole , MemberRole } from "@/types/enums" ;
2022-10-11 17:48:58 +02:00
import { GRAPHQL _API _ENDPOINT } from "@/api/_entrypoint" ;
import { computed , defineAsyncComponent , inject , onMounted , ref } from "vue" ;
import { useI18n } from "vue-i18n" ;
import Flag from "vue-material-design-icons/Flag.vue" ;
import CalendarPlus from "vue-material-design-icons/CalendarPlus.vue" ;
import ContentDuplicate from "vue-material-design-icons/ContentDuplicate.vue" ;
import Delete from "vue-material-design-icons/Delete.vue" ;
import Pencil from "vue-material-design-icons/Pencil.vue" ;
import HelpCircleOutline from "vue-material-design-icons/HelpCircleOutline.vue" ;
import TicketConfirmationOutline from "vue-material-design-icons/TicketConfirmationOutline.vue" ;
import Share from "vue-material-design-icons/Share.vue" ;
import {
EVENT _PERSON _PARTICIPATION ,
FETCH _EVENT ,
JOIN _EVENT ,
LEAVE _EVENT ,
} from "@/graphql/event" ;
import { Notifier } from "@/plugins/notifier" ;
import { Dialog } from "@/plugins/dialog" ;
import { Snackbar } from "@/plugins/snackbar" ;
import RouteName from "@/router/name" ;
import {
AnonymousParticipationNotFoundError ,
getLeaveTokenForParticipation ,
isParticipatingInThisEvent ,
removeAnonymousParticipation ,
} from "@/services/AnonymousParticipationStorage" ;
import {
useAnonymousActorId ,
useAnonymousParticipationConfig ,
useAnonymousReportsConfig ,
} from "@/composition/apollo/config" ;
import { useCurrentUserIdentities } from "@/composition/apollo/actor" ;
import { useRouter } from "vue-router" ;
import { IParticipant } from "@/types/participant.model" ;
import { ApolloCache , FetchResult } from "@apollo/client/core" ;
import { useMutation } from "@vue/apollo-composable" ;
import { useCreateReport } from "@/composition/apollo/report" ;
import { useDeleteEvent } from "@/composition/apollo/event" ;
2022-10-27 18:12:48 +02:00
import { useProgrammatic } from "@oruga-ui/oruga-next" ;
2022-10-11 17:48:58 +02:00
const ShareEventModal = defineAsyncComponent (
( ) => import ( "@/components/Event/ShareEventModal.vue" )
) ;
const props = defineProps < {
event : IEvent ;
currentActor : IPerson | undefined ;
participations : IParticipant [ ] ;
person : IPerson | undefined ;
} > ( ) ;
const { t } = useI18n ( { useScope : "global" } ) ;
const notifier = inject < Notifier > ( "notifier" ) ;
const dialog = inject < Dialog > ( "dialog" ) ;
const router = useRouter ( ) ;
const { anonymousReportsConfig } = useAnonymousReportsConfig ( ) ;
const { anonymousActorId } = useAnonymousActorId ( ) ;
const { anonymousParticipationConfig } = useAnonymousParticipationConfig ( ) ;
const { identities } = useCurrentUserIdentities ( ) ;
const event = computed ( ( ) => props . event ) ;
const identity = ref < IPerson | undefined | null > ( null ) ;
const ableToReport = computed ( ( ) : boolean => {
return (
props . currentActor ? . id != null ||
anonymousReportsConfig . value ? . allowed === true
) ;
} ) ;
const organizer = computed ( ( ) : IActor | null => {
if ( event . value ? . attributedTo ? . id ) {
return event . value . attributedTo ;
}
if ( event . value ? . organizerActor ) {
return event . value . organizerActor ;
}
return null ;
} ) ;
const organizerDomain = computed ( ( ) : string | undefined => {
return organizer . value ? . domain ? ? undefined ;
} ) ;
const reportModal = ref ( ) ;
const isReportModalActive = ref ( false ) ;
const isShareModalActive = ref ( false ) ;
const isJoinModalActive = ref ( false ) ;
const isJoinConfirmationModalActive = ref ( false ) ;
const actorForConfirmation = ref < IPerson | null > ( null ) ;
const messageForConfirmation = ref ( "" ) ;
const anonymousParticipation = ref < boolean | null > ( null ) ;
const downloadIcsEvent = async ( ) : Promise < void > => {
const data = await (
await fetch ( ` ${ GRAPHQL _API _ENDPOINT } /events/ ${ event . value . uuid } /export/ics ` )
) . text ( ) ;
const blob = new Blob ( [ data ] , { type : "text/calendar" } ) ;
const link = document . createElement ( "a" ) ;
link . href = window . URL . createObjectURL ( blob ) ;
link . download = ` ${ event . value ? . title } .ics ` ;
document . body . appendChild ( link ) ;
link . click ( ) ;
document . body . removeChild ( link ) ;
} ;
const triggerShare = ( ) : void => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-start
if ( navigator . share ) {
navigator
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
. share ( {
title : event . value ? . title ,
url : event . value ? . url ,
} )
. then ( ( ) => console . debug ( "Successful share" ) )
. catch ( ( error : any ) => console . debug ( "Error sharing" , error ) ) ;
} else {
isShareModalActive . value = true ;
// send popup
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-end
} ;
const canManageEvent = computed ( ( ) : boolean => {
return actorIsOrganizer . value || hasGroupPrivileges . value ;
} ) ;
// const actorIsParticipant = computed((): boolean => {
// if (actorIsOrganizer.value) return true;
// return (
// participations.value.length > 0 &&
// participations.value[0].role === ParticipantRole.PARTICIPANT
// );
// });
const actorIsOrganizer = computed ( ( ) : boolean => {
return (
props . participations . length > 0 &&
props . participations [ 0 ] . role === ParticipantRole . CREATOR
) ;
} ) ;
const hasGroupPrivileges = computed ( ( ) : boolean => {
return (
props . person ? . memberships !== undefined &&
props . person ? . memberships ? . total > 0 &&
[ MemberRole . MODERATOR , MemberRole . ADMINISTRATOR ] . includes (
props . person ? . memberships ? . elements [ 0 ] . role
)
) ;
} ) ;
const joinEventWithConfirmation = ( actor : IPerson ) : void => {
isJoinConfirmationModalActive . value = true ;
actorForConfirmation . value = actor ;
} ;
const {
mutate : joinEventMutation ,
onDone : onJoinEventMutationDone ,
onError : onJoinEventMutationError ,
} = useMutation < {
joinEvent : IParticipant ;
} > ( JOIN _EVENT , ( ) => ( {
update : (
store : ApolloCache < {
joinEvent : IParticipant ;
} > ,
{ data } : FetchResult
) => {
if ( data == null ) return ;
const participationCachedData = store . readQuery < { person : IPerson } > ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : event . value ? . id , actorId : identity . value ? . id } ,
} ) ;
if ( participationCachedData ? . person == undefined ) {
console . error (
"Cannot update participation cache, because of null value."
) ;
return ;
}
store . writeQuery ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : event . value ? . id , actorId : identity . value ? . id } ,
data : {
person : {
... participationCachedData ? . person ,
participations : {
elements : [ data . joinEvent ] ,
total : 1 ,
} ,
} ,
} ,
} ) ;
const cachedData = store . readQuery < { event : IEvent } > ( {
query : FETCH _EVENT ,
variables : { uuid : event . value ? . uuid } ,
} ) ;
if ( cachedData == null ) return ;
const { event : cachedEvent } = cachedData ;
if ( cachedEvent === null ) {
console . error (
"Cannot update event participant cache, because of null value."
) ;
return ;
}
const participantStats = { ... cachedEvent . participantStats } ;
if ( data . joinEvent . role === ParticipantRole . NOT _APPROVED ) {
participantStats . notApproved += 1 ;
} else {
participantStats . going += 1 ;
participantStats . participant += 1 ;
}
store . writeQuery ( {
query : FETCH _EVENT ,
variables : { uuid : props . event . uuid } ,
data : {
event : {
... cachedEvent ,
participantStats ,
} ,
} ,
} ) ;
} ,
} ) ) ;
const joinEvent = (
identityForJoin : IPerson ,
message : string | null = null
) : void => {
isJoinConfirmationModalActive . value = false ;
isJoinModalActive . value = false ;
joinEventMutation ( {
eventId : event . value ? . id ,
actorId : identityForJoin ? . id ,
message ,
} ) ;
} ;
const participationRequestedMessage = ( ) => {
notifier ? . success ( t ( "Your participation has been requested" ) ) ;
} ;
const participationConfirmedMessage = ( ) => {
notifier ? . success ( t ( "Your participation has been confirmed" ) ) ;
} ;
onJoinEventMutationDone ( ( { data } ) => {
if ( data ) {
if ( data . joinEvent . role === ParticipantRole . NOT _APPROVED ) {
participationRequestedMessage ( ) ;
} else {
participationConfirmedMessage ( ) ;
}
}
} ) ;
2022-10-27 18:12:48 +02:00
const { oruga } = useProgrammatic ( ) ;
2022-10-11 17:48:58 +02:00
onJoinEventMutationError ( ( error ) => {
2022-10-27 18:12:48 +02:00
if ( error . message ) {
oruga . notification . open ( {
message : error . message ,
variant : "danger" ,
position : "bottom-right" ,
duration : 5000 ,
} ) ;
}
2022-10-11 17:48:58 +02:00
console . error ( error ) ;
} ) ;
const confirmLeave = ( ) : void => {
dialog ? . confirm ( {
title : t ( 'Leaving event "{title}"' , {
title : event . value ? . title ,
} ) ,
message : t (
'Are you sure you want to cancel your participation at event "{title}"?' ,
{
title : event . value ? . title ,
}
) ,
confirmText : t ( "Leave event" ) ,
cancelText : t ( "Cancel" ) ,
variant : "danger" ,
hasIcon : true ,
onConfirm : ( ) => {
if ( event . value && props . currentActor ? . id ) {
console . debug ( "calling leave event" ) ;
leaveEvent ( event . value , props . currentActor . id ) ;
}
} ,
} ) ;
} ;
const {
mutate : createReportMutation ,
onDone : onCreateReportDone ,
onError : onCreateReportError ,
} = useCreateReport ( ) ;
onCreateReportDone ( ( ) => {
notifier ? . success (
t ( "Event {eventTitle} reported" , { eventTitle : props ? . event ? . title } )
) ;
} ) ;
onCreateReportError ( ( error ) => {
console . error ( error ) ;
} ) ;
const reportEvent = async (
content : string ,
forward : boolean
) : Promise < void > => {
isReportModalActive . value = false ;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
reportModal . value . close ( ) ;
if ( ! organizer . value ) return ;
createReportMutation ( {
eventId : event . value ? . id ? ? "" ,
reportedId : organizer . value ? . id ? ? "" ,
content ,
forward ,
} ) ;
} ;
const maximumAttendeeCapacity = computed ( ( ) : number | undefined => {
return event . value ? . options ? . maximumAttendeeCapacity ;
} ) ;
const eventCapacityOK = computed ( ( ) : boolean => {
if ( event . value ? . draft ) return true ;
if ( ! maximumAttendeeCapacity . value ) return true ;
return (
event . value ? . options ? . maximumAttendeeCapacity !== undefined &&
event . value . participantStats . participant !== undefined &&
event . value ? . options ? . maximumAttendeeCapacity >
event . value . participantStats . participant
) ;
} ) ;
// const numberOfPlacesStillAvailable = computed((): number | undefined => {
// if (event.value?.draft) return maximumAttendeeCapacity.value;
// return (
// (maximumAttendeeCapacity.value ?? 0) -
// (event.value?.participantStats.participant ?? 0)
// );
// });
const {
mutate : leaveEventMutation ,
onDone : onLeaveEventMutationDone ,
onError : onLeaveEventMutationError ,
} = useMutation < { leaveEvent : { actor : { id : string } } } > ( LEAVE _EVENT , ( ) => ( {
update : (
store : ApolloCache < {
leaveEvent : IParticipant ;
} > ,
{ data } : FetchResult ,
{ context , variables }
) => {
if ( data == null ) return ;
let participation ;
const token = context ? . token ;
const actorId = variables ? . actorId ;
const localEventId = variables ? . eventId ;
const eventUUID = context ? . eventUUID ;
const isAnonymousParticipationConfirmed =
context ? . isAnonymousParticipationConfirmed ;
if ( ! token ) {
const participationCachedData = store . readQuery < {
person : IPerson ;
} > ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : localEventId , actorId } ,
} ) ;
if ( participationCachedData == null ) return ;
const { person : cachedPerson } = participationCachedData ;
[ participation ] = cachedPerson ? . participations ? . elements ? ? [ undefined ] ;
store . modify ( {
id : ` Person: ${ actorId } ` ,
fields : {
participations ( ) {
return {
elements : [ ] ,
total : 0 ,
} ;
} ,
} ,
} ) ;
}
const eventCachedData = store . readQuery < { event : IEvent } > ( {
query : FETCH _EVENT ,
variables : { uuid : eventUUID } ,
} ) ;
if ( eventCachedData == null ) return ;
const { event : eventCached } = eventCachedData ;
if ( eventCached === null ) {
console . error ( "Cannot update event cache, because of null value." ) ;
return ;
}
const participantStats = { ... eventCached . participantStats } ;
if ( participation && participation ? . role === ParticipantRole . NOT _APPROVED ) {
participantStats . notApproved -= 1 ;
} else if ( isAnonymousParticipationConfirmed === false ) {
participantStats . notConfirmed -= 1 ;
} else {
participantStats . going -= 1 ;
participantStats . participant -= 1 ;
}
store . writeQuery ( {
query : FETCH _EVENT ,
variables : { uuid : eventUUID } ,
data : {
event : {
... eventCached ,
participantStats ,
} ,
} ,
} ) ;
} ,
} ) ) ;
const leaveEvent = (
eventToLeave : IEvent ,
actorId : string ,
token : string | null = null ,
isAnonymousParticipationConfirmed : boolean | null = null
) : void => {
leaveEventMutation (
{
eventId : eventToLeave . id ,
actorId ,
token ,
} ,
{
context : {
token ,
isAnonymousParticipationConfirmed ,
eventUUID : eventToLeave . uuid ,
} ,
}
) ;
} ;
onLeaveEventMutationDone ( ( { data } ) => {
if ( data ) {
notifier ? . success ( t ( "You have cancelled your participation" ) ) ;
}
} ) ;
const snackbar = inject < Snackbar > ( "snackbar" ) ;
onLeaveEventMutationError ( ( error ) => {
snackbar ? . open ( {
message : error . message ,
variant : "danger" ,
position : "bottom" ,
} ) ;
console . error ( error ) ;
} ) ;
const anonymousParticipationConfirmed = async ( ) : Promise < boolean > => {
return isParticipatingInThisEvent ( props . event ? . uuid ) ;
} ;
const cancelAnonymousParticipation = async ( ) : Promise < void > => {
if ( ! event . value || ! anonymousActorId . value ) return ;
const token = ( await getLeaveTokenForParticipation (
props . event ? . uuid
) ) as string ;
leaveEvent ( event . value , anonymousActorId . value , token ) ;
await removeAnonymousParticipation ( props . event ? . uuid ) ;
anonymousParticipation . value = null ;
} ;
onMounted ( async ( ) => {
identity . value = props . currentActor ;
try {
if ( window . isSecureContext ) {
anonymousParticipation . value = await anonymousParticipationConfirmed ( ) ;
}
} catch ( e ) {
if ( e instanceof AnonymousParticipationNotFoundError ) {
anonymousParticipation . value = null ;
} else {
console . error ( e ) ;
}
}
} ) ;
const {
mutate : deleteEvent ,
onDone : onDeleteEventDone ,
onError : onDeleteEventError ,
} = useDeleteEvent ( ) ;
const escapeRegExp = ( string : string ) => {
return string . replace ( /[.*+?^${}()|[\]\\]/g , "\\$&" ) ; // $& means the whole matched string
} ;
const deleteEventMessage = computed ( ( ) => {
const participantsLength = event . value ? . participantStats . participant ;
const prefix = participantsLength
? t (
"There are {participants} participants." ,
{
participants : event . value . participantStats . participant ,
} ,
event . value . participantStats . participant
)
: "" ;
return ` ${ prefix }
$ { t (
"Are you sure you want to delete this event? This action cannot be reverted."
) }
< br > < br >
$ { t ( 'To confirm, type your event title "{eventTitle}"' , {
eventTitle : event . value ? . title ,
} ) } ` ;
} ) ;
const openDeleteEventModal = ( ) => {
dialog ? . prompt ( {
title : t ( "Delete event" ) ,
message : deleteEventMessage . value ,
confirmText : t ( "Delete event" ) ,
cancelText : t ( "Cancel" ) ,
variant : "danger" ,
hasIcon : true ,
hasInput : true ,
inputAttrs : {
placeholder : event . value ? . title ,
pattern : escapeRegExp ( event . value ? . title ? ? "" ) ,
} ,
onConfirm : ( result : string ) => {
console . debug ( "calling delete event" , result ) ;
if ( result . trim ( ) === event . value ? . title ) {
event . value ? . id ? deleteEvent ( { eventId : event . value ? . id } ) : null ;
}
} ,
} ) ;
} ;
onDeleteEventDone ( ( ) => {
router . push ( { name : RouteName . MY _EVENTS } ) ;
} ) ;
onDeleteEventError ( ( error ) => {
console . error ( error ) ;
} ) ;
< / script >