From 2e67c423db7d53082fb23cde0fbe8a8ad6da2bd3 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 1 Oct 2020 15:57:07 +0200
Subject: [PATCH] Fix group event list

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 js/src/components/Event/EventListViewCard.vue | 10 ++++---
 js/src/components/Post/PostElementItem.vue    |  5 +++-
 js/src/graphql/group.ts                       |  6 ++++
 js/src/i18n/en_US.json                        |  4 ++-
 js/src/i18n/fr_FR.json                        |  4 ++-
 js/src/types/event.model.ts                   |  1 +
 js/src/views/Event/EventList.vue              |  4 +--
 js/src/views/Event/GroupEvents.vue            | 29 +++++++++++++++++--
 js/src/views/Group/Group.vue                  | 15 +++++++++-
 js/src/views/Posts/List.vue                   |  3 +-
 10 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/js/src/components/Event/EventListViewCard.vue b/js/src/components/Event/EventListViewCard.vue
index aed279d58..be744e239 100644
--- a/js/src/components/Event/EventListViewCard.vue
+++ b/js/src/components/Event/EventListViewCard.vue
@@ -14,10 +14,11 @@
           <span v-if="event.physicalAddress && event.physicalAddress.locality">
             {{ event.physicalAddress.locality }}
           </span>
-          <span>
-            <span>
-              {{ $t("Organized by {name}", { name: usernameWithDomain(event.organizerActor) }) }}
-            </span>
+          <span v-if="event.attributedTo && options.memberofGroup">
+            {{ $t("Created by {name}", { name: usernameWithDomain(event.organizerActor) }) }}
+          </span>
+          <span v-else-if="options.memberofGroup">
+            {{ $t("Organized by {name}", { name: usernameWithDomain(event.organizerActor) }) }}
           </span>
         </div>
         <div class="columns">
@@ -65,6 +66,7 @@ const defaultOptions: IEventCardOptions = {
   loggedPerson: false,
   hideDetails: false,
   organizerActor: null,
+  memberofGroup: false,
 };
 
 @Component({
diff --git a/js/src/components/Post/PostElementItem.vue b/js/src/components/Post/PostElementItem.vue
index 6a76998c7..79c1a26f4 100644
--- a/js/src/components/Post/PostElementItem.vue
+++ b/js/src/components/Post/PostElementItem.vue
@@ -15,7 +15,10 @@
           <p class="post-minimalist-title">{{ post.title }}</p>
           <div class="metadata">
             <b-tag type="is-warning" size="is-small" v-if="post.draft">{{ $t("Draft") }}</b-tag>
-            <small v-if="post.visibility === PostVisibility.PUBLIC" class="has-text-grey">
+            <small
+              v-if="post.visibility === PostVisibility.PUBLIC && isCurrentActorMember"
+              class="has-text-grey"
+            >
               <b-icon icon="earth" size="is-small" />{{ $t("Public") }}</small
             >
             <small v-else-if="post.visibility === PostVisibility.UNLISTED" class="has-text-grey">
diff --git a/js/src/graphql/group.ts b/js/src/graphql/group.ts
index a87f30127..e09d34a1d 100644
--- a/js/src/graphql/group.ts
+++ b/js/src/graphql/group.ts
@@ -96,6 +96,12 @@ export const GROUP_FIELDS_FRAGMENTS = gql`
           participant
           notApproved
         }
+        attributedTo {
+          id
+          preferredUsername
+          name
+          domain
+        }
         organizerActor {
           id
           preferredUsername
diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json
index 2d74e9cee..dbbd5480d 100644
--- a/js/src/i18n/en_US.json
+++ b/js/src/i18n/en_US.json
@@ -782,5 +782,7 @@
   "Join group": "Join group",
   "Created by {username}": "Created by {username}",
   "Accessible through link": "Accessible through link",
-  "Accessible only to members": "Accessible only to members"
+  "Accessible only to members": "Accessible only to members",
+  "Created by {name}": "Created by {name}",
+  "View all posts": "View all posts"
 }
diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json
index 89b27dcf1..d25f1203d 100644
--- a/js/src/i18n/fr_FR.json
+++ b/js/src/i18n/fr_FR.json
@@ -819,5 +819,7 @@
   "Join group": "Rejoindre le groupe",
   "Created by {username}": "Créé par {username}",
   "Accessible through link": "Accessible uniquement par lien",
-  "Accessible only to members": "Accessible uniquement aux membres"
+  "Accessible only to members": "Accessible uniquement aux membres",
+  "Created by {name}": "Créé par {name}",
+  "View all posts": "Voir tous les billets"
 }
diff --git a/js/src/types/event.model.ts b/js/src/types/event.model.ts
index 09fb2998a..d357c5d3a 100644
--- a/js/src/types/event.model.ts
+++ b/js/src/types/event.model.ts
@@ -53,6 +53,7 @@ export interface IEventCardOptions {
   loggedPerson: IPerson | boolean;
   hideDetails: boolean;
   organizerActor: IActor | null;
+  memberofGroup: boolean;
 }
 
 export interface IParticipant {
diff --git a/js/src/views/Event/EventList.vue b/js/src/views/Event/EventList.vue
index c412dab9c..1b9ddc293 100644
--- a/js/src/views/Event/EventList.vue
+++ b/js/src/views/Event/EventList.vue
@@ -17,13 +17,11 @@
 </template>
 
 <script lang="ts">
-import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { Component, Prop, Vue } from "vue-property-decorator";
 import EventCard from "../../components/Event/EventCard.vue";
 import RouteName from "../../router/name";
 import { IEvent } from "../../types/event.model";
 
-const ngeohash = require("ngeohash");
-
 @Component({
   components: {
     EventCard,
diff --git a/js/src/views/Event/GroupEvents.vue b/js/src/views/Event/GroupEvents.vue
index 5395edc0b..13248b764 100644
--- a/js/src/views/Event/GroupEvents.vue
+++ b/js/src/views/Event/GroupEvents.vue
@@ -26,7 +26,7 @@
       <h1 class="title" v-if="group">
         {{ $t("{group}'s events", { group: group.name || group.preferredUsername }) }}
       </h1>
-      <p>
+      <p v-if="isCurrentActorMember">
         {{
           $t(
             "When someone from the group creates an event and attributes it to the group, it will show up here."
@@ -44,6 +44,7 @@
             v-for="event in group.organizedEvents.elements"
             :key="event.id"
             :event="event"
+            :options="{ memberofGroup: isCurrentActorMember }"
           />
         </transition-group>
         <b-message
@@ -62,10 +63,25 @@ import { FETCH_GROUP } from "@/graphql/group";
 import RouteName from "@/router/name";
 import Subtitle from "@/components/Utils/Subtitle.vue";
 import EventListViewCard from "@/components/Event/EventListViewCard.vue";
-import { IGroup, usernameWithDomain } from "../../types/actor";
+import { CURRENT_ACTOR_CLIENT, PERSON_MEMBERSHIPS } from "@/graphql/actor";
+import { IGroup, IMember, IPerson, usernameWithDomain } from "../../types/actor";
 
 @Component({
   apollo: {
+    currentActor: CURRENT_ACTOR_CLIENT,
+    memberships: {
+      query: PERSON_MEMBERSHIPS,
+      fetchPolicy: "cache-and-network",
+      variables() {
+        return {
+          id: this.currentActor.id,
+        };
+      },
+      update: (data) => data.person.memberships.elements,
+      skip() {
+        return !this.currentActor || !this.currentActor.id;
+      },
+    },
     group: {
       query: FETCH_GROUP,
       variables() {
@@ -85,10 +101,19 @@ import { IGroup, usernameWithDomain } from "../../types/actor";
 export default class GroupEvents extends Vue {
   group!: IGroup;
 
+  memberships!: IMember[];
+
+  currentActor!: IPerson;
+
   usernameWithDomain = usernameWithDomain;
 
   RouteName = RouteName;
 
   showPassedEvents = false;
+
+  get isCurrentActorMember(): boolean {
+    if (!this.group || !this.memberships) return false;
+    return this.memberships.map(({ parent: { id } }) => id).includes(this.group.id);
+  }
 }
 </script>
diff --git a/js/src/views/Group/Group.vue b/js/src/views/Group/Group.vue
index 2c335c3e5..093bb781b 100644
--- a/js/src/views/Group/Group.vue
+++ b/js/src/views/Group/Group.vue
@@ -286,7 +286,13 @@
             :key="event.uuid"
             class="organized-event"
           />
-          <router-link :to="{}">{{ $t("View all upcoming events") }}</router-link>
+          <router-link
+            :to="{
+              name: RouteName.GROUP_EVENTS,
+              params: { preferredUsername: usernameWithDomain(group) },
+            }"
+            >{{ $t("View all upcoming events") }}</router-link
+          >
         </div>
         <span v-else-if="group">{{ $t("No public upcoming events") }}</span>
         <b-skeleton animated v-else></b-skeleton>
@@ -295,6 +301,13 @@
         <subtitle>{{ $t("Latest posts") }}</subtitle>
         <div v-if="group.posts.total > 0" class="posts-wrapper">
           <post-list-item v-for="post in group.posts.elements" :key="post.id" :post="post" />
+          <router-link
+            :to="{
+              name: RouteName.POSTS,
+              params: { preferredUsername: usernameWithDomain(group) },
+            }"
+            >{{ $t("View all posts") }}</router-link
+          >
         </div>
         <div v-else-if="group" class="content has-text-grey has-text-centered">
           <p>{{ $t("No posts yet") }}</p>
diff --git a/js/src/views/Posts/List.vue b/js/src/views/Posts/List.vue
index 9d36a297d..30d515820 100644
--- a/js/src/views/Posts/List.vue
+++ b/js/src/views/Posts/List.vue
@@ -28,7 +28,7 @@
     </nav>
     <section>
       <div class="intro">
-        <p>
+        <p v-if="isCurrentActorMember">
           {{
             $t(
               "A place to publish something to the whole world, your community or just your group members."
@@ -36,6 +36,7 @@
           }}
         </p>
         <router-link
+          v-if="isCurrentActorMember"
           :to="{
             name: RouteName.POST_CREATE,
             params: { preferredUsername: usernameWithDomain(group) },