Skip to content

Commit

Permalink
feat(dashboard): sort archived announcements+pagination
Browse files Browse the repository at this point in the history
Closes #1604
  • Loading branch information
JasonGrace2282 committed Apr 6, 2024
1 parent 3feb200 commit 7e09bc5
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 30 deletions.
1 change: 1 addition & 0 deletions Ion.egg-info/SOURCES.txt
Expand Up @@ -789,6 +789,7 @@ intranet/apps/templatetags/form_field.py
intranet/apps/templatetags/forms.py
intranet/apps/templatetags/math.py
intranet/apps/templatetags/newtab_links.py
intranet/apps/templatetags/paginate.py
intranet/apps/templatetags/strings.py
intranet/apps/templatetags/tests.py
intranet/apps/users/__init__.py
Expand Down
8 changes: 8 additions & 0 deletions docs/sourcedoc/intranet.apps.templatetags.rst
Expand Up @@ -52,6 +52,14 @@ intranet.apps.templatetags.newtab\_links module
:undoc-members:
:show-inheritance:

intranet.apps.templatetags.paginate module
------------------------------------------

.. automodule:: intranet.apps.templatetags.paginate
:members:
:undoc-members:
:show-inheritance:

intranet.apps.templatetags.strings module
-----------------------------------------

Expand Down
50 changes: 26 additions & 24 deletions intranet/apps/dashboard/views.py
Expand Up @@ -4,6 +4,7 @@

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils import timezone
Expand Down Expand Up @@ -255,39 +256,43 @@ def get_announcements_list(request, context):
midnight = timezone.localtime().replace(hour=0, minute=0, second=0, microsecond=0)
events = Event.objects.visible_to_user(user).filter(time__gte=midnight, show_on_dashboard=True)

items = sorted(chain(announcements, events), key=lambda item: (item.pinned, item.added))
items.reverse()
def announcements_sorting_key(item: Announcement):
if context["show_expired"]:
# sort items first by expiration date then by added date
return (item.expiration_date, item.added)
# otherwise sort by pinned and then added date
return (item.pinned, item.added)

items = sorted(chain(announcements, events), key=announcements_sorting_key, reverse=True)

return items


def paginate_announcements_list(request, context, items):
"""
***TODO*** Migrate to django Paginator (see lostitems)
Paginate ``items`` in groups of 15
"""
DEFAULT_PAGE_NUM = 1

# pagination
if "start" in request.GET:
try:
start_num = int(request.GET.get("start"))
except ValueError:
start_num = 0
if request.GET.get("page", "INVALID").isdigit():
page_num = int(request.GET["page"])
else:
start_num = 0
page_num = DEFAULT_PAGE_NUM

display_num = 15
end_num = start_num + display_num
prev_page = start_num - display_num
more_items = (len(items) - start_num) > display_num
try:
items_sorted = items[start_num:end_num]
except (ValueError, AssertionError):
items_sorted = items[:display_num]
else:
items = items_sorted
paginator = Paginator(items, 15)
if page_num not in paginator.page_range:
page_num = DEFAULT_PAGE_NUM

context.update({"items": items, "start_num": start_num, "end_num": end_num, "prev_page": prev_page, "more_items": more_items})
items = paginator.page(page_num)

more_items = items.has_next()
prev_page = items.previous_page_number() if items.has_previous() else 0
next_page = items.next_page_number() if more_items else 0

context.update(
{"items": items, "page_num": page_num, "prev_page": prev_page, "next_page": next_page, "more_items": more_items, "page_obj": paginator}
)

return context, items

Expand Down Expand Up @@ -431,8 +436,6 @@ def dashboard_view(request, show_widgets=True, show_expired=False, ignore_dashbo
# Show all by default to 8th period office
show_all = True

# Include show_all postfix on next/prev links
paginate_link_suffix = "&show_all=1" if show_all else ""
is_index_page = request.path_info in ["/", ""]

context = {
Expand All @@ -442,7 +445,6 @@ def dashboard_view(request, show_widgets=True, show_expired=False, ignore_dashbo
"events_admin": events_admin,
"is_index_page": is_index_page,
"show_all": show_all,
"paginate_link_suffix": paginate_link_suffix,
"show_expired": show_expired,
"show_tjstar": settings.TJSTAR_BANNER_START_DATE <= now.date() <= settings.TJSTAR_DATE,
}
Expand Down
46 changes: 46 additions & 0 deletions intranet/apps/templatetags/paginate.py
@@ -0,0 +1,46 @@
from typing import List, Union

from django import template

register = template.Library()


@register.simple_tag
def query_transform(request, **kwargs):
query = request.GET.copy()
for k, v in kwargs.items():
query[k] = v
return query.urlencode()


@register.filter # TODO: replace return type with list[int | None]
def page_list(paginator, current_page) -> List[Union[int, None]]:
"""Pagination
If there is a ``None`` in the output, it should be replaced
with ...'s.
"""
SURROUNDING_PAGES = 2
BEGINNING_PAGES = 2
EXTRA_END_PAGES = 1
total_pages = paginator.page_range

# The page numbers to show
actual_numbers = [
page
for page in total_pages
if (
page >= total_pages[-1] - EXTRA_END_PAGES
or page <= BEGINNING_PAGES
or (current_page.number - SURROUNDING_PAGES <= page <= current_page.number + SURROUNDING_PAGES)
)
]

pages = []
for i, number in enumerate(actual_numbers[:-1]):
pages.append(number)
# if there is a mismatch, that means we should add a ...
if actual_numbers[i + 1] != number + 1:
pages.append(None)
pages.append(actual_numbers[-1])
return pages
4 changes: 4 additions & 0 deletions intranet/static/css/dark/dashboard.widgets.scss
Expand Up @@ -16,3 +16,7 @@
.btn-link {
border-color: $darkborder;
}

.ellipses {
--ellipses-color: white;
}
21 changes: 21 additions & 0 deletions intranet/static/css/dashboard.widgets.scss
Expand Up @@ -483,6 +483,27 @@ a.btn-link {
}
}

.ellipses {
padding: 7px 10px;
margin: 2px 0;
font-size: 13px;
font-weight: bold;
--ellipses-color: $grey;
color: var(--ellipses-color);

&:hover {
color: var(--ellipses-color);
text-decoration: none;
// don't change cursor while hovering on
// ...'s in pagination
cursor: default;
}

&:visited {
color: var(--ellipses-color);
}
}

/* BIRTHDAYS */

.birthdays-widget {
Expand Down
4 changes: 3 additions & 1 deletion intranet/static/js/dashboard/common.js
Expand Up @@ -12,6 +12,8 @@ $(function() {
if(e.keyCode === 9) {
e.preventDefault();
}
$("#searchbox").focus();
if(!$(".dashboard-textinput").is(":focus")) {
$("#searchbox").focus();
}
});
});
28 changes: 23 additions & 5 deletions intranet/templates/dashboard/dashboard.html
Expand Up @@ -3,6 +3,7 @@
{% load dates %}
{% load cacheops %}
{% load pipeline %}
{% load paginate %}

{% block title %}
{{ block.super }} - {{ dashboard_title }}
Expand Down Expand Up @@ -118,7 +119,7 @@ <h2>{{ dashboard_header }}</h2>
{% else %}
{% if announcements_admin %}
{% if "show_all" not in request.GET %}
<a class="button" href="{% url view_announcements_url %}?show_all=1">
<a class="button" href="{% url view_announcements_url %}?{% query_transform request show_all=1 %}">
Show All
</a>
{% else %}
Expand Down Expand Up @@ -206,15 +207,32 @@ <h3>
</div>
{% endfor %}
{% if not request.user.is_restricted %}
{% if start_num == 0 and view_announcements_url != 'announcements_archive' %}
{% if page_num == 1 and view_announcements_url != 'announcements_archive' %}
<a href="{% url 'announcements_archive' %}" class="button" style="float:left"><i class="fas fa-archive" style="width: 13px"></i> View Archive</a>
{% endif %}

{% if start_num > 0 %}
<a href="{% url view_announcements_url %}?start={{ prev_page }}{{ paginate_link_suffix }}" class="button" style="float:left">&larr; Newer Posts</a>
{% if prev_page > 0 %}
<a href="{% url view_announcements_url %}?{% query_transform request page=prev_page %}" class="button" style="float:left">&larr; Newer Posts</a>
{% endif %}
{% if more_items %}
<a href="{% url view_announcements_url %}?start={{ end_num }}{{ paginate_link_suffix }}" class="button" style="float:right">Older Posts &rarr;</a>
<a href="{% url view_announcements_url %}?{% query_transform request page=next_page %}" class="button" style="float:right">Older Posts &rarr;</a>
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="text-align: center">
{% for page in page_obj|page_list:items %}
<a {% if page %} class="button" {% else %} class="ellipses" {% endif %}
{% if page == items.number %} style="color: #7AAEF7" {% endif %}
href="{% url view_announcements_url %}{% if page %}?{% query_transform request page=page %}{% else %}#{% endif %}">{{ page|default:". . ." }}</a>
{% endfor %}
<div style="text-align: center">
<form action="{% url view_announcements_url %}" method="get">
<input name="page" type="number"
min="1" max={{ page_obj.num_pages }} class="dashboard-textinput" style="width: 75px"
placeholder={{ items.number }}> of {{ page_obj.num_pages }}
<input type="submit" value="Go"/>
</form>
</div>
</div>
{% endif %}
{% endif %}
</div>
Expand Down

0 comments on commit 7e09bc5

Please sign in to comment.