#1546 Harmonization between public and private view + improved CSS
This commit is contained in:
parent
906985478d
commit
861c445b63
|
@ -1,15 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<section class="flex flex-col mb-3 border-2 border-yellow-1">
|
<section class="flex flex-col border-2 border-yellow-1 rounded-lg">
|
||||||
<div class="flex items-stretch py-3 px-1 bg-yellow-1 text-violet-title">
|
<div class="flex items-stretch py-3 px-1 bg-yellow-1 text-violet-title">
|
||||||
<div class="flex flex-1 gap-1">
|
<div class="flex flex-1 gap-1">
|
||||||
<o-icon :icon="icon" custom-size="36" />
|
<o-icon :icon="icon" custom-size="36" />
|
||||||
<h2 class="text-2xl font-medium mt-0">{{ title }}</h2>
|
<h2 class="text-2xl font-medium mt-0">{{ title }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<router-link class="self-center" :to="route">{{
|
<router-link v-if="route" class="self-center" :to="route">{{
|
||||||
t("View all")
|
t("View all")
|
||||||
}}</router-link>
|
}}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1 min-h-40">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end p-2">
|
<div class="flex justify-end p-2">
|
||||||
|
@ -27,7 +27,7 @@ withDefaults(
|
||||||
icon: string;
|
icon: string;
|
||||||
route: { name: string; params: { preferredUsername: string } };
|
route: { name: string; params: { preferredUsername: string } };
|
||||||
}>(),
|
}>(),
|
||||||
{}
|
{ route: undefined }
|
||||||
);
|
);
|
||||||
const { t } = useI18n({ useScope: "global" });
|
const { t } = useI18n({ useScope: "global" });
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
>
|
>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap gap-2 py-1"
|
class="flex flex-wrap gap-2 p-2"
|
||||||
v-if="group && group.organizedEvents.total > 0"
|
v-if="group && group.organizedEvents.total > 0"
|
||||||
>
|
>
|
||||||
<event-minimalist-card
|
<event-minimalist-card
|
||||||
|
@ -24,6 +24,17 @@
|
||||||
<!-- <o-skeleton animated v-else></o-skeleton> -->
|
<!-- <o-skeleton animated v-else></o-skeleton> -->
|
||||||
</template>
|
</template>
|
||||||
<template #create>
|
<template #create>
|
||||||
|
<o-button
|
||||||
|
tag="router-link"
|
||||||
|
class="button"
|
||||||
|
variant="text"
|
||||||
|
:to="{
|
||||||
|
name: RouteName.GROUP_EVENTS,
|
||||||
|
params: { preferredUsername: usernameWithDomain(group) },
|
||||||
|
query: { showPassedEvents: true },
|
||||||
|
}"
|
||||||
|
>{{ t("View past events") }}</o-button
|
||||||
|
>
|
||||||
<o-button
|
<o-button
|
||||||
tag="router-link"
|
tag="router-link"
|
||||||
v-if="isModerator"
|
v-if="isModerator"
|
||||||
|
|
|
@ -8,9 +8,22 @@
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="p-1">
|
<div class="p-2">
|
||||||
<multi-post-list-item
|
<multi-post-list-item
|
||||||
v-if="group?.posts?.total ?? 0 > 0"
|
v-if="
|
||||||
|
!isMember &&
|
||||||
|
group?.posts.elements.filter(
|
||||||
|
(post) => !post.draft && post.visibility === PostVisibility.PUBLIC
|
||||||
|
).length > 0
|
||||||
|
"
|
||||||
|
:posts="
|
||||||
|
group?.posts.elements.filter(
|
||||||
|
(post) => !post.draft && post.visibility === PostVisibility.PUBLIC
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<multi-post-list-item
|
||||||
|
v-else-if="group?.posts?.total ?? 0 > 0"
|
||||||
:posts="(group?.posts?.elements ?? []).slice(0, 3)"
|
:posts="(group?.posts?.elements ?? []).slice(0, 3)"
|
||||||
:isCurrentActorMember="isMember"
|
:isCurrentActorMember="isMember"
|
||||||
/>
|
/>
|
||||||
|
@ -42,6 +55,7 @@ import { useI18n } from "vue-i18n";
|
||||||
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
||||||
import MultiPostListItem from "@/components/Post/MultiPostListItem.vue";
|
import MultiPostListItem from "@/components/Post/MultiPostListItem.vue";
|
||||||
import GroupSection from "@/components/Group/GroupSection.vue";
|
import GroupSection from "@/components/Group/GroupSection.vue";
|
||||||
|
import { PostVisibility } from "@/types/enums";
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: "global" });
|
const { t } = useI18n({ useScope: "global" });
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="posts-wrapper grid gap-4">
|
<div class="posts-wrapper grid gap-2">
|
||||||
<post-list-item
|
<post-list-item
|
||||||
v-for="post in posts"
|
v-for="post in posts"
|
||||||
:key="post.id"
|
:key="post.id"
|
||||||
|
|
|
@ -29,6 +29,10 @@ const icons: Record<string, () => Promise<any>> = {
|
||||||
import(`../../../node_modules/vue-material-design-icons/LinkOff.vue`),
|
import(`../../../node_modules/vue-material-design-icons/LinkOff.vue`),
|
||||||
Image: () =>
|
Image: () =>
|
||||||
import(`../../../node_modules/vue-material-design-icons/Image.vue`),
|
import(`../../../node_modules/vue-material-design-icons/Image.vue`),
|
||||||
|
Information: () =>
|
||||||
|
import(
|
||||||
|
`../../../node_modules/vue-material-design-icons/InformationVariant.vue`
|
||||||
|
),
|
||||||
FormatListBulleted: () =>
|
FormatListBulleted: () =>
|
||||||
import(
|
import(
|
||||||
`../../../node_modules/vue-material-design-icons/FormatListBulleted.vue`
|
`../../../node_modules/vue-material-design-icons/FormatListBulleted.vue`
|
||||||
|
|
|
@ -638,6 +638,7 @@
|
||||||
"Live": "Direct",
|
"Live": "Direct",
|
||||||
"Load more": "Voir plus",
|
"Load more": "Voir plus",
|
||||||
"Load more activities": "Charger plus d'activités",
|
"Load more activities": "Charger plus d'activités",
|
||||||
|
"Loading…": "Chargement…",
|
||||||
"Loading comments…": "Chargement des commentaires…",
|
"Loading comments…": "Chargement des commentaires…",
|
||||||
"Loading map": "Chargement de la carte",
|
"Loading map": "Chargement de la carte",
|
||||||
"Loading search results...": "Chargement des résultats...",
|
"Loading search results...": "Chargement des résultats...",
|
||||||
|
@ -726,6 +727,7 @@
|
||||||
"Next month": "Le mois-prochain",
|
"Next month": "Le mois-prochain",
|
||||||
"Next page": "Page suivante",
|
"Next page": "Page suivante",
|
||||||
"Next week": "La semaine prochaine",
|
"Next week": "La semaine prochaine",
|
||||||
|
"No about content yet":"À propos n'est pas encore renseigné",
|
||||||
"No activities found": "Aucun activité trouvé",
|
"No activities found": "Aucun activité trouvé",
|
||||||
"No address defined": "Aucune adresse définie",
|
"No address defined": "Aucune adresse définie",
|
||||||
"No apps authorized yet": "Aucune application autorisée pour le moment",
|
"No apps authorized yet": "Aucune application autorisée pour le moment",
|
||||||
|
@ -753,6 +755,7 @@
|
||||||
"No instance to remove|Remove instance|Remove {number} instances": "Pas d'instances à supprimer|Supprimer une instance|Supprimer {number} instances",
|
"No instance to remove|Remove instance|Remove {number} instances": "Pas d'instances à supprimer|Supprimer une instance|Supprimer {number} instances",
|
||||||
"No instances match this filter. Try resetting filter fields?": "Aucune instance ne correspond à ce filtre. Essayer de remettre à zéro les champs des filtres ?",
|
"No instances match this filter. Try resetting filter fields?": "Aucune instance ne correspond à ce filtre. Essayer de remettre à zéro les champs des filtres ?",
|
||||||
"No languages found": "Aucune langue trouvée",
|
"No languages found": "Aucune langue trouvée",
|
||||||
|
"No location yet":"Localisation non renseignée",
|
||||||
"No member matches the filters": "Aucun·e membre ne correspond aux filtres",
|
"No member matches the filters": "Aucun·e membre ne correspond aux filtres",
|
||||||
"No members found": "Aucun·e membre trouvé·e",
|
"No members found": "Aucun·e membre trouvé·e",
|
||||||
"No memberships found": "Aucune adhésion trouvée",
|
"No memberships found": "Aucune adhésion trouvée",
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container mx-auto is-widescreen">
|
<div class="container mx-auto is-widescreen">
|
||||||
<div class="header flex flex-col">
|
<o-notification v-if="groupLoading" variant="info">
|
||||||
|
{{ t("Loading…") }}
|
||||||
|
</o-notification>
|
||||||
|
<o-notification v-if="!group && groupLoading === false" variant="danger">
|
||||||
|
{{ t("No group found") }}
|
||||||
|
</o-notification>
|
||||||
|
<div class="header flex flex-col" v-if="group">
|
||||||
<breadcrumbs-nav
|
<breadcrumbs-nav
|
||||||
v-if="group"
|
|
||||||
:links="[
|
:links="[
|
||||||
{ name: RouteName.MY_GROUPS, text: t('My groups') },
|
{ name: RouteName.MY_GROUPS, text: t('My groups') },
|
||||||
{
|
{
|
||||||
|
@ -12,8 +17,7 @@
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
<!-- <o-loading v-model:active="$apollo.loading"></o-loading> -->
|
<header class="block-container presentation">
|
||||||
<header class="block-container presentation" v-if="group">
|
|
||||||
<div class="banner-container">
|
<div class="banner-container">
|
||||||
<lazy-image-wrapper :picture="group.banner" />
|
<lazy-image-wrapper :picture="group.banner" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,64 +35,14 @@
|
||||||
<AccountGroup v-else :size="128" />
|
<AccountGroup v-else :size="128" />
|
||||||
</div>
|
</div>
|
||||||
<div class="title-container flex flex-1 flex-col text-center">
|
<div class="title-container flex flex-1 flex-col text-center">
|
||||||
<h1 class="m-0" v-if="group.name">
|
<h1 class="m-1" v-if="group.name">
|
||||||
{{ group.name }}
|
{{ group.name }}
|
||||||
</h1>
|
</h1>
|
||||||
<!-- <o-skeleton v-else :animated="true" /> -->
|
<span dir="ltr" class="m-1" v-if="group.preferredUsername"
|
||||||
<span dir="ltr" class="" v-if="group.preferredUsername"
|
|
||||||
>@{{ usernameWithDomain(group) }}</span
|
>@{{ usernameWithDomain(group) }}</span
|
||||||
>
|
>
|
||||||
<!-- <o-skeleton v-else :animated="true" /> -->
|
|
||||||
<br />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap justify-center flex-col md:flex-row">
|
<div class="flex flex-wrap justify-center flex-col md:flex-row">
|
||||||
<div
|
|
||||||
class="flex flex-col items-center flex-1 m-0"
|
|
||||||
v-if="isCurrentActorAGroupMember && !previewPublic && members"
|
|
||||||
>
|
|
||||||
<div class="flex">
|
|
||||||
<figure
|
|
||||||
:title="
|
|
||||||
t(`{'@'}{username} ({role})`, {
|
|
||||||
username: usernameWithDomain(member.actor),
|
|
||||||
role: member.role,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
v-for="member in members.elements"
|
|
||||||
:key="member.actor.id"
|
|
||||||
class="-mr-3"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="rounded-full h-8"
|
|
||||||
:src="member.actor.avatar.url"
|
|
||||||
v-if="member.actor.avatar"
|
|
||||||
alt=""
|
|
||||||
width="32"
|
|
||||||
height="32"
|
|
||||||
/>
|
|
||||||
<AccountCircle v-else :size="32" />
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
{{
|
|
||||||
t(
|
|
||||||
"{count} members",
|
|
||||||
{
|
|
||||||
count: group.members?.total,
|
|
||||||
},
|
|
||||||
group.members?.total
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
<router-link
|
|
||||||
v-if="isCurrentActorAGroupAdmin"
|
|
||||||
:to="{
|
|
||||||
name: RouteName.GROUP_MEMBERS_SETTINGS,
|
|
||||||
params: { preferredUsername: usernameWithDomain(group) },
|
|
||||||
}"
|
|
||||||
>{{ t("Add / Remove…") }}</router-link
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-wrap gap-3 justify-center">
|
<div class="flex flex-wrap gap-3 justify-center">
|
||||||
<o-button
|
<o-button
|
||||||
outlined
|
outlined
|
||||||
|
@ -375,12 +329,14 @@
|
||||||
:invitations="[groupMember]"
|
:invitations="[groupMember]"
|
||||||
/>
|
/>
|
||||||
<o-notification
|
<o-notification
|
||||||
|
class="my-2"
|
||||||
v-if="isCurrentActorARejectedGroupMember"
|
v-if="isCurrentActorARejectedGroupMember"
|
||||||
variant="danger"
|
variant="danger"
|
||||||
>
|
>
|
||||||
{{ t("You have been removed from this group's members.") }}
|
{{ t("You have been removed from this group's members.") }}
|
||||||
</o-notification>
|
</o-notification>
|
||||||
<o-notification
|
<o-notification
|
||||||
|
class="my-2"
|
||||||
v-if="
|
v-if="
|
||||||
isCurrentActorAGroupMember &&
|
isCurrentActorAGroupMember &&
|
||||||
isCurrentActorARecentMember &&
|
isCurrentActorARecentMember &&
|
||||||
|
@ -394,47 +350,11 @@
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</o-notification>
|
</o-notification>
|
||||||
</div>
|
<o-notification
|
||||||
</header>
|
class="my-2"
|
||||||
</div>
|
v-if="group && group.domain && !isCurrentActorAGroupMember"
|
||||||
<div
|
variant="info"
|
||||||
v-if="isCurrentActorAGroupMember && !previewPublic && group"
|
>
|
||||||
class="block-container flex gap-2 flex-wrap mt-3"
|
|
||||||
>
|
|
||||||
<!-- Private things -->
|
|
||||||
<div class="flex-1 m-0 flex flex-col flex-wrap gap-2">
|
|
||||||
<!-- Group discussions -->
|
|
||||||
<Discussions :group="discussionGroup ?? group" class="flex-1" />
|
|
||||||
<!-- Resources -->
|
|
||||||
<Resources :group="resourcesGroup ?? group" class="flex-1" />
|
|
||||||
</div>
|
|
||||||
<!-- Public things -->
|
|
||||||
<div class="flex-1 m-0 flex flex-col flex-wrap gap-2">
|
|
||||||
<!-- Events -->
|
|
||||||
<Events
|
|
||||||
:group="group"
|
|
||||||
:isModerator="isCurrentActorAGroupModerator"
|
|
||||||
class="flex-1"
|
|
||||||
/>
|
|
||||||
<!-- Posts -->
|
|
||||||
<Posts
|
|
||||||
:group="group"
|
|
||||||
:isModerator="isCurrentActorAGroupModerator"
|
|
||||||
:isMember="isCurrentActorAGroupMember"
|
|
||||||
class="flex-1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<o-notification
|
|
||||||
v-else-if="!group && groupLoading === false"
|
|
||||||
variant="danger"
|
|
||||||
>
|
|
||||||
{{ t("No group found") }}
|
|
||||||
</o-notification>
|
|
||||||
<div v-else-if="group" class="public-container flex flex-col">
|
|
||||||
<aside class="group-metadata">
|
|
||||||
<div class="sticky">
|
|
||||||
<o-notification v-if="group.domain && !isCurrentActorAGroupMember">
|
|
||||||
<p>
|
<p>
|
||||||
{{
|
{{
|
||||||
t(
|
t(
|
||||||
|
@ -450,173 +370,196 @@
|
||||||
>{{ t("View full profile") }}</o-button
|
>{{ t("View full profile") }}</o-button
|
||||||
>
|
>
|
||||||
</o-notification>
|
</o-notification>
|
||||||
<event-metadata-block
|
</div>
|
||||||
:title="t('About')"
|
</header>
|
||||||
v-if="group.summary && group.summary !== '<p></p>'"
|
</div>
|
||||||
|
<div v-if="group">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 mb-2">
|
||||||
|
<!-- Private thing: Group discussions -->
|
||||||
|
<Discussions
|
||||||
|
v-if="isCurrentActorAGroupMember && !previewPublic"
|
||||||
|
:group="discussionGroup ?? group"
|
||||||
|
/>
|
||||||
|
<!-- Private thing: Resources -->
|
||||||
|
<Resources
|
||||||
|
v-if="isCurrentActorAGroupMember && !previewPublic"
|
||||||
|
:group="resourcesGroup ?? group"
|
||||||
|
/>
|
||||||
|
<!-- Public thing: Events -->
|
||||||
|
<Events
|
||||||
|
:group="group"
|
||||||
|
:isModerator="isCurrentActorAGroupModerator && !previewPublic"
|
||||||
|
/>
|
||||||
|
<!-- Public thing: Posts -->
|
||||||
|
<Posts
|
||||||
|
:group="group"
|
||||||
|
:isModerator="isCurrentActorAGroupModerator && !previewPublic"
|
||||||
|
:isMember="isCurrentActorAGroupMember && !previewPublic"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-2">
|
||||||
|
<!-- Public thing: Members -->
|
||||||
|
<group-section :title="t('Members')" icon="account-group">
|
||||||
|
<template #default>
|
||||||
|
<div class="flex flex-col justify-center h-full">
|
||||||
|
<div
|
||||||
|
class="flex flex-col items-center"
|
||||||
|
v-if="isCurrentActorAGroupMember && !previewPublic && members"
|
||||||
|
>
|
||||||
|
<div class="flex">
|
||||||
|
<figure
|
||||||
|
:title="
|
||||||
|
t(`{'@'}{username} ({role})`, {
|
||||||
|
username: usernameWithDomain(member.actor),
|
||||||
|
role: member.role,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
v-for="member in members.elements"
|
||||||
|
:key="member.actor.id"
|
||||||
|
class="-mr-3"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="rounded-full h-8"
|
||||||
|
:src="member.actor.avatar.url"
|
||||||
|
v-if="member.actor.avatar"
|
||||||
|
alt=""
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
/>
|
||||||
|
<AccountCircle v-else :size="32" />
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="">
|
||||||
|
<h2 class="text-center">
|
||||||
|
{{
|
||||||
|
t(
|
||||||
|
"{count} members",
|
||||||
|
{
|
||||||
|
count: group.members?.total,
|
||||||
|
},
|
||||||
|
group.members?.total
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div></template
|
||||||
>
|
>
|
||||||
|
<template #create>
|
||||||
|
<o-button
|
||||||
|
v-if="isCurrentActorAGroupAdmin && !previewPublic"
|
||||||
|
tag="router-link"
|
||||||
|
:to="{
|
||||||
|
name: RouteName.GROUP_MEMBERS_SETTINGS,
|
||||||
|
params: { preferredUsername: usernameWithDomain(group) },
|
||||||
|
}"
|
||||||
|
class="button is-primary"
|
||||||
|
>{{ t("Add / Remove…") }}</o-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</group-section>
|
||||||
|
<!-- Public thing: About -->
|
||||||
|
<group-section :title="t('About')" icon="information">
|
||||||
|
<template #default>
|
||||||
<div
|
<div
|
||||||
|
v-if="group.summary"
|
||||||
dir="auto"
|
dir="auto"
|
||||||
class="prose lg:prose-xl dark:prose-invert"
|
class="prose lg:prose-xl dark:prose-invert p-2"
|
||||||
v-html="group.summary"
|
v-html="group.summary"
|
||||||
/>
|
></div>
|
||||||
</event-metadata-block>
|
<empty-content v-else icon="information" :inline="true">
|
||||||
<event-metadata-block :title="t('Members')">
|
{{ t("No about content yet") }}
|
||||||
<template #icon>
|
</empty-content>
|
||||||
<AccountGroup :size="48" />
|
</template>
|
||||||
</template>
|
<template #create>
|
||||||
{{
|
<o-button
|
||||||
t(
|
v-if="isCurrentActorAGroupAdmin && !previewPublic"
|
||||||
"{count} members",
|
tag="router-link"
|
||||||
{
|
:to="{
|
||||||
count: group.members?.total,
|
name: RouteName.GROUP_PUBLIC_SETTINGS,
|
||||||
},
|
params: { preferredUsername: usernameWithDomain(group) },
|
||||||
group.members?.total
|
}"
|
||||||
)
|
class="button is-primary"
|
||||||
}}
|
>{{ t("Edit") }}</o-button
|
||||||
</event-metadata-block>
|
>
|
||||||
<event-metadata-block
|
</template>
|
||||||
v-if="physicalAddress && physicalAddress.url"
|
</group-section>
|
||||||
:title="t('Location')"
|
<!-- Public thing: Location -->
|
||||||
>
|
<group-section :title="t('Location')" icon="earth">
|
||||||
<template #icon>
|
<template #default
|
||||||
|
><div
|
||||||
|
class="flex flex-col justify-center h-full"
|
||||||
|
v-if="physicalAddress && physicalAddress.url"
|
||||||
|
>
|
||||||
<o-icon
|
<o-icon
|
||||||
v-if="physicalAddress.poiInfos.poiIcon.icon"
|
v-if="physicalAddress.poiInfos.poiIcon.icon"
|
||||||
:icon="physicalAddress.poiInfos.poiIcon.icon"
|
:icon="physicalAddress.poiInfos.poiIcon.icon"
|
||||||
customSize="48"
|
customSize="48"
|
||||||
/>
|
/>
|
||||||
<Earth v-else :size="48" />
|
<Earth v-else :size="48" />
|
||||||
</template>
|
<div class="address-wrapper">
|
||||||
<div class="address-wrapper">
|
<div class="address">
|
||||||
<span
|
<div class="text-center">
|
||||||
v-if="!physicalAddress || !addressFullName(physicalAddress)"
|
<span v-if="!addressFullName(physicalAddress)">{{
|
||||||
>{{ t("No address defined") }}</span
|
t("No address defined")
|
||||||
>
|
}}</span>
|
||||||
<div class="address" v-if="physicalAddress">
|
<address dir="auto">
|
||||||
<div>
|
<p
|
||||||
<address dir="auto">
|
class="addressDescription"
|
||||||
<p
|
:title="physicalAddress.poiInfos.name"
|
||||||
class="addressDescription"
|
>
|
||||||
:title="physicalAddress.poiInfos.name"
|
{{ physicalAddress.poiInfos.name }}
|
||||||
>
|
</p>
|
||||||
{{ physicalAddress.poiInfos.name }}
|
<p class="has-text-grey-dark">
|
||||||
</p>
|
{{ physicalAddress.poiInfos.alternativeName }}
|
||||||
<p class="has-text-grey-dark">
|
</p>
|
||||||
{{ physicalAddress.poiInfos.alternativeName }}
|
</address>
|
||||||
</p>
|
</div>
|
||||||
</address>
|
|
||||||
</div>
|
</div>
|
||||||
<o-button
|
|
||||||
class="map-show-button"
|
|
||||||
variant="text"
|
|
||||||
@click="showMap = !showMap"
|
|
||||||
@keyup.enter="showMap = !showMap"
|
|
||||||
v-if="physicalAddress.geom"
|
|
||||||
>
|
|
||||||
{{ t("Show map") }}
|
|
||||||
</o-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</event-metadata-block>
|
<empty-content v-else icon="earth" :inline="true">
|
||||||
</div>
|
{{ t("No location yet") }}
|
||||||
</aside>
|
</empty-content></template
|
||||||
<div class="main-content min-w-min flex-auto py-0 px-2">
|
|
||||||
<section>
|
|
||||||
<h2 class="text-2xl font-bold">{{ t("Upcoming events") }}</h2>
|
|
||||||
<div
|
|
||||||
class="flex flex-col gap-3"
|
|
||||||
v-if="group && organizedEvents.elements.length > 0"
|
|
||||||
>
|
>
|
||||||
<event-minimalist-card
|
<template #create>
|
||||||
v-for="event in organizedEvents.elements.slice(0, 3)"
|
|
||||||
:event="event"
|
|
||||||
:key="event.uuid"
|
|
||||||
class="organized-event"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<empty-content
|
|
||||||
v-else-if="group"
|
|
||||||
icon="calendar"
|
|
||||||
:inline="true"
|
|
||||||
description-classes="flex flex-col items-stretch"
|
|
||||||
>
|
|
||||||
{{ t("No public upcoming events") }}
|
|
||||||
<template #desc>
|
|
||||||
<template v-if="isCurrentActorFollowing">
|
|
||||||
<i18n-t
|
|
||||||
keypath="You will receive notifications about this group's public activity depending on %{notification_settings}."
|
|
||||||
>
|
|
||||||
<template #notification_settings>
|
|
||||||
<router-link :to="{ name: RouteName.NOTIFICATIONS }">{{
|
|
||||||
t("your notification settings")
|
|
||||||
}}</router-link>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</template>
|
|
||||||
<o-button
|
|
||||||
tag="router-link"
|
|
||||||
class="my-2 self-center"
|
|
||||||
variant="text"
|
|
||||||
:to="{
|
|
||||||
name: RouteName.GROUP_EVENTS,
|
|
||||||
params: { preferredUsername: usernameWithDomain(group) },
|
|
||||||
query: { showPassedEvents: true },
|
|
||||||
}"
|
|
||||||
>{{ t("View past events") }}</o-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</empty-content>
|
|
||||||
<!-- <o-skeleton animated v-else-if="$apollo.loading"></o-skeleton> -->
|
|
||||||
<div class="flex justify-center">
|
|
||||||
<o-button
|
<o-button
|
||||||
tag="router-link"
|
v-if="physicalAddress && physicalAddress.geom"
|
||||||
class="my-4"
|
|
||||||
variant="text"
|
variant="text"
|
||||||
v-if="organizedEvents.total > 0"
|
@click="showMap = !showMap"
|
||||||
:to="{
|
@keyup.enter="showMap = !showMap"
|
||||||
name: RouteName.GROUP_EVENTS,
|
|
||||||
params: { preferredUsername: usernameWithDomain(group) },
|
|
||||||
query: {
|
|
||||||
showPassedEvents: organizedEvents.elements.length === 0,
|
|
||||||
},
|
|
||||||
}"
|
|
||||||
>{{ t("View all events") }}</o-button
|
|
||||||
>
|
>
|
||||||
</div>
|
{{ t("Show map") }}
|
||||||
</section>
|
</o-button>
|
||||||
<section class="flex flex-col items-stretch">
|
<o-button
|
||||||
<h2 class="ml-0 text-2xl font-bold">{{ t("Latest posts") }}</h2>
|
v-if="isCurrentActorAGroupAdmin && !previewPublic"
|
||||||
|
tag="router-link"
|
||||||
<multi-post-list-item
|
:to="{
|
||||||
v-if="
|
name: RouteName.GROUP_PUBLIC_SETTINGS,
|
||||||
posts.elements.filter(
|
params: { preferredUsername: usernameWithDomain(group) },
|
||||||
(post) =>
|
}"
|
||||||
!post.draft && post.visibility === PostVisibility.PUBLIC
|
class="button is-primary"
|
||||||
).length > 0
|
>{{ t("Edit") }}</o-button
|
||||||
"
|
>
|
||||||
:posts="
|
</template>
|
||||||
posts.elements.filter(
|
</group-section>
|
||||||
(post) =>
|
|
||||||
!post.draft && post.visibility === PostVisibility.PUBLIC
|
|
||||||
)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<empty-content v-else-if="group" icon="bullhorn" :inline="true">
|
|
||||||
{{ t("No posts yet") }}
|
|
||||||
</empty-content>
|
|
||||||
<!-- <o-skeleton animated v-else-if="$apollo.loading"></o-skeleton> -->
|
|
||||||
<o-button
|
|
||||||
class="self-center my-2"
|
|
||||||
v-if="posts.total > 0"
|
|
||||||
tag="router-link"
|
|
||||||
variant="text"
|
|
||||||
:to="{
|
|
||||||
name: RouteName.POSTS,
|
|
||||||
params: { preferredUsername: usernameWithDomain(group) },
|
|
||||||
}"
|
|
||||||
>{{ t("View all posts") }}</o-button
|
|
||||||
>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="my-2">
|
||||||
|
<template v-if="isCurrentActorFollowing">
|
||||||
|
<i18n-t
|
||||||
|
class="my-2"
|
||||||
|
keypath="You will receive notifications about this group's public activity depending on %{notification_settings}."
|
||||||
|
>
|
||||||
|
<template #notification_settings>
|
||||||
|
<router-link :to="{ name: RouteName.NOTIFICATIONS }">{{
|
||||||
|
t("your notification settings")
|
||||||
|
}}</router-link>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div v-if="group" class="public-container flex flex-col">
|
||||||
<o-modal
|
<o-modal
|
||||||
v-if="physicalAddress && physicalAddress.geom"
|
v-if="physicalAddress && physicalAddress.geom"
|
||||||
v-model:active="showMap"
|
v-model:active="showMap"
|
||||||
|
@ -654,7 +597,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// import EventCard from "@/components/Event/EventCard.vue";
|
|
||||||
import {
|
import {
|
||||||
displayName,
|
displayName,
|
||||||
IActor,
|
IActor,
|
||||||
|
@ -662,14 +604,11 @@ import {
|
||||||
IPerson,
|
IPerson,
|
||||||
usernameWithDomain,
|
usernameWithDomain,
|
||||||
} from "@/types/actor";
|
} from "@/types/actor";
|
||||||
// import CompactTodo from "@/components/Todo/CompactTodo.vue";
|
|
||||||
import EventMinimalistCard from "@/components/Event/EventMinimalistCard.vue";
|
|
||||||
import MultiPostListItem from "@/components/Post/MultiPostListItem.vue";
|
|
||||||
import { Address, addressFullName } from "@/types/address.model";
|
import { Address, addressFullName } from "@/types/address.model";
|
||||||
import InvitationsList from "@/components/Group/InvitationsList.vue";
|
import InvitationsList from "@/components/Group/InvitationsList.vue";
|
||||||
import { addMinutes } from "date-fns";
|
import { addMinutes } from "date-fns";
|
||||||
import { JOIN_GROUP } from "@/graphql/member";
|
import { JOIN_GROUP } from "@/graphql/member";
|
||||||
import { MemberRole, Openness, PostVisibility } from "@/types/enums";
|
import { MemberRole, Openness } from "@/types/enums";
|
||||||
import { IMember } from "@/types/actor/member.model";
|
import { IMember } from "@/types/actor/member.model";
|
||||||
import RouteName from "../../router/name";
|
import RouteName from "../../router/name";
|
||||||
import ReportModal from "@/components/Report/ReportModal.vue";
|
import ReportModal from "@/components/Report/ReportModal.vue";
|
||||||
|
@ -678,11 +617,7 @@ import {
|
||||||
PERSON_STATUS_GROUP,
|
PERSON_STATUS_GROUP,
|
||||||
} from "@/graphql/actor";
|
} from "@/graphql/actor";
|
||||||
import LazyImageWrapper from "../../components/Image/LazyImageWrapper.vue";
|
import LazyImageWrapper from "../../components/Image/LazyImageWrapper.vue";
|
||||||
import EventMetadataBlock from "../../components/Event/EventMetadataBlock.vue";
|
|
||||||
import EmptyContent from "../../components/Utils/EmptyContent.vue";
|
import EmptyContent from "../../components/Utils/EmptyContent.vue";
|
||||||
import { Paginate } from "@/types/paginate";
|
|
||||||
import { IEvent } from "@/types/event.model";
|
|
||||||
import { IPost } from "@/types/post.model";
|
|
||||||
import {
|
import {
|
||||||
FOLLOW_GROUP,
|
FOLLOW_GROUP,
|
||||||
UNFOLLOW_GROUP,
|
UNFOLLOW_GROUP,
|
||||||
|
@ -715,6 +650,7 @@ import { Dialog } from "@/plugins/dialog";
|
||||||
import { Notifier } from "@/plugins/notifier";
|
import { Notifier } from "@/plugins/notifier";
|
||||||
import { useGroupResourcesList } from "@/composition/apollo/resources";
|
import { useGroupResourcesList } from "@/composition/apollo/resources";
|
||||||
import { useGroupMembers } from "@/composition/apollo/members";
|
import { useGroupMembers } from "@/composition/apollo/members";
|
||||||
|
import GroupSection from "@/components/Group/GroupSection.vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
preferredUsername: string;
|
preferredUsername: string;
|
||||||
|
@ -1092,32 +1028,6 @@ const ableToReport = computed((): boolean => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const organizedEvents = computed((): Paginate<IEvent> => {
|
|
||||||
return {
|
|
||||||
total: group.value?.organizedEvents.total ?? 0,
|
|
||||||
elements:
|
|
||||||
group.value?.organizedEvents.elements.filter((event: IEvent) => {
|
|
||||||
if (previewPublic.value) {
|
|
||||||
return !event.draft; // TODO when events get visibility access add visibility constraint like below for posts
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}) ?? [],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const posts = computed((): Paginate<IPost> => {
|
|
||||||
return {
|
|
||||||
total: group.value?.posts.total ?? 0,
|
|
||||||
elements:
|
|
||||||
group.value?.posts.elements.filter((post: IPost) => {
|
|
||||||
if (previewPublic.value || !isCurrentActorAGroupMember.value) {
|
|
||||||
return !post.draft && post.visibility == PostVisibility.PUBLIC;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}) ?? [],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const showFollowButton = computed((): boolean => {
|
const showFollowButton = computed((): boolean => {
|
||||||
return !isCurrentActorFollowing.value || previewPublic.value;
|
return !isCurrentActorFollowing.value || previewPublic.value;
|
||||||
});
|
});
|
||||||
|
@ -1244,10 +1154,6 @@ div.container {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.map-show-button {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
address {
|
address {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue