From b5a5de5c0c3d0bf575e9a0da14a0267b04dc22ec Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 17 May 2021 09:38:04 +0200 Subject: [PATCH] Event edit and participant fixes Signed-off-by: Thomas Citharel --- js/src/apollo/utils.ts | 39 ++++++++++---- js/src/graphql/comment.ts | 1 + js/src/types/event.model.ts | 14 ++++- js/src/views/Event/Edit.vue | 80 ++++++----------------------- js/src/views/Event/Participants.vue | 63 +++++++++++++++++------ lib/graphql/resolvers/event.ex | 3 ++ 6 files changed, 110 insertions(+), 90 deletions(-) diff --git a/js/src/apollo/utils.ts b/js/src/apollo/utils.ts index 0e3ed7f51..7486c0961 100644 --- a/js/src/apollo/utils.ts +++ b/js/src/apollo/utils.ts @@ -1,6 +1,7 @@ import { AUTH_ACCESS_TOKEN, AUTH_REFRESH_TOKEN } from "@/constants"; import { REFRESH_TOKEN } from "@/graphql/auth"; import { IFollower } from "@/types/actor/follower.model"; +import { IParticipant } from "@/types/participant.model"; import { Paginate } from "@/types/paginate"; import { saveTokenData } from "@/utils/auth"; import { @@ -11,6 +12,9 @@ import { TypePolicies, } from "@apollo/client/core"; import introspectionQueryResultData from "../../fragmentTypes.json"; +import { IMember } from "@/types/actor/member.model"; +import { IComment } from "@/types/comment.model"; +import { IEvent } from "@/types/event.model"; type possibleTypes = { name: string }; type schemaType = { @@ -31,19 +35,34 @@ export const possibleTypes = types.reduce((acc, type) => { export const typePolicies: TypePolicies = { Discussion: { fields: { - comments: pageLimitPagination(), + comments: paginatedLimitPagination(), }, }, Group: { fields: { - organizedEvents: pageLimitPagination(["afterDatetime", "beforeDatetime"]), + organizedEvents: paginatedLimitPagination([ + "afterDatetime", + "beforeDatetime", + ]), }, }, Person: { fields: { organizedEvents: pageLimitPagination(), - participations: pageLimitPagination(["eventId"]), - memberships: pageLimitPagination(["group"]), + participations: paginatedLimitPagination(["eventId"]), + memberships: paginatedLimitPagination(["group"]), + }, + }, + Event: { + fields: { + participants: paginatedLimitPagination(["roles"]), + commnents: pageLimitPagination(), + relatedEvents: pageLimitPagination(), + }, + }, + Comment: { + fields: { + replies: pageLimitPagination(), }, }, RootQueryType: { @@ -53,15 +72,15 @@ export const typePolicies: TypePolicies = { "orderBy", "direction", ]), - events: pageLimitPagination(), - groups: pageLimitPagination([ + events: paginatedLimitPagination(), + groups: paginatedLimitPagination([ "preferredUsername", "name", "domain", "local", "suspended", ]), - persons: pageLimitPagination([ + persons: paginatedLimitPagination([ "preferredUsername", "name", "domain", @@ -103,12 +122,12 @@ type KeyArgs = FieldPolicy["keyArgs"]; export function pageLimitPagination( keyArgs: KeyArgs = false ): FieldPolicy { - console.log("pageLimitPagination"); return { keyArgs, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore merge(existing, incoming, { args }) { + console.log("pageLimitPagination"); console.log("existing", existing); console.log("incoming", incoming); // console.log("args", args); @@ -123,12 +142,14 @@ export function pageLimitPagination( export function paginatedLimitPagination>( keyArgs: KeyArgs = false ): FieldPolicy> { - console.log("paginatedLimitPagination"); return { keyArgs, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore merge(existing, incoming, { args }) { + console.log("paginatedLimitPagination"); + console.log("existing", existing); + console.log("incoming", incoming); if (!incoming) return existing; if (!existing) return incoming; // existing will be empty the first time diff --git a/js/src/graphql/comment.ts b/js/src/graphql/comment.ts index ce4b2ce2e..8ef20812c 100644 --- a/js/src/graphql/comment.ts +++ b/js/src/graphql/comment.ts @@ -21,6 +21,7 @@ export const COMMENT_FIELDS_FRAGMENT = gql` summary } totalReplies + insertedAt updatedAt deletedAt } diff --git a/js/src/types/event.model.ts b/js/src/types/event.model.ts index e67b107f6..3dcf496e0 100644 --- a/js/src/types/event.model.ts +++ b/js/src/types/event.model.ts @@ -42,6 +42,7 @@ interface IEventEditJSON { draft: boolean; picture?: IMedia | { mediaId: string } | null; attributedToId: string | null; + organizerActorId?: string; onlineAddress?: string; phoneAddress?: string; physicalAddress?: IAddress; @@ -209,8 +210,8 @@ export class EventModel implements IEvent { tags: this.tags.map((t) => t.title), onlineAddress: this.onlineAddress, phoneAddress: this.phoneAddress, - physicalAddress: this.physicalAddress, - options: this.options, + physicalAddress: this.removeTypeName(this.physicalAddress), + options: this.removeTypeName(this.options), attributedToId: this.attributedTo && this.attributedTo.id ? this.attributedTo.id : null, contacts: this.contacts.map(({ id }) => ({ @@ -218,4 +219,13 @@ export class EventModel implements IEvent { })), }; } + + 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; + } } diff --git a/js/src/views/Event/Edit.vue b/js/src/views/Event/Edit.vue index 95460777e..88e4d3fc3 100644 --- a/js/src/views/Event/Edit.vue +++ b/js/src/views/Event/Edit.vue @@ -486,6 +486,7 @@ import "intersection-observer"; import { CONFIG } from "../../graphql/config"; import { IConfig } from "../../types/config.model"; import { ApolloCache, FetchResult, InMemoryCache } from "@apollo/client/core"; +import { cloneDeep } from "@apollo/client/utilities"; const DEFAULT_LIMIT_NUMBER_OF_PLACES = 10; @@ -512,7 +513,7 @@ const DEFAULT_LIMIT_NUMBER_OF_PLACES = 10; }; }, update(data) { - return new EventModel(data.event); + return new EventModel(cloneDeep(data.event)); }, skip() { return !this.eventId; @@ -547,8 +548,6 @@ export default class EditEvent extends Vue { config!: IConfig; - unmodifiedEvent!: IEvent; - pictureFile: File | null = null; EventStatus = EventStatus; @@ -646,7 +645,11 @@ export default class EditEvent extends Vue { if (!(this.isUpdate || this.isDuplicate)) { this.initializeEvent(); } else { - this.event.description = this.event.description || ""; + this.event = { + ...this.event, + options: this.event.options, + description: this.event.description || "", + }; } } @@ -669,27 +672,6 @@ export default class EditEvent extends Vue { } } - @Watch("event") - setInitialData(): void { - if ( - this.isUpdate && - this.unmodifiedEvent === undefined && - this.event && - this.event.uuid - ) { - this.unmodifiedEvent = JSON.parse( - JSON.stringify(this.event.toEditJSON()) - ); - } - } - - // @Watch('event.attributedTo', { deep: true }) - // updateHideOrganizerWhenGroupEventOption(attributedTo) { - // if (!attributedTo.preferredUsername) { - // this.event.options.hideOrganizerWhenGroupEvent = false; - // } - // } - private validateForm() { const form = this.$refs.form as HTMLFormElement; if (form.checkValidity()) { @@ -777,8 +759,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") @@ -884,24 +866,12 @@ export default class EditEvent extends Vue { ? this.event.organizerActor : this.organizerActor; if (organizerActor) { - res = Object.assign(res, { - organizerActorId: organizerActor.id, - }); + res = { ...res, organizerActorId: organizerActor?.id }; } const attributedToId = this.event.attributedTo?.id ? this.event.attributedTo.id : null; - res = Object.assign(res, { attributedToId }); - - // eslint-disable-next-line - // @ts-ignore - delete this.event.options.__typename; - - if (this.event.physicalAddress) { - // eslint-disable-next-line - // @ts-ignore - delete this.event.physicalAddress.__typename; - } + res = { ...res, attributedToId }; if (this.endsOnNull) { res.endsOn = null; @@ -931,25 +901,6 @@ export default class EditEvent extends Vue { return res; } - private async getEvent() { - const result = await this.$apollo.query({ - query: FETCH_EVENT, - variables: { - uuid: this.eventId, - }, - }); - - if (result.data.event.endsOn === null) { - this.endsOnNull = true; - } - // 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 = ""; - } - return new EventModel(result.data.event); - } - @Watch("limitedPlaces") updatedEventCapacityOptions(limitedPlaces: boolean): void { if (!limitedPlaces) { @@ -1023,10 +974,11 @@ export default class EditEvent extends Vue { } get isEventModified(): boolean { - return ( - JSON.stringify(this.event.toEditJSON()) !== - JSON.stringify(this.unmodifiedEvent) - ); + // return ( + // JSON.stringify(this.event.toEditJSON()) !== + // JSON.stringify(this.unmodifiedEvent) + // ); + return false; } get beginsOn(): Date { diff --git a/js/src/views/Event/Participants.vue b/js/src/views/Event/Participants.vue index 7f48fb050..47e1ac9a7 100644 --- a/js/src/views/Event/Participants.vue +++ b/js/src/views/Event/Participants.vue @@ -30,8 +30,8 @@

{{ $t("Participants") }}

- -