Add a breadcrumbs component

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
chapril
Thomas Citharel 1 year ago
parent 40758a83d5
commit 1daa8c5f5a
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773

@ -0,0 +1,69 @@
<template>
<nav class="flex mb-3" :aria-label="$t('Breadcrumbs')">
<ol class="inline-flex items-center space-x-1 md:space-x-3">
<li
class="inline-flex items-center"
v-for="(element, index) in links"
:key="index"
:aria-current="index > 0 ? 'page' : undefined"
>
<router-link
v-if="index === 0"
:to="element"
class="inline-flex items-center text-gray-700 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
>
{{ element.text }}
</router-link>
<div class="flex items-center" v-else-if="index === links.length - 1">
<svg
class="w-6 h-6 text-gray-400 rtl:rotate-180"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
></path>
</svg>
<span
class="ltr:ml-1 rtl:mr-1 font-medium text-gray-400 md:ltr:ml-2 md:rtl:mr-2 dark:text-gray-500"
>{{ element.text }}</span
>
</div>
<div class="flex items-center" v-else>
<svg
class="w-6 h-6 text-gray-400 rtl:rotate-180"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
></path>
</svg>
<router-link
:to="element"
class="ltr:ml-1 rtl:mr-1 font-medium text-gray-700 hover:text-gray-900 md:ltr:ml-2 md:rtl:mr-2 dark:text-gray-400 dark:hover:text-white"
>{{ element.text }}</router-link
>
</div>
</li>
<slot></slot>
</ol>
</nav>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { Location } from "vue-router";
type LinkElement = Location & { text: string };
@Component
export default class Breadcrumbs extends Vue {
@Prop({ type: Array, required: true }) links!: LinkElement[];
}
</script>

