-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Create My Books Dropper #8019
Create My Books Dropper #8019
Conversation
ef80d92
to
5448579
Compare
Codecov Report
@@ Coverage Diff @@
## master #8019 +/- ##
==========================================
- Coverage 17.14% 16.67% -0.47%
==========================================
Files 71 83 +12
Lines 3750 4419 +669
Branches 647 757 +110
==========================================
+ Hits 643 737 +94
- Misses 2695 3199 +504
- Partials 412 483 +71
|
* @param {object} data Object containing the new list's name, description, and seeds. | ||
* @returns {Promise<Response>} The results of the POST request | ||
*/ | ||
export async function createList(userKey, data) { |
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.
What happens if there is a request error/failure?
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.
Nothing now, but maybe we trigger a toast message?
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.
Quick note: any errors are meant to be handled by the caller of this function. Whatever we decide to do on list creation failure will be included inside of a catch()
call, here:
openlibrary/openlibrary/plugins/openlibrary/js/my-books/ReadingLists.js
Lines 379 to 383 in 965c75f
await createList(this.userKey, data) | |
.then(response => response.json()) | |
.then((data) => { | |
this.onListCreationSuccess(data['key'], listTitle) | |
}) |
Q: Is it possible for us to use a param or a separate endpoint (e.g addtolist.json v. addtolist) one which returns The problem we'd be trying to solve is making the Want to Read button work more naturally in the case where js is disabled (so it doesn't look like a bug / return json) |
@@ -62,8 +62,17 @@ def get_seed_info(doc): | |||
|
|||
@public | |||
def get_list_data(list, seed, include_cover_url=True): | |||
list_items = [] | |||
for s in list.get_seeds(): |
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.
@mekarpeles to check whether any caching here.
@jimchamp: may have performance issues if list has many seeds?
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.
Noting that this section isn't properly feature-flagged. list_items
should only be populated and added to list data d
if my_books_dropper
feature is enabled.
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.
@jimchamp: may have performance issues if list has many seeds?
Yes, on book pages. This is only called once on search results pages, but several times in book pages. The public get_user_lists
function also calls this while iterating over a list. Cleaning up the lists widget template a bit should help.
7078bf5
to
fdc7e30
Compare
bundlesize.config.json
Outdated
@@ -78,11 +78,11 @@ | |||
}, | |||
{ | |||
"path": "static/build/page-admin.css", | |||
"maxSize": "25KB" | |||
"maxSize": "26KB" |
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 surprised that this size needed to be adjusted. I wonder if our Less references need investigation.
f1f55f3
to
ec70452
Compare
@@ -0,0 +1,17 @@ | |||
$def with(primary_button, dropdown_content, additional_classes='') |
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 needs comments. Would be good to know that passing generic-dropper--disabled
as an additional class will disable the dropper for logged out patrons.
Important Note: Feature flag should be reinstated. If we're seeing a severe performance hit on search pages after this is released, we'll want to be able to quickly revert to the old droppers. |
456f6b5
to
946bc22
Compare
$ data_list_key = 'data-list-key=%s' % list.key if actionable else '' | ||
<li $actionable $data_list_key> |
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.
Hey @jimchamp do you mind if I commit this change? I think that should let both our PRs co-exist on testing (mine is #8168 )
$ data_list_key = 'data-list-key=%s' % list.key if actionable else '' | |
<li $actionable $data_list_key> | |
<li $actionable $:cond(actionable, 'data-list-key=%s' % list.key)> |
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.
Messaged you on slack and you preferred to remove it from testing. Removed it 👍 Accept this suggestion at your discretion 😋
d4b7492
to
4c2a306
Compare
bc6ed32
to
ce0938f
Compare
- These are meant to be overridden by Dropper subclasses, if needed. - `onDisabledClick` is called whenever a disable dropper is clicked - `onOpen` is called when the dropper is opened - `onClose` is called when the dropper is closed - My Books dropper `toggleDropper` override has been replaced with an `onOpen` override.
Bugs fixed:
Subclasses of
The intention is that the new New changes have not been deployed to LLEs. |
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.
LGTM, there were 4 considerations outstanding last time we discussed:
- Clicking dropdown arrow when logged out should redirect to login page
- Errors on Authors page
- Book covers not loading -- similar problems on production (at least for initial load)
- Create an issue for ability to see selected lists in dropper even when minimized/closed – volunteer wanted (limit to 3, scrollable)
Co-authored-by: Mek <michael.karpeles@gmail.com>
for more information, see https://pre-commit.ci
Closes #6531
Closes #6897
Closes #6992
Closes #8009
Creates reusable dropper component, and refactors code such that the My Books dropper uses the new generic dropper.
Issue where works cannot added to / removed from a list has been fixed as well.
Technical
The Generic Dropper Component
The generic dropper component comprised of a primary button and dropdown content. The template for the dropper takes a rendered HTML string for each of these. The template also takes a additional classes as a string, enabling the dropper to be styled as needed.
Visibility of the dropdown content can be changed by clicking the "dropclick" arrow. If a patron clicks outside of the dropper component when the dropdown is visible, it will be hidden. This functionality is business as usual (BAU). What is new is that dropdown visibility can now be changed with 'toggle-dropper
and
close-dropperevents. Using these new event is as easy as passing a reference to a child element of a dropper to the
fireDropperToggleEventand
fireDropperCloseEvent` functions, which dispatch the appropriate event from the given element to the parent dropper.The new template for generic droppers is
/openlibrary/templates/lib/dropper.html
. All BAU dropper functionality will automatically be added to components created using that template.The My Books Dropper
The My Books Dropper combines reading log shelf, list, and last read date management in a single component. Three new templates have been created for this component:
/openlibrary/templates/my_books/dropper.html
: Takes apage
(work, edition, author, etc.) and renders a new My Books Dropper/openlibrary/templates/my_books/dropdown_content.html
: Renders reading log buttons (if applicable), dropdown list affordances, and the "Create a new list" modal content./openlibrary/templates/my_books/primary_action.html
: Renders the primary reading log button, or "Add to list" CTA button (depending on context).New JS classes have been created in order to better encapsulate different "My Books" actions:
ReadingLogForms
handles everything related to our reading log bookshelves.ReadDateComponents
contains code that toggles visibility of our "Last read date" components.ReadingLists
handles all list management functionality.Additionally, a new
MyBooksDropper
class has been created, which creates instances of the aforementioned classes (if possible), and asynchronously loads the patrons lists. Creating a new MyBooksDropper object will hydrate all parts of the dropper that the object represents.The following diagram illustrates which class affects what part of the My Books dropper:
Note that the
ReadingList
class also provides the "Remove from list" functionality for showcase items:General
The My Books droppers are feature flagged. Legacy "lists/widget" droppers will be used unless
features.my_books_dropper
isenabled
in theopenlibrary.yml
. To quickly check if the new droppers are enabled, you can search the page's HTML source for the classdropper-wrapper
, which is unique to My Books droppers.New functions have been added to
ListService.js
which make/lists
POST requests withfetch
. The legacy, callback-based, approach was largely untestable.Limitations
Testing
When logged out:
When logged in, on a book page:
When logged in, on a search result page:
Screenshot
Next steps
We may want to avoid using the new My Books droppers until lists can be fully managed from search results pages. This will require list removal from inside of the dropdown content. Until that time, we could enable the droppers in testing in order to get feedback from folks.
We should also make sure that read date, list, and reading log data used to create these droppers is fetched in a performant manner (maybe in bulk and from a cache?).
After the feature is rolled out, we could consider the following improvements:
ReadingLogDropper.html
, etc.).lists/widget
template.ListService.js
Stakeholders