Handle errors better

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2019-10-13 13:56:24 +02:00
parent 57f0b5dad1
commit 33e51a05ec
13 changed files with 214 additions and 78 deletions

View File

@@ -385,6 +385,14 @@ export default class EditEvent extends Vue {
refetchQueries: ({ data: { createEvent } }) => this.postRefetchQueries(createEvent),
});
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,
});
await this.$router.push({
name: 'Event',
params: { uuid: data.createEvent.uuid },
@@ -403,6 +411,12 @@ export default class EditEvent extends Vue {
refetchQueries: ({ data: { updateEvent } }) => this.postRefetchQueries(updateEvent),
});
this.$buefy.notification.open({
message: this.updateEventMessage,
type: 'is-success',
position: 'is-bottom-right',
duration: 5000,
});
await this.$router.push({
name: 'Event',
params: { uuid: this.eventId as string },
@@ -412,6 +426,11 @@ export default class EditEvent extends Vue {
}
}
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;
}
/**
* Put in cache the updated or created event.
* If the event is not a draft anymore, also put in cache the participation

View File

@@ -54,7 +54,7 @@ import {ParticipantRole} from "@/types/event.model";
</div>
<div class="metadata columns">
<div class="column is-three-quarters-desktop">
<p class="tags" v-if="event.tags.length > 0">
<p class="tags">
<b-tag type="is-warning" size="is-medium" v-if="event.draft">{{ $t('Draft') }}</b-tag>
<span class="event-status" v-if="event.status !== EventStatus.CONFIRMED">
<b-tag type="is-warning" v-if="event.status === EventStatus.TENTATIVE">{{ $t('Event to be confirmed') }}</b-tag>
@@ -64,7 +64,7 @@ import {ParticipantRole} from "@/types/event.model";
<b-tag type="is-info" v-if="event.visibility === EventVisibility.PUBLIC">{{ $t('Public event') }}</b-tag>
<b-tag type="is-info" v-if="event.visibility === EventVisibility.UNLISTED">{{ $t('Private event') }}</b-tag>
</span>
<b-tag type="is-success" v-if="event.tags" v-for="tag in event.tags" :key="tag.title">{{ tag.title }}</b-tag>
<b-tag type="is-success" v-if="event.tags && event.tags.length > 0" v-for="tag in event.tags" :key="tag.title">{{ tag.title }}</b-tag>
<span v-if="event.tags > 0"></span>
</p>
<div class="date-and-add-to-calendar">
@@ -488,7 +488,7 @@ export default class Event extends EventMixin {
}
async handleErrors(errors: GraphQLError) {
if (errors[0].message.includes('not found')) {
if (errors[0].message.includes('not found') || errors[0].message.includes('has invalid value $uuid')) {
await this.$router.push({ name: RouteName.PAGE_NOT_FOUND });
}
}

View File

@@ -1,6 +1,9 @@
import {ParticipantRole} from "@/types/event.model";
import {ParticipantRole} from "@/types/event.model";
import {ParticipantRole} from "@/types/event.model";
<template>
<main class="container">
<b-tabs type="is-boxed" v-if="event">
<b-tabs type="is-boxed" v-if="event" v-model="activeTab">
<b-tab-item>
<template slot="header">
<b-icon icon="account-multiple"></b-icon>
@@ -69,9 +72,9 @@
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { IEvent, IParticipant, Participant, ParticipantRole } from '@/types/event.model';
import { UPDATE_PARTICIPANT, PARTICIPANTS } from '@/graphql/event';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { IEvent, IEventParticipantStats, IParticipant, Participant, ParticipantRole } from '@/types/event.model';
import { PARTICIPANTS, UPDATE_PARTICIPANT } from '@/graphql/event';
import ParticipantCard from '@/components/Account/ParticipantCard.vue';
import { CURRENT_ACTOR_CLIENT } from '@/graphql/actor';
import { IPerson } from '@/types/actor';
@@ -96,6 +99,9 @@ import { IPerson } from '@/types/actor';
actorId: this.currentActor.id,
};
},
skip() {
return !this.currentActor.id;
},
},
organizers: {
query: PARTICIPANTS,
@@ -109,6 +115,9 @@ import { IPerson } from '@/types/actor';
};
},
update: data => data.event.participants.map(participation => new Participant(participation)),
skip() {
return !this.currentActor.id;
},
},
queue: {
query: PARTICIPANTS,
@@ -122,6 +131,9 @@ import { IPerson } from '@/types/actor';
};
},
update: data => data.event.participants.map(participation => new Participant(participation)),
skip() {
return !this.currentActor.id;
},
},
rejected: {
query: PARTICIPANTS,
@@ -135,6 +147,9 @@ import { IPerson } from '@/types/actor';
};
},
update: data => data.event.participants.map(participation => new Participant(participation)),
skip() {
return !this.currentActor.id;
},
},
},
})
@@ -143,7 +158,6 @@ export default class Participants extends Vue {
page: number = 1;
limit: number = 10;
// participants: IParticipant[] = [];
organizers: IParticipant[] = [];
queue: IParticipant[] = [];
rejected: IParticipant[] = [];
@@ -153,22 +167,29 @@ export default class Participants extends Vue {
currentActor!: IPerson;
hasMoreParticipants: boolean = false;
activeTab: number = 0;
get participants(): IParticipant[] {
return this.event.participants.map(participant => new Participant(participant));
}
get participantStats(): Object {
get participantStats(): IEventParticipantStats | null {
if (!this.event) return null;
return this.event.participantStats;
}
get participantsAndCreators(): IParticipant[] {
if (this.event) {
return [...this.organizers, ...this.participants];
return [...this.organizers, ...this.event.participants]
.filter(participant => [ParticipantRole.PARTICIPANT, ParticipantRole.CREATOR].includes(participant.role));
}
return [];
}
@Watch('participantStats', { deep: true })
watchParticipantStats(stats: IEventParticipantStats) {
if (!stats) return;
if ((stats.unapproved === 0 && this.activeTab === 1) || stats.rejected === 0 && this.activeTab === 2 ) {
this.activeTab = 0;
}
}
loadMoreParticipants() {
this.page += 1;
this.$apollo.queries.participants.fetchMore({
@@ -203,9 +224,17 @@ export default class Participants extends Vue {
},
});
if (data) {
this.queue.filter(participant => participant !== data.updateParticipation.id);
this.rejected.filter(participant => participant !== data.updateParticipation.id);
this.participants.push(participant);
this.queue = this.queue.filter(participant => participant.id !== data.updateParticipation.id);
this.rejected = this.rejected.filter(participant => participant.id !== data.updateParticipation.id);
this.event.participantStats.approved += 1;
if (participant.role === ParticipantRole.NOT_APPROVED) {
this.event.participantStats.unapproved -= 1;
}
if (participant.role === ParticipantRole.REJECTED) {
this.event.participantStats.rejected -= 1;
}
participant.role = ParticipantRole.PARTICIPANT;
this.event.participants.push(participant);
}
} catch (e) {
console.error(e);
@@ -223,8 +252,18 @@ export default class Participants extends Vue {
},
});
if (data) {
this.participants.filter(participant => participant !== data.updateParticipation.id);
this.queue.filter(participant => participant !== data.updateParticipation.id);
this.event.participants = this.event.participants.filter(participant => participant.id !== data.updateParticipation.id);
this.queue = this.queue.filter(participant => participant.id !== data.updateParticipation.id);
this.event.participantStats.rejected += 1;
if (participant.role === ParticipantRole.PARTICIPANT) {
this.event.participantStats.participants -= 1;
this.event.participantStats.approved -= 1;
}
if (participant.role === ParticipantRole.NOT_APPROVED) {
this.event.participantStats.unapproved -= 1;
}
participant.role = ParticipantRole.REJECTED;
this.rejected = this.rejected.filter(participantIn => participantIn.id !== participant.id);
this.rejected.push(participant);
}
} catch (e) {