Similar to the shift occurrence filter, this allows admins to filter shifts on the shift index page. Since we're filtering shifts with their representative events (ShiftSummary), it mostly filters things on events:
- recurring, non-recurring, recurring-agnostic
- has a specific site
- has a specific user
- has no users
- happens on a particular weekday
- time of day overlaps with a time range
Technical notes
Time range and weekday filter were tricky because they need to take into account
the organization's time zone. We don't store a time zone on the starts_at
timestamp (this is a rails default). When Rails creates an event, starts_at is
converted from the org's time zone to UTC and stored in postgres. When we
filter, first we need to tell postgres that the time is in UTC. Then, we tell it
convert the timestamp to the org's time zone, and finally convert it to
postgres' time type, or day-of-week (dow) for comparison.
This also required joining the event to the organization. Events have a
polymorphic association to the org which rails does not allow you to join on, so
I also added the organization relationship explicitly.
- user input: 2026年01月01日 10:00AM MST
- postgres stored: 2026年01月01日 17:00 (no time zone)
- utc zone convert: 2026年01月01日 17:00 UTC
- org zone convert: 2026年01月01日 10:00 MST
- time convert: 10:00
Similar to the shift occurrence filter, this allows admins to filter shifts on the shift index page. Since we're filtering shifts with their representative events (ShiftSummary), it mostly filters things on events:
- recurring, non-recurring, recurring-agnostic
- has a specific site
- has a specific user
- has no users
- happens on a particular weekday
- time of day overlaps with a time range
<video src="/attachments/42c51a55-8007-423a-9eff-c5d89551e84a" title="Waterfox" controls></video>
## Technical notes
Time range and weekday filter were tricky because they need to take into account
the organization's time zone. We don't store a time zone on the `starts_at`
timestamp (this is a rails default). When Rails creates an event, `starts_at` is
converted from the org's time zone to UTC and stored in postgres. When we
filter, first we need to tell postgres that the time is in UTC. Then, we tell it
convert the timestamp to the org's time zone, and finally convert it to
postgres' `time` type, or day-of-week (`dow`) for comparison.
This also required joining the event to the organization. Events have a
polymorphic association to the org which rails does not allow you to join on, so
I also added the organization relationship explicitly.
- user input: 2026年01月01日 10:00AM MST
- postgres stored: 2026年01月01日 17:00 (no time zone)
- utc zone convert: 2026年01月01日 17:00 UTC
- org zone convert: 2026年01月01日 10:00 MST
- time convert: 10:00