Skip to content

feat: configurable first day of week for date pickers - #1626

Open
chunjiw wants to merge 2 commits into
sysadminsmedia:mainfrom
chunjiw:feat/configurable-first-day-of-week
Open

feat: configurable first day of week for date pickers#1626
chunjiw wants to merge 2 commits into
sysadminsmedia:mainfrom
chunjiw:feat/configurable-first-day-of-week

Conversation

@chunjiw

@chunjiw chunjiw commented Jul 22, 2026

Copy link
Copy Markdown

What type of PR is this?

  • feature

What this PR does / why we need it

Date pickers always start the week on Monday today — not by choice, but because @vuepic/vue-datepicker defaults week-start to 1 and we never set the prop. This adds a First day of week user preference (Auto / Sunday / Monday / Saturday) so users whose region starts on Sunday or Saturday can change it.

  • firstDayOfWeek added to the existing user-preferences sync (localStorage + PUT /users/self/settings) — no backend changes; the settings blob is schemaless.
  • resolveWeekStart() (new, unit-tested pure helper) maps the preference to VueDatePicker's week-start; "auto" derives from Intl.Locale week info with a Monday fallback.
  • Applied to both VueDatePicker usages (item date picker + invite-expiry picker); select added beside the language settings.

Special notes for your reviewer

Default is "auto" (locale-derived), which changes the current default for existing users (e.g. en-US now shows Sunday). Happy to default to Monday and make it purely opt-in instead — let me know your preference.

Testing

  • Unit test for resolveWeekStart (explicit passthrough, locale auto-detection, invalid-tag fallback).
  • Manual: changing the setting updates both pickers immediately and persists across reload / devices.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9213d566-118b-4af0-aa29-fe9049c1e4ce

📥 Commits

Reviewing files that changed from the base of the PR and between bef73e6 and 478d418.

📒 Files selected for processing (2)
  • frontend/lib/datelib/weekStart.test.ts
  • frontend/lib/datelib/weekStart.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/lib/datelib/weekStart.test.ts
  • frontend/lib/datelib/weekStart.ts

Summary by CodeRabbit

  • New Features
    • Added a configurable “first day of week” preference.
    • Includes options for automatic regional selection and specific choices (Sunday, Monday, Saturday).
    • Date pickers now consistently reflect the selected week-start preference.
    • Added localized labels for the new calendar options.
  • Bug Fixes
    • Improved handling of invalid or malformed saved week-start values by safely falling back to Monday.

Walkthrough

Adds a configurable first day of the week, resolves automatic values from locale data, and applies the result to shared and invite date pickers.

Changes

Week start preferences

Layer / File(s) Summary
Week-start resolution and validation
frontend/lib/datelib/weekStart.ts, frontend/lib/datelib/weekStart.test.ts
Defines WeekStart, resolves explicit or locale-derived values, supports multiple Intl.Locale week-info shapes, and tests fallback behavior.
Preference contract and selector
frontend/composables/use-preferences.ts, frontend/components/App/LanguageSelector.vue, frontend/locales/en.json
Adds firstDayOfWeek with an auto default and exposes automatic, Sunday, Monday, and Saturday selection options.
Date-picker week-start integration
frontend/components/Form/DatePicker.vue, frontend/components/Collection/InviteCreateModal.vue
Resolves the configured week start using preferences and locale overrides, then passes it to both date-picker variants and the invite date picker.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LanguageSelector
  participant useViewPreferences
  participant resolveWeekStart
  participant VueDatePicker

  LanguageSelector->>useViewPreferences: Update firstDayOfWeek
  VueDatePicker->>useViewPreferences: Read firstDayOfWeek
  VueDatePicker->>resolveWeekStart: Resolve preference and locale
  resolveWeekStart-->>VueDatePicker: Return week-start value
  VueDatePicker-->>LanguageSelector: Render configured calendar
Loading

Possibly related PRs

  • sysadminsmedia/homebox#958: Adds the server-synced user-settings infrastructure that includes the preference layer used by this change.

Poem

Sunday, Monday, regions decide,
A tiny setting turns the tide.
Calendars now start just right,
With locale wisdom shining bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: configurable first-day-of-week support for date pickers.
Description check ✅ Passed The description is mostly complete and follows the template, but it omits the required issue-fix section.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added go Pull requests that update Go code 🕷️ bug Something isn't working labels Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/lib/datelib/weekStart.ts`:
- Around line 13-27: Update resolveWeekStart to return non-"auto" preferences
only when they are numeric values from 0 through 6; otherwise fall back to
Monday. Also validate the firstDay value obtained from Intl.Locale before
mapping Sunday (7) to 0, treating missing or out-of-range values as fallback
cases. In frontend/components/App/LanguageSelector.vue lines 38-43, apply the
same validation at the affected usage site as requested by the shared week-start
handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 72fd62a8-5a49-4df1-ab38-737ba5643f87

📥 Commits

Reviewing files that changed from the base of the PR and between 52eb6f3 and bef73e6.

📒 Files selected for processing (7)
  • frontend/components/App/LanguageSelector.vue
  • frontend/components/Collection/InviteCreateModal.vue
  • frontend/components/Form/DatePicker.vue
  • frontend/composables/use-preferences.ts
  • frontend/lib/datelib/weekStart.test.ts
  • frontend/lib/datelib/weekStart.ts
  • frontend/locales/en.json

Comment thread frontend/lib/datelib/weekStart.ts Outdated
Comment on lines +13 to +27
export function resolveWeekStart(pref: WeekStart, locale?: string | null): number {
if (pref !== "auto") {
return pref;
}
try {
const tag = locale || (typeof navigator !== "undefined" ? navigator.language : "en-US");
const loc = new Intl.Locale(tag);
// getWeekInfo() is the current spec API; older engines (including current
// Node/V8) expose a `weekInfo` getter instead — support both.
const info =
(loc as unknown as { getWeekInfo?: () => { firstDay?: number } }).getWeekInfo?.() ??
(loc as unknown as { weekInfo?: { firstDay?: number } }).weekInfo;
const firstDay = info?.firstDay; // 1 = Monday … 7 = Sunday (ISO-8601)
if (typeof firstDay === "number") {
return firstDay === 7 ? 0 : firstDay; // map ISO → VueDatePicker (0 = Sunday)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== weekStart.ts outline ==\n'
ast-grep outline frontend/lib/datelib/weekStart.ts --view expanded || true

printf '\n== LanguageSelector.vue outline ==\n'
ast-grep outline frontend/components/App/LanguageSelector.vue --view expanded || true

printf '\n== Relevant snippets ==\n'
sed -n '1,220p' frontend/lib/datelib/weekStart.ts
printf '\n---\n'
sed -n '1,180p' frontend/components/App/LanguageSelector.vue

printf '\n== Search for WeekStart type and usage ==\n'
rg -n "type WeekStart|interface WeekStart|WeekStart\b|firstDayOfWeek" frontend -S

Repository: sysadminsmedia/homebox

Length of output: 8950


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== composable outline ==\n'
ast-grep outline frontend/composables/use-preferences.ts --view expanded || true

printf '\n== composable snippet ==\n'
sed -n '1,220p' frontend/composables/use-preferences.ts

printf '\n== search for persisted preference schema/validation ==\n'
rg -n "firstDayOfWeek|useViewPreferences|defineStore|persist|schema|zod|superjson|localStorage|useStorage|WeekStart" frontend -S

Repository: sysadminsmedia/homebox

Length of output: 24901


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== useViewPreferences implementation tail ==\n'
sed -n '220,340p' frontend/composables/use-preferences.ts

printf '\n== any normalization helpers for preferences ==\n'
rg -n "normalize|saniti[sz]e|coerce|firstDayOfWeek.*auto|week-start|weekStart" frontend/composables frontend/lib frontend/components -S

Repository: sysadminsmedia/homebox

Length of output: 3393


Clamp invalid week-start preferences before returning them.

resolveWeekStart currently returns any non-"auto" value as-is, so a malformed persisted setting can leak into week-start instead of falling back to Monday. Accept only explicit 06 values and treat out-of-range Intl.Locale.weekInfo.firstDay values the same way.

📍 Affects 2 files
  • frontend/lib/datelib/weekStart.ts#L13-L27 (this comment)
  • frontend/components/App/LanguageSelector.vue#L38-L43
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/lib/datelib/weekStart.ts` around lines 13 - 27, Update
resolveWeekStart to return non-"auto" preferences only when they are numeric
values from 0 through 6; otherwise fall back to Monday. Also validate the
firstDay value obtained from Intl.Locale before mapping Sunday (7) to 0,
treating missing or out-of-range values as fallback cases. In
frontend/components/App/LanguageSelector.vue lines 38-43, apply the same
validation at the affected usage site as requested by the shared week-start
handling.

Address CodeRabbit review: resolveWeekStart returned non-"auto" preferences
as-is, so a malformed value from schemaless storage (settings blob / localStorage)
could reach the picker. Validate 0-6 and guard the Intl firstDay range.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai coderabbitai Bot removed 🕷️ bug Something isn't working go Pull requests that update Go code labels Jul 22, 2026
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 participant