-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…ations Implementing in-app notification
- Loading branch information
Showing
15 changed files
with
276 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from .models import Activity | ||
|
||
|
||
def notification_context(request): | ||
context_data = dict() | ||
if hasattr(request, 'user'): | ||
if request.user.is_authenticated and request.user.is_apply_staff: | ||
context_data['latest_notifications'] = Activity.objects.latest().order_by('-timestamp')[:5] | ||
return context_data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from datetime import timedelta | ||
|
||
import django_filters | ||
from django.utils.timezone import now | ||
from django.utils.translation import gettext_lazy as _ | ||
from django_filters.filters import DateRangeFilter, _truncate | ||
|
||
from .models import Activity | ||
|
||
|
||
class NotificationFilter(django_filters.FilterSet): | ||
timestamp_choices = [ | ||
('today', _('Today')), | ||
('yesterday', _('Yesterday')), | ||
('week', _('Past 7 days')), | ||
('month', _('This month')) | ||
] | ||
timestamp_filters = { | ||
'today': lambda qs, name: qs.filter(**{ | ||
'%s__year' % name: now().year, | ||
'%s__month' % name: now().month, | ||
'%s__day' % name: now().day | ||
}), | ||
'yesterday': lambda qs, name: qs.filter(**{ | ||
'%s__year' % name: (now() - timedelta(days=1)).year, | ||
'%s__month' % name: (now() - timedelta(days=1)).month, | ||
'%s__day' % name: (now() - timedelta(days=1)).day, | ||
}), | ||
'week': lambda qs, name: qs.filter(**{ | ||
'%s__gte' % name: _truncate(now() - timedelta(days=7)), | ||
'%s__lt' % name: _truncate(now() + timedelta(days=1)), | ||
}), | ||
'month': lambda qs, name: qs.filter(**{ | ||
'%s__year' % name: now().year, | ||
'%s__month' % name: now().month | ||
}) | ||
} | ||
|
||
date = DateRangeFilter(field_name='timestamp', choices=timestamp_choices, filters=timestamp_filters) | ||
|
||
class Meta: | ||
model = Activity | ||
fields = {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
hypha/apply/activity/templates/activity/include/notifications_dropdown.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{% load i18n activity_tags bleach_tags markdown_tags submission_tags apply_tags %} | ||
|
||
<div class="notifications notifications--dropdown"> | ||
<a href="#" class="button button--contains-icons notifications__bell" aria-label="{% trans "Notifications" %}" aria-haspopup="activity" aria-expanded="false" role="button"> | ||
<svg class="icon"><use xlink:href="#bell-icon"></use></svg> | ||
</a> | ||
<div class="notifications__content zeta hidden" role="activity"> | ||
<h5>Notifications</h5> | ||
{% for activity in latest_notifications %} | ||
<p class="notifications__item"> | ||
<strong>{{ activity.source_content_type.name|source_type }} </strong> | ||
<a href="{{ activity.source.get_absolute_url }}{% ifequal activity.type 'comment' %}#communications{% endifequal %}">{{ activity.source.title|capfirst|truncatechars:15 }}</a> | ||
: {{ activity.user.get_full_name }} {% ifequal activity.type 'comment' %}{% trans "made a comment" %}{% else %} {{ activity|display_for:request.user }}{% endifequal %} | ||
{% if activity.related_object %}<a href="{{ activity.related_object.get_absolute_url }}">{{ activity.related_object|model_verbose_name }}</a>{% endif %} | ||
</p> | ||
{% endfor %} | ||
<p class="notifications__more"><a href="{% url "activity:notifications" %}">Show All</a></p> | ||
</div> | ||
</div> |
72 changes: 72 additions & 0 deletions
72
hypha/apply/activity/templates/activity/notifications.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
{% extends "base-apply.html" %} | ||
{% load i18n static activity_tags apply_tags bleach_tags markdown_tags submission_tags %} | ||
|
||
{% block content %} | ||
<div class="admin-bar"> | ||
<div class="admin-bar__inner"> | ||
<div class="admin-bar__inner--with-button"> | ||
<h1 class="gamma heading heading--no-margin heading--bold">{% trans "Notifications" %}</h1> | ||
<form class="form notifications__filters" method="get"> | ||
{{ filter.form }} | ||
<button class="button button--primary" type="submit" value="Filter">{% trans "Filter" %}</button> | ||
</form> | ||
</div> | ||
|
||
<div class="tabs js-tabs"> | ||
<div class="tabs__container"> | ||
<a class="tab__item" href="#comments" data-tab="tab-1"> | ||
{% trans "Communications" %} | ||
</a> | ||
|
||
<a class="tab__item" href="#actions" data-tab="tab-2"> | ||
{% trans "Activity Feed" %} | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="wrapper wrapper--large wrapper--tabs js-tabs-content"> | ||
{# Tab 1 #} | ||
<div class="tabs__content" id="tab-1"> | ||
{% for activity in object_list %} | ||
{% if activity.type == 'comment' %} | ||
<div class="feed__item feed__item--{{ activity.type }}"> | ||
<div class="feed__pre-content"> | ||
<p class="feed__label feed__label--{{ activity.source_content_type.name|source_type|lower }}">{{ activity.source_content_type.name|source_type }}</p> | ||
</div> | ||
<div class="feed__content js-feed-content"> | ||
<div class="feed__meta js-feed-meta"> | ||
<p class="feed__meta-item"><a href="{{ activity.source.get_absolute_url }}#communications">{{ activity.source.title|capfirst }}</a> | ||
: {{ activity.user.get_full_name }} {% trans "made a comment" %} – {{ activity.timestamp|date:"SHORT_DATE_FORMAT" }}</p> | ||
</div> | ||
</div> | ||
</div> | ||
{% endif %} | ||
{% endfor %} | ||
</div> | ||
{# Tab 2 #} | ||
<div class="tabs__content" id="tab-2"> | ||
{% for activity in object_list %} | ||
{% if activity.type == 'action' %} | ||
<div class="feed__item feed__item--{{ activity.type }}"> | ||
<div class="feed__pre-content"> | ||
<p class="feed__label feed__label--{{ activity.source_content_type.name|source_type|lower }}">{{ activity.source_content_type.name|source_type }}</p> | ||
</div> | ||
<div class="feed__content js-feed-content"> | ||
<div class="feed__meta js-feed-meta"> | ||
<p class="feed__meta-item"><a href="{{ activity.source.get_absolute_url }}">{{ activity.source.title|capfirst }}</a> | ||
: {{ activity.user.get_full_name }} – {{ activity.timestamp|date:"SHORT_DATE_FORMAT" }} – {{ activity|display_for:request.user }} {% if activity.related_object %}<a href="{{ activity.related_object.get_absolute_url }}" class="feed__related-item">{{ activity.related_object|model_verbose_name }} <svg><use xlink:href="#arrow-head-pixels--solid"></use></svg></a>{% endif %}</p> | ||
</div> | ||
</div> | ||
</div> | ||
{% endif %} | ||
{% endfor %} | ||
</div> | ||
</div> | ||
|
||
{% endblock %} | ||
|
||
{% block extra_js %} | ||
<script src="{% static 'js/apply/tabs.js' %}"></script> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
from django.urls import include, path | ||
|
||
from .views import NotificationsView | ||
|
||
app_name = 'activity' | ||
|
||
|
||
urlpatterns = [ | ||
path('anymail/', include('anymail.urls')), | ||
path('notifications/', NotificationsView.as_view(), name='notifications') | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
(function () { | ||
|
||
'use strict'; | ||
|
||
// Open/close dropdown when users clicks the bell. | ||
document.querySelector('.notifications__bell').addEventListener('click', function () { | ||
document.querySelector('.notifications__content').classList.toggle('hidden'); | ||
}); | ||
|
||
// Close the dropdown menu if the user clicks outside of it. | ||
window.onclick = function (event) { | ||
if (!event.target.matches('.notifications--dropdown, .notifications--dropdown *')) { | ||
const dropdown = document.querySelector('.notifications__content'); | ||
if (!dropdown.classList.contains('hidden')) { | ||
dropdown.classList.add('hidden'); | ||
} | ||
} | ||
}; | ||
|
||
|
||
})(); |
54 changes: 54 additions & 0 deletions
54
hypha/static_src/src/sass/apply/components/_activity-notifications.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
.notifications { | ||
&--dropdown { | ||
position: relative; | ||
display: inline-block; | ||
z-index: 200; | ||
} | ||
|
||
&__bell { | ||
padding: 7px 12px; | ||
cursor: pointer; | ||
} | ||
|
||
&__content { | ||
position: absolute; | ||
right: 1em; | ||
padding: 1em; | ||
margin-top: .5em; | ||
background-color: $color--light-grey; | ||
min-width: 400px; | ||
box-shadow: 2px 2px 6px 1px $color--dark-grey; | ||
} | ||
|
||
&__item { | ||
padding-bottom: 1em; | ||
border-bottom: 1px solid $color--dark-grey; | ||
} | ||
|
||
&__more { | ||
text-align: center; | ||
font-weight: $weight--semibold; | ||
} | ||
|
||
&__filters { | ||
display: flex; | ||
align-items: center; | ||
padding: 4px; | ||
justify-content: space-between; | ||
|
||
label { | ||
font-weight: $weight--semibold; | ||
padding-right: 1em; | ||
} | ||
|
||
select { | ||
padding-right: 1em; | ||
} | ||
|
||
.form { | ||
&__select { | ||
margin-right: 1em; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters