Fix discussion list page showing empty content when not a member

Introduce the EmptyContent component to display an empty content message

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-01-14 19:17:12 +01:00
parent 7b051346a4
commit 4100fd8705
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
3 changed files with 117 additions and 9 deletions

View File

@ -0,0 +1,37 @@
<template>
<div class="empty-content" :class="{ inline }" role="note">
<b-icon :icon="icon" size="is-large" />
<h2 class="empty-content__title">
<!-- @slot Mandatory title -->
<slot />
</h2>
<p v-show="$slots.desc">
<!-- @slot Optional description -->
<slot name="desc" />
</p>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component
export default class EmptyContent extends Vue {
@Prop({ type: String, required: true }) icon!: string;
@Prop({ type: Boolean, required: false, default: false }) inline!: boolean;
}
</script>
<style lang="scss">
.empty-content {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20vh;
&__title {
margin-bottom: 10px;
}
&.inline {
margin-top: 5vh;
}
}
</style>

View File

@ -27,7 +27,7 @@
</li>
</ul>
</nav>
<section>
<section v-if="isCurrentActorAGroupMember">
<p>
{{
$t(
@ -39,7 +39,7 @@
tag="router-link"
:to="{
name: RouteName.CREATE_DISCUSSION,
params: { preferredUsername: this.preferredUsername },
params: { preferredUsername },
}"
>{{ $t("New discussion") }}</b-button
>
@ -50,18 +50,38 @@
:key="discussion.id"
/>
</div>
<empty-content v-else icon="chat">
{{ $t("There's no discussions yet") }}
</empty-content>
</section>
<section class="section" v-else>
<empty-content icon="chat">
{{ $t("Only group members can access discussions") }}
<template #desc>
<router-link
:to="{ name: RouteName.GROUP, params: { preferredUsername } }"
>
{{ $t("Return to the group page") }}
</router-link>
</template>
</empty-content>
</section>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { FETCH_GROUP } from "@/graphql/group";
import { IGroup, usernameWithDomain } from "@/types/actor";
import { IActor, IGroup, IPerson, usernameWithDomain } from "@/types/actor";
import DiscussionListItem from "@/components/Discussion/DiscussionListItem.vue";
import RouteName from "../../router/name";
import { MemberRole } from "@/types/enums";
import { CURRENT_ACTOR_CLIENT, PERSON_MEMBERSHIPS } from "@/graphql/actor";
import { GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED } from "@/graphql/event";
import { IMember } from "@/types/actor/member.model";
import EmptyContent from "@/components/Utils/EmptyContent.vue";
@Component({
components: { DiscussionListItem },
components: { DiscussionListItem, EmptyContent },
apollo: {
group: {
query: FETCH_GROUP,
@ -75,6 +95,30 @@ import RouteName from "../../router/name";
return !this.preferredUsername;
},
},
person: {
query: PERSON_MEMBERSHIPS,
fetchPolicy: "cache-and-network",
variables() {
return {
id: this.currentActor.id,
};
},
subscribeToMore: {
document: GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED,
variables() {
return {
actorId: this.currentActor.id,
};
},
skip() {
return !this.currentActor || !this.currentActor.id;
},
},
skip() {
return !this.currentActor || !this.currentActor.id;
},
},
currentActor: CURRENT_ACTOR_CLIENT,
},
metaInfo() {
return {
@ -89,11 +133,36 @@ import RouteName from "../../router/name";
export default class DiscussionsList extends Vue {
@Prop({ type: String, required: true }) preferredUsername!: string;
person!: IPerson;
group!: IGroup;
currentActor!: IActor;
RouteName = RouteName;
usernameWithDomain = usernameWithDomain;
get groupMemberships(): (string | undefined)[] {
if (!this.person || !this.person.id) return [];
return this.person.memberships.elements
.filter(
(membership: IMember) =>
![
MemberRole.REJECTED,
MemberRole.NOT_APPROVED,
MemberRole.INVITED,
].includes(membership.role)
)
.map(({ parent: { id } }) => id);
}
get isCurrentActorAGroupMember(): boolean {
return (
this.groupMemberships !== undefined &&
this.groupMemberships.includes(this.group.id)
);
}
}
</script>
<style lang="scss">

View File

@ -218,11 +218,9 @@
</div>
</b-table-column>
<template slot="empty">
<section class="section">
<div class="content has-text-grey has-text-centered">
<p>{{ $t("No member matches the filters") }}</p>
</div>
</section>
<empty-content icon="account" inline>
{{ $t("No member matches the filters") }}
</empty-content>
</template>
</b-table>
</section>
@ -247,6 +245,7 @@ import {
UPDATE_MEMBER,
} from "../../graphql/member";
import { usernameWithDomain } from "../../types/actor";
import EmptyContent from "@/components/Utils/EmptyContent.vue";
@Component({
apollo: {
@ -263,6 +262,9 @@ import { usernameWithDomain } from "../../types/actor";
update: (data) => data.group.members,
},
},
components: {
EmptyContent,
},
})
export default class GroupMembers extends mixins(GroupMixin) {
loading = true;