Introduce group basic federation, event new page and notifications
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -1,104 +1,123 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-table
|
||||
v-show="relayFollowers.elements.length > 0"
|
||||
:data="relayFollowers.elements"
|
||||
:loading="$apollo.queries.relayFollowers.loading"
|
||||
ref="table"
|
||||
:checked-rows.sync="checkedRows"
|
||||
detailed
|
||||
:show-detail-icon="false"
|
||||
paginated
|
||||
backend-pagination
|
||||
:total="relayFollowers.total"
|
||||
:per-page="perPage"
|
||||
@page-change="onPageChange"
|
||||
checkable
|
||||
checkbox-position="left">
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="actor.id" label="ID" width="40" numeric>
|
||||
{{ props.row.actor.id }}
|
||||
</b-table-column>
|
||||
<div>
|
||||
<b-table
|
||||
v-show="relayFollowers.elements.length > 0"
|
||||
:data="relayFollowers.elements"
|
||||
:loading="$apollo.queries.relayFollowers.loading"
|
||||
ref="table"
|
||||
:checked-rows.sync="checkedRows"
|
||||
detailed
|
||||
:show-detail-icon="false"
|
||||
paginated
|
||||
backend-pagination
|
||||
:total="relayFollowers.total"
|
||||
:per-page="perPage"
|
||||
@page-change="onPageChange"
|
||||
checkable
|
||||
checkbox-position="left"
|
||||
>
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="actor.id" label="ID" width="40" numeric>{{
|
||||
props.row.actor.id
|
||||
}}</b-table-column>
|
||||
|
||||
<b-table-column field="actor.type" :label="$t('Type')" width="80">
|
||||
<b-icon icon="lan" v-if="isInstance(props.row.actor)" />
|
||||
<b-icon icon="account-circle" v-else />
|
||||
</b-table-column>
|
||||
<b-table-column field="actor.type" :label="$t('Type')" width="80">
|
||||
<b-icon icon="lan" v-if="RelayMixin.isInstance(props.row.actor)" />
|
||||
<b-icon icon="account-circle" v-else />
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column field="approved" :label="$t('Status')" width="100" sortable centered>
|
||||
<span :class="`tag ${props.row.approved ? 'is-success' : 'is-danger' }`">
|
||||
{{ props.row.approved ? $t('Accepted') : $t('Pending') }}
|
||||
</span>
|
||||
</b-table-column>
|
||||
<b-table-column field="approved" :label="$t('Status')" width="100" sortable centered>
|
||||
<span :class="`tag ${props.row.approved ? 'is-success' : 'is-danger'}`">{{
|
||||
props.row.approved ? $t("Accepted") : $t("Pending")
|
||||
}}</span>
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column field="actor.domain" :label="$t('Domain')" sortable>
|
||||
<template>
|
||||
<a @click="toggle(props.row)" v-if="isInstance(props.row.actor)">
|
||||
{{ props.row.actor.domain }}
|
||||
</a>
|
||||
<a @click="toggle(props.row)" v-else>
|
||||
{{ `${props.row.actor.preferredUsername}@${props.row.actor.domain}` }}
|
||||
</a>
|
||||
</template>
|
||||
</b-table-column>
|
||||
<b-table-column field="actor.domain" :label="$t('Domain')" sortable>
|
||||
<template>
|
||||
<a @click="toggle(props.row)" v-if="RelayMixin.isInstance(props.row.actor)">{{
|
||||
props.row.actor.domain
|
||||
}}</a>
|
||||
<a @click="toggle(props.row)" v-else>{{
|
||||
`${props.row.actor.preferredUsername}@${props.row.actor.domain}`
|
||||
}}</a>
|
||||
</template>
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column field="actor.updatedAt" :label="$t('Date')" sortable>
|
||||
{{ props.row.updatedAt | formatDateTimeString }}
|
||||
</b-table-column>
|
||||
</template>
|
||||
<b-table-column field="actor.updatedAt" :label="$t('Date')" sortable>{{
|
||||
props.row.updatedAt | formatDateTimeString
|
||||
}}</b-table-column>
|
||||
</template>
|
||||
|
||||
<template slot="detail" slot-scope="props">
|
||||
<article>
|
||||
<div class="content">
|
||||
<strong>{{ props.row.actor.domain }}</strong>
|
||||
<small>@{{ props.row.actor.preferredUsername }}</small>
|
||||
<small>31m</small>
|
||||
<br>
|
||||
<p v-html="props.row.actor.summary" />
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
<template slot="detail" slot-scope="props">
|
||||
<article>
|
||||
<div class="content">
|
||||
<strong>{{ props.row.actor.domain }}</strong>
|
||||
<small>@{{ props.row.actor.preferredUsername }}</small>
|
||||
<small>31m</small>
|
||||
<br />
|
||||
<p v-html="props.row.actor.summary" />
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<template slot="bottom-left" v-if="checkedRows.length > 0">
|
||||
<div class="buttons">
|
||||
<b-button @click="acceptRelays" type="is-success" v-if="checkedRowsHaveAtLeastOneToApprove">
|
||||
{{ $tc('No instance to approve|Approve instance|Approve {number} instances', checkedRows.length, { number: checkedRows.length }) }}
|
||||
</b-button>
|
||||
<b-button @click="rejectRelays" type="is-danger">
|
||||
{{ $tc('No instance to reject|Reject instance|Reject {number} instances', checkedRows.length, { number: checkedRows.length }) }}
|
||||
</b-button>
|
||||
</div>
|
||||
</template>
|
||||
</b-table>
|
||||
<b-message type="is-danger" v-if="relayFollowers.elements.length === 0">
|
||||
{{ $t("No instance follows your instance yet.") }}
|
||||
</b-message>
|
||||
</div>
|
||||
<template slot="bottom-left" v-if="checkedRows.length > 0">
|
||||
<div class="buttons">
|
||||
<b-button
|
||||
@click="acceptRelays"
|
||||
type="is-success"
|
||||
v-if="checkedRowsHaveAtLeastOneToApprove"
|
||||
>
|
||||
{{
|
||||
$tc(
|
||||
"No instance to approve|Approve instance|Approve {number} instances",
|
||||
checkedRows.length,
|
||||
{ number: checkedRows.length }
|
||||
)
|
||||
}}
|
||||
</b-button>
|
||||
<b-button @click="rejectRelays" type="is-danger">
|
||||
{{
|
||||
$tc(
|
||||
"No instance to reject|Reject instance|Reject {number} instances",
|
||||
checkedRows.length,
|
||||
{ number: checkedRows.length }
|
||||
)
|
||||
}}
|
||||
</b-button>
|
||||
</div>
|
||||
</template>
|
||||
</b-table>
|
||||
<b-message type="is-danger" v-if="relayFollowers.elements.length === 0">{{
|
||||
$t("No instance follows your instance yet.")
|
||||
}}</b-message>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Mixins } from 'vue-property-decorator';
|
||||
import { ACCEPT_RELAY, REJECT_RELAY, RELAY_FOLLOWERS } from '@/graphql/admin';
|
||||
import { Paginate } from '@/types/paginate';
|
||||
import { IFollower } from '@/types/actor/follower.model';
|
||||
import RelayMixin from '@/mixins/relay';
|
||||
import { Component, Mixins } from "vue-property-decorator";
|
||||
import { ACCEPT_RELAY, REJECT_RELAY, RELAY_FOLLOWERS } from "../../graphql/admin";
|
||||
import { Paginate } from "../../types/paginate";
|
||||
import { IFollower } from "../../types/actor/follower.model";
|
||||
import RelayMixin from "../../mixins/relay";
|
||||
|
||||
@Component({
|
||||
apollo: {
|
||||
relayFollowers: {
|
||||
query: RELAY_FOLLOWERS,
|
||||
fetchPolicy: 'cache-and-network',
|
||||
fetchPolicy: "cache-and-network",
|
||||
},
|
||||
},
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.$t('Followers') as string,
|
||||
titleTemplate: '%s | Mobilizon',
|
||||
title: this.$t("Followers") as string,
|
||||
titleTemplate: "%s | Mobilizon",
|
||||
};
|
||||
},
|
||||
})
|
||||
export default class Followers extends Mixins(RelayMixin) {
|
||||
relayFollowers: Paginate<IFollower> = { elements: [], total: 0 };
|
||||
|
||||
RelayMixin = RelayMixin;
|
||||
|
||||
async acceptRelays() {
|
||||
await this.checkedRows.forEach((row: IFollower) => {
|
||||
this.acceptRelay(`${row.actor.preferredUsername}@${row.actor.domain}`);
|
||||
@@ -111,7 +130,7 @@ export default class Followers extends Mixins(RelayMixin) {
|
||||
});
|
||||
}
|
||||
|
||||
async acceptRelay(address: String) {
|
||||
async acceptRelay(address: string) {
|
||||
await this.$apollo.mutate({
|
||||
mutation: ACCEPT_RELAY,
|
||||
variables: {
|
||||
@@ -122,7 +141,7 @@ export default class Followers extends Mixins(RelayMixin) {
|
||||
this.checkedRows = [];
|
||||
}
|
||||
|
||||
async rejectRelay(address: String) {
|
||||
async rejectRelay(address: string) {
|
||||
await this.$apollo.mutate({
|
||||
mutation: REJECT_RELAY,
|
||||
variables: {
|
||||
@@ -134,7 +153,7 @@ export default class Followers extends Mixins(RelayMixin) {
|
||||
}
|
||||
|
||||
get checkedRowsHaveAtLeastOneToApprove(): boolean {
|
||||
return this.checkedRows.some(checkedRow => !checkedRow.approved);
|
||||
return this.checkedRows.some((checkedRow) => !checkedRow.approved);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -1,125 +1,134 @@
|
||||
<template>
|
||||
<div>
|
||||
<form @submit="followRelay">
|
||||
<b-field :label="$t('Add an instance')" custom-class="add-relay" horizontal>
|
||||
<b-field grouped expanded size="is-large">
|
||||
<p class="control">
|
||||
<b-input v-model="newRelayAddress" :placeholder="$t('Ex: test.mobilizon.org')" />
|
||||
</p>
|
||||
<p class="control">
|
||||
<b-button type="is-primary" native-type="submit">{{ $t('Add an instance') }}</b-button>
|
||||
</p>
|
||||
</b-field>
|
||||
</b-field>
|
||||
</form>
|
||||
<b-table
|
||||
v-show="relayFollowings.elements.length > 0"
|
||||
:data="relayFollowings.elements"
|
||||
:loading="$apollo.queries.relayFollowings.loading"
|
||||
ref="table"
|
||||
:checked-rows.sync="checkedRows"
|
||||
:is-row-checkable="(row) => row.id !== 3"
|
||||
detailed
|
||||
:show-detail-icon="false"
|
||||
paginated
|
||||
backend-pagination
|
||||
:total="relayFollowings.total"
|
||||
:per-page="perPage"
|
||||
@page-change="onPageChange"
|
||||
checkable
|
||||
checkbox-position="left">
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="targetActor.id" label="ID" width="40" numeric>
|
||||
{{ props.row.targetActor.id }}
|
||||
</b-table-column>
|
||||
<div>
|
||||
<form @submit="followRelay">
|
||||
<b-field :label="$t('Add an instance')" custom-class="add-relay" horizontal>
|
||||
<b-field grouped expanded size="is-large">
|
||||
<p class="control">
|
||||
<b-input v-model="newRelayAddress" :placeholder="$t('Ex: test.mobilizon.org')" />
|
||||
</p>
|
||||
<p class="control">
|
||||
<b-button type="is-primary" native-type="submit">{{ $t("Add an instance") }}</b-button>
|
||||
</p>
|
||||
</b-field>
|
||||
</b-field>
|
||||
</form>
|
||||
<b-table
|
||||
v-show="relayFollowings.elements.length > 0"
|
||||
:data="relayFollowings.elements"
|
||||
:loading="$apollo.queries.relayFollowings.loading"
|
||||
ref="table"
|
||||
:checked-rows.sync="checkedRows"
|
||||
:is-row-checkable="(row) => row.id !== 3"
|
||||
detailed
|
||||
:show-detail-icon="false"
|
||||
paginated
|
||||
backend-pagination
|
||||
:total="relayFollowings.total"
|
||||
:per-page="perPage"
|
||||
@page-change="onPageChange"
|
||||
checkable
|
||||
checkbox-position="left"
|
||||
>
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="targetActor.id" label="ID" width="40" numeric>{{
|
||||
props.row.targetActor.id
|
||||
}}</b-table-column>
|
||||
|
||||
<b-table-column field="targetActor.type" :label="$t('Type')" width="80">
|
||||
<b-icon icon="lan" v-if="isInstance(props.row.targetActor)" />
|
||||
<b-icon icon="account-circle" v-else />
|
||||
</b-table-column>
|
||||
<b-table-column field="targetActor.type" :label="$t('Type')" width="80">
|
||||
<b-icon icon="lan" v-if="RelayMixin.isInstance(props.row.targetActor)" />
|
||||
<b-icon icon="account-circle" v-else />
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column field="approved" :label="$t('Status')" width="100" sortable centered>
|
||||
<span :class="`tag ${props.row.approved ? 'is-success' : 'is-danger' }`">
|
||||
{{ props.row.approved ? $t('Accepted') : $t('Pending') }}
|
||||
</span>
|
||||
</b-table-column>
|
||||
<b-table-column field="approved" :label="$t('Status')" width="100" sortable centered>
|
||||
<span :class="`tag ${props.row.approved ? 'is-success' : 'is-danger'}`">{{
|
||||
props.row.approved ? $t("Accepted") : $t("Pending")
|
||||
}}</span>
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column field="targetActor.domain" :label="$t('Domain')" sortable>
|
||||
<template>
|
||||
<a @click="toggle(props.row)" v-if="isInstance(props.row.targetActor)">
|
||||
{{ props.row.targetActor.domain }}
|
||||
</a>
|
||||
<a @click="toggle(props.row)" v-else>
|
||||
{{ `${props.row.targetActor.preferredUsername}@${props.row.targetActor.domain}` }}
|
||||
</a>
|
||||
</template>
|
||||
</b-table-column>
|
||||
<b-table-column field="targetActor.domain" :label="$t('Domain')" sortable>
|
||||
<template>
|
||||
<a @click="toggle(props.row)" v-if="RelayMixin.isInstance(props.row.targetActor)">{{
|
||||
props.row.targetActor.domain
|
||||
}}</a>
|
||||
<a @click="toggle(props.row)" v-else>{{
|
||||
`${props.row.targetActor.preferredUsername}@${props.row.targetActor.domain}`
|
||||
}}</a>
|
||||
</template>
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column field="targetActor.updatedAt" :label="$t('Date')" sortable>
|
||||
{{ props.row.updatedAt | formatDateTimeString }}
|
||||
</b-table-column>
|
||||
</template>
|
||||
<b-table-column field="targetActor.updatedAt" :label="$t('Date')" sortable>{{
|
||||
props.row.updatedAt | formatDateTimeString
|
||||
}}</b-table-column>
|
||||
</template>
|
||||
|
||||
<template slot="detail" slot-scope="props">
|
||||
<article>
|
||||
<div class="content">
|
||||
<strong>{{ props.row.targetActor.domain }}</strong>
|
||||
<small>@{{ props.row.targetActor.preferredUsername }}</small>
|
||||
<small>31m</small>
|
||||
<br>
|
||||
<p v-html="props.row.targetActor.summary" />
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
<template slot="detail" slot-scope="props">
|
||||
<article>
|
||||
<div class="content">
|
||||
<strong>{{ props.row.targetActor.domain }}</strong>
|
||||
<small>@{{ props.row.targetActor.preferredUsername }}</small>
|
||||
<small>31m</small>
|
||||
<br />
|
||||
<p v-html="props.row.targetActor.summary" />
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<template slot="bottom-left" v-if="checkedRows.length > 0">
|
||||
<b-button @click="removeRelays" type="is-danger">
|
||||
{{ $tc('No instance to remove|Remove instance|Remove {number} instances', checkedRows.length, { number: checkedRows.length }) }}
|
||||
</b-button>
|
||||
</template>
|
||||
</b-table>
|
||||
<b-message type="is-danger" v-if="relayFollowings.elements.length === 0">
|
||||
{{ $t("You don't follow any instances yet.") }}
|
||||
</b-message>
|
||||
</div>
|
||||
<template slot="bottom-left" v-if="checkedRows.length > 0">
|
||||
<b-button @click="removeRelays" type="is-danger">
|
||||
{{
|
||||
$tc(
|
||||
"No instance to remove|Remove instance|Remove {number} instances",
|
||||
checkedRows.length,
|
||||
{ number: checkedRows.length }
|
||||
)
|
||||
}}
|
||||
</b-button>
|
||||
</template>
|
||||
</b-table>
|
||||
<b-message type="is-danger" v-if="relayFollowings.elements.length === 0">{{
|
||||
$t("You don't follow any instances yet.")
|
||||
}}</b-message>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Mixins } from 'vue-property-decorator';
|
||||
import { ADD_RELAY, RELAY_FOLLOWINGS, REMOVE_RELAY } from '@/graphql/admin';
|
||||
import { IFollower } from '@/types/actor/follower.model';
|
||||
import { Paginate } from '@/types/paginate';
|
||||
import RelayMixin from '@/mixins/relay';
|
||||
import { Component, Mixins } from "vue-property-decorator";
|
||||
import { ADD_RELAY, RELAY_FOLLOWINGS, REMOVE_RELAY } from "../../graphql/admin";
|
||||
import { IFollower } from "../../types/actor/follower.model";
|
||||
import { Paginate } from "../../types/paginate";
|
||||
import RelayMixin from "../../mixins/relay";
|
||||
|
||||
@Component({
|
||||
apollo: {
|
||||
relayFollowings: {
|
||||
query: RELAY_FOLLOWINGS,
|
||||
fetchPolicy: 'cache-and-network',
|
||||
fetchPolicy: "cache-and-network",
|
||||
},
|
||||
},
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.$t('Followings') as string,
|
||||
titleTemplate: '%s | Mobilizon',
|
||||
title: this.$t("Followings") as string,
|
||||
titleTemplate: "%s | Mobilizon",
|
||||
};
|
||||
},
|
||||
})
|
||||
export default class Followings extends Mixins(RelayMixin) {
|
||||
|
||||
relayFollowings: Paginate<IFollower> = { elements: [], total: 0 };
|
||||
newRelayAddress: String = '';
|
||||
|
||||
async followRelay(e) {
|
||||
newRelayAddress = "";
|
||||
|
||||
RelayMixin = RelayMixin;
|
||||
|
||||
async followRelay(e: Event) {
|
||||
e.preventDefault();
|
||||
await this.$apollo.mutate({
|
||||
mutation: ADD_RELAY,
|
||||
variables: {
|
||||
address: this.newRelayAddress,
|
||||
},
|
||||
// TODO: Handle cache update properly without refreshing
|
||||
// TODO: Handle cache update properly without refreshing
|
||||
});
|
||||
await this.$apollo.queries.relayFollowings.refetch();
|
||||
this.newRelayAddress = '';
|
||||
this.newRelayAddress = "";
|
||||
}
|
||||
|
||||
async removeRelays() {
|
||||
@@ -128,7 +137,7 @@ export default class Followings extends Mixins(RelayMixin) {
|
||||
});
|
||||
}
|
||||
|
||||
async removeRelay(address: String) {
|
||||
async removeRelay(address: string) {
|
||||
await this.$apollo.mutate({
|
||||
mutation: REMOVE_RELAY,
|
||||
variables: {
|
||||
@@ -139,4 +148,4 @@ export default class Followings extends Mixins(RelayMixin) {
|
||||
this.checkedRows = [];
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user