Skip to content

Commit 0f36e2e

Browse files
agjohnsonhumitos
andauthored
Add API notification support to new dashboard (#300)
* Proof of concept Lit notification element * More experimenting with API notifications in other spots in the UI * WIP, includes web component for notification * Add notification message styles and overrides, mostly working implementation This shows top level and build detail notifications with only some small bugs remaining. * Clean up rough edges on build view, JS, and templates - Adds build error handling in templates - Fixes polling bugs with build and notification API * Relint files * Add missing file * Fix notification over polling * Change API notification query to state__in * Fix up docs * Drop extra messages block, it is unused. * Add missing web components API doc file --------- Co-authored-by: Manuel Kaufmann <[email protected]>
1 parent 8eafe7f commit 0f36e2e

File tree

27 files changed

+658
-234
lines changed

27 files changed

+658
-234
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ commands:
1515
steps:
1616
- checkout
1717
- run: pip install djhtml
18-
- run: djhtml --tabwidth 2 readthedocsext/
18+
- run: djhtml --check --tabwidth 2 readthedocsext/
1919
run-build:
2020
description: "Ensure built assets are up to date"
2121
steps:

docs/api/javascript.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ JavaScript API
66

77
js/application
88
js/plugins
9+
js/webcomponents
910
js/views

docs/api/js/plugins.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Display
99

1010
.. autofunction:: ./application/plugins.semanticui
1111

12+
.. autofunction:: ./application/plugins.webcomponent
13+
1214
Data
1315
~~~~
1416

@@ -25,8 +27,6 @@ How to pass data between the templates and our JavaScript in a secure manner.
2527
Modules
2628
~~~~~~~
2729

28-
.. autofunction:: ./application/plugins.message
29-
3030
.. autofunction:: ./application/plugins.chart
3131

3232
jQuery

docs/api/js/webcomponents.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Web components
2+
==============
3+
4+
Elements
5+
--------
6+
7+
.. js:autoclass:: NotificationListElement
8+
:members:
9+
10+
.. js:autoclass:: NotificationElement
11+
:members:
12+
13+
Views
14+
-----

package-lock.json

Lines changed: 62 additions & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"knockout": "^3.5.1",
4747
"lato-font": "^3.0.0",
4848
"less": "^4.2.0",
49-
"less-loader": "^11.1.3",
49+
"less-loader": "^12.2.0",
50+
"lit": "^3.1.2",
5051
"matchdep": "~2.0.0",
5152
"mini-css-extract-plugin": "^2.7.6",
5253
"plausible-tracker": "^0.3.8",

readthedocsext/theme/static/readthedocsext/theme/css/site.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

readthedocsext/theme/static/readthedocsext/theme/js/site.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

readthedocsext/theme/static/readthedocsext/theme/js/vendor.js

Lines changed: 69 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

readthedocsext/theme/templates/account/login.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626

2727
<div
2828
{# The password URL is listed as an additional tab if present #}
29-
class="ui small stackable secondary item menu {% if project_password_url %}three{% else %}two{% endif %}"
30-
data-bind="semanticui: {tabs: {history: true, autoTabActivation: false}}">
29+
class="ui small stackable secondary item menu {% if project_password_url %}three{% else %}two{% endif %}"
30+
data-bind="semanticui: {tabs: {history: true, autoTabActivation: false}}">
3131

3232
{# This is purposely minimal, as the verbiage for "Log in with connected account" is a mountful #}
3333
<a class="item" data-tab="vcs">
@@ -40,18 +40,18 @@
4040
<a class="item {% if allowed_providers %}disabled{% endif %}"
4141
data-tab="email"
4242
{% if allowed_providers %}
43-
data-content="{{ text_email_disabled }}"
44-
aria-label="{{ text_email_disabled }}"
43+
data-content="{{ text_email_disabled }}"
44+
aria-label="{{ text_email_disabled }}"
4545
{% endif %}>
4646
<i class="fad fa-envelope icon"></i>
4747
{% block authentication_email_text %}{% trans "Log in with email" %}{% endblock %}
4848
</a>
4949

5050
{% if project_password_url %}
51-
<a class="item" href="{{ project_password_url }}">
52-
<i class="fad fa-lock icon"></i>
53-
{% trans "Use a password" %}
54-
</a>
51+
<a class="item" href="{{ project_password_url }}">
52+
<i class="fad fa-lock icon"></i>
53+
{% trans "Use a password" %}
54+
</a>
5555
{% endif %}
5656
</div>
5757

readthedocsext/theme/templates/base.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050

5151
{% block content-wrapper %}
5252
<div class="ui very padded container">
53-
{% block messages %}
53+
{% block notifications %}
5454
{% include "includes/utils/messages.html" %}
55-
{% endblock messages %}
55+
{% endblock notifications %}
5656

5757
{# TODO move admin-bar usage to content-header #}
5858
{% block admin-bar %}{% endblock %}

readthedocsext/theme/templates/builds/build_detail.html

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
{% endblock %}
2929

3030
{% block content %}
31-
<div class="ui basic segment padded" data-bind="using: BuildDetailView({id: {{ build.pk }}})">
31+
<div class="ui basic segment padded" data-bind="using: BuildDetailView({}, '{% url "build-detail" build.id %}', '{% url "projects-builds-notifications-list" build.project.slug build.id %}')">
3232

3333
{% block build_detail_metadata %}
3434
<div class="ui top attached segment">
@@ -202,25 +202,40 @@ <h3>{% trans "Build Errors" %}</h3>
202202

203203
{% else %}
204204

205-
{% comment %}
206-
Error list
207-
{% endcomment %}
208-
{% if build.notifications.exists %}
209-
{% for notification in build.notifications.all %}
210-
{% if notification.get_message.type == "error" %}
211-
<div class="ui attached inverted red segment">
212-
<i class="fa-solid fa-exclamation circular icon"></i>
213-
<span>{{ notification.get_message.get_rendered_body|safe }}</span>
214-
<span>{% trans "For more information on this error, see our documentation." %}</span>
205+
{% block build_detail_notifications %}
206+
{% comment %}
207+
Build notification and error list
208+
209+
This uses ``readthedocs-notification`` directly, so that the build
210+
detail view can handle all of the API requests in one place.
211+
212+
We pass the entire API notification response object into the web
213+
component, which handles the data the same way as the notification
214+
list element.
215+
{% endcomment %}
216+
<div class="ko hidden ui attached fitted inverted basic segment" data-bind="css: { hidden: !has_notifications() }, foreach: notifications">
217+
<readthedocs-notification
218+
inverted=true
219+
csrf-token="{{ csrf_token }}"
220+
data-bind="webcomponent: {notification: $data}">
221+
</readthedocs-notification>
222+
</div>
223+
224+
{% comment %}
225+
Support for old style build errors, without notifications. In these
226+
builds, ``error`` is a string and there is no header, so we use a
227+
generic header instead.
228+
{% endcomment %}
229+
<div class="ko hidden ui attached fitted inverted basic segment" data-bind="css: { hidden: !error() }">
230+
<div class="ui inverted error notification message">
231+
<div class="header">
232+
<i class="fad fa-circle-exclamation icon"></i>
233+
{% trans "There was an error with this build" %}
215234
</div>
216-
{% endif %}
217-
{% endfor %}
218-
{% else %}
219-
<div class="ui attached inverted red segment" data-bind="visible: error" style="display: none;">
220-
<span data-bind="text: error"></span>
221-
<span>{% trans "For more information on this error, see our documentation." %}</span>
235+
<p data-bind="text: error"></p>
236+
</div>
222237
</div>
223-
{% endif %}
238+
{% endblock build_detail_notifications %}
224239

225240
<div class="ui inverted bottom attached segment transition slide">
226241

readthedocsext/theme/templates/includes/utils/messages.html

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,6 @@
77
page content pane.
88
{% endcomment %}
99

10-
{% comment %}
11-
``user_notifications`` comes from a Context Processor.
12-
We need to use a CustomUser to have access to "user.notifications"
13-
See https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-AUTH_USER_MODEL
14-
{% endcomment %}
15-
{% if user_notifications %}
16-
{% for notification in user_notifications %}
17-
<div class="ui message">
18-
{% comment %}
19-
Add this Xmark here once we implement dismissing notifications.
20-
<i class="fa-duotone fa-circle-xmark close icon"></i>
21-
{% endcomment %}
22-
{{ notification.get_message.get_rendered_body|safe }}
23-
</div>
24-
{% endfor %}
25-
{% endif %}
26-
2710
{% if messages %}
2811
{% for message in messages %}
2912
{% comment %}

0 commit comments

Comments
 (0)