Skip to content

Commit

Permalink
budgeting/proposal-list/pagination: removing default pagination from …
Browse files Browse the repository at this point in the history
…settings.py

creating better response structur from backend
changing page_size to be set on backend only
  • Loading branch information
Kha committed Nov 18, 2021
1 parent a3e3e9e commit 25836d3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 30 deletions.
34 changes: 32 additions & 2 deletions meinberlin/apps/budgeting/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from rest_framework import mixins
from rest_framework import status
from rest_framework import viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

from adhocracy4.api.mixins import ModuleMixin
from adhocracy4.api.permissions import ViewSetRulesPermission
Expand All @@ -9,9 +11,37 @@
from .serializers import ProposalSerializer


# To be changed to a more general IdeaPagination, when using
# pagination via rest api for more idea lists
class BudgetPagination(PageNumberPagination):
page_size_query_param = 'page_size'
max_page_size = 100
page_size = 15

def get_next_page(self):
if self.page.has_next():
return self.page.next_page_number()
else:
return None

def get_previous_page(self):
if self.page.has_previous():
return self.page.previous_page_number()
else:
return None

def get_paginated_response(self, data):
return Response({
'status': True,
'results': data,
'meta': {
'results_count': self.page.paginator.count,
'current_page': self.page.number,
'previous_page': self.get_previous_page(),
'next_page': self.get_next_page(),
'page_count': self.page.paginator.num_pages,
'page_size': self.page_size,
'is_paginated': self.page.paginator.num_pages > 1
}},
status=status.HTTP_200_OK)


class ProposalViewSet(ModuleMixin,
Expand Down
27 changes: 10 additions & 17 deletions meinberlin/apps/budgeting/assets/BudgetingProposalList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,23 @@ import React, { useEffect, useState } from 'react'
import { BudgetingProposalListItem } from './BudgetingProposalListItem'
import { Pagination } from './Pagination'

// How many items are shown on one pagination page.
// change this number to a lower number to test the pagination.
const PAGE_SIZE = 10

export const BudgetingProposalList = (props) => {
const [list, setList] = useState()
const [currPageIndex, setCurrPageIndex] = useState(1)
const [isPaginated, setIsPaginated] = useState(false)
const [data, setData] = useState([])
const [meta, setMeta] = useState()

const fetchProposals = (newIndex) => {
const pageNumber = newIndex || currPageIndex
const url = `${props.proposals_api_url}?page_size=${PAGE_SIZE}&page=${pageNumber}`
const pageNumber = newIndex || 1
const url = `${props.proposals_api_url}?page=${pageNumber}`
fetch(url)
.then(resp => resp.json())
.then(json => {
setList(json)
setIsPaginated(json.count / PAGE_SIZE > 1)
setData(json.results)
setMeta(json.meta)
})
.catch(error => console.log(error))
}

const onPaginate = (selectedPage) => {
setCurrPageIndex(selectedPage)
fetchProposals(selectedPage)
}

Expand All @@ -34,17 +28,16 @@ export const BudgetingProposalList = (props) => {
<div className="l-wrapper">
<div className="l-center-8">
<ul className="u-list-reset">
{list?.results?.map((proposal, idx) =>
{data.map((proposal, idx) =>
<BudgetingProposalListItem
key={`budgeting-proposal-${idx}`}
proposal={proposal}
/>)}
</ul>
{isPaginated &&
{meta?.is_paginated &&
<Pagination
{...list}
pageSize={PAGE_SIZE}
currPageIndex={currPageIndex}
currPageIndex={meta.current_page}
pageCount={meta.page_count}
onPaginate={newUrl => onPaginate(newUrl)}
/>}
</div>
Expand Down
13 changes: 7 additions & 6 deletions meinberlin/apps/budgeting/assets/Pagination.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import django from 'django'

export const Pagination = (props) => {
const {
pageSize,
count,
currPageIndex
currPageIndex,
pageCount
} = props
// FIXME: this is beyond any readability. It just calculates how many
// pages are needed in the pagination using the PAGE_SIZE.
const pages = [...Array(Math.ceil(count / pageSize)).keys()].map(n => n + 1)

// Creating an Array from single digit, example: 5 = [0,1,2,3,4]
// and map to start by 1
const pages = [...Array(pageCount).keys()].map(n => n + 1)

return (
<nav aria-label={django.gettext('Page navigation')}>
<ul className="pagination">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends extends %}
{% load i18n discovery_tags static maps_tags %}
{% load i18n discovery_tags static maps_tags react_proposals %}

{% block extra_js %}
<script type="text/javascript" src="{% static 'a4maps_display_points.js' %}"></script>
Expand Down Expand Up @@ -40,6 +40,7 @@
</div>
{% else %}
<div class="module-content--light">
{% react_proposals view.module %}
<div class="l-wrapper">
<div class="l-center-8">
{% if object_list.count > 0 %}
Expand Down
4 changes: 0 additions & 4 deletions meinberlin/config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,3 @@

A4_ACTIONS_PHASE_ENDS_HOURS = 48

REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}

0 comments on commit 25836d3

Please sign in to comment.