@ -12,6 +12,7 @@ import { NotifierPlugin } from "./plugins/notifier";
import filters from "./filters";
import { i18n } from "./utils/i18n";
import apolloProvider from "./vue-apollo";
import Breadcrumbs from "@/components/Utils/Breadcrumbs.vue";
import "./registerServiceWorker";
import "./assets/tailwind.css";
@ -25,6 +26,7 @@ Vue.use(VueScrollTo);
Vue.use(VTooltip);
Vue.use(VueAnnouncer);
Vue.use(VueSkipTo);
Vue.component("breadcrumbs-nav", Breadcrumbs);
// Register the router hooks with their names
Component.registerHooks([

@ -1,28 +1,6 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.IDENTITIES }">{{
$t("Profiles")
}}</router-link>
</li>
<li class="is-active" v-if="isUpdate && identity">
<router-link
:to="{
name: RouteName.UPDATE_IDENTITY,
params: { identityName: identity.preferredUsername },
}"
>{{ identity.name }}</router-link
>
</li>
<li class="is-active" v-else>
<router-link :to="{ name: RouteName.CREATE_IDENTITY }">{{
$t("New profile")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav :links="breadcrumbsLinks" />
<div class="root" v-if="identity">
<h1 class="title">
<span v-if="isUpdate">{{ identity.displayName() }}</span>
@ -253,6 +231,7 @@ import { ServerParseError } from "@apollo/client/link/http";
import { ApolloCache, FetchResult, InMemoryCache } from "@apollo/client/core";
import pick from "lodash/pick";
import { ActorType } from "@/types/enums";
import { Location } from "vue-router";
@Component({
components: {
@ -670,5 +649,29 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
this.oldDisplayName = null;
this.avatarFile = null;
}
get breadcrumbsLinks(): (Location & { text: string })[] {
const links = [
{
name: RouteName.IDENTITIES,
params: {},
text: this.$t("Profiles") as string,
},
];
if (this.isUpdate && this.identity) {
links.push({
name: RouteName.UPDATE_IDENTITY,
params: { identityName: this.identity.preferredUsername },
text: this.identity.name,
});
} else {
links.push({
name: RouteName.CREATE_IDENTITY,
params: {},
text: this.$t("New profile") as string,
});
}
return links;
}
}
</script>

@ -1,31 +1,19 @@
<template>
<div v-if="group" class="section">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li>
<router-link
:to="{
name: RouteName.ADMIN_GROUPS,
}"
>{{ $t("Groups") }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.PROFILES,
params: { id: group.id },
}"
>{{ group.name || usernameWithDomain(group) }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{
name: RouteName.ADMIN_GROUPS,
text: $t('Groups'),
},
{
name: RouteName.PROFILES,
params: { id: group.id },
text: displayName(group),
},
]"
/>
<div class="actor-card">
<p v-if="group.suspended">
<actor-card
@ -305,7 +293,11 @@ import { formatBytes } from "@/utils/datetime";
import { MemberRole } from "@/types/enums";
import { SUSPEND_PROFILE, UNSUSPEND_PROFILE } from "../../graphql/actor";
import { IGroup } from "../../types/actor";
import { usernameWithDomain, IActor } from "../../types/actor/actor.model";
import {
usernameWithDomain,
displayName,
IActor,
} from "../../types/actor/actor.model";
import RouteName from "../../router/name";
import ActorCard from "../../components/Account/ActorCard.vue";
import EmptyContent from "../../components/Utils/EmptyContent.vue";
@ -359,6 +351,8 @@ export default class AdminGroupProfile extends Vue {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
RouteName = RouteName;
EVENTS_PER_PAGE = EVENTS_PER_PAGE;

@ -1,31 +1,20 @@
<template>
<div v-if="person" class="section">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li>
<router-link
:to="{
name: RouteName.PROFILES,
}"
>{{ $t("Profiles") }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.PROFILES,
params: { id: person.id },
}"
>{{ person.name || person.preferredUsername }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{
name: RouteName.PROFILES,
text: $t('Profiles'),
},
{
name: RouteName.PROFILES,
params: { id: person.id },
text: displayName(person),
},
]"
/>
<div class="actor-card">
<actor-card
:actor="person"
@ -279,7 +268,7 @@ import {
UNSUSPEND_PROFILE,
} from "../../graphql/actor";
import { IPerson } from "../../types/actor";
import { usernameWithDomain } from "../../types/actor/actor.model";
import { displayName, usernameWithDomain } from "../../types/actor/actor.model";
import RouteName from "../../router/name";
import ActorCard from "../../components/Account/ActorCard.vue";
import EmptyContent from "../../components/Utils/EmptyContent.vue";
@ -334,6 +323,8 @@ export default class AdminProfile extends Vue {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
RouteName = RouteName;
EVENTS_PER_PAGE = EVENTS_PER_PAGE;

@ -1,31 +1,20 @@
<template>
<div v-if="user" class="section">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li>
<router-link
:to="{
name: RouteName.USERS,
}"
>{{ $t("Users") }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.ADMIN_USER_PROFILE,
params: { id: user.id },
}"
>{{ user.email }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{
name: RouteName.USERS,
text: $t('Users'),
},
{
name: RouteName.ADMIN_USER_PROFILE,
params: { id: user.id },
text: user.email,
},
]"
/>
<table v-if="metadata.length > 0" class="table is-fullwidth">
<tbody>
<tr v-for="{ key, value, link, elements, type } in metadata" :key="key">

@ -1,19 +1,11 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.ADMIN_DASHBOARD }">{{
$t("Dashboard")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{ text: $t('Dashboard') },
]"
/>
<section>
<h1 class="title">{{ $t("Administration") }}</h1>
<div class="tile is-ancestor" v-if="dashboard">

@ -1,19 +1,14 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{
$t("Moderation")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.PROFILES }">{{
$t("Groups")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.MODERATION, text: $t('Moderation') },
{
name: RouteName.ADMIN_GROUPS,
text: $t('Groups'),
},
]"
/>
<div class="buttons" v-if="showCreateGroupsButton">
<router-link
class="button is-primary"

@ -1,28 +1,12 @@
<template>
<div v-if="instance">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li>
<router-link :to="{ name: RouteName.INSTANCES }">{{
$t("Instances")
}}</router-link>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.INSTANCE,
params: { domain: instance.domain },
}"
>{{ instance.domain }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{ name: RouteName.INSTANCES, text: $t('Instances') },
{ text: instance.domain },
]"
/>
<h1 class="text-2xl">{{ instance.domain }}</h1>
<div class="grid md:grid-cols-4 gap-2 content-center text-center mt-2">
<div class="bg-gray-50 rounded-xl p-8 dark:bg-gray-800">

@ -1,28 +1,16 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.INSTANCES }">{{
$t("Instances")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{ text: $t('Instances') },
]"
/>
<section>
<h1 class="title">{{ $t("Instances") }}</h1>
<form @submit="followInstance" class="my-4">
<b-field
:label="$t('Follow a new instance')"
custom-class="add-relay"
horizontal
>
<b-field grouped expanded size="is-large">
<b-field :label="$t('Follow a new instance')" horizontal>
<b-field grouped group-multiline expanded size="is-large">
<p class="control">
<b-input
v-model="newRelayAddress"

