Skip to content

Add configurable per-item hold duration#2118

Open
phinze wants to merge 2 commits intomainfrom
configurable-hold-duration
Open

Add configurable per-item hold duration#2118
phinze wants to merge 2 commits intomainfrom
configurable-hold-duration

Conversation

@phinze
Copy link
Copy Markdown
Contributor

@phinze phinze commented Mar 17, 2026

What it does

Adds an optional hold_duration field to items, letting staff set how long a member has to pick up a held item. Items without a custom duration keep the existing 7-day behavior. Items with a shorter duration (like 1 day) expire at the end of the next day the library is open, calculated using the library's event calendar.

Member-facing messaging updates throughout: item detail page, hold placement, holds index sidebar, and the holds-available email all conditionally explain the shorter window in a friendly way.

Why it is important

Librarians need a way to keep high-demand seasonal items (tillers, weed whackers, etc.) circulating faster. The only options today are a 7-day hold or disabling holds entirely, and disabling holds leads to members calling the library for informal holds, which is harder for everyone.

UI Change Screenshot

Admin: hold duration dropdown on item edit

admin edit

Member: placing a hold on a short-hold item

place a hold

Member: item already on hold, ready for pickup

on hold nudge

Holds sidebar: new bullet about popular items

holds sidebar

Implementation notes

  • hold_duration is a nullable integer on items. nil means "use the default (7 calendar days)." A value like 1 means "1 day, landing on the next open day."
  • When an item has an explicit hold_duration, expiration is calculated via Event.next_open_day so holds don't expire on days the library is closed. The default path is unchanged to avoid any behavioral surprises for existing items.
  • Admin UI uses a dropdown (not a free text field) to keep the options clear and intentional.
  • Added tests covering default duration, custom duration with open-day awareness, and the 1-day hold scenario specifically.

Closes #2115

phinze added 2 commits March 17, 2026 11:43
Some seasonal items had holds disabled because 7-day holds led
to long waitlists with no-shows. But no holds meant members
calling librarians to set items aside informally. Tessa
suggested 1-day holds as a middle ground.

Adds hold_duration to items with a dropdown in the admin form.
When set, expiration uses Event.next_open_day so "1 day" means
the next day the library is actually open. Default 7-day
behavior is unchanged for items without an explicit duration.

Member-facing copy updated across item detail, place-hold
button, holds sidebar, and notification email.

Closes #2115
Switch the "heads up" text from gray italic to a toast-warning callout
box for better visibility. Add a similar nudge on the "you have this
on hold" view when the item is ready for pickup but no appointment is
scheduled yet.
@phinze phinze requested a review from a team March 17, 2026 19:35
expires_at = if item.hold_duration
Event.next_open_day(now + item.hold_duration.days).end_of_day
else
(now + DEFAULT_HOLD_DURATION.days).end_of_day
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be change in behavior, but I wonder if we should also make this branch use Event.next_open_day so that we aren't picking a day that we're closed? It would make closing for holidays more seamless.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I thought about this a while too - I made the more conservative change to start... but if we agree it's strictly better I can make the change!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal either way! We can merge this as-is to unblock staff and then make the other change if everything is working.

Comment on lines +1 to +5
<% if short_hold_item?(item) %>
<div class="toast toast-warning text-small">
<strong>Heads up:</strong> this item has a short hold window, so be ready to schedule a pickup right away!
</div>
<% end %>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call adding these notices for members!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1-day hold periods

2 participants