-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(remaining-messages-summary): add new component * feat(storybook): add a lightweight "storybook" route so we can test components more easily * task: add testids * feat(storybook): add storybooks for components * test(rms): add suite of tests; add tests to ci * chore: formatting * a11y(rms): add icon labels [review] * a11y(storybook): fix up heading issues * chore: add translation * ai [review] plz * chore: remove unnecessary code * chore(tests): fix test descriptions * Please [review] again * task: remove content from styleguide that was moved to a storybook * task: remove testing code * Update app/templates/components/remaining-messages-summary.html * Update app/templates/views/storybook/remaining-messages-summary.html * fix: undo AI suggestion as it errors * fix(storybook_menu): move component array; use ul/li * import faCircleCheck, move icon out of the summary div, add some wrapping, adjust spaing and alignments * chore: regen css * fix: update link for usage reports in the component --------- Co-authored-by: Jumana B <[email protected]> Co-authored-by: Philippe Caron <[email protected]>
- Loading branch information
1 parent
40f91d7
commit 35b037d
Showing
15 changed files
with
575 additions
and
4 deletions.
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
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
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
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 |
---|---|---|
|
@@ -29,6 +29,7 @@ | |
set_lang, | ||
sign_in, | ||
sign_out, | ||
storybook, | ||
styleguide, | ||
templates, | ||
two_factor, | ||
|
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,12 @@ | ||
from flask import render_template, request | ||
|
||
from app.main import main | ||
|
||
|
||
@main.route("/_storybook") | ||
def storybook(): | ||
component = None | ||
if "component" in request.args: | ||
component = request.args["component"] | ||
|
||
return render_template("views/storybook.html", component=component) |
108 changes: 108 additions & 0 deletions
108
app/templates/components/remaining-messages-summary.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,108 @@ | ||
{% macro remaining_messages_summary(dailyLimit, dailyUsed, yearlyLimit, yearlyUsed, notification_type, textOnly=None) %} | ||
<!-- Validate textOnly param --> | ||
{% set textOnly_allowed_values = ['text', 'emoji'] %} | ||
{% if textOnly not in textOnly_allowed_values %} | ||
{% set textOnly = None %} | ||
{% set textOnlyMode = false %} | ||
{% else %} | ||
{% set textOnlyMode = true %} | ||
{% endif %} | ||
|
||
<!-- Validate notification_type param --> | ||
{% set notificationType_allowed_values = ['sms', 'email'] %} | ||
{% if notification_type not in notificationType_allowed_values %} | ||
{% set notification_type = None %} | ||
{% if config["NOTIFY_ENVIRONMENT"].lower() == 'development' %} | ||
<p class="text-red-300 mt-6 mb-6"><i aria-hidden="true" class="fa-solid fa-fas fa-triangle-exclamation text-yellow w-8 h-8 text-xs rounded-full mx-1" data-testid="rms-icon"></i> Invalid notification type - check your jinja template!</p> | ||
{% endif %} | ||
{% else %} | ||
{% if notification_type == 'sms' %} | ||
{% set notification_type = _('text messages') %} | ||
{% elif notification_type == 'email' %} | ||
{% set notification_type = _('emails') %} | ||
{% endif %} | ||
{% endif %} | ||
|
||
<!-- Set some constants --> | ||
{% set current_year = current_year or (now().year if now().month < 4 else now().year + 1) %} | ||
{% set next_april = _('April 1, ') ~ current_year %} | ||
{% set icon_default = 'fa-circle-check text-blue-300 text-base self-start' %} | ||
{% set icon_warning = 'fa-circle-exclamation text-red-300 text-base self-start' %} | ||
{% set warning_threshold = 0.8 %} | ||
|
||
{% set sections = [ | ||
{ | ||
'type': 'daily', | ||
'used': dailyUsed, | ||
'limit': dailyLimit, | ||
'text': _('remaining until') ~ ' ' ~ ('7 pm ET'), | ||
'link_text': _('Request a daily limit increase'), | ||
'link_href': url_for('main.contact'), | ||
'remaining': "{:,}".format(dailyLimit - dailyUsed) if session['userlang'] == 'en' else "{:,}".format(dailyLimit - dailyUsed).replace(',', ' '), | ||
'skip': false if textOnlyMode else dailyLimit - dailyUsed == 0 and yearlyLimit - yearlyUsed == 0, | ||
'warn': dailyUsed / dailyLimit >= warning_threshold | ||
}, | ||
{ | ||
'type': 'yearly', | ||
'used': yearlyUsed, | ||
'limit': yearlyLimit, | ||
'text': _('remaining until') ~ ' ' ~ next_april, | ||
'link_text': _('Visit Usage reports'), | ||
'link_href': url_for('.monthly', service_id=current_service.id), | ||
'remaining': "{:,}".format(yearlyLimit - yearlyUsed) if session['userlang'] == 'en' else "{:,}".format(yearlyLimit - yearlyUsed).replace(',', ' '), | ||
'warn': yearlyUsed / yearlyLimit >= warning_threshold | ||
} | ||
] %} | ||
|
||
{% if textOnlyMode %} | ||
<div class="mt-4 pl-10 py-2 border-l-8 border-gray-300"> | ||
{% endif %} | ||
<div data-testid="rms"> | ||
{% for section in sections if not section.skip %} | ||
{% if textOnly == None %} | ||
<div class="flex items-baseline border-b border-gray-300 py-4 gap-4 text-small " data-testid="rms-item"> | ||
{% set icon_class = icon_default %} | ||
{% set icon_type = "default" %} | ||
{% if section.warn %} | ||
{% set icon_class = icon_warning %} | ||
{% set icon_type = "warning" %} | ||
{% endif %} | ||
<span data-testid="rms-icon-{{ icon_type }}"></span> | ||
<i aria-hidden="true" class="fa-solid fa-fas {{ icon_class }}" {{ 'aria-label=' ~ _('warning') if icon_type=="warning" | ||
else "" }}></i> | ||
<div class="flex flex-wrap items-baseline gap-x-2"> | ||
<span class="font-bold" data-testid="rms-{{ section.type }}-remaining">{{ section.remaining }}</span> {{ section.text | ||
}} | ||
</div> | ||
<a href="{{ section.link_href }}" data-testid="rms-{{ section.type }}-link" class="ml-auto text-blue-500">{{ | ||
section.link_text }}</a> | ||
</div> | ||
{% else %} | ||
<p class="m-0 p-0" data-testid="rms-item"> | ||
{% if section.remaining == "0" %} | ||
<span data-testid="text-prefix-at-limit">{{ _('At limit: ') if textOnly == 'text' else '⚠️' }}</span> | ||
{% elif section.warn %} | ||
<span data-testid="text-prefix-near-limit">{{ _('Near limit: ') if textOnly == 'text' else '⚠️' }}</span> | ||
{% else %} | ||
<span data-testid="text-prefix-below-limit">{{ _('Below limit: ') if textOnly == 'text' else '🆗' }}</span> | ||
{% endif %} | ||
{{ section.remaining }} {{notification_type}} {{ section.text }} | ||
</p> | ||
{% endif %} | ||
{% endfor %} | ||
</div> | ||
{% if textOnlyMode %} | ||
</div> | ||
{% endif %} | ||
|
||
{% if sections[0].skip %} | ||
<p class="mt-4 pl-10 py-4 border-l-4 border-gray-300" data-testid="yearly-sending-paused"> | ||
Sending paused until annual limit resets | ||
</p> | ||
{% elif sections[0].remaining == "0" %} | ||
<p class="mt-4 pl-10 py-4 border-l-4 border-gray-300" data-testid="daily-sending-paused"> | ||
Sending paused until 7pm ET. You can schedule more messages to send later. | ||
</p> | ||
{% endif %} | ||
|
||
{% endmacro %} |
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,29 @@ | ||
{% extends "admin_template.html" %} | ||
{% from 'views/storybook/storybook-menu.html' import storybook_menu %} | ||
|
||
{% block page_title %} Storybook {% endblock %} | ||
|
||
{% block maincolumn_content %} | ||
<style> | ||
.container { | ||
max-width: 1536px; | ||
} | ||
</style> | ||
|
||
<div class="flex"> | ||
<!-- Left Column --> | ||
<div class="w-1/4 p-4 bg-gray-100"> | ||
<h1 class="text-lg font-bold mb-4">Components</h1> | ||
{{ storybook_menu() }} | ||
</div> | ||
|
||
<!-- Main Content Area --> | ||
<div class="w-3/4 p-4"> | ||
{% if component %} | ||
{% include 'views/storybook/' ~ component ~ '.html' %} | ||
{% else %} | ||
<p>Choose a component</p> | ||
{% endif %} | ||
</div> | ||
|
||
{% endblock %} |
85 changes: 85 additions & 0 deletions
85
app/templates/views/storybook/remaining-messages-summary.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,85 @@ | ||
{% from 'components/remaining-messages-summary.html' import remaining_messages_summary with context %} | ||
|
||
<h2><code>remaining_messages_summary</code></h2> | ||
<hr /> | ||
<h3 class="heading-medium">Below limits</h3> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-below"> | ||
|
||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 799, 1000, 799, "email") }} | ||
</div> | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(10000, 699, 10000, 699, "sms") }} | ||
</div> | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 0, 1000, 0, "email") }} | ||
</div> | ||
</div> | ||
|
||
<h3 class="heading-medium">Warning</h3> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-warning"> | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 800, 1000, 800, "email") }} | ||
</div> | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 900, 1000, 900, "email") }} | ||
</div> | ||
</div> | ||
|
||
<h3 class="heading-medium">At limit</h3> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-limit-both"> | ||
At both limits | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 1000, 1000, 1000, "email") }} | ||
</div> | ||
</div> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-limit-daily"> | ||
At daily limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 1000, 1000, 500, "email") }} | ||
</div> | ||
</div> | ||
|
||
<h3 class="heading-medium">Mixed</h3> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-mixed"> | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 100, 1000, 1000, "email") }} | ||
</div> | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 1000, 1000, 100, "email") }} | ||
</div> | ||
</div> | ||
|
||
<h3 class="heading-medium">Text only</h3> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-text-below">below limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(10000, 700, 10000, 750, "email", "text") }} | ||
</div> | ||
</div> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-text-warning">near limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 800, 1000, 900, "email", "text") }} | ||
</div> | ||
</div> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-text-limit">at limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 1000, 1000, 1000, "email", "text") }} | ||
</div> | ||
</div> | ||
|
||
<h3 class="heading-medium">Text only emoji</h3> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-emoji-below">below limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 700, 1000, 750, "email", "emoji") }} | ||
</div> | ||
</div> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-emoji-warning">near limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 800, 1000, 900, "email", "emoji") }} | ||
</div> | ||
</div> | ||
<div class="grid grid-cols-2 gap-6 bg-gray p-6" data-testid="rms-emoji-limit">at limit | ||
<div class="mb-6 bg-white p-4"> | ||
{{ remaining_messages_summary(1000, 1000, 1000, 1000, "email", "emoji") }} | ||
</div> | ||
</div> |
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,46 @@ | ||
{% from 'components/remaining-messages.html' import remaining_messages with context %} | ||
|
||
<h1 class="heading-large">remaining_messages</h1> | ||
<hr /> | ||
<h2 class="heading-medium">Below limits</h2> | ||
<div class="grid grid-cols-2 gap-4" data-testid="rm-below"> | ||
{{ remaining_messages(header=_('emails'), total=1000, used=1) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=250) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=500) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=799) }} | ||
</div> | ||
|
||
<h2 class="heading-medium">Warning</h2> | ||
<div class="grid grid-cols-2 gap-4" data-testid="rm-warning"> | ||
{{ remaining_messages(header=_('emails'), total=1000, used=800) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=825) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=900) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=999) }} | ||
</div> | ||
|
||
<h2 class="heading-medium">At limit</h2> | ||
<div class="grid grid-cols-2 gap-4" data-testid="rm-limit"> | ||
{{ remaining_messages(header=_('emails'), total=1000, used=1000) }} | ||
</div> | ||
|
||
|
||
<h2 class="heading-medium">Muted - Below limits</h2> | ||
<div class="grid grid-cols-2 gap-4" data-testid="rm-muted-below"> | ||
{{ remaining_messages(header=_('emails'), total=1000, used=1, muted=true) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=250, muted=true) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=500, muted=true) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=799, muted=true) }} | ||
</div> | ||
|
||
<h2 class="heading-medium">Muted - Warning</h2> | ||
<div class="grid grid-cols-2 gap-4" data-testid="rm-muted-warning"> | ||
{{ remaining_messages(header=_('emails'), total=1000, used=800, muted=true) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=825, muted=true) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=900, muted=true) }} | ||
{{ remaining_messages(header=_('emails'), total=1000, used=999, muted=true) }} | ||
</div> | ||
|
||
<h2 class="heading-medium">Muted - At limit</h2> | ||
<div class="grid grid-cols-2 gap-4" data-testid="rm-muted-limit"> | ||
{{ remaining_messages(header=_('emails'), total=1000, used=1000, muted=true) }} | ||
</div> |
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 @@ | ||
<!-- macro to display the component menu --> | ||
|
||
{% macro storybook_menu() %} | ||
{% set components = [ | ||
{ | ||
'name': 'Remaining Messages Summary', | ||
'path': 'remaining-messages-summary' | ||
}, | ||
{ | ||
'name': 'Remaining Messages', | ||
'path': 'remaining-messages' | ||
}, | ||
] %} | ||
<ul class="list list-bullet ml-10"> | ||
<!-- loop through components --> | ||
{% for component in components %} | ||
<li><a href="{{ url_for('main.storybook', component=component.path) }}" | ||
class="text-blue-500 hover:underline">{{ component.name }}</a></li> | ||
{% endfor %} | ||
</ul> | ||
{% endmacro %} |
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
Oops, something went wrong.