@ -1,19 +1,14 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{
$t("Moderation")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.PROFILES }">{{
$t("Profiles")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.MODERATION, text: $t('Moderation') },
{
name: RouteName.PROFILES,
text: $t('Profiles'),
},
]"
/>
<div v-if="persons">
<b-switch v-model="local">{{ $t("Local") }}</b-switch>
<b-switch v-model="suspended">{{ $t("Suspended") }}</b-switch>

@ -1,19 +1,12 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.ADMIN }">{{
$t("Admin")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.ADMIN_SETTINGS }">{{
$t("Instance settings")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.ADMIN, text: $t('Admin') },
{ text: $t('Instance settings') },
]"
/>
<section v-if="settingsToWrite">
<form @submit.prevent="updateSettings">
<b-field :label="$t('Instance Name')" label-for="instance-name">

@ -1,19 +1,14 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{
$t("Moderation")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.USERS }">{{
$t("Users")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.MODERATION, text: $t('Moderation') },
{
name: RouteName.USERS,
text: $t('Users'),
},
]"
/>
<div v-if="users">
<b-table
:data="users.elements"

@ -1,42 +1,29 @@
<template>
<section class="section container">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul v-if="group">
<li>
<router-link :to="{ name: RouteName.MY_GROUPS }">{{
$t("My groups")
}}</router-link>
</li>
<li>
<router-link
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ group.name }}</router-link
>
</li>
<li>
<router-link
:to="{
name: RouteName.DISCUSSION_LIST,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Discussions") }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.CREATE_DISCUSSION,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Create") }}</router-link
>
</li>
</ul>
<b-skeleton v-else-if="$apollo.loading" :animated="animated"></b-skeleton>
</nav>
<breadcrumbs-nav
v-if="group"
:links="[
{
name: RouteName.MY_GROUPS,
text: $t('My groups'),
},
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.DISCUSSION_LIST,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Discussions'),
},
{
name: RouteName.CREATE_DISCUSSION,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Create'),
},
]"
/>
<h1 class="title">{{ $t("Create a discussion") }}</h1>
<form @submit.prevent="createDiscussion">
@ -67,7 +54,12 @@
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { IGroup, IPerson, usernameWithDomain } from "@/types/actor";
import {
displayName,
IGroup,
IPerson,
usernameWithDomain,
} from "@/types/actor";
import { CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
import { FETCH_GROUP } from "@/graphql/group";
import { CREATE_DISCUSSION } from "@/graphql/discussion";
@ -113,6 +105,8 @@ export default class CreateDiscussion extends Vue {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
async createDiscussion(): Promise<void> {
this.errors = { title: "" };
try {

@ -1,46 +1,29 @@
<template>
<div class="container section" v-if="discussion">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MY_GROUPS }">{{
$t("My groups")
}}</router-link>
</li>
<li>
<router-link
v-if="discussion.actor"
:to="{
name: RouteName.GROUP,
params: {
preferredUsername: usernameWithDomain(discussion.actor),
},
}"
>{{ discussion.actor.name }}</router-link
>
<b-skeleton v-else-if="$apollo.loading" animated />
</li>
<li>
<router-link
v-if="discussion.actor"
:to="{
name: RouteName.DISCUSSION_LIST,
params: {
preferredUsername: usernameWithDomain(discussion.actor),
},
}"
>{{ $t("Discussions") }}</router-link
>
<b-skeleton animated v-else-if="$apollo.loading" />
</li>
<li class="is-active">
<router-link
:to="{ name: RouteName.DISCUSSION, params: { id: discussion.id } }"
>{{ discussion.title }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
v-if="group"
:links="[
{
name: RouteName.MY_GROUPS,
text: $t('My groups'),
},
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.DISCUSSION_LIST,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Discussions'),
},
{
name: RouteName.DISCUSSION,
params: { id: discussion.id },
text: discussion.title,
},
]"
/>
<b-message v-if="error" type="is-danger">
{{ error }}
</b-message>
@ -148,7 +131,7 @@ import {
} from "@/graphql/discussion";
import { IDiscussion } from "@/types/discussions";
import { Discussion as DiscussionModel } from "@/types/discussions";
import { usernameWithDomain } from "@/types/actor";
import { displayName, usernameWithDomain } from "@/types/actor";
import DiscussionComment from "@/components/Discussion/DiscussionComment.vue";
import { GraphQLError } from "graphql";
import { DELETE_COMMENT, UPDATE_COMMENT } from "@/graphql/comment";
@ -250,6 +233,7 @@ export default class Discussion extends mixins(GroupMixin) {
RouteName = RouteName;
usernameWithDomain = usernameWithDomain;
displayName = displayName;
error: string | null = null;
async reply(): Promise<void> {

@ -1,32 +1,23 @@
<template>
<div class="container section" v-if="group">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MY_GROUPS }">{{
$t("My groups")
}}</router-link>
</li>
<li>
<router-link
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ group.name }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.DISCUSSION_LIST,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Discussions") }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{
name: RouteName.MY_GROUPS,
text: $t('My groups'),
},
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.DISCUSSION_LIST,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Discussions'),
},
]"
/>
<section v-if="isCurrentActorAGroupMember">
<p>
{{
@ -82,7 +73,13 @@
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { FETCH_GROUP } from "@/graphql/group";
import { IActor, IGroup, IPerson, usernameWithDomain } from "@/types/actor";
import {
displayName,
IActor,
IGroup,
IPerson,
usernameWithDomain,
} from "@/types/actor";
import DiscussionListItem from "@/components/Discussion/DiscussionListItem.vue";
import RouteName from "../../router/name";
import { MemberRole } from "@/types/enums";
@ -166,6 +163,7 @@ export default class DiscussionsList extends Vue {
RouteName = RouteName;
usernameWithDomain = usernameWithDomain;
displayName = displayName;
DISCUSSIONS_PER_PAGE = DISCUSSIONS_PER_PAGE;

@ -1,27 +1,19 @@
<template>
<div class="container section" v-if="group">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ group.name }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.TODO_LISTS,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Events") }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.EVENTS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Events'),
},
]"
/>
<section>
<h1 class="title" v-if="group">
{{
@ -89,7 +81,7 @@ import { PERSON_MEMBERSHIPS } from "@/graphql/actor";
import GroupMixin from "@/mixins/group";
import { IMember } from "@/types/actor/member.model";
import { FETCH_GROUP_EVENTS } from "@/graphql/event";
import { usernameWithDomain } from "../../types/actor";
import { displayName, usernameWithDomain } from "../../types/actor";
const EVENTS_PAGE_LIMIT = 10;
@ -143,6 +135,8 @@ export default class GroupEvents extends mixins(GroupMixin) {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
RouteName = RouteName;
EVENTS_PAGE_LIMIT = EVENTS_PAGE_LIMIT;

@ -1,32 +1,20 @@
<template>
<section class="section container" v-if="event">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MY_EVENTS }">{{
$t("My events")
}}</router-link>
</li>
<li>
<router-link
:to="{
name: RouteName.EVENT,
params: { uuid: event.uuid },
}"
>{{ event.title }}</router-link
>
</li>
<li class="is-active">
<router-link
:to="{
name: RouteName.PARTICIPANTS,
params: { uuid: event.uuid },
}"
>{{ $t("Participants") }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{ name: RouteName.MY_EVENTS, text: $t('My events') },
{
name: RouteName.EVENT,
params: { uuid: event.uuid },
text: event.title,
},
{
name: RouteName.PARTICIPANTS,
params: { uuid: event.uuid },
text: $t('Participants'),
},
]"
/>
<h1 class="title">{{ $t("Participants") }}</h1>
<div class="level">
<div class="level-left">

