Commit graph

221 commits

Author SHA1 Message Date
Alexandre Brandizzi
3141adba13
Merge branch 'dev' into feat/sh-254-fe-deactivate-confirm 2026-08-20 11:24:12 -03:00
Alexandre Brandizzi
326ac18eb0
Merge branch 'dev' into feat/sh-254-fe-deactivate-confirm 2026-08-20 11:15:10 -03:00
Codex Review Integration
aebb2c6b1a Merge remote-tracking branch 'origin/dev' into feat/sh-253-vendor-detail-parity
# Conflicts:
#	src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx
2026-08-20 11:14:51 -03:00
Alexandre Brandizzi
98daf9832d
Merge branch 'dev' into feat/sh-255-deactivate-toggle-gate 2026-08-20 11:06:54 -03:00
Alexandre Brandizzi
fc63948d4e
Merge branch 'dev' into feat/sh-254-fe-deactivate-confirm 2026-08-20 10:58:38 -03:00
Alexandre Brandizzi
4e36396868
Merge branch 'dev' into feat/sh-253-vendor-detail-parity 2026-08-20 10:58:34 -03:00
Alexandre Brandizzi
8684cb6c8b
Merge branch 'dev' into feat/sh-255-deactivate-toggle-gate 2026-08-20 10:58:31 -03:00
Alexandre Brandizzi
8edcb6659d
Merge branch 'dev' into feat/sh-250-fe-additive-add 2026-08-20 10:58:26 -03:00
Arthur Bassi
be975c792c fix(work-orders): wait for Unassigned queue before empty search (SH-240)
Keep SH-165 loading and error visible instead of a premature empty-search shell.
2026-08-20 10:28:04 -03:00
Arthur Bassi
1a54cbd2af
Merge branch 'dev' into feat/sh-240-week-day-nav 2026-08-20 09:44:33 -03:00
Arthur Bassi
959dda08fe fix(work-orders): stack week selector with day tabs in the filter bar
Keep SH-240 nav grouped under the type row and coerce the Live badge for JSX &&.
2026-08-20 09:40:02 -03:00
Arthur Bassi
0c75bd42f4 fix(work-orders): keep search and reschedule on the selected day (SH-240)
Empty search and Schedule On must follow the day-tab board, not the whole week or Unscheduled.
2026-08-20 09:21:45 -03:00
Arthur Bassi
8ab56d9782 refactor(work-orders): extract WoTable loading and empty shells
Keep the list table under the changed-file function length gate.
2026-08-19 14:48:04 -03:00
Arthur Bassi
2c14b08945 feat(work-orders): day-scoped week navigation (SH-240)
Let dispatchers pick one week and one weekday so the board
replaces rows instead of stacking the full week.
2026-08-19 14:45:59 -03:00
Codex Review Integration
22b03b8ac0 fix(vendors): deactivation dialog follows the approved design (SH-254)
The dialog's wording, its actions and its behaviour all diverged from the
design prototype. It refused deactivation outright when the vendor had
open work orders, which SH-44 and SH-82 left as an open question rather
than a decided requirement.

Deactivation with open work orders now proceeds on explicit confirmation:
the design's title and body copy, the affected work orders listed as
links, and "Deactivate anyway" in place of a disabled button. The API
call carries confirmOpenWorkOrders so the server-side guard is cleared
deliberately rather than removed.
2026-08-19 13:36:37 -03:00
Codex Review Integration
038ce263da fix(vendors): vendor detail parity with the design prototype (SH-253)
Three divergences in the vendor detail drawer:

- The header rendered the company as a subtitle under a title that had
  already fallen back to the company, printing the same name twice when
  the row carried no technician. The subtitle is now dropped when it
  would repeat the title.
- The Google Maps link appeared only when a URL was stored, unlabelled,
  so an empty value left no trace of the field. It is now a labelled
  field below Address that reads em-dash when unset, as every other
  field in the panel does.
- The status sat immediately beside Total Jobs. It now sits opposite it
  at the right edge, and reuses the vendors table's dot-plus-text badge
  so the state never reads by colour alone.
2026-08-19 13:22:11 -03:00
Codex Review Integration
90a5256dee fix(vendors): gate deactivation prompt on saved status (SH-255)
The drawer's Active toggle asked to deactivate whenever the switch moved
from on to off, reading the unsaved form value. An inactive vendor toggled
on and back off without saving therefore raised "Deactivate this vendor"
for a vendor that was already inactive.

Gate on the persisted technician status from the loaded roster instead,
falling back to the clicked row. Deactivation is a property of the saved
vendor, not of the toggle.
2026-08-19 13:18:17 -03:00
Adam Moussa
d5a04d318a
Merge branch 'dev' into feat/sh-245-login-parity 2026-08-19 11:03:37 -04:00
Arthur Bassi
afdf667364
Merge branch 'dev' into feature/wo-multi-poc-contacts 2026-08-19 10:29:18 -03:00
Alexandre Brandizzi
a71407b426
Merge branch 'dev' into feat/sh-250-fe-additive-add 2026-08-19 10:28:04 -03:00
Codex Review Integration
1305bf35dd fix(vendors): bypass the query cache when reloading after a conflict (SH-250)
The reload fix re-seeded the form from queryClient.fetchQuery, which inherits the
global 5-minute staleTime. A 409 never invalidates that key -
useSaveVendorCompanyRoster invalidates only in onSuccess and its onError returns
early for conflicts - and the Add flow has no mounted observer on it, so reload
returned the cached roster with the same stale rowVersion and every retry 409'd
again. Update mode was unaffected because it recovers via query.refetch(), which
bypasses staleTime.

Pass staleTime: 0 on that fetch, since its sole purpose is the freshest
rowVersion. The regression test uses a client with the app's real staleTime; the
default test client uses 0, which masked this entirely.
2026-08-19 10:26:28 -03:00
Alexandre Brandizzi
4b73af9688
Merge branch 'dev' into feat/sh-245-login-parity 2026-08-19 10:23:56 -03:00
Arthur Bassi
15dbda3c8f
Merge branch 'dev' into feature/sh-114-wo-closability-gate 2026-08-19 09:43:05 -03:00
Arthur Bassi
5718ca2b92
Merge branch 'dev' into feature/wo-multi-poc-contacts 2026-08-19 09:42:54 -03:00
Arthur Bassi
d534e92d03
Merge branch 'dev' into feature/wo-advanced-filters-parity 2026-08-19 09:33:07 -03:00
Arthur Bassi
a75b094564
Merge branch 'dev' into feature/wo-multi-poc-contacts 2026-08-19 09:32:29 -03:00
arthur.bassi
0182345ba3 refactor(work-orders): address SH-114 review naming and utils placement 2026-08-19 09:28:32 -03:00
arthur.bassi
1485903898 merge(dev): resolve SH-114 closability conflicts with uplifts overlays 2026-08-19 09:28:05 -03:00
arthur.bassi
9801d6a50e chore(work-orders): merge origin/dev and keep both search date windows
Keep SH-121 all-weeks constants and the SH-165 unassigned Custom range.
2026-08-18 22:13:51 -03:00
arthur.bassi
081d9b67c6 Merge remote-tracking branch 'origin/dev' into feature/wo-multi-poc-contacts
# Conflicts:
#	src/test/domain/work-orders/mappers/work-order-mapper.test.ts
2026-08-18 21:52:04 -03:00
arthur.bassi
fe86d46bec Merge remote-tracking branch 'origin/dev' into feature/wo-uplifts-column-and-tab
# Conflicts:
#	src/domain/work-orders/mappers/work-order-table-row-mapper.ts
#	src/domain/work-orders/types/work-order-table-row.ts
2026-08-18 21:42:53 -03:00
arthur.bassi
ce6e19ebaa Merge remote-tracking branch 'origin/dev' into feature/sh-114-wo-closability-gate
# Conflicts:
#	src/app/(protected)/workorders/_components/list/table/cells/status-cell.tsx
#	src/domain/work-orders/utils/wo-closability.ts
#	src/test/domain/work-orders/utils/wo-closability.test.ts
2026-08-18 21:18:49 -03:00
arthur.bassi
07c8c72ee6 Merge remote-tracking branch 'origin/dev' into feat/SH-165-unscheduled-pin 2026-08-18 20:53:13 -03:00
Alexandre Brandizzi
5ad13d38ca
Merge branch 'dev' into feature/sh-114-wo-closability-gate 2026-08-18 17:46:59 -03:00
Alexandre Brandizzi
2c10d2b7cb
Merge branch 'dev' into feature/wo-advanced-filters-parity 2026-08-18 17:46:53 -03:00
Alexandre Brandizzi
0de695362a
Merge branch 'dev' into feat/sh-250-fe-additive-add 2026-08-18 17:46:49 -03:00
Alexandre Brandizzi
defdc4c75b
Merge branch 'dev' into feat/sh-245-login-parity 2026-08-18 17:46:44 -03:00
arthur.bassi
bea2858c81 fix(work-orders): search all weeks when advanced filters are applied 2026-08-18 17:40:47 -03:00
Codex Review Integration
9a066092b3 fix(vendors): correct additive add reload, phone and contact (SH-250, SH-246)
Three review findings on the additive add path:

- Create-mode reload refreshed selectedRoster (including rowVersion) but left
  the form company fields on their pre-conflict values, so a retry diffed stale
  fields against the reloaded roster and could overwrite the concurrent company
  update that caused the 409. Reload now resets the form from the fresh roster,
  matching the select path.
- mapVendorRosterAdditivePatchToBackend copied companyFields verbatim while the
  reconcile write mapper canonicalizes companyPhone, so PATCH and PUT could send
  different phone shapes for the same input.
- emptyRosterTechnician seeded preferredContact "Phone" even though that
  control was removed from the form, so filling the first blank row submitted a
  fabricated value. append already omitted it; both paths now agree.
2026-08-18 17:28:48 -03:00
Codex Review Integration
ac9ce34101 fix(work-orders): distinguish loading from empty in Unassigned pin (SH-165)
The pinned Unassigned section folded the queue query's pending state into
isFetching only, which the section never read. On first mount, once GET /board
resolved while the queue was still paging GET /board/search, the pin announced
"No unassigned work orders." instead of a loading state.

Expose the queue query's own isLoading as unassignedLoading, thread it through
the table data hook, and render an aria-busy loading row while it is true so the
loading and empty states are separately observable.
2026-08-18 17:22:32 -03:00
Codex Review Integration
9624c264de fix(vendors): send only user-edited company fields on additive add (SH-250)
Adversarial review found a last-writer-wins window: after a stale 409 the
roster is refetched while the form keeps its pre-conflict values, so the
form-vs-roster diff resent our stale value for any company field another
user changed in that window, silently reverting their edit.

Transmit only fields the user actually edited, taken from react-hook-form
dirty state. Selecting a company calls reset(), so loaded values are never
dirty and only genuine edits are sent.

dirtyFields is resolved during render: formState is a Proxy that only tracks
properties read at render time, so reading it inside the submit callback
returned empty. The vendors E2E caught that; unit tests could not, since
they pass the flags in directly.
2026-08-18 14:42:01 -03:00
arthur.bassi
090130a2c0 chore(work-orders): merge origin/dev into uplifts PR
Keep upliftSummary fixtures and add isAddOn after the Add-On indicator landed on dev.
2026-08-18 13:24:21 -03:00
arthur.bassi
0c2ef6ac5e merge origin/dev into feature/wo-multi-poc-contacts
Use the extracted inline Schedule On cell from dev and keep additional-contacts fixtures complete.
2026-08-18 13:19:45 -03:00
arthur.bassi
dc9e146080 merge origin/dev into feat/SH-165-unscheduled-pin
Keep SH-165 non-terminal lifecycle statuses next to the Add-On type mapping from dev.
2026-08-18 13:19:44 -03:00
Codex Review Integration
a710e21281 fix(vendors): additive technician add for existing companies (SH-250, SH-246) 2026-08-18 13:09:33 -03:00
Codex Review Integration
54c90e0e36 fix(login): design parity — official logo, h1 welcome heading, label color (SH-245) 2026-08-18 12:08:17 -03:00
arthur.bassi
bf1def809b chore(work-orders): merge origin/dev into SH-188 closability gate
Keep PastDueStatusCell extraction and SH-185 Schedule On copy from merged #102.
2026-08-18 12:01:23 -03:00
arthur.bassi
0966962d8f fix(work-orders): keep Unassigned pin visible when empty
Render the weekly Unassigned section at count 0 and cover assignment through the board PATCH path.
2026-08-18 11:50:46 -03:00
arthur.bassi
d93ae683c7 fix(work-orders): restore additionalContacts contract and name+phone extras (SH-218)
Document the backend #66 producer, drop incomplete extras from persist, and show the same required-field errors on POC 2+.
2026-08-18 10:03:14 -03:00
arthur.bassi
b60d0474bc fix(work-orders): keep admin-approved revoke off the WO dialog (SH-214)
SH-214/SH-212 own that action on Uplift Approvals; the WO surface only revokes the requester's auto-approved uplift.
2026-08-18 09:28:49 -03:00