-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Create check-in form from template #10974
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 check-in form from template #10974
Conversation
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.
There are accessibility issues in these changes.
this.checkInDisplay.hide() | ||
this.checkInPrompt.show() | ||
}) | ||
.catch(err => { |
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.
.catch(err => { | |
.catch(() => { |
err
is unused, and this is causing our CI/CD checks to fail.
data = json.loads(web.data()) | ||
if not self.validate_data(data): | ||
raise web.HTTPError( | ||
"404 Bad Request", headers={"Content-Type": "application/json"} |
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.
"404 Bad Request", headers={"Content-Type": "application/json"} | |
"400 Bad Request", headers={"Content-Type": "application/json"} |
Fix copy-paste oversight.
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 might be best as a 400 Bad Request than a 404
648fbfa
to
8d74f4f
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.
This should probably be renamed to yearly_reading_goals.py
, to match the name of the DB API for this feature.
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.
Woohoo great refactor! Separating out the yearly reading goal logic makes a ton of sense. And this fixes the bug about not being able to update the date! 🥳
No blockers, a few suggestions on code/naming/arch.
I tested:
- Moving a book to "Already read" shows the prompt
- I can click "2025" and it saves
- I can then later edit it to add month/year
- Today link works
- Edition persisted when on books page
- Existing bug: not persisted when from search page.
Merge at your discretion!
const splitKey = this.workKey ? this.workKey.split('/') : [''] | ||
const workOlid = splitKey[splitKey.length - 1] |
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.
const splitKey = this.workKey ? this.workKey.split('/') : [''] | |
const workOlid = splitKey[splitKey.length - 1] | |
const workOlid = this.workKey ? this.workKey.split('/')[2] : ''; |
|
||
const splitKey = this.workKey ? this.workKey.split('/') : [''] | ||
const workOlid = splitKey[splitKey.length - 1] | ||
this.checkInComponents = new CheckInComponents(document.querySelector(`#check-in-container-${workOlid}`)) |
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.
Note this could cause some subtle bugs if a book appears twice on a page; can we avoid having it being a global id? Something like this.dropper.querySelector('.checkin-form')
? Although it seems like this exists outside the my-books
div. I think that makes the dividing line between our components a bit messy; it might make more sense to either have checkin-form be its own independent component outside the book dropper.
But those are kind of bigger changes; maybe quicker might be this.dropper.parentElement.querySelector('.last-read-date')
with a comment about the assumptions.
|
||
const splitKey = this.workKey ? this.workKey.split('/') : [''] | ||
const workOlid = splitKey[splitKey.length - 1] | ||
this.checkInComponents = new CheckInComponents(document.querySelector(`#check-in-container-${workOlid}`)) |
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.
Regardless, a bit odd this is plural, confused me for a bit whether this was initializing all the check in components on the page.
this.checkInComponents = new CheckInComponents(document.querySelector(`#check-in-container-${workOlid}`)) | |
this.checkInComponent = new CheckInComponents(document.querySelector(`#check-in-container-${workOlid}`)) |
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 CheckInComponents
object is comprised of three individual components:
- The check-in form, which is displayed in a modal.
- The check-in prompt, which appears below the dropper and prompts the patron for a last-read date.
- A display that shows the last check-in date, and provided an affordance to edit the date.
* | ||
* @class | ||
*/ | ||
export class CheckInComponents { |
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.
Ditto here, the plural is a little misleading.
export class CheckInComponents { | |
export class CheckInComponent { |
openlibrary/plugins/openlibrary/js/my-books/MyBooksDropper/CheckInComponents.js
Show resolved
Hide resolved
let hiddenModalContentContainer = document.querySelector('#hidden-modal-content-container') | ||
if (!hiddenModalContentContainer) { | ||
hiddenModalContentContainer = document.createElement('div') | ||
hiddenModalContentContainer.classList.add('hidden') | ||
hiddenModalContentContainer.id = 'hidden-modal-content-container' | ||
document.body.appendChild(hiddenModalContentContainer) | ||
} | ||
|
||
const modalContent = this.createModalContentFromTemplate() | ||
hiddenModalContentContainer.appendChild(modalContent) | ||
|
||
this.modalContent = hiddenModalContentContainer.querySelector(`#modal-content-${this.config.workOlid}`) |
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.
If I understand correctly, this is creating one shared #hidden-modal-content-container
used by all the CheckIn components, and putting inside it CheckInForms from all check-ins on the page? And then only getting things with the given work olid to apply to this.
Could we make the form generate dynamically only when needed? The current approach will create a lot of DOM, the majority of which is very unlikely to be used, which has a memory impact.
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.
Will create follow-up issue to track this.
openlibrary/plugins/openlibrary/js/my-books/MyBooksDropper/CheckInComponents.js
Outdated
Show resolved
Hide resolved
data = json.loads(web.data()) | ||
if not self.validate_data(data): | ||
raise web.HTTPError( | ||
"404 Bad Request", headers={"Content-Type": "application/json"} |
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 might be best as a 400 Bad Request than a 404
<span> | ||
<label class="check-in__year-label">$_('Year:')</label> | ||
<select class="check-in__select" name="year"> | ||
<option value="">$_('Year')</option> | ||
<option class="hidden show-if-local-year" value="$(year + 1)">$(year + 1)</option> | ||
$for i in range(120): | ||
<option value="$(year - i)">$(year - i)</option> | ||
</select> | ||
</span> |
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.
Oh and another thing: we can avoid having to align these via JS by using this HTML trick. This automatically associated the label without having to specify for
.
<span> | |
<label class="check-in__year-label">$_('Year:')</label> | |
<select class="check-in__select" name="year"> | |
<option value="">$_('Year')</option> | |
<option class="hidden show-if-local-year" value="$(year + 1)">$(year + 1)</option> | |
$for i in range(120): | |
<option value="$(year - i)">$(year - i)</option> | |
</select> | |
</span> | |
<label> | |
$_('Year:') | |
<select class="check-in__select" name="year"> | |
<option value="">$_('Year')</option> | |
<option class="hidden show-if-local-year" value="$(year + 1)">$(year + 1)</option> | |
$for i in range(120): | |
<option value="$(year - i)">$(year - i)</option> | |
</select> | |
</label> |
Blocked on necessary rebase. |
- Handler will fail fast if called while unauthenticated - Errors are returned as `application/json`
- Client-side check-in code has been consolidated in `ReadDateComponents.js` - Check-in templates have been moved to `templates/mybooks/` - Check-in form is now displayed in a `colorbox` component - Check-in forms are now created client-side, from a template rendered in `check_in_prompt.html`
The `ajax` `error` callbacks were not being executed when responses were not `OK`. These calls have been replaced with `fetch`. Any errors are handled by the caller.
Adds `dialog--open` class and `aria-controls` to the dialog opener affordances (the "Edit" and "Other" links). These changes cause the dialog openers to be initialized in the main `index.js` flow, in the typical manner. `open-modal` custom events and the `openModal` method were removed from `CheckInComponents.js, as the dialog openers are now initialized in `index.js``. Adds `initDialogClosers` function to `dialog.js` for adding listeners to elements that were created client-side.
37e3a6c
to
dc9211e
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #10974 +/- ##
==========================================
+ Coverage 17.14% 17.85% +0.71%
==========================================
Files 91 92 +1
Lines 4981 5096 +115
Branches 867 887 +20
==========================================
+ Hits 854 910 +56
- Misses 3588 3639 +51
- Partials 539 547 +8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
eb0911d
to
3e15cb3
Compare
for more information, see https://pre-commit.ci
Closes #10582
Makes the following changes:
my-books
modulecolorbox
$.ajax
calls withfetch
Technical
Testing
Screenshot
Stakeholders