-
Notifications
You must be signed in to change notification settings - Fork 2
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
Add API notification support to new dashboard #300
Conversation
@humitos I am putting this example because I wanted to see what you thought here. I can push up the basic KO view here too if you'd like comparison on the two approaches. There are some downsides to this approach I feel -- mainly that this moves HTML templating into JS, which is harder. However, there are no more KO data bindings to be aware of, it's just straight JS string/HTML template interpolation. I will say it felt way easier to author this as a web component. If it feels like an upgrade, I feel it's worth testing the pattern a bit more and taking on Lit as a dependency (even if at least just temporarily). |
5d3d6fc
to
daadd68
Compare
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'm pretty biased on this and it's hard to not be subjective here.
I never felt comfortable with KO and each time I touch that code it feels confusing to me. In my opinion, WebComponents and Lit have been a lot more clear (not perfect, tho) than any other thing I've tried in JavaScript.
I understand this code a lot more easily and any other KO code you wrote on this project. I feel it's pretty explicit now I have more background on Lit.
Hah, yeah. I would say this is objectively better overall 😄 The places that I feel like this pattern is not obvious yet are:
I am going to experiment really quick with the second issue there on the build detail page. But if I don't make quick progress here, the build detail page might show notifications through a KO view instead. This PR doesn't need to be blocked by using Lit, but I feel it's a pretty safe/obvious/isolated/low stakes place to experiment with moving towards Lit. |
A pattern to make a hybrid KO view and Lit web component is actually rather straight forward: <rtd-notification-list
url="{% url "projects-builds-notifications-list" project.slug build.pk %}"
csrf-token="{{ csrf_token }}"
data-bind="webcomponent: {finished: !isPolling()}">
</rtd-notification-list> This is a (custom) KO So, I think I proceed and the first use case needs some more thought, but I am not prioritizing replacing big KO views like that yet. |
Wow 😲! It looks pretty straightforward. Is this a pattern that you designed or it's a standard way to set webcomponent attributes? |
This is not standard, but it was also really similar to the other KO plugins in this repo. I reused the I'll learn more while I play with it today, but the nice thing is that we can pass in whole data objects -- as opposed to passing in individual strings/booleans as you would normally do with web components. This feels like it will be really easy to integrate the two and slowly move towards Lit. |
I am on to cleaning things up, but I am rather happy with the end result so far. Here is what the notification messages look like at the top of the page currently: (Note this is just hacked HTML, if this were 5 separate messages the icons/text would be different) The order of notifications here are: error, warning, info, note, tip. Note and tip notifications don't use the inverted styling as a way to appear less visually important - for optional tasks, where error/warning/info are for mandatory tasks/information. On the build detail view, where the background in the area for errors is already inverted, note and tip have inverted styles: I'm not yet settled if this should also replace the default The style changes here are:
Work left here is all pretty minor |
I would use always the same rule no matter what page we are. Otherwise the thought behind the pattern becomes unnecessary complex and harder to understand for users.
Why not using the same style everywhere for simplification? The style that have the header separated from the body looks pretty good --like the one you shared before in https://usercontent.irccloud-cdn.com/file/WLO4Qb75/image.png Also, it seems these matches other "in page" notifications we are showing to users on settings pages and similar. IMHO, it makes sense to re-use these style as much as we can instead of creating a specific style for each of these notifications. From a user perspective will be easier to parse and for us to maintain the code. |
Thanks. There is a lot to cover here on why these changes are needed and I don't know if it help to go through all of this process again. Overall, I don't want to get too stuck on the visual styles here though, I feel it's better to tune as we go, and the main reasoning is allow us to explore notifications more.
Users aren't going to know what tip or note blocks mean by the colors used either way, so this alone is not going to confuse users.
Tip and note use a light background to help communicate to the user that they don't require attention. This is opposed to error, warning, and info, which stand out and pull the users attention away from everything else on the dashboard. The user should feel they need to do something with these immediately. We are not using tip or note level messages yet either way however. Tip level messages to me would be "You are using our beta" or "Have you tried Addons?". These styles allow for us to experiment with adding more frequent tip/note notifications without visually overwhelming the dashboard and user.
I noted this above, this is already the end goal. I am isolating the work here to just notifications at the moment. Eventually the default
In addition to the reasons above regarding
Anyways, this is all just background. Most important here is that the style changes here are quite minimal. I feel it's best to move forward and tune these as we actually start using things like tip/note messages. |
…ntation This shows top level and build detail notifications with only some small bugs remaining.
- Adds build error handling in templates - Fixes polling bugs with build and notification API
eabb09d
to
58844f2
Compare
4c9888e
to
08bea40
Compare
I don't want to block this work on this at all. I was just providing some feedback on what I saw without the intention of blocking it since the important piece here is to discuss about is the pattern itself, not the styling. That said, thanks for all the explanation about the style and the reasons behind them 👍🏼 |
These tip/note notifications and styles will feel a bit new and out of place until we are using them more, and certainly something we can tweak as we go. I've put more background on the continuation of this style work for other instances of This would be something to chip away at later, it's not a strong priority. |
Here's a wrap up of all of the various instances of notifications, dismissable and permanent. Screencast.from.2024-03-25.16-34-11.webm |
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.
Looks good to me. It took me a while to review, but I think we are going in the right direction here. I'm sure we will come back later and make some improvements on this code, but it's ready for a v1 👍🏼 -- I'm excited to start testing this in production.
@@ -27,12 +27,12 @@ export class Registry { | |||
console.error("View view_name is unspecified", view); | |||
return; | |||
} | |||
this.views[view.view_name] = (params) => { | |||
this.views[view.view_name] = (...params) => { |
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 know what ...
means here. Do you have a link I can read about?
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 is the spread operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
It's synonymous with Python's *args
basically. The change above changes this from a function that takes one argument to a function that takes any number of arguments.
const params = new URLSearchParams({ | ||
state__in: this.state, | ||
}); | ||
this.request = fetch(`${this.url}?${params}`) |
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.request
is used just a flag to not keep polling if we already have the results, or it means something different?
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.
Yup, exactly, this just prevents multiple polling.
Lit actually has a whole implementation for async tasks that seems worthwhile, but I didn't want to complicate things too much just yet:
https://lit.dev/docs/data/task/
I could see us using this later.
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.
Maybe is it worth to add a TODO comment in the code with a link to this documentation page so it's easier to come back to this.
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 opened up an issue:
I think we could explore this API usage here or even on Addons. It seems like a good improvement over a hand rolled solution, so maybe there isn't much blocking us. I mostly avoided it to avoid stacking complexities on this first pass. If we're sold, maybe I just bring this dependency in next time I do something with Lit (maybe one of the missing popupcards?).
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 opening the issue.
I think we could explore this API usage here or even on Addons
I'm not sure how this applies to the addons since the only call we do to fetch the JSON object from the API is done at early load stage before even initializing the Lit elements and it's done only once and shared across all the Lit elements.
Can you expand about this here or open an issue on the addons explaining how we can use this?
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 also do requests for the search API and docdiff, this could applicable there. It's a place we could decide to experiment with this, but I don't necessarily feel we need to change any patterns with Addons either.
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.
Good point! Sounds good to me 👍🏼
{% block build_detail_notifications %} | ||
{% comment %} | ||
Build notification and error list | ||
|
||
This uses ``readthedocs-notification`` directly, so that the build | ||
detail view can handle all of the API requests in one place. | ||
|
||
We pass the entire API notification response object into the web | ||
component, which handles the data the same way as the notification | ||
list element. | ||
{% endcomment %} | ||
<div class="ko hidden ui attached fitted inverted basic segment" data-bind="css: { hidden: !has_notifications() }, foreach: notifications"> |
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.
It's not clear to me why we don't use readthedocs-notifications-list
here. Can you expand on that? Do we plan to use it in the future?
I saw the polling is done via KO and each of the notification is rendered using readthedocs-notification
with the data coming from KO --but I'm not sure to understand what's the thought behind that.
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.
You are correct, given the current structure I could have used list here to do the API polling.
The reason I did not is because it seemed like we might be moving towards returning notifications in the build API v3 response -- so everything would happen with one API call. In this case, the readthedocs-notification-list
element doesn't do anything.
If we decide to not do that, the polling can be pushed on to the list element, and the KO view can call into this element method instead of performing its own API call for notifications.
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 reason I did not is because it seemed like we might be moving towards returning notifications in the build API v3 response -- so everything would happen with one API call
Do we have an issue for this? I suppose that ?expand=notifications
on the request should be enough here.
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.
Loosely, though there are a few individual issues combined here:
I'm merging changes from |
Things look good, including built assets. Thanks for taking a look through this! |
I started with a KO view for notifications, and the amount of boilerplate was
fairly heavy, as observables are needed for each notification attribute.
This is a quick test of using Lit for digestible chunks of HTML. I will say it's
way nicer than using KO views.
I'm wondering if it's worth testing Lit in this application. We're gaining more
knowledge on web components, and this is one of the use cases that seems like a
good fit.
Work left here is all pretty minor:
.ui.message
first of all.state__in
filter