@ -1,27 +1,17 @@
<template>
<div class="container is-widescreen">
<div class="header">
<nav class="breadcrumb" :aria-label="$t('Breadcrumbs')">
<ul>
<li>
<router-link :to="{ name: RouteName.MY_GROUPS }">{{
$t("My groups")
}}</router-link>
</li>
<li class="is-active">
<router-link
aria-current-value="location"
v-if="group && group.preferredUsername"
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ group.name }}</router-link
>
<b-skeleton v-else :animated="true"></b-skeleton>
</li>
</ul>
</nav>
<breadcrumbs-nav
v-if="group"
:links="[
{ name: RouteName.MY_GROUPS, text: $t('My groups') },
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
]"
/>
<b-loading :active.sync="$apollo.loading"></b-loading>
<header class="block-container presentation" v-if="group">
<div class="banner-container">
@ -776,6 +766,8 @@ export default class Group extends mixins(GroupMixin) {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
PostVisibility = PostVisibility;
Openness = Openness;

@ -1,36 +1,25 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul v-if="group">
<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_FOLLOWERS_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Followers") }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
v-if="group"
:links="[
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.GROUP_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Settings'),
},
{
name: RouteName.GROUP_FOLLOWERS_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Followers'),
},
]"
/>
<b-loading :active="$apollo.loading" />
<section
class="container section"
@ -138,7 +127,7 @@ import GroupMixin from "@/mixins/group";
import { mixins } from "vue-class-component";
import { GROUP_FOLLOWERS, UPDATE_FOLLOWER } from "@/graphql/followers";
import RouteName from "../../router/name";
import { usernameWithDomain } from "../../types/actor";
import { displayName, usernameWithDomain } from "../../types/actor";
import EmptyContent from "@/components/Utils/EmptyContent.vue";
import { IFollower } from "@/types/actor/follower.model";
import { Paginate } from "@/types/paginate";
@ -181,6 +170,8 @@ export default class GroupFollowers extends mixins(GroupMixin) {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
followers!: Paginate<IFollower>;
mounted(): void {

@ -1,36 +1,25 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul v-if="group">
<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_MEMBERS_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Members") }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
v-if="group"
:links="[
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.GROUP_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Settings'),
},
{
name: RouteName.GROUP_MEMBERS_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Members'),
},
]"
/>
<b-loading :active="$apollo.loading" />
<section
class="container section"
@ -312,6 +301,8 @@ export default class GroupMembers extends mixins(GroupMixin) {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
mounted(): void {
const roleQuery = this.$route.query.role as string;
if (Object.values(MemberRole).includes(roleQuery as MemberRole)) {

@ -1,37 +1,25 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link
v-if="group"
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ group.name || usernameWithDomain(group) }}</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>
<breadcrumbs-nav
v-if="group"
:links="[
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.GROUP_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Settings'),
},
{
name: RouteName.GROUP_PUBLIC_SETTINGS,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Group settings'),
},
]"
/>
<b-loading :active="$apollo.loading" />
<section
class="container section"
@ -197,7 +185,12 @@ import { mixins } from "vue-class-component";
import GroupMixin from "@/mixins/group";
import { GroupVisibility, Openness } from "@/types/enums";
import { UPDATE_GROUP } from "../../graphql/group";
import { Group, IGroup, usernameWithDomain } from "../../types/actor";
import {
Group,
IGroup,
usernameWithDomain,
displayName,
} from "../../types/actor";
import { Address, IAddress } from "../../types/address.model";
import { CONFIG } from "@/graphql/config";
import { IConfig } from "@/types/config.model";
@ -234,6 +227,8 @@ export default class GroupSettings extends mixins(GroupMixin) {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
GroupVisibility = GroupVisibility;
Openness = Openness;

@ -1,27 +1,21 @@
<template>
<div class="container section">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul v-if="group">
<li>
<router-link
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ group.name }}</router-link
>
</li>
<li>
<router-link
:to="{
name: RouteName.TIMELINE,
params: { preferredUsername: usernameWithDomain(group) },
}"
>{{ $t("Activity") }}</router-link
>
</li>
</ul>
</nav>
<breadcrumbs-nav
v-if="group"
:links="[
{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(group) },
text: displayName(group),
},
{
name: RouteName.TIMELINE,
params: { preferredUsername: usernameWithDomain(group) },
text: $t('Activity'),
},
]"
/>
<section class="timeline">
<b-field>
<b-radio-button v-model="activityType" :native-value="undefined">
@ -160,7 +154,7 @@
</template>
<script lang="ts">
import { GROUP_TIMELINE } from "@/graphql/group";
import { IGroup, usernameWithDomain } from "@/types/actor";
import { IGroup, usernameWithDomain, displayName } from "@/types/actor";
import { ActivityType } from "@/types/enums";
import { Paginate } from "@/types/paginate";
import { Component, Prop, Vue } from "vue-property-decorator";
@ -234,6 +228,8 @@ export default class Timeline extends Vue {
usernameWithDomain = usernameWithDomain;
displayName = displayName;
ActivityType = ActivityType;
ActivityAuthorFilter = ActivityAuthorFilter;

@ -1,19 +1,17 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{
$t("Moderation")
}}</router-link>
</li>
<li class="is-active">
<router-link :to="{ name: RouteName.REPORT_LOGS }">{{
$t("Moderation log")
}}</router-link>
</li>
</ul>
</nav>
<breadcrumbs-nav
:links="[
{
name: RouteName.MODERATION,
text: $t('Moderation'),
},
{
name: RouteName.REPORT_LOGS,
text: $t('Moderation log'),
},
]"
/>
<section v-if="actionLogs.total > 0 && actionLogs.elements.length > 0">
<ul>
<li v-for="log in actionLogs.elements" :key="log.id">

@ -1,27 +1,23 @@
<template>
<div>
<nav class="breadcrumb" aria-label="breadcrumbs" v-if="report">
<ul>
<li>
<router-link :to="{ name: RouteName.MODERATION }">{{
$t("Moderation")
}}</router-link>
</li>