diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json index 0615a1480..a4447f023 100644 --- a/js/src/i18n/fr_FR.json +++ b/js/src/i18n/fr_FR.json @@ -99,7 +99,7 @@ "Are you sure you want to delete this event? This action cannot be undone. You may want to engage the discussion with the event creator or edit its event instead.": "Êtes-vous certain⋅e de vouloir supprimer cet événement ? Cette action n'est pas réversible. Vous voulez peut-être engager la discussion avec le créateur de l'événement ou bien modifier son événement à la place.", "Are you sure you want to suspend this group? All members - including remote ones - will be notified and removed from the group, and all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed.": "Êtes-vous certain·e de vouloir suspendre ce groupe ? Tous les membres - y compris ceux·elles sur d'autres instances - seront notifié·e·s et supprimé·e·s du groupe, et toutes les données associées au groupe (événements, billets, discussions, todos…) seront irrémédiablement détruites.", "Are you sure you want to suspend this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.": "Êtes-vous certain·e de vouloir suspendre ce groupe ? Comme ce groupe provient de l'instance {instance}, cela supprimera seulement les membres locaux et supprimera les données locales, et rejettera également toutes les données futures.", - "Are you sure you want to cancel the event creation? You'll lose all modifications.": "Étes-vous certain⋅e de vouloir annuler la création de l'événement ? Vous allez perdre toutes vos modifications.", + "Are you sure you want to cancel the event creation? You'll lose all modifications.": "Êtes-vous certain⋅e de vouloir annuler la création de l'événement ? Vous allez perdre toutes vos modifications.", "Are you sure you want to cancel the event edition? You'll lose all modifications.": "Êtes-vous certain⋅e de vouloir annuler la modification de l'événement ? Vous allez perdre toutes vos modifications.", "Are you sure you want to cancel your participation at event \"{title}\"?": "Êtes-vous certain⋅e de vouloir annuler votre participation à l'événement « {title} » ?", "Are you sure you want to delete this entire discussion?": "Êtes-vous certain⋅e de vouloir supprimer l'entièreté de cette discussion ?", diff --git a/js/src/main.ts b/js/src/main.ts index 2ace9af59..cae711f1a 100644 --- a/js/src/main.ts +++ b/js/src/main.ts @@ -1,5 +1,3 @@ -// The Vue build version to load with the `import` command -// (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from "vue"; import Buefy from "buefy"; import Component from "vue-class-component"; diff --git a/js/src/types/event.model.ts b/js/src/types/event.model.ts index eb3c02469..c724e0aa3 100644 --- a/js/src/types/event.model.ts +++ b/js/src/types/event.model.ts @@ -203,41 +203,47 @@ export class EventModel implements IEvent { } toEditJSON(): IEventEditJSON { - return { - id: this.id, - title: this.title, - description: this.description, - beginsOn: this.beginsOn.toISOString(), - endsOn: this.endsOn ? this.endsOn.toISOString() : null, - status: this.status, - visibility: this.visibility, - joinOptions: this.joinOptions, - draft: this.draft, - tags: this.tags.map((t) => t.title), - onlineAddress: this.onlineAddress, - phoneAddress: this.phoneAddress, - physicalAddress: this.removeTypeName(this.physicalAddress), - options: this.removeTypeName(this.options), - metadata: this.metadata.map(({ key, value, type, title }) => ({ - key, - value, - type, - title, - })), - attributedToId: - this.attributedTo && this.attributedTo.id ? this.attributedTo.id : null, - contacts: this.contacts.map(({ id }) => ({ - id, - })), - }; - } - - private removeTypeName(entity: any): any { - if (entity?.__typename) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { __typename, ...purgedEntity } = entity; - return purgedEntity; - } - return entity; + return toEditJSON(this); } } + +function removeTypeName(entity: any): any { + if (entity?.__typename) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { __typename, ...purgedEntity } = entity; + return purgedEntity; + } + return entity; +} + +export function toEditJSON(event: IEvent): IEventEditJSON { + return { + id: event.id, + title: event.title, + description: event.description, + beginsOn: event.beginsOn.toISOString(), + endsOn: event.endsOn ? event.endsOn.toISOString() : null, + status: event.status, + visibility: event.visibility, + joinOptions: event.joinOptions, + draft: event.draft, + tags: event.tags.map((t) => t.title), + onlineAddress: event.onlineAddress, + phoneAddress: event.phoneAddress, + physicalAddress: removeTypeName(event.physicalAddress), + options: removeTypeName(event.options), + metadata: event.metadata.map(({ key, value, type, title }) => ({ + key, + value, + type, + title, + })), + attributedToId: + event.attributedTo && event.attributedTo.id + ? event.attributedTo.id + : null, + contacts: event.contacts.map(({ id }) => ({ + id, + })), + }; +} diff --git a/js/src/views/Event/Edit.vue b/js/src/views/Event/Edit.vue index eaacac57b..8cb7fdffc 100644 --- a/js/src/views/Event/Edit.vue +++ b/js/src/views/Event/Edit.vue @@ -463,7 +463,7 @@ import FullAddressAutoComplete from "@/components/Event/FullAddressAutoComplete. import EventMetadataList from "@/components/Event/EventMetadataList.vue"; import IdentityPickerWrapper from "@/views/Account/IdentityPickerWrapper.vue"; import Subtitle from "@/components/Utils/Subtitle.vue"; -import { Route } from "vue-router"; +import { RawLocation, Route } from "vue-router"; import { formatList } from "@/utils/i18n"; import { ActorType, @@ -481,7 +481,7 @@ import { EVENT_PERSON_PARTICIPATION, FETCH_EVENT, } from "../../graphql/event"; -import { EventModel, IEvent } from "../../types/event.model"; +import { EventModel, IEvent, toEditJSON } from "../../types/event.model"; import { CURRENT_ACTOR_CLIENT, IDENTITIES, @@ -586,6 +586,8 @@ export default class EditEvent extends Vue { event: IEvent = new EventModel(); + unmodifiedEvent: IEvent = new EventModel(); + identities: IActor[] = []; person!: IPerson; @@ -687,12 +689,13 @@ export default class EditEvent extends Vue { if (!(this.isUpdate || this.isDuplicate)) { this.initializeEvent(); } else { - this.event = { + this.event = new EventModel({ ...this.event, options: cloneDeep(this.event.options), description: this.event.description || "", - }; + }); } + this.unmodifiedEvent = cloneDeep(this.event); } createOrUpdateDraft(e: Event): void { @@ -813,8 +816,8 @@ 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; + 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") @@ -910,7 +913,7 @@ export default class EditEvent extends Vue { * Build variables for Event GraphQL creation query */ private async buildVariables() { - let res = new EventModel(this.event).toEditJSON(); + let res = toEditJSON(new EventModel(this.event)); const organizerActor = this.event.organizerActor?.id ? this.event.organizerActor : this.organizerActor; @@ -984,10 +987,12 @@ export default class EditEvent extends Vue { /** * Confirm cancel */ - confirmGoElsewhere(callback: () => any): void { - if (!this.isEventModified) { - callback(); - } + confirmGoElsewhere(): Promise { + // TODO: Make calculation of changes work again and bring this back + // If the event wasn't modified, no need to warn + // if (!this.isEventModified) { + // return Promise.resolve(true); + // } const title: string = this.isUpdate ? (this.$t("Cancel edition") as string) : (this.$t("Cancel creation") as string); @@ -1001,14 +1006,17 @@ export default class EditEvent extends Vue { { title: this.event.title } ) as string); - this.$buefy.dialog.confirm({ - title, - message, - confirmText: this.$t("Abandon editing") as string, - cancelText: this.$t("Continue editing") as string, - type: "is-warning", - hasIcon: true, - onConfirm: callback, + return new Promise((resolve) => { + this.$buefy.dialog.confirm({ + title, + message, + confirmText: this.$t("Abandon editing") as string, + cancelText: this.$t("Continue editing") as string, + type: "is-warning", + hasIcon: true, + onConfirm: () => resolve(true), + onCancel: () => resolve(false), + }); }); } @@ -1016,21 +1024,29 @@ export default class EditEvent extends Vue { * Confirm cancel */ confirmGoBack(): void { - this.confirmGoElsewhere(() => this.$router.go(-1)); + this.$router.go(-1); } // eslint-disable-next-line consistent-return - beforeRouteLeave(to: Route, from: Route, next: () => void): void { + async beforeRouteLeave( + to: Route, + from: Route, + next: (to?: RawLocation | false | ((vm: any) => void)) => void + ): Promise { if (to.name === RouteName.EVENT) return next(); - this.confirmGoElsewhere(() => next()); + if (await this.confirmGoElsewhere()) { + return next(); + } + return next(false); } get isEventModified(): boolean { - // return ( - // JSON.stringify(this.event.toEditJSON()) !== - // JSON.stringify(this.unmodifiedEvent) - // ); - return false; + return ( + this.event && + this.unmodifiedEvent && + JSON.stringify(toEditJSON(this.event)) !== + JSON.stringify(this.unmodifiedEvent) + ); } get beginsOn(): Date {