Add pagination to resources
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
9d64a80434
commit
24b94d1860
|
@ -11,7 +11,12 @@ export const RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT = gql`
|
|||
`;
|
||||
|
||||
export const GET_RESOURCE = gql`
|
||||
query GetResource($path: String!, $username: String!) {
|
||||
query GetResource(
|
||||
$path: String!
|
||||
$username: String!
|
||||
$page: Int
|
||||
$limit: Int
|
||||
) {
|
||||
resource(path: $path, username: $username) {
|
||||
id
|
||||
title
|
||||
|
@ -38,7 +43,7 @@ export const GET_RESOURCE = gql`
|
|||
name
|
||||
domain
|
||||
}
|
||||
children {
|
||||
children(page: $page, limit: $limit) {
|
||||
total
|
||||
elements {
|
||||
id
|
||||
|
|
|
@ -145,6 +145,17 @@
|
|||
<p>{{ $t("No resources in this folder") }}</p>
|
||||
</div>
|
||||
</section>
|
||||
<b-pagination
|
||||
v-if="resource.children.total > RESOURCES_PER_PAGE"
|
||||
:total="resource.children.total"
|
||||
v-model="page"
|
||||
:per-page="RESOURCES_PER_PAGE"
|
||||
:aria-next-label="$t('Next page')"
|
||||
:aria-previous-label="$t('Previous page')"
|
||||
:aria-page-label="$t('Page')"
|
||||
:aria-current-label="$t('Current page')"
|
||||
>
|
||||
</b-pagination>
|
||||
<b-modal :active.sync="renameModal" has-modal-card>
|
||||
<div class="modal-card">
|
||||
<section class="modal-card-body">
|
||||
|
@ -250,6 +261,8 @@ import { IConfig } from "../../types/config.model";
|
|||
import ResourceMixin from "../../mixins/resource";
|
||||
import ResourceSelector from "../../components/Resource/ResourceSelector.vue";
|
||||
import { ApolloCache, FetchResult } from "@apollo/client/core";
|
||||
import VueRouter from "vue-router";
|
||||
const { isNavigationFailure, NavigationFailureType } = VueRouter;
|
||||
|
||||
@Component({
|
||||
components: { FolderItem, ResourceItem, Draggable, ResourceSelector },
|
||||
|
@ -265,6 +278,8 @@ import { ApolloCache, FetchResult } from "@apollo/client/core";
|
|||
return {
|
||||
path,
|
||||
username: this.$route.params.preferredUsername,
|
||||
page: this.page,
|
||||
limit: this.RESOURCES_PER_PAGE,
|
||||
};
|
||||
},
|
||||
error({ graphQLErrors }) {
|
||||
|
@ -303,6 +318,8 @@ export default class Resources extends Mixins(ResourceMixin) {
|
|||
|
||||
usernameWithDomain = usernameWithDomain;
|
||||
|
||||
RESOURCES_PER_PAGE = 10;
|
||||
|
||||
newResource: IResource = {
|
||||
title: "",
|
||||
summary: "",
|
||||
|
@ -344,6 +361,16 @@ export default class Resources extends Mixins(ResourceMixin) {
|
|||
|
||||
mapServiceTypeToIcon = mapServiceTypeToIcon;
|
||||
|
||||
get page(): number {
|
||||
return parseInt((this.$route.query.page as string) || "1", 10);
|
||||
}
|
||||
|
||||
set page(page: number) {
|
||||
this.pushRouter({
|
||||
page: page.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
get actualPath(): string {
|
||||
const path = Array.isArray(this.$route.params.path)
|
||||
? this.$route.params.path.join("/")
|
||||
|
@ -641,16 +668,51 @@ export default class Resources extends Mixins(ResourceMixin) {
|
|||
}
|
||||
}
|
||||
|
||||
@Watch("page")
|
||||
loadMoreResources(): void {
|
||||
this.$apollo.queries.resource.fetchMore({
|
||||
// New variables
|
||||
variables: {
|
||||
page: this.page,
|
||||
limit: this.RESOURCES_PER_PAGE,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
handleErrors(errors: any[]): void {
|
||||
if (errors.some((error) => error.status_code === 404)) {
|
||||
this.$router.replace({ name: RouteName.PAGE_NOT_FOUND });
|
||||
}
|
||||
}
|
||||
|
||||
async pushRouter(args: Record<string, string>): Promise<void> {
|
||||
try {
|
||||
const path = this.filteredPath.toString();
|
||||
const routeName =
|
||||
path === ""
|
||||
? RouteName.RESOURCE_FOLDER_ROOT
|
||||
: RouteName.RESOURCE_FOLDER;
|
||||
|
||||
await this.$router.push({
|
||||
name: routeName,
|
||||
params: { path },
|
||||
query: { ...this.$route.query, ...args },
|
||||
});
|
||||
} catch (e) {
|
||||
if (isNavigationFailure(e, NavigationFailureType.redirected)) {
|
||||
throw Error(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.container.section {
|
||||
background: $white;
|
||||
|
||||
& > nav.pagination {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
nav.breadcrumb ul {
|
||||
|
|
|
@ -50,7 +50,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
|
||||
def find_resources_for_parent(
|
||||
%Resource{actor_id: group_id} = parent,
|
||||
_args,
|
||||
%{page: page, limit: limit},
|
||||
%{
|
||||
context: %{
|
||||
current_user: %User{} = user
|
||||
|
@ -59,7 +59,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
) do
|
||||
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
%Page{} = page <- Resources.get_resources_for_folder(parent) do
|
||||
%Page{} = page <- Resources.get_resources_for_folder(parent, page, limit) do
|
||||
{:ok, page}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,6 +27,14 @@ defmodule Mobilizon.GraphQL.Schema.ResourceType do
|
|||
|
||||
field :children, :paginated_resource_list do
|
||||
description("Children resources in folder")
|
||||
|
||||
arg(:page, :integer,
|
||||
default_value: 1,
|
||||
description: "The page in the paginated resource list"
|
||||
)
|
||||
|
||||
arg(:limit, :integer, default_value: 10, description: "The limit of resources per page")
|
||||
|
||||
resolve(&Resource.find_resources_for_parent/3)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue