-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updated Tock iconography based on Reporting Period Audit #769
Conversation
My thinking is that the first step would be to add an |
Keep in mind for the JS refactor here, |
Yeah, what I'm seeing is something like
|
Codecov Report
@@ Coverage Diff @@
## master #769 +/- ##
==========================================
+ Coverage 90.89% 90.94% +0.05%
==========================================
Files 38 38
Lines 1691 1701 +10
==========================================
+ Hits 1537 1547 +10
Misses 154 154
Continue to review full report at Codecov.
|
tock/employees/models.py
Outdated
@@ -128,6 +131,27 @@ def organization_name(self): | |||
|
|||
return '' | |||
|
|||
def is_late(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider this just a stub. There are no tests yet or anything. Just a way of knowing from the user object if they are late, so we can in turn flex the UI for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm. Thinking about this functionality again, what do you think about modifying this lookup so that the default is happy tock unless the following condition is met.
It’s the first weekday after the latest reporting period less than the current date and the user hasn’t submitted.
I’m just thinking that it would be better if the default wasn’t that the user was late but rather that the user is on time. But idk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it! Most people are on time. Makes perfect sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other quick thing here - would it make sense to have this behave as a property? It's a small semantic thing, but seeing as how this ultimately just returns True
or False
based on checking a couple of conditions and is not modifying anything or accepting any arguments, the @property
decorator for the method seems appropriate to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no real opinion either way. I don't think there's any real advantage to doing so, but I don't think there's any downside at all, either.
e6393a4
to
0914743
Compare
var links = document.getElementsByTagName('link'); | ||
var paths = [].slice.call(links).map(function (e) { | ||
if (e.getAttribute('rel') === 'shortcut icon') { | ||
return e.getAttribute('href'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of iterating through all links, will this work?
iconPath = document.querySelector("[rel='shortcut icon']").href;
You'd still want to be sure that iconPath was found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the suggestion. I submitted an updated patch.
The issue with |
https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission This also allows for the Notification code to pull from the HTML for the "shortcut icon" link tag rather than have that hardcoded in a JS file.
The `is_not_late` test is failing though 😞
246c5ca
to
0767d7f
Compare
|
Not sure what's happening with the tests here. This was working fine on an individual test level, but seems to be failing when running the whole suite. Looking into it. |
awww. dang. looks like this requires a refactor of all the tests, or possibly just where this lookup is occurring, since ReportingPeriods are now being checked all the time in the |
tock/tock/templates/base.html
Outdated
@@ -7,7 +7,11 @@ | |||
<title>Tock</title> | |||
|
|||
{% load staticfiles %} | |||
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}"> | |||
{% if x_tock_user_is_late %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need a context processor for this. I think you can just do {% if request.user.userdata.is_late %}
request.user should always be available, and I think it's more clear to see the check than the cp-supplied variable,, which are always a little less transparent than one would like. I think the only advantage of a context processor would be if you were doing the check a lot to avoid extra DB lookups.
That said, I could see you wanting to add a "late" body class as a simple hook for some styling changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you taken a look at the failing tests? Looks like not having timecard or reporting periods for all the users in all the tests is causing the tests to fail. But I’m not 100% sure either. But I do like that approach of checking the request object considering that’s where the user data lives in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't. But would the combo of skipping the CP and flipping the is_late check polarity clear it up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A user may not have all of the reporting periods or timecards associated with them though, so to me that seems to be an issue with the check itself. Should we have a bit more error handling or checks in the code to look for the existence of the reporting period first before using it?
Then again, you're calling .filter()
with them, not .get()
, so I'm also not entirely sure why the tests are failing with a message saying hours.models.DoesNotExist: ReportingPeriod matching query does not exist.
Shouldn't that just be returning an empty QuerySet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good so far, @rogeruiz! I have some other questions and additional feedback off of what @tbaxter-18f has pointed out already.
tock/employees/models.py
Outdated
@@ -128,6 +131,27 @@ def organization_name(self): | |||
|
|||
return '' | |||
|
|||
def is_late(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other quick thing here - would it make sense to have this behave as a property? It's a small semantic thing, but seeing as how this ultimately just returns True
or False
based on checking a couple of conditions and is not modifying anything or accepting any arguments, the @property
decorator for the method seems appropriate to me.
if timecard_count is 0: | ||
return True | ||
else: | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good - filter out all timecards that match the user, reporting period and if they've been submitted; if none are returned, we know they're late. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have this logic elsewhere in the code, do we? It seems familiar, perhaps in one of the views. I wonder if this could serve to replace it, or if perhaps it should be abstracted out as a utility method that both this model method and the logic in the view call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll revisit this as a later time, there's no need to hold things up here with it! One potential spot: https://github.com/18F/tock/blob/master/tock/api/views.py#L139-L162
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may also want to extract this in the future to provide support for crafting manager methods that allow us to filter query sets specifically around whether or not someone is late.
tock/tock/context_processors.py
Outdated
except UserData.DoesNotExist: | ||
response['x_tock_user_is_late'] = False | ||
|
||
return response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @tbaxter-18f - there should be a way to get this information off of request.user
or request.user.user_data
directly, which would keep things simpler and obviate the need for an extra context processor. :-)
tock/tock/templates/base.html
Outdated
@@ -7,7 +7,11 @@ | |||
<title>Tock</title> | |||
|
|||
{% load staticfiles %} | |||
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}"> | |||
{% if x_tock_user_is_late %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A user may not have all of the reporting periods or timecards associated with them though, so to me that seems to be an issue with the check itself. Should we have a bit more error handling or checks in the code to look for the existence of the reporting period first before using it?
Then again, you're calling .filter()
with them, not .get()
, so I'm also not entirely sure why the tests are failing with a message saying hours.models.DoesNotExist: ReportingPeriod matching query does not exist.
Shouldn't that just be returning an empty QuerySet?
tock/tock/templates/base.html
Outdated
@@ -7,7 +7,7 @@ | |||
<title>Tock</title> | |||
|
|||
{% load staticfiles %} | |||
{% if request.user.user_data.is_late %} | |||
{% if request.user.is_authenticated and request.user.user_data.is_late %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a comment here mentioning that both checks are required might be prudent.
I'm not going to bother updating the |
This is possibly helpful for future iterations on the Tock notification work which is comprised of JS rather than Python. We'd have to really refactor the Notification code to be aware of users when they're late to properly swap the icon. But for now, the icon will default to whatever is on the page when the user first loads it.
tock/tock/templates/base.html
Outdated
@@ -12,6 +12,8 @@ | |||
{% else %} | |||
<link rel="shortcut icon" href="{% static 'img/favicon-happy.png' %}"> | |||
{% endif %} | |||
<meta name="tock-icon-happy" content="{% static 'img/favicon-happy' %}"> | |||
<meta name="tock-icon-angry" content="{% static 'img/favicon-angry' %}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curious: why are these custom meta elements needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from 0b361eb
Add meta tags with icons;
This is possibly helpful for future iterations on the Tock notification
work which is comprised of JS rather than Python. We'd have to really
refactor the Notification code to be aware of users when they're late to
properly swap the icon. But for now, the icon will default to whatever
is on the page when the user first loads it.
My original intention was to have these get pulled in from the JS code and leveraged whenever the notification timer would run, but the current implementation of the notification code relies on time rather than actually checking if the user is late or not. So without building an API endpoint for that now, I'm leaving the <meta>
tags here in case someone wants to implement it in the future, myself or whomever. For now it's useful for the the notification code to pull from the <link>
tag as it's mostly accurate. But by the time the notification actually goes out, the user may or may not be late.
This PR though I think achieves my original intent with these changes. It's all to make Tock less aggressive about reminding folks to Tock their time. AngryTock is a nice tool when it's needed, but a majority of folks aren't late and it's a bit overly aggressive to only have AngryTock be the iconography for the site. Even if it is just used in the Favicon and Notifications for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The notification code is intended as a reminder for later in the day on Friday so folks don't forget to Tock their time on time. If anything, this would be a slight enhancement to the feature to also notify the user that their timecard is actually late come the following week.
I think we're at a good place to stop here, and a future PR can address this tweak in functionality and add the necessary enhancements. :-)
/cc @mgwalker since he put the original notifications in place and may be interested to see all of this work and discussion!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything looks good to go for me at this point, @rogeruiz, thank you very much for this!
Description
This PR focuses on updating the iconography of Tock (HappyTock and AngryTock) from a UX perspective. If folks aren't late, they should be greeted with HappyTock in any use of the Tock icon. For now this functionality only exists in the favicon and the notifications. If folks are late, i.e. it's Monday, then they should be greeted with AngryTock in any use of the Tock icon.
Additional information
This may require some new functionality not built into the backend for Tock, but it could also just cover updating the icon to use the HappyTock instead of AngryTock.
Anyone can take on this work. I'm just opening the PR for visibility. Feel free to commit onto this branch directly.