Skip to content

Add manual time entry form - #163

Merged
pierredup merged 5 commits into
mainfrom
manual-time-entry
Sep 9, 2026
Merged

pierredup merged 5 commits into
mainfrom
manual-time-entry

Conversation

@pierredup

Copy link
Copy Markdown
Member

No description provided.

Copilot AI lite review requested due to automatic review settings September 9, 2026 11:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

It changes core time-entry form behavior (including CSRF + entity date/validation semantics) across multiple UI entry points and needs final human verification of end-to-end flows.

Pull request overview

This PR introduces a manual time entry workflow (modal + LiveComponent form) so users can log work retroactively across key pages (dashboard, projects, clients, reports), integrating with existing time entry entities and UI patterns.

Changes:

  • Added a reusable “Add time entry” modal + trigger button and wired them into multiple pages and list rows (project/client).
  • Implemented a ManualTimeEntry LiveComponent + ManualTimeEntryType form, including CSRF handling, validation, and a duration hint.
  • Updated TimeEntry date handling/validation and expanded PHPUnit coverage for the new behavior and UI presence.
File summaries
File Description
tests/Twig/Components/ManualTimeEntryTest.php New Kernel test covering manual-entry component save behavior, CSRF, and validation cases.
tests/Entity/TimeEntryTest.php Adds coverage for TimeEntry date setters normalizing to Carbon and accepting null.
tests/Controller/ManualEntryModalPageTest.php New WebTest ensuring the modal/trigger appears on key pages and prefill metadata is present.
templates/report/index.html.twig Adds manual-entry trigger + modal include to reports page.
templates/project/show.html.twig Adds project-scoped manual-entry trigger + modal include.
templates/project/index.html.twig Includes the shared manual-entry modal on the projects list page.
templates/dashboard/index.html.twig Adds manual-entry trigger + modal include to dashboard.
templates/components/ProjectList.html.twig Adds per-row manual-entry trigger buttons with project prefill.
templates/components/ManualTimeEntry.html.twig New Twig template for the manual-entry form UI (TomSelect + duration hint).
templates/components/ClientList.html.twig Adds per-row manual-entry trigger buttons with client narrowing.
templates/components/_manual_entry_modal.html.twig New shared modal wrapper wiring Stimulus controllers + LiveComponent.
templates/components/_manual_entry_button.html.twig New shared trigger button template with optional project/client prefill.
templates/client/index.html.twig Includes the shared manual-entry modal on the clients list page.
src/Twig/Components/ManualTimeEntry.php New LiveComponent implementing manual entry save, flashes, and safe return redirect.
src/Kernel.php Uses a typed class constant for app version (referenced from platform.yaml).
src/Form/TimeTrackerType.php Refactors tracker form to extend the new shared AbstractTimeEntryType.
src/Form/ManualTimeEntryType.php New form type for manual entry (adds datetime + required constraints).
src/Form/AbstractTimeEntryType.php New shared form type consolidating common TimeEntry fields + CSRF token id.
src/Entity/TimeEntry.php Allows DateTimeInterface inputs for date setters; adds end-after-start validation constraint.
platform.yaml Reads platform version from App\Kernel::APP_VERSION.
assets/controllers/manual_entry_controller.ts New Stimulus controller to narrow project options by client using TomSelect.
assets/controllers.json Enables the platform modal-prefill controller (lazy).
Review details
  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread templates/components/_manual_entry_modal.html.twig
Comment thread tests/Twig/Components/ManualTimeEntryTest.php
The icon-only trigger rendered as a 2px sliver next to Edit/Delete.

Tabler's `.btn-icon` negative-margins the icon by the button's padding-x
on all four sides, expecting `.btn`'s min-width to absorb it. That
min-width calc references `--tblr-btn-line-height`, which is unset here,
so it resolves to `auto`, the icon's width cancels out, and the button
collapses to its borders. Use a plain `btn-sm` instead, which sizes from
the icon's own min-width.

Also whitespace-control the label so an empty one leaves no stray text
node beside the icon.
Same `btn-sm btn-icon` collapse as the manual time entry trigger: with
`btn-sm` the button's min-width resolves to 0, the icon's negative margins
cancel its width, and the button renders as a 2px sliver. Measured 2x12
before, 36x28 after.

`btn-icon` is fine at the default size (min-width 40px), so the mobile-only
"Create new" buttons on the project, client and tag index pages are
unaffected.

Claude-Session: https://claude.ai/code/session_01M1uNeTMKW9ZWuRtKvTpR95
Symfony 8.1.5 to 8.1.6 and related bumps within the existing composer.json
constraints; config/reference.php regenerated to match. Suite green apart
from the two pre-existing failures.

Claude-Session: https://claude.ai/code/session_01M1uNeTMKW9ZWuRtKvTpR95
Pass the modal title through the translator at the call site, matching the
three delete modals. The Ui:Modal component already translates `title`, so
this is about consistency and making the string extractable, not a runtime
fix.

Assert the saved duration numerically rather than on CarbonInterval's
string form, which is presentation-oriented.

Claude-Session: https://claude.ai/code/session_01M1uNeTMKW9ZWuRtKvTpR95
@pierredup
pierredup merged commit 415e29b into main Sep 9, 2026
3 of 7 checks passed
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.

2 participants