Merge branch 'fix-followings-pagination' into 'master'

Fix followings/followers pagination

See merge request framasoft/mobilizon!657
This commit is contained in:
Thomas Citharel 2020-10-27 16:38:33 +01:00
commit 5eb746ffca
4 changed files with 96 additions and 46 deletions

View File

@ -12,7 +12,7 @@
backend-pagination backend-pagination
:total="relayFollowers.total" :total="relayFollowers.total"
:per-page="perPage" :per-page="perPage"
@page-change="onPageChange" @page-change="onFollowersPageChange"
checkable checkable
checkbox-position="left" checkbox-position="left"
> >
@ -103,18 +103,11 @@
import { Component, Mixins } from "vue-property-decorator"; import { Component, Mixins } from "vue-property-decorator";
import { SnackbarProgrammatic as Snackbar } from "buefy"; import { SnackbarProgrammatic as Snackbar } from "buefy";
import { formatDistanceToNow } from "date-fns"; import { formatDistanceToNow } from "date-fns";
import { ACCEPT_RELAY, REJECT_RELAY, RELAY_FOLLOWERS } from "../../graphql/admin"; import { ACCEPT_RELAY, REJECT_RELAY } from "../../graphql/admin";
import { Paginate } from "../../types/paginate";
import { IFollower } from "../../types/actor/follower.model"; import { IFollower } from "../../types/actor/follower.model";
import RelayMixin from "../../mixins/relay"; import RelayMixin from "../../mixins/relay";
@Component({ @Component({
apollo: {
relayFollowers: {
query: RELAY_FOLLOWERS,
fetchPolicy: "cache-and-network",
},
},
metaInfo() { metaInfo() {
return { return {
title: this.$t("Followers") as string, title: this.$t("Followers") as string,
@ -123,8 +116,6 @@ import RelayMixin from "../../mixins/relay";
}, },
}) })
export default class Followers extends Mixins(RelayMixin) { export default class Followers extends Mixins(RelayMixin) {
relayFollowers: Paginate<IFollower> = { elements: [], total: 0 };
RelayMixin = RelayMixin; RelayMixin = RelayMixin;
formatDistanceToNow = formatDistanceToNow; formatDistanceToNow = formatDistanceToNow;

View File

@ -25,7 +25,7 @@
backend-pagination backend-pagination
:total="relayFollowings.total" :total="relayFollowings.total"
:per-page="perPage" :per-page="perPage"
@page-change="onPageChange" @page-change="onFollowingsPageChange"
checkable checkable
checkbox-position="left" checkbox-position="left"
> >
@ -101,18 +101,12 @@
import { Component, Mixins } from "vue-property-decorator"; import { Component, Mixins } from "vue-property-decorator";
import { SnackbarProgrammatic as Snackbar } from "buefy"; import { SnackbarProgrammatic as Snackbar } from "buefy";
import { formatDistanceToNow } from "date-fns"; import { formatDistanceToNow } from "date-fns";
import { ADD_RELAY, RELAY_FOLLOWINGS, REMOVE_RELAY } from "../../graphql/admin"; import { ADD_RELAY, REMOVE_RELAY } from "../../graphql/admin";
import { IFollower } from "../../types/actor/follower.model"; import { IFollower } from "../../types/actor/follower.model";
import { Paginate } from "../../types/paginate"; import { Paginate } from "../../types/paginate";
import RelayMixin from "../../mixins/relay"; import RelayMixin from "../../mixins/relay";
@Component({ @Component({
apollo: {
relayFollowings: {
query: RELAY_FOLLOWINGS,
fetchPolicy: "cache-and-network",
},
},
metaInfo() { metaInfo() {
return { return {
title: this.$t("Followings") as string, title: this.$t("Followings") as string,
@ -121,8 +115,6 @@ import RelayMixin from "../../mixins/relay";
}, },
}) })
export default class Followings extends Mixins(RelayMixin) { export default class Followings extends Mixins(RelayMixin) {
relayFollowings: Paginate<IFollower> = { elements: [], total: 0 };
newRelayAddress = ""; newRelayAddress = "";
RelayMixin = RelayMixin; RelayMixin = RelayMixin;
@ -137,12 +129,11 @@ export default class Followings extends Mixins(RelayMixin) {
variables: { variables: {
address: this.newRelayAddress, address: this.newRelayAddress,
}, },
// TODO: Handle cache update properly without refreshing
}); });
await this.$apollo.queries.relayFollowings.refetch(); await this.$apollo.queries.relayFollowings.refetch();
this.newRelayAddress = ""; this.newRelayAddress = "";
} catch (e) { } catch (err) {
Snackbar.open({ message: e.message, type: "is-danger", position: "is-bottom" }); Snackbar.open({ message: err.message, type: "is-danger", position: "is-bottom" });
} }
} }

View File

@ -1,40 +1,100 @@
import { Component, Vue, Ref } from "vue-property-decorator"; import { Component, Vue, Ref } from "vue-property-decorator";
import { ActorType, IActor } from "@/types/actor"; import { ActorType, IActor } from "@/types/actor";
import { IFollower } from "@/types/actor/follower.model"; import { IFollower } from "@/types/actor/follower.model";
import { RELAY_FOLLOWERS, RELAY_FOLLOWINGS } from "@/graphql/admin";
import { Paginate } from "@/types/paginate";
@Component @Component({
apollo: {
relayFollowings: {
query: RELAY_FOLLOWINGS,
fetchPolicy: "cache-and-network",
variables() {
return {
page: this.followingsPage,
limit: this.perPage,
};
},
},
relayFollowers: {
query: RELAY_FOLLOWERS,
fetchPolicy: "cache-and-network",
variables() {
return {
page: this.followersPage,
limit: this.perPage,
};
},
},
},
})
export default class RelayMixin extends Vue { export default class RelayMixin extends Vue {
@Ref("table") readonly table!: any; @Ref("table") readonly table!: any;
relayFollowers: Paginate<IFollower> = { elements: [], total: 0 };
relayFollowings: Paginate<IFollower> = { elements: [], total: 0 };
checkedRows: IFollower[] = []; checkedRows: IFollower[] = [];
page = 1; followingsPage = 1;
perPage = 10; followersPage = 1;
perPage = 1;
toggle(row: Record<string, unknown>): void { toggle(row: Record<string, unknown>): void {
this.table.toggleDetails(row); this.table.toggleDetails(row);
} }
async onPageChange(page: number): Promise<void> { async onFollowingsPageChange(page: number): Promise<void> {
this.page = page; this.followingsPage = page;
await this.$apollo.queries.relayFollowings.fetchMore({ try {
variables: { await this.$apollo.queries.relayFollowings.fetchMore({
page: this.page, variables: {
limit: this.perPage, page: this.followingsPage,
}, limit: this.perPage,
updateQuery: (previousResult, { fetchMoreResult }) => { },
if (!fetchMoreResult) return previousResult; updateQuery: (previousResult, { fetchMoreResult }) => {
const newFollowings = fetchMoreResult.relayFollowings.elements; if (!fetchMoreResult) return previousResult;
return { const newFollowings = fetchMoreResult.relayFollowings.elements;
relayFollowings: { return {
__typename: previousResult.relayFollowings.__typename, relayFollowings: {
total: previousResult.relayFollowings.total, __typename: previousResult.relayFollowings.__typename,
elements: [...previousResult.relayFollowings.elements, ...newFollowings], total: previousResult.relayFollowings.total,
}, elements: [...previousResult.relayFollowings.elements, ...newFollowings],
}; },
}, };
}); },
});
} catch (err) {
console.error(err);
}
}
async onFollowersPageChange(page: number): Promise<void> {
this.followersPage = page;
try {
await this.$apollo.queries.relayFollowers.fetchMore({
variables: {
page: this.followersPage,
limit: this.perPage,
},
updateQuery: (previousResult, { fetchMoreResult }) => {
if (!fetchMoreResult) return previousResult;
const newFollowers = fetchMoreResult.relayFollowers.elements;
return {
relayFollowers: {
__typename: previousResult.relayFollowers.__typename,
total: previousResult.relayFollowers.total,
elements: [...previousResult.relayFollowers.elements, ...newFollowers],
},
};
},
});
} catch (err) {
console.error(err);
}
} }
static isInstance(actor: IActor): boolean { static isInstance(actor: IActor): boolean {

View File

@ -69,10 +69,18 @@ import RouteName from "../../router/name";
relayFollowings: { relayFollowings: {
query: RELAY_FOLLOWINGS, query: RELAY_FOLLOWINGS,
fetchPolicy: "cache-and-network", fetchPolicy: "cache-and-network",
variables: {
page: 1,
limit: 10,
},
}, },
relayFollowers: { relayFollowers: {
query: RELAY_FOLLOWERS, query: RELAY_FOLLOWERS,
fetchPolicy: "cache-and-network", fetchPolicy: "cache-and-network",
variables: {
page: 1,
limit: 10,
},
}, },
}, },
}) })