From 75bd7a3d75a6a387cba6da87de054501a634c147 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 3 Oct 2019 16:54:56 +0200
Subject: [PATCH] Fix edit event cache issues

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/src/graphql/event.ts            | 21 ++++++-
 js/src/types/current-user.model.ts |  3 +-
 js/src/views/Event/Edit.vue        | 97 +++++++++++++++++++++++++++---
 js/src/views/Event/MyEvents.vue    |  3 +
 4 files changed, 115 insertions(+), 9 deletions(-)

diff --git a/js/src/graphql/event.ts b/js/src/graphql/event.ts
index aa1798174..a3a7cd5e9 100644
--- a/js/src/graphql/event.ts
+++ b/js/src/graphql/event.ts
@@ -52,6 +52,7 @@ const optionsQuery = `
   program,
   commentModeration,
   showParticipationPrice
+  __typename
 `;
 
 export const FETCH_EVENT = gql`
@@ -62,7 +63,6 @@ export const FETCH_EVENT = gql`
       url,
       local,
       title,
-      slug,
       description,
       beginsOn,
       endsOn,
@@ -244,6 +244,9 @@ export const CREATE_EVENT = gql`
       },
       options {
         ${optionsQuery}
+      },
+      organizerActor {
+        id
       }
     }
   }
@@ -289,6 +292,8 @@ export const EDIT_EVENT = gql`
       id,
       uuid,
       title,
+      url,
+      local,
       description,
       beginsOn,
       endsOn,
@@ -307,6 +312,20 @@ export const EDIT_EVENT = gql`
       physicalAddress {
         ${physicalAddressQuery}
       },
+      organizerActor {
+        avatar {
+          url
+        },
+        preferredUsername,
+        domain,
+        name,
+        url,
+        id,
+      },
+      participantStats {
+        approved,
+        unapproved
+      },
       tags {
         ${tagsQuery}
       },
diff --git a/js/src/types/current-user.model.ts b/js/src/types/current-user.model.ts
index 257dbc76a..f64387835 100644
--- a/js/src/types/current-user.model.ts
+++ b/js/src/types/current-user.model.ts
@@ -1,4 +1,4 @@
-import { IParticipant } from '@/types/event.model';
+import { IEvent, IParticipant } from '@/types/event.model';
 
 export enum ICurrentUserRole {
   USER = 'USER',
@@ -12,4 +12,5 @@ export interface ICurrentUser {
   isLoggedIn: boolean;
   role: ICurrentUserRole;
   participations: IParticipant[];
+  drafts: IEvent[];
 }
diff --git a/js/src/views/Event/Edit.vue b/js/src/views/Event/Edit.vue
index bb997786f..b5240df7b 100644
--- a/js/src/views/Event/Edit.vue
+++ b/js/src/views/Event/Edit.vue
@@ -1,3 +1,4 @@
+import {ParticipantRole} from "@/types/event.model";
 <template>
   <section>
     <div class="container">
@@ -234,13 +235,15 @@
 import { CREATE_EVENT, EDIT_EVENT, FETCH_EVENT } from '@/graphql/event';
 import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
 import {
-  CommentModeration, EventJoinOptions,
-  EventModel,
-  EventStatus,
-  EventVisibility, IEvent,
-} from '@/types/event.model';
-import { CURRENT_ACTOR_CLIENT } from '@/graphql/actor';
-import { IActor, Person } from '@/types/actor';
+    CommentModeration,
+    EventJoinOptions,
+    EventModel,
+    EventStatus,
+    EventVisibility,
+    IEvent, ParticipantRole,
+  } from '@/types/event.model';
+import { CURRENT_ACTOR_CLIENT, IDENTITIES, LOGGED_USER_DRAFTS, LOGGED_USER_PARTICIPATIONS } from '@/graphql/actor';
+import { Person } from '@/types/actor';
 import PictureUpload from '@/components/PictureUpload.vue';
 import Editor from '@/components/Editor.vue';
 import DateTimePicker from '@/components/Event/DateTimePicker.vue';
@@ -250,6 +253,7 @@ import { ITag } from '@/types/tag.model';
 import AddressAutoComplete from '@/components/Event/AddressAutoComplete.vue';
 import { buildFileFromIPicture, buildFileVariable } from '@/utils/image';
 import IdentityPickerWrapper from '@/views/Account/IdentityPickerWrapper.vue';
+import { ICurrentUser } from '@/types/current-user.model';
 
 @Component({
   components: { IdentityPickerWrapper, AddressAutoComplete, TagInput, DateTimePicker, PictureUpload, Editor },
@@ -361,6 +365,41 @@ export default class EditEvent extends Vue {
       const { data } = await this.$apollo.mutate({
         mutation: CREATE_EVENT,
         variables: this.buildVariables(),
+        update: (store, { data: { createEvent } }) => {
+          if (createEvent.draft) {
+            const data = store.readQuery<{ loggedUser: ICurrentUser }>({ query: LOGGED_USER_DRAFTS, variables: {
+              page: 1,
+              limit: 10,
+            } });
+
+            if (data) {
+              data.loggedUser.drafts.push(createEvent);
+              store.writeQuery({ query: LOGGED_USER_DRAFTS, variables: {
+                page: 1,
+                limit: 10,
+              }, data });
+            }
+          } else {
+            const data = store.readQuery<{ loggedUser: ICurrentUser }>({ query: LOGGED_USER_PARTICIPATIONS, variables: {
+              page: 1,
+              limit: 10,
+              afterDateTime: (new Date()).toISOString(),
+            } });
+
+            if (data) {
+              data.loggedUser.participations.push({
+                role: ParticipantRole.CREATOR,
+                actor: createEvent.organizerActor,
+                event: createEvent,
+              });
+              store.writeQuery({ query: LOGGED_USER_PARTICIPATIONS, variables: {
+                page: 1,
+                limit: 10,
+                afterDateTime: (new Date()).toISOString(),
+              }, data });
+            }
+          }
+        },
       });
 
       console.log('Event created', data);
@@ -379,6 +418,50 @@ export default class EditEvent extends Vue {
       await this.$apollo.mutate({
         mutation: EDIT_EVENT,
         variables: this.buildVariables(),
+        update: (store, { data: { updateEvent } }) => {
+          if (updateEvent.draft) {
+            const data = store.readQuery<{ loggedUser: ICurrentUser }>({ query: LOGGED_USER_DRAFTS, variables: {
+              page: 1,
+              limit: 10,
+            } });
+
+            if (data) {
+              data.loggedUser.drafts.push(updateEvent);
+              store.writeQuery({ query: LOGGED_USER_DRAFTS, data });
+            }
+          } else {
+            let participationData: { loggedUser: ICurrentUser}|null = null;
+            try {
+              participationData = store.readQuery<{ loggedUser: ICurrentUser }>({
+                query: LOGGED_USER_PARTICIPATIONS, variables: {
+                  page: 1,
+                  limit: 10,
+                  afterDateTime: (new Date()).toISOString(),
+                },
+              });
+            } catch (e) {
+              // no worries, it seems we can't update participation cache because it's not linked to an ID
+            }
+
+            if (participationData) {
+              participationData.loggedUser.participations.push({
+                role: ParticipantRole.CREATOR,
+                actor: updateEvent.organizerActor,
+                event: updateEvent,
+              });
+              store.writeQuery({ query: LOGGED_USER_PARTICIPATIONS, variables: {
+                page: 1,
+                limit: 10,
+                afterDateTime: (new Date()).toISOString(),
+              }, data: participationData });
+            }
+            const resultEvent: IEvent = Object.assign({}, updateEvent);
+            resultEvent.organizerActor = this.event.organizerActor;
+            resultEvent.relatedEvents = [];
+
+            store.writeQuery({ query: FETCH_EVENT, variables: { uuid: updateEvent.uuid }, data: { event: resultEvent } });
+          }
+        },
       });
 
       await this.$router.push({
diff --git a/js/src/views/Event/MyEvents.vue b/js/src/views/Event/MyEvents.vue
index 5114bfda0..19e5f4e77 100644
--- a/js/src/views/Event/MyEvents.vue
+++ b/js/src/views/Event/MyEvents.vue
@@ -83,6 +83,7 @@ import EventCard from '@/components/Event/EventCard.vue';
   apollo: {
     futureParticipations: {
       query: LOGGED_USER_PARTICIPATIONS,
+      fetchPolicy: 'network-only',
       variables: {
         page: 1,
         limit: 10,
@@ -92,6 +93,7 @@ import EventCard from '@/components/Event/EventCard.vue';
     },
     drafts: {
       query: LOGGED_USER_DRAFTS,
+      fetchPolicy: 'network-only',
       variables: {
         page: 1,
         limit: 10,
@@ -100,6 +102,7 @@ import EventCard from '@/components/Event/EventCard.vue';
     },
     pastParticipations: {
       query: LOGGED_USER_PARTICIPATIONS,
+      fetchPolicy: 'network-only',
       variables: {
         page: 1,
         limit: 10,