Commit graph

1140 commits

Author SHA1 Message Date
Alexandre Brandizzi
810fa5d5b0
Merge pull request #283 from Sea-Haven-Industries/fix/ab/sh-406-no-revoke-auto-approved
Hide Revoke from admins on auto-approved uplifts
2026-09-25 22:17:01 +00:00
Alexandre Brandizzi
a27695b217
Merge pull request #274 from Sea-Haven-Industries/feat/ab/sh-385-invite-registration
feat(team-members): invite registration wizard and resend invite (SH-385)
2026-09-25 22:16:36 +00:00
Alexandre Brandizzi
3cdb5e7d7b
Merge pull request #281 from Sea-Haven-Industries/feat/ab/sh-317-a4-pagination
feat(comp-doc): A4 multi-page completion document preview
2026-09-25 22:16:32 +00:00
Alexandre Brandizzi
727588ab52 fix(comp-doc): keep the page pill current on re-layout and stamp NOT REQUIRED on the sheet
The page being read is re-derived after every render and every observed
resize, not only when the page count changes. The NOT REQUIRED stamp is
rendered inside the first sheet, above its greyed-out content, instead of
floating over the scroll panel.
2026-09-25 18:49:13 -03:00
Alexandre Brandizzi
18127c0f30 fix(uplifts): hide Revoke from admins on auto-approved uplifts
Admins may revoke only admin-approved uplifts. The Work Order Uplifts
dialog showed Revoke to whoever requested an auto-approved uplift, so an
admin requester saw it and was sent into the optional-reason revoke flow.
2026-09-25 18:14:06 -03:00
Alexandre Brandizzi
dc2565e3fe feat(comp-doc): paginate the completion document preview into A4 sheets
Both the template preview and a work order's completion document render
through the shared frame, which now splits the letterhead and blocks into
A4-sized sheets with the brand bars on every sheet and shows Page X of Y
in the preview pill.
2026-09-25 18:03:33 -03:00
Alexandre Brandizzi
0b654bb07c Merge remote-tracking branch 'origin/main' into feat/ab/sh-385-invite-registration
# Conflicts:
#	src/api/api-paths.ts
2026-09-25 17:46:17 -03:00
Alexandre Brandizzi
3b7cf83332 fix(team-members): offer a retry when the invite cannot be checked
The invite page showed "invalid or has expired, ask your admin for a new
invite" for any failed resolve call, including offline, timeouts and 5xx.
A member on a flaky connection was sent to their admin for a resend, which
revokes a token that was still valid.

Only the server's invalid_invite answer now ends on "Invite unavailable".
Any other failure shows "Couldn't load your invite" with a Try again
button that re-runs resolve, without a global error toast. Regression
tests cover a network rejection and a 500 followed by a successful retry.
2026-09-25 17:45:08 -03:00
Alexandre Brandizzi
f068beb45e
Merge pull request #277 from Sea-Haven-Industries/fix/ab/sh-402-effective-permissions
Some checks are pending
Frontend checks / static (push) Waiting to run
Frontend checks / build (push) Waiting to run
Frontend checks / unit (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Frontend checks / browser-smoke (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / ci-complete (push) Blocked by required conditions
Deploy Web / Resolve target (push) Waiting to run
Deploy Web / Deploy SPA to (push) Blocked by required conditions
fix(completion-docs): show template actions from the user's effective permissions
2026-09-25 20:31:22 +00:00
Alexandre Brandizzi
06f70c193d Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	src/test/app/(protected)/completion-docs/completion-docs-page.test.tsx
#	src/test/app/(protected)/completion-docs/completion-template-dialog.test.tsx
2026-09-25 17:26:10 -03:00
Alexandre Brandizzi
e8cdb9814a
Merge pull request #273 from Sea-Haven-Industries/feat/ab/sh-334-site-delete
feat(sites): delete a site from the detail panel with an open work-order warning
2026-09-25 20:22:20 +00:00
Alexandre Brandizzi
8e02031152
Merge pull request #268 from Sea-Haven-Industries/feat/ab/sh-313-completion-templates-page
feat(completion-docs): manage completion document templates
2026-09-25 20:18:17 +00:00
Alexandre Brandizzi
7bde8aacf2 fix(sites): hold Delete until the reopened dialog's open work-order recheck lands
The open work-order query keeps its cached result between dialog opens, so on
reopen the background refetch ran while isLoading was false and Delete was
enabled with the previous count. A work order created at the site since the
last open could be deleted past without a warning.

Treat an in-flight fetch as an unknown count: Delete and View open work orders
wait, the stale copy is hidden and the checking spinner shows until the fresh
count arrives.
2026-09-25 17:17:20 -03:00
Alexandre Brandizzi
2b338b36c6 test(completion-docs): keep the dialog closed when dismissed mid-save
Dismissing the edit dialog with Escape or the Close button while an update
is still in flight must not bring it back when the save lands. The per-call
mutate callbacks that reopen it in view mode are dropped by TanStack Query
once the dialog unmounts, so this pins that behaviour: the test fails if the
save is moved to mutateAsync().then(), which would reopen the dialog.
2026-09-25 17:13:20 -03:00
Alexandre Brandizzi
2281c7c82d fix(sites): open the site's board when open work orders exceed the id cap
The delete dialog states the server's full open work-order count, but the
server returns at most 200 ids. "View open work orders" navigated with
that capped list, so a site with 240 open work orders showed 200, and an
empty list opened the unfiltered board.

The exact-id link is now used only when the ids cover the whole count.
Otherwise the link opens Work Orders filtered to the site and every open
status across all weeks, the ticket's "board filtered to that site". The
board drilldown now reads a `sites` param for this; `ids` still wins.
2026-09-25 17:10:51 -03:00
Alexandre Brandizzi
85a45e9fc0
Merge pull request #279 from Sea-Haven-Industries/feat/ab/sh-389-rejected-uplift-queue
feat(uplifts): add the Rejected archive tab to Uplift Approvals (SH-389)
2026-09-25 20:08:16 +00:00
Alexandre Brandizzi
090c977659 fix(uplifts): report a failed approvals queue once, inline, without the global toast 2026-09-25 17:03:15 -03:00
Alexandre Brandizzi
d866cf1b87 fix(completion-docs): hide the empty-search row when templates fail to load 2026-09-25 17:00:23 -03:00
Alexandre Brandizzi
73f639c271
Merge pull request #269 from Sea-Haven-Industries/feat/ab/sh-322-overdue-type
feat(work-orders): send Overdue as its own work order type
2026-09-25 19:57:00 +00:00
Alexandre Brandizzi
a031239259 fix(uplifts): keep the count and pager when a refetch fails over loaded rows 2026-09-25 16:56:35 -03:00
Alexandre Brandizzi
7c38ebd579 Merge commit 'd281cbd663b7b4106f104cb40207e4d5d1271387' into HEAD 2026-09-25 16:51:25 -03:00
Alexandre Brandizzi
b53d91b1da Merge remote-tracking branch 'origin/main' into HEAD 2026-09-25 16:48:47 -03:00
Alexandre Brandizzi
3ed45547db fix(uplifts): keep a failed queue from rendering as an empty archive 2026-09-25 16:48:46 -03:00
Alexandre Brandizzi
d281cbd663 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	e2e/__screenshots__/dashboard/dashboard.visual.spec.ts/dashboard-admin.png
#	e2e/__screenshots__/dashboard/dashboard.visual.spec.ts/dashboard-dispatcher.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-add.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-detail.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-edit.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-empty.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-error.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-filter.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-inactive.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-list.png
#	e2e/__screenshots__/vendors/vendors.visual.spec.ts/vendor-mobile-navigation.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-empty.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-error.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-filters.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-list.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-mobile-navigation.png
#	e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-new.png
2026-09-25 16:46:17 -03:00
Alexandre Brandizzi
70501693c8 fix(uplifts): show an unavailable count pill while a queue is loading or failed 2026-09-25 13:43:11 -03:00
Alexandre Brandizzi
403bc66383
Merge pull request #271 from Sea-Haven-Industries/feat/ab/sh-386-password-policy
Some checks are pending
Frontend checks / static (push) Waiting to run
Frontend checks / build (push) Waiting to run
Frontend checks / unit (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Frontend checks / browser-smoke (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / ci-complete (push) Blocked by required conditions
Deploy Web / Resolve target (push) Waiting to run
Deploy Web / Deploy SPA to (push) Blocked by required conditions
feat(account): My Account page with a live password checklist (SH-386)
2026-09-25 16:35:20 +00:00
Alexandre Brandizzi
dcc9429da8
Merge pull request #270 from Sea-Haven-Industries/feat/ab/sh-331-sites-panel
feat(sites): Add Site modal and site detail panel with in-place edit
2026-09-25 16:29:09 +00:00
Alexandre Brandizzi
70e52937aa feat(uplifts): add the rejected uplifts archive tab to Uplift Approvals 2026-09-25 13:23:32 -03:00
Alexandre Brandizzi
3f3a3701c3 feat(sites): suggest addresses as Street Address is typed
SH-331 requires Street Address suggestions after 3 typed characters,
with a pick filling Street, City and State and unpicked typing kept as
free text. SH-272, which SH-331 consolidates, specifies those
suggestions as mocked, and the shared AddressAutocompleteField that
Vendors already uses (SH-271) was built for Sites to reuse. No Places
key is involved.

The Add Site modal and the detail panel's edit mode now render that
field. A pick writes all three values through their own controllers,
so the form marks them dirty and Save changes enables in edit mode.
The field gains an opt-in requiredMarker prop so Sites keeps its label
asterisk while Vendors stays without one.
2026-09-25 13:10:03 -03:00
Alexandre Brandizzi
6e0967eaf0
Merge pull request #267 from Sea-Haven-Industries/feat/ab/wo-ids-filter
Some checks are pending
Frontend checks / static (push) Waiting to run
Frontend checks / build (push) Waiting to run
Frontend checks / unit (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Frontend checks / browser-smoke (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / ci-complete (push) Blocked by required conditions
Deploy Web / Resolve target (push) Waiting to run
Deploy Web / Deploy SPA to (push) Blocked by required conditions
feat(notifications): SLA at-risk banner opening Work Orders on an exact id set
2026-09-25 15:58:37 +00:00
Alexandre Brandizzi
383d5c3c6c feat(team-members): warn when the invite to a corrected email could not be sent 2026-09-25 12:54:31 -03:00
Alexandre Brandizzi
9c19287172 test(completion-docs): keep the dialog closed when a save finishes after closing 2026-09-25 12:53:43 -03:00
Alexandre Brandizzi
d5cd0659a2 fix(completion-docs): gate template actions on the user's effective permissions
Add Template, Edit and Delete now follow the permissions the server
computes for the signed-in user, role defaults plus their individual
overrides, instead of role defaults alone. The actions stay hidden while
the permissions load or when they fail to load.
2026-09-25 12:34:01 -03:00
Alexandre Brandizzi
ca42d6e59f fix(team-members): cover mid-wizard invite loss and accept empty invite responses 2026-09-25 12:33:37 -03:00
Alexandre Brandizzi
976cd908e3 feat(team-members): invite registration wizard and resend invite (SH-385) 2026-09-25 12:26:42 -03:00
Alexandre Brandizzi
73090d05e4 fix(auth): keep change-password failures inline without a global toast 2026-09-25 12:26:31 -03:00
Alexandre Brandizzi
9bb0416346 fix(sites): block delete until the open work-order check succeeds 2026-09-25 12:24:16 -03:00
Alexandre Brandizzi
3ab9c9a65b Merge remote-tracking branch 'origin/feat/ab/sh-331-sites-panel' into feat/ab/sh-334-site-delete 2026-09-25 12:23:27 -03:00
Alexandre Brandizzi
fe0d1a2571 fix(sites): keep the legacy contact name when an update sends no contacts 2026-09-25 12:23:18 -03:00
Alexandre Brandizzi
7fed941435 test(visual): refresh sidebar baselines for the My Account link 2026-09-25 12:14:19 -03:00
Alexandre Brandizzi
c16b7e03e4 Merge remote-tracking branch 'origin/feat/ab/sh-331-sites-panel' into feat/ab/sh-334-site-delete
# Conflicts:
#	src/app/(protected)/locations/_components/location-delete-dialog.tsx
2026-09-25 11:59:29 -03:00
Alexandre Brandizzi
5bcc0f7081 feat(sites): delete a site from the detail panel with an open work-order warning
- Delete sits in the view-mode footer for Admin and Scheduler only; the row delete icon is gone
- Confirmation states the open work-order count and links to exactly those work orders
- Sites without open work orders confirm with the plain permanent-removal copy
- A server refusal keeps the site and shows the error
2026-09-25 11:59:08 -03:00
Alexandre Brandizzi
c5816f8907 fix(sites): name the site in the delete confirmation and toast 2026-09-25 11:55:09 -03:00
Alexandre Brandizzi
7de34d359e Merge branch 'feat/ab/wo-ids-filter' into feat/ab/sh-295-sla-alerts 2026-09-25 11:52:57 -03:00
Alexandre Brandizzi
74dd1292a4 fix(workorders): applying a panel filter replaces the exact id selection
The server honours only the id set when one is sent, so a facet applied during an ids drill-down showed as an active chip while doing nothing. Applying any facet now drops the selection; applying the panel unchanged keeps it. The ids param is also capped at the server limit whatever built the set.
2026-09-25 11:52:27 -03:00
Alexandre Brandizzi
cadfe1ee8d fix(auth): announce password rule changes to screen readers 2026-09-25 11:52:10 -03:00
Alexandre Brandizzi
ffc4a9da68 Merge remote-tracking branch 'origin/feat/ab/wo-ids-filter' into feat/ab/sh-334-site-delete 2026-09-25 11:47:31 -03:00
Alexandre Brandizzi
fac0d1885c test(visual): update sidebar baselines for the Completion Docs entry 2026-09-25 11:46:50 -03:00
Alexandre Brandizzi
551f6af208 refactor(sites): read optional site fields through one helper 2026-09-25 11:45:31 -03:00
Alexandre Brandizzi
a75b9c8be6 feat(sites): Add Site modal and site detail panel with in-place edit
- Sites page: Add Site modal with Site Code, Client, address, State/Area, optional Site Phone and Email, points of contact
- Duplicate Site Code shows inline under the field and keeps the modal open
- Row opens a non-modal detail panel; Street Address links to Google Maps; key-less map preview
- Edit switches the panel in place with Site Code read-only; Save needs a valid change, Cancel makes no call
- Site Phone is sent independently of the contacts; zip and title are carried through edits
- Retire the separate new/edit location pages
2026-09-25 11:43:30 -03:00