feat(ui): standardize date selection behind one DateField component (MAPPS-204) #183

Merged
longjacksonle merged 1 commit from feat/MAPPS-204-standardize-date-inputs into main 2026-06-16 02:50:15 +02:00

Implements MAPPS-204. Approach confirmed with the owner: native calendar picker + validation (one shared component, consistent bounds; required fields error if empty, optional save as no-date).

Change

  • New DateField component (src/components/form.rs): native <input type="date"> with consistent min/max bounds (2000-2100) so out-of-range dates are rejected by the picker, plus required / error / help passthrough. Behavior documented on the props.
  • Converted all 19 date inputs to DateField across time, projects, contracts, assets, billing, audit log, and reports. The report range filters were raw <input> elements; they now match every other date field.
  • Required fields (time entry date, contract start date, billing invoice/due/payment dates) keep their existing submit-time "is required" validation, so an empty required date errors visibly instead of being silently dropped. Optional fields save as "no date" - the documented default.

Acceptance criteria

  • All date inputs share one behavior (single DateField).
  • Partial/invalid input is not silently dropped: the native picker can't hold a half-date, out-of-range is rejected by the bounds, required-empty errors with a message, optional-empty saves as no-date.
  • Documented, consistent default for missing/empty (on DateFieldProps).
  • Covers every date field in the app.

Verification

just pre-commit (pinned rust 1.94 = CI) passes: fmt, clippy -D warnings, cargo check --target wasm32-unknown-unknown, 100 lib tests. The reports range-filter styling changes slightly (now the standard labeled field) - worth an eyeball on that screen.

🤖 Generated with Claude Code

Implements MAPPS-204. Approach confirmed with the owner: native calendar picker + validation (one shared component, consistent bounds; required fields error if empty, optional save as no-date). ## Change - New `DateField` component (`src/components/form.rs`): native `<input type="date">` with consistent `min`/`max` bounds (2000-2100) so out-of-range dates are rejected by the picker, plus `required` / `error` / `help` passthrough. Behavior documented on the props. - Converted **all 19** date inputs to `DateField` across time, projects, contracts, assets, billing, audit log, and reports. The report range filters were raw `<input>` elements; they now match every other date field. - Required fields (time entry date, contract start date, billing invoice/due/payment dates) keep their existing submit-time "is required" validation, so an empty required date errors visibly instead of being silently dropped. Optional fields save as "no date" - the documented default. ## Acceptance criteria - [x] All date inputs share one behavior (single `DateField`). - [x] Partial/invalid input is not silently dropped: the native picker can't hold a half-date, out-of-range is rejected by the bounds, required-empty errors with a message, optional-empty saves as no-date. - [x] Documented, consistent default for missing/empty (on `DateFieldProps`). - [x] Covers every date field in the app. ## Verification `just pre-commit` (pinned rust 1.94 = CI) passes: fmt, clippy `-D warnings`, `cargo check --target wasm32-unknown-unknown`, 100 lib tests. The reports range-filter styling changes slightly (now the standard labeled field) - worth an eyeball on that screen. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(ui): standardize date selection behind one DateField component (MAPPS-204)
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 57s
Create release / Create release from merged PR (pull_request) Has been skipped
0e5afd4e93
Date inputs were ad-hoc <input type="date"> scattered across screens (some bare HTML inputs, some via Input, inconsistent bounds), so behavior differed and partial entries could be silently dropped. Introduce one shared DateField component (components/form.rs): a native calendar picker with consistent min/max bounds (2000-2100) so an out-of-range date is rejected by the picker, plus required/error/help passthrough.

Converted all 19 date inputs to DateField across time, projects, contracts, assets, billing, audit log, and reports (the report range filters were raw inputs; they now match every other date field). Required date fields keep their marker and their existing submit-time "is required" validation (time entry date, contract start date, billing invoice/due/payment dates), so an empty required date errors with a visible message rather than being dropped. Optional date fields save as "no date" - the documented, consistent default. Behavior is documented on DateFieldProps.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/MAPPS-204-standardize-date-inputs 2026-06-16 02:50:15 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!183
No description provided.