dc52cd042b
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
197 lines
5.7 KiB
TypeScript
197 lines
5.7 KiB
TypeScript
import { mixins } from "vue-class-component";
|
|
import { Component, Vue } from "vue-property-decorator";
|
|
import { SnackbarProgrammatic as Snackbar } from "buefy";
|
|
import { ParticipantRole } from "@/types/enums";
|
|
import { IParticipant } from "../types/participant.model";
|
|
import { IEvent } from "../types/event.model";
|
|
import {
|
|
DELETE_EVENT,
|
|
EVENT_PERSON_PARTICIPATION,
|
|
FETCH_EVENT,
|
|
LEAVE_EVENT,
|
|
} from "../graphql/event";
|
|
import { IPerson } from "../types/actor";
|
|
import { ApolloCache, FetchResult, InMemoryCache } from "@apollo/client/core";
|
|
|
|
@Component
|
|
export default class EventMixin extends mixins(Vue) {
|
|
protected async leaveEvent(
|
|
event: IEvent,
|
|
actorId: string,
|
|
token: string | null = null,
|
|
anonymousParticipationConfirmed: boolean | null = null
|
|
): Promise<void> {
|
|
try {
|
|
const { data: resultData } = await this.$apollo.mutate<{
|
|
leaveEvent: IParticipant;
|
|
}>({
|
|
mutation: LEAVE_EVENT,
|
|
variables: {
|
|
eventId: event.id,
|
|
actorId,
|
|
token,
|
|
},
|
|
update: (
|
|
store: ApolloCache<{
|
|
leaveEvent: IParticipant;
|
|
}>,
|
|
{ data }: FetchResult
|
|
) => {
|
|
if (data == null) return;
|
|
let participation;
|
|
|
|
if (!token) {
|
|
const participationCachedData = store.readQuery<{
|
|
person: IPerson;
|
|
}>({
|
|
query: EVENT_PERSON_PARTICIPATION,
|
|
variables: { eventId: event.id, actorId },
|
|
});
|
|
if (participationCachedData == null) return;
|
|
const { person } = participationCachedData;
|
|
[participation] = person.participations.elements;
|
|
|
|
store.modify({
|
|
id: `Person:${actorId}`,
|
|
fields: {
|
|
participations() {
|
|
return {
|
|
elements: [],
|
|
total: 0,
|
|
};
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
const eventCachedData = store.readQuery<{ event: IEvent }>({
|
|
query: FETCH_EVENT,
|
|
variables: { uuid: event.uuid },
|
|
});
|
|
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 (anonymousParticipationConfirmed === false) {
|
|
participantStats.notConfirmed -= 1;
|
|
} else {
|
|
participantStats.going -= 1;
|
|
participantStats.participant -= 1;
|
|
}
|
|
store.writeQuery({
|
|
query: FETCH_EVENT,
|
|
variables: { uuid: event.uuid },
|
|
data: {
|
|
event: {
|
|
...eventCached,
|
|
participantStats,
|
|
},
|
|
},
|
|
});
|
|
},
|
|
});
|
|
if (resultData) {
|
|
this.participationCancelledMessage();
|
|
}
|
|
} catch (error: any) {
|
|
Snackbar.open({
|
|
message: error.message,
|
|
type: "is-danger",
|
|
position: "is-bottom",
|
|
});
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
private participationCancelledMessage() {
|
|
this.$notifier.success(
|
|
this.$t("You have cancelled your participation") as string
|
|
);
|
|
}
|
|
|
|
protected async openDeleteEventModal(event: IEvent): Promise<void> {
|
|
function escapeRegExp(string: string) {
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
|
}
|
|
const participantsLength = event.participantStats.participant;
|
|
const prefix = participantsLength
|
|
? this.$tc(
|
|
"There are {participants} participants.",
|
|
event.participantStats.participant,
|
|
{
|
|
participants: event.participantStats.participant,
|
|
}
|
|
)
|
|
: "";
|
|
|
|
this.$buefy.dialog.prompt({
|
|
type: "is-danger",
|
|
title: this.$t("Delete event") as string,
|
|
message: `${prefix}
|
|
${this.$t(
|
|
"Are you sure you want to delete this event? This action cannot be reverted."
|
|
)}
|
|
<br><br>
|
|
${this.$t('To confirm, type your event title "{eventTitle}"', {
|
|
eventTitle: event.title,
|
|
})}`,
|
|
confirmText: this.$t("Delete {eventTitle}", {
|
|
eventTitle: event.title,
|
|
}) as string,
|
|
inputAttrs: {
|
|
placeholder: event.title,
|
|
pattern: escapeRegExp(event.title),
|
|
},
|
|
onConfirm: () => this.deleteEvent(event),
|
|
});
|
|
}
|
|
|
|
private async deleteEvent(event: IEvent) {
|
|
const { title: eventTitle, id: eventId } = event;
|
|
|
|
try {
|
|
await this.$apollo.mutate<IParticipant>({
|
|
mutation: DELETE_EVENT,
|
|
variables: {
|
|
eventId: event.id,
|
|
},
|
|
});
|
|
const cache = this.$apollo.getClient().cache as InMemoryCache;
|
|
cache.evict({ id: `Event:${eventId}` });
|
|
cache.gc();
|
|
/**
|
|
* When the event corresponding has been deleted (by the organizer).
|
|
* A notification is already triggered.
|
|
*
|
|
* @type {string}
|
|
*/
|
|
this.$emit("event-deleted", event.id);
|
|
|
|
this.$buefy.notification.open({
|
|
message: this.$t("Event {eventTitle} deleted", {
|
|
eventTitle,
|
|
}) as string,
|
|
type: "is-success",
|
|
position: "is-bottom-right",
|
|
duration: 5000,
|
|
});
|
|
} catch (error: any) {
|
|
Snackbar.open({
|
|
message: error.message,
|
|
type: "is-danger",
|
|
position: "is-bottom",
|
|
});
|
|
|
|
console.error(error);
|
|
}
|
|
}
|
|
}
|