@@ -1,60 +1,71 @@
|
||||
<template>
|
||||
<div class="container is-widescreen">
|
||||
<div
|
||||
v-if="group && groupMemberships && groupMemberships.includes(group.id)"
|
||||
class="block-container"
|
||||
>
|
||||
<div class="block-column">
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs" v-if="group">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: RouteName.MY_GROUPS }">{{ $t("My groups") }}</router-link>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP,
|
||||
params: { preferredUsername: usernameWithDomain(group.preferredUsername) },
|
||||
}"
|
||||
>{{ group.name }}</router-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<section class="presentation">
|
||||
<div class="media">
|
||||
<div class="media-left">
|
||||
<figure class="image is-128x128" v-if="group.avatar">
|
||||
<img :src="group.avatar.url" />
|
||||
</figure>
|
||||
<b-icon v-else size="is-large" icon="account-group" />
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<h1>{{ group.name }}</h1>
|
||||
<small class="has-text-grey">@{{ usernameWithDomain(group) }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="members">
|
||||
<figure
|
||||
class="image is-48x48"
|
||||
:title="
|
||||
$t(`@{username} ({role})`, {
|
||||
username: usernameWithDomain(member.actor),
|
||||
role: member.role,
|
||||
})
|
||||
"
|
||||
v-for="member in group.members.elements"
|
||||
:key="member.actor.id"
|
||||
<div class="header">
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: RouteName.MY_GROUPS }">{{ $t("My groups") }}</router-link>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<router-link
|
||||
v-if="group.preferredUsername"
|
||||
:to="{
|
||||
name: RouteName.GROUP,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ group.name }}</router-link
|
||||
>
|
||||
<img
|
||||
class="is-rounded"
|
||||
:src="member.actor.avatar.url"
|
||||
v-if="member.actor.avatar"
|
||||
alt
|
||||
/>
|
||||
<b-skeleton v-else :animated="true"></b-skeleton>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<header class="block-container presentation">
|
||||
<div class="block-column media">
|
||||
<div class="media-left">
|
||||
<figure class="image rounded is-128x128" v-if="group.avatar">
|
||||
<img :src="group.avatar.url" />
|
||||
</figure>
|
||||
<b-icon v-else size="is-large" icon="account-group" />
|
||||
</div>
|
||||
</section>
|
||||
<div class="media-content">
|
||||
<h1 v-if="group.name">{{ group.name }}</h1>
|
||||
<b-skeleton v-else :animated="true" />
|
||||
<small class="has-text-grey" v-if="group.preferredUsername"
|
||||
>@{{ usernameWithDomain(group) }}</small
|
||||
>
|
||||
<b-skeleton v-else :animated="true" />
|
||||
<br />
|
||||
<router-link
|
||||
v-if="isCurrentActorAGroupAdmin"
|
||||
:to="{
|
||||
name: RouteName.GROUP_PUBLIC_SETTINGS,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
class="button is-outlined"
|
||||
>{{ $t("Group settings") }}</router-link
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-column members">
|
||||
<figure
|
||||
class="image is-48x48"
|
||||
:title="
|
||||
$t(`@{username} ({role})`, {
|
||||
username: usernameWithDomain(member.actor),
|
||||
role: member.role,
|
||||
})
|
||||
"
|
||||
v-for="member in group.members.elements"
|
||||
:key="member.actor.id"
|
||||
>
|
||||
<img class="is-rounded" :src="member.actor.avatar.url" v-if="member.actor.avatar" alt />
|
||||
<b-icon v-else size="is-large" icon="account-circle" />
|
||||
</figure>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div v-if="isCurrentActorAGroupMember" class="block-container">
|
||||
<div class="block-column">
|
||||
<section>
|
||||
<subtitle>{{ $t("Upcoming events") }}</subtitle>
|
||||
<div class="organized-events-wrapper" v-if="group.organizedEvents.total > 0">
|
||||
@@ -92,8 +103,17 @@
|
||||
<section>
|
||||
<subtitle>{{ $t("Public page") }}</subtitle>
|
||||
<p>{{ $t("Followed by {count} persons", { count: group.members.total }) }}</p>
|
||||
<b-button type="is-light">{{ $t("Edit biography") }}</b-button>
|
||||
<b-button type="is-primary">{{ $t("Post a public message") }}</b-button>
|
||||
<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" />
|
||||
</div>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.POST_CREATE,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
class="button is-primary"
|
||||
>{{ $t("Post a public message") }}</router-link
|
||||
>
|
||||
</section>
|
||||
<section>
|
||||
<subtitle>{{ $t("Ongoing tasks") }}</subtitle>
|
||||
@@ -122,15 +142,15 @@
|
||||
</section>
|
||||
<section>
|
||||
<subtitle>{{ $t("Discussions") }}</subtitle>
|
||||
<conversation-list-item
|
||||
v-if="group.conversations.total > 0"
|
||||
v-for="conversation in group.conversations.elements"
|
||||
:key="conversation.id"
|
||||
:conversation="conversation"
|
||||
<discussion-list-item
|
||||
v-if="group.discussions.total > 0"
|
||||
v-for="discussion in group.discussions.elements"
|
||||
:key="discussion.id"
|
||||
:discussion="discussion"
|
||||
/>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.CONVERSATION_LIST,
|
||||
name: RouteName.DISCUSSION_LIST,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ $t("View all discussions") }}</router-link
|
||||
@@ -138,24 +158,13 @@
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="group">
|
||||
<section class="presentation">
|
||||
<div class="media">
|
||||
<div class="media-left">
|
||||
<figure class="image is-128x128" v-if="group.avatar">
|
||||
<img :src="group.avatar.url" alt />
|
||||
</figure>
|
||||
<b-icon v-else size="is-large" icon="account-group" />
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<h2>{{ group.name }}</h2>
|
||||
<small class="has-text-grey">@{{ usernameWithDomain(group) }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<b-message v-else-if="!group && $apollo.loading === false" type="is-danger">
|
||||
{{ $t("No group found") }}
|
||||
</b-message>
|
||||
<div v-else class="public-container">
|
||||
<section>
|
||||
<subtitle>{{ $t("Upcoming events") }}</subtitle>
|
||||
<div class="organized-events-wrapper" v-if="group.organizedEvents.total > 0">
|
||||
<div class="organized-events-wrapper" v-if="group && group.organizedEvents.total > 0">
|
||||
<EventMinimalistCard
|
||||
v-for="event in group.organizedEvents.elements"
|
||||
:event="event"
|
||||
@@ -164,16 +173,24 @@
|
||||
/>
|
||||
<router-link :to="{}">{{ $t("View all upcoming events") }}</router-link>
|
||||
</div>
|
||||
<span v-else>{{ $t("No public upcoming events") }}</span>
|
||||
<span v-else-if="group">{{ $t("No public upcoming events") }}</span>
|
||||
<b-skeleton animated v-else></b-skeleton>
|
||||
</section>
|
||||
<!-- {{ group }}-->
|
||||
<section>
|
||||
<subtitle>{{ $t("Latest posts") }}</subtitle>
|
||||
<div v-if="group && group.posts.elements">
|
||||
<router-link
|
||||
v-for="post in group.posts.elements"
|
||||
:key="post.id"
|
||||
:to="{ name: RouteName.POST, params: { slug: post.slug } }"
|
||||
>
|
||||
{{ post.title }}
|
||||
</router-link>
|
||||
</div>
|
||||
<b-skeleton animated v-else></b-skeleton>
|
||||
</section>
|
||||
</div>
|
||||
<b-message v-else-if="!group && $apollo.loading === false" type="is-danger">
|
||||
{{ $t("No group found") }}
|
||||
</b-message>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -181,11 +198,19 @@
|
||||
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
|
||||
import EventCard from "@/components/Event/EventCard.vue";
|
||||
import { FETCH_GROUP, CURRENT_ACTOR_CLIENT, PERSON_MEMBERSHIPS } from "@/graphql/actor";
|
||||
import { IActor, IGroup, IPerson, usernameWithDomain } from "@/types/actor";
|
||||
import {
|
||||
IActor,
|
||||
IGroup,
|
||||
IPerson,
|
||||
usernameWithDomain,
|
||||
Group as GroupModel,
|
||||
MemberRole,
|
||||
} from "@/types/actor";
|
||||
import Subtitle from "@/components/Utils/Subtitle.vue";
|
||||
import CompactTodo from "@/components/Todo/CompactTodo.vue";
|
||||
import EventMinimalistCard from "@/components/Event/EventMinimalistCard.vue";
|
||||
import ConversationListItem from "@/components/Conversation/ConversationListItem.vue";
|
||||
import DiscussionListItem from "@/components/Discussion/DiscussionListItem.vue";
|
||||
import PostListItem from "@/components/Post/PostListItem.vue";
|
||||
import ResourceItem from "@/components/Resource/ResourceItem.vue";
|
||||
import FolderItem from "@/components/Resource/FolderItem.vue";
|
||||
import RouteName from "../../router/name";
|
||||
@@ -214,7 +239,8 @@ import RouteName from "../../router/name";
|
||||
currentActor: CURRENT_ACTOR_CLIENT,
|
||||
},
|
||||
components: {
|
||||
ConversationListItem,
|
||||
DiscussionListItem,
|
||||
PostListItem,
|
||||
EventMinimalistCard,
|
||||
CompactTodo,
|
||||
Subtitle,
|
||||
@@ -243,7 +269,7 @@ export default class Group extends Vue {
|
||||
|
||||
person!: IPerson;
|
||||
|
||||
group!: IGroup;
|
||||
group: IGroup = new GroupModel();
|
||||
|
||||
loading = true;
|
||||
|
||||
@@ -272,18 +298,63 @@ export default class Group extends Vue {
|
||||
if (!this.person || !this.person.id) return undefined;
|
||||
return this.person.memberships.elements.map(({ parent: { id } }) => id);
|
||||
}
|
||||
|
||||
get isCurrentActorAGroupMember(): boolean {
|
||||
return this.groupMemberships != undefined && this.groupMemberships.includes(this.group.id);
|
||||
}
|
||||
|
||||
get isCurrentActorAGroupAdmin(): boolean {
|
||||
return (
|
||||
this.person &&
|
||||
this.person.memberships.elements.some(
|
||||
({ parent: { id }, role }) => id === this.group.id && role === MemberRole.ADMINISTRATOR
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../variables.scss";
|
||||
|
||||
div.container {
|
||||
background: white;
|
||||
margin-bottom: 3rem;
|
||||
padding: 2rem 0;
|
||||
|
||||
.header,
|
||||
.public-container {
|
||||
margin: auto 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.block-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&.presentation {
|
||||
border: 2px solid $purple-2;
|
||||
padding: 10px 0;
|
||||
|
||||
h1 {
|
||||
color: $purple-1;
|
||||
font-size: 2rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.button.is-outlined {
|
||||
border-color: $purple-2;
|
||||
}
|
||||
}
|
||||
|
||||
.members {
|
||||
display: flex;
|
||||
|
||||
figure:not(:first-child) {
|
||||
margin-left: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.block-column {
|
||||
flex: 1;
|
||||
margin: 0 2rem;
|
||||
@@ -293,10 +364,8 @@ div.container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.presentation {
|
||||
.members {
|
||||
display: flex;
|
||||
}
|
||||
.posts-wrapper {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.organized-events-wrapper {
|
||||
|
||||
@@ -3,15 +3,31 @@
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: RouteName.GROUP }">{{ group.name }}</router-link>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ group.name }}</router-link
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: RouteName.GROUP_SETTINGS }">{{ $t("Settings") }}</router-link>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP_SETTINGS,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ $t("Settings") }}</router-link
|
||||
>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<router-link :to="{ name: RouteName.GROUP_MEMBERS_SETTINGS }">{{
|
||||
$t("Members")
|
||||
}}</router-link>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP_MEMBERS_SETTINGS,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ $t("Members") }}</router-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -29,26 +45,127 @@
|
||||
</b-field>
|
||||
</form>
|
||||
<h1>{{ $t("Group Members") }} ({{ group.members.total }})</h1>
|
||||
<b-field :label="$t('Status')" horizontal>
|
||||
<b-select v-model="roles">
|
||||
<option value="">
|
||||
{{ $t("Everything") }}
|
||||
</option>
|
||||
<option :value="MemberRole.ADMINISTRATOR">
|
||||
{{ $t("Administrator") }}
|
||||
</option>
|
||||
<option :value="MemberRole.MODERATOR">
|
||||
{{ $t("Moderator") }}
|
||||
</option>
|
||||
<option :value="MemberRole.MEMBER">
|
||||
{{ $t("Member") }}
|
||||
</option>
|
||||
<option :value="MemberRole.INVITED">
|
||||
{{ $t("Invited") }}
|
||||
</option>
|
||||
<option :value="MemberRole.NOT_APPROVED">
|
||||
{{ $t("Not approved") }}
|
||||
</option>
|
||||
<option :value="MemberRole.REJECTED">
|
||||
{{ $t("Rejected") }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-table
|
||||
:data="group.members.elements"
|
||||
ref="queueTable"
|
||||
:loading="this.$apollo.loading"
|
||||
paginated
|
||||
backend-pagination
|
||||
:pagination-simple="true"
|
||||
:aria-next-label="$t('Next page')"
|
||||
:aria-previous-label="$t('Previous page')"
|
||||
:aria-page-label="$t('Page')"
|
||||
:aria-current-label="$t('Current page')"
|
||||
:total="group.members.total"
|
||||
:per-page="MEMBERS_PER_PAGE"
|
||||
backend-sorting
|
||||
:default-sort-direction="'desc'"
|
||||
:default-sort="['insertedAt', 'desc']"
|
||||
@page-change="(newPage) => (page = newPage)"
|
||||
@sort="(field, order) => $emit('sort', field, order)"
|
||||
>
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="actor.preferredUsername" :label="$t('Member')">
|
||||
<article class="media">
|
||||
<figure class="media-left image is-48x48" v-if="props.row.actor.avatar">
|
||||
<img class="is-rounded" :src="props.row.actor.avatar.url" alt="" />
|
||||
</figure>
|
||||
<b-icon class="media-left" v-else size="is-large" icon="account-circle" />
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<span v-if="props.row.actor.name">{{ props.row.actor.name }}</span
|
||||
><br />
|
||||
<span class="is-size-7 has-text-grey"
|
||||
>@{{ usernameWithDomain(props.row.actor) }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</b-table-column>
|
||||
<b-table-column field="role" :label="$t('Role')">
|
||||
<b-tag type="is-primary" v-if="props.row.role === MemberRole.ADMINISTRATOR">
|
||||
{{ $t("Administrator") }}
|
||||
</b-tag>
|
||||
<b-tag type="is-primary" v-else-if="props.row.role === MemberRole.MODERATOR">
|
||||
{{ $t("Moderator") }}
|
||||
</b-tag>
|
||||
<b-tag v-else-if="props.row.role === MemberRole.MEMBER">
|
||||
{{ $t("Member") }}
|
||||
</b-tag>
|
||||
<b-tag type="is-warning" v-else-if="props.row.role === MemberRole.NOT_APPROVED">
|
||||
{{ $t("Not approved") }}
|
||||
</b-tag>
|
||||
<b-tag type="is-danger" v-else-if="props.row.role === MemberRole.REJECTED">
|
||||
{{ $t("Rejected") }}
|
||||
</b-tag>
|
||||
<b-tag type="is-danger" v-else-if="props.row.role === MemberRole.INVITED">
|
||||
{{ $t("Invited") }}
|
||||
</b-tag>
|
||||
</b-table-column>
|
||||
<b-table-column field="insertedAt" :label="$t('Date')">
|
||||
<span class="has-text-centered">
|
||||
{{ props.row.insertedAt | formatDateString }}<br />{{
|
||||
props.row.insertedAt | formatTimeString
|
||||
}}
|
||||
</span>
|
||||
</b-table-column>
|
||||
</template>
|
||||
<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>
|
||||
</template>
|
||||
</b-table>
|
||||
<pre>{{ group.members }}</pre>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from "vue-property-decorator";
|
||||
import { Component, Vue, Watch } from "vue-property-decorator";
|
||||
import RouteName from "../../router/name";
|
||||
import { FETCH_GROUP } from "../../graphql/actor";
|
||||
import { INVITE_MEMBER } from "../../graphql/member";
|
||||
import { IGroup } from "../../types/actor";
|
||||
import { IMember } from "../../types/actor/group.model";
|
||||
import { INVITE_MEMBER, GROUP_MEMBERS } from "../../graphql/member";
|
||||
import { IGroup, usernameWithDomain } from "../../types/actor";
|
||||
import { IMember, MemberRole } from "../../types/actor/group.model";
|
||||
|
||||
@Component({
|
||||
apollo: {
|
||||
group: {
|
||||
query: FETCH_GROUP,
|
||||
query: GROUP_MEMBERS,
|
||||
// fetchPolicy: "network-only",
|
||||
variables() {
|
||||
return {
|
||||
name: this.$route.params.preferredUsername,
|
||||
page: 1,
|
||||
limit: this.MEMBERS_PER_PAGE,
|
||||
roles: this.roles,
|
||||
};
|
||||
},
|
||||
skip() {
|
||||
@@ -66,6 +183,23 @@ export default class GroupMembers extends Vue {
|
||||
|
||||
newMemberUsername = "";
|
||||
|
||||
MemberRole = MemberRole;
|
||||
|
||||
roles: MemberRole | "" = "";
|
||||
|
||||
page = 1;
|
||||
|
||||
MEMBERS_PER_PAGE = 10;
|
||||
|
||||
usernameWithDomain = usernameWithDomain;
|
||||
|
||||
mounted() {
|
||||
const roleQuery = this.$route.query.role as string;
|
||||
if (Object.values(MemberRole).includes(roleQuery as MemberRole)) {
|
||||
this.roles = roleQuery as MemberRole;
|
||||
}
|
||||
}
|
||||
|
||||
async inviteMember() {
|
||||
await this.$apollo.mutate<{ inviteMember: IMember }>({
|
||||
mutation: INVITE_MEMBER,
|
||||
@@ -75,5 +209,32 @@ export default class GroupMembers extends Vue {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@Watch("page")
|
||||
loadMoreMembers() {
|
||||
this.$apollo.queries.event.fetchMore({
|
||||
// New variables
|
||||
variables: {
|
||||
page: this.page,
|
||||
limit: this.MEMBERS_PER_PAGE,
|
||||
},
|
||||
// Transform the previous result with new data
|
||||
updateQuery: (previousResult, { fetchMoreResult }) => {
|
||||
const oldMembers = previousResult.group.members;
|
||||
const newMembers = fetchMoreResult.group.members;
|
||||
|
||||
return {
|
||||
group: {
|
||||
...previousResult.event,
|
||||
members: {
|
||||
elements: [...oldMembers.elements, ...newMembers.elements],
|
||||
total: newMembers.total,
|
||||
__typename: oldMembers.__typename,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
91
js/src/views/Group/GroupSettings.vue
Normal file
91
js/src/views/Group/GroupSettings.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div>
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ group.name }}</router-link
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP_SETTINGS,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ $t("Settings") }}</router-link
|
||||
>
|
||||
</li>
|
||||
<li class="is-active">
|
||||
<router-link
|
||||
:to="{
|
||||
name: RouteName.GROUP_PUBLIC_SETTINGS,
|
||||
params: { preferredUsername: usernameWithDomain(group) },
|
||||
}"
|
||||
>{{ $t("Group settings") }}</router-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<section class="container section">
|
||||
<form @submit.prevent="updateGroup">
|
||||
<b-field :label="$t('Group name')">
|
||||
<b-input v-model="group.name" />
|
||||
</b-field>
|
||||
<b-field :label="$t('Group short description')">
|
||||
<b-input type="textarea" v-model="group.summary"
|
||||
/></b-field>
|
||||
<b-button native-type="submit" type="is-primary">{{ $t("Update group") }}</b-button>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from "vue-property-decorator";
|
||||
import RouteName from "../../router/name";
|
||||
import { FETCH_GROUP, UPDATE_GROUP } from "../../graphql/actor";
|
||||
import { IGroup, usernameWithDomain } from "../../types/actor";
|
||||
import { IMember, Group } from "../../types/actor/group.model";
|
||||
import { Paginate } from "../../types/paginate";
|
||||
|
||||
@Component({
|
||||
apollo: {
|
||||
group: {
|
||||
query: FETCH_GROUP,
|
||||
variables() {
|
||||
return {
|
||||
name: this.$route.params.preferredUsername,
|
||||
};
|
||||
},
|
||||
skip() {
|
||||
return !this.$route.params.preferredUsername;
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
export default class GroupSettings extends Vue {
|
||||
group: IGroup = new Group();
|
||||
|
||||
loading = true;
|
||||
|
||||
RouteName = RouteName;
|
||||
|
||||
newMemberUsername = "";
|
||||
|
||||
usernameWithDomain = usernameWithDomain;
|
||||
|
||||
async updateGroup() {
|
||||
await this.$apollo.mutate<{ updateGroup: IGroup }>({
|
||||
mutation: UPDATE_GROUP,
|
||||
variables: {
|
||||
...this.group,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -36,7 +36,7 @@ import { ACCEPT_INVITATION } from "../../graphql/member";
|
||||
InvitationCard,
|
||||
},
|
||||
apollo: {
|
||||
paginatedGroups: {
|
||||
membershipsPages: {
|
||||
query: LOGGED_USER_MEMBERSHIPS,
|
||||
fetchPolicy: "network-only",
|
||||
variables: {
|
||||
@@ -57,18 +57,22 @@ import { ACCEPT_INVITATION } from "../../graphql/member";
|
||||
},
|
||||
})
|
||||
export default class MyEvents extends Vue {
|
||||
paginatedGroups!: Paginate<IMember>;
|
||||
membershipsPages!: Paginate<IMember>;
|
||||
|
||||
RouteName = RouteName;
|
||||
|
||||
get invitations() {
|
||||
if (!this.paginatedGroups) return [];
|
||||
return this.paginatedGroups.elements.filter((member) => member.role === MemberRole.INVITED);
|
||||
if (!this.membershipsPages) return [];
|
||||
return this.membershipsPages.elements.filter(
|
||||
(member: IMember) => member.role === MemberRole.INVITED
|
||||
);
|
||||
}
|
||||
|
||||
get memberships() {
|
||||
if (!this.paginatedGroups) return [];
|
||||
return this.paginatedGroups.elements.filter((member) => member.role !== MemberRole.INVITED);
|
||||
if (!this.membershipsPages) return [];
|
||||
return this.membershipsPages.elements.filter(
|
||||
(member: IMember) => member.role !== MemberRole.INVITED
|
||||
);
|
||||
}
|
||||
|
||||
async acceptInvitation(id: string) {
|
||||
|
||||
Reference in New Issue
Block a user