feat(approvals): ticket-detail Approvals section + top-bar badge (PMS-486) #334

Merged
YousifShkara merged 1 commit from feat/PMS-486-approvals-tab-and-badge into main 2026-06-25 08:04:49 +02:00
Owner

PMS-481 shipped the standalone /approvals queue; PMS-486 lands the
two remaining surfaces that touch existing high-traffic chrome.

Top-bar pending-approvals chip (ApprovalsBadge in components/layout.rs):

  • Polls GET /approvals/pending on mount + on every active-org switch.
  • Collapses to an empty span when count == 0 so non-approver users see
    no extra chrome.
  • Otherwise renders a yellow rounded chip ("Approvals N") linking to
    the /approvals page; carries an aria-label so screen readers
    announce the count.

Ticket-detail Approvals section (ApprovalsSection in pages/tickets.rs):

  • Self-contained component invoked once from TicketDetailPage above
    the Activity timeline; owns its own fetch
    (GET /tickets/{id}/approvals), modal state, and refresh cycle so
    the diff to TicketDetailPage stays at one line.
  • Lists every approval row with a state Badge, approver scope
    ("To: name" / "Role: role"), requester, requested-at, optional
    notes, and decision + decided-at + decision_notes once decided.
  • "Request approval" button opens a Modal with a user-picker Select
    (mutually exclusive with) a free-text role Input, plus an optional
    notes Textarea. Submit POSTs /tickets/{id}/approvals and refreshes
    the list on success; the server's XOR validator surfaces inline if
    both or neither are filled.
  • Rendered as a Card rather than a tab: the ticket-detail page has no
    Tabs primitive in use today, so a tab would have meant introducing
    a new component just for one section. A Card matches every other
    ticket-detail section (Details, Activity, etc.).

#PMS-486

PMS-481 shipped the standalone /approvals queue; PMS-486 lands the two remaining surfaces that touch existing high-traffic chrome. Top-bar pending-approvals chip (ApprovalsBadge in components/layout.rs): - Polls `GET /approvals/pending` on mount + on every active-org switch. - Collapses to an empty span when count == 0 so non-approver users see no extra chrome. - Otherwise renders a yellow rounded chip ("Approvals N") linking to the /approvals page; carries an aria-label so screen readers announce the count. Ticket-detail Approvals section (ApprovalsSection in pages/tickets.rs): - Self-contained component invoked once from TicketDetailPage above the Activity timeline; owns its own fetch (`GET /tickets/{id}/approvals`), modal state, and refresh cycle so the diff to TicketDetailPage stays at one line. - Lists every approval row with a state Badge, approver scope ("To: name" / "Role: role"), requester, requested-at, optional notes, and decision + decided-at + decision_notes once decided. - "Request approval" button opens a Modal with a user-picker Select (mutually exclusive with) a free-text role Input, plus an optional notes Textarea. Submit POSTs `/tickets/{id}/approvals` and refreshes the list on success; the server's XOR validator surfaces inline if both or neither are filled. - Rendered as a Card rather than a tab: the ticket-detail page has no Tabs primitive in use today, so a tab would have meant introducing a new component just for one section. A Card matches every other ticket-detail section (Details, Activity, etc.). #PMS-486
feat(approvals): ticket-detail Approvals section + top-bar badge (PMS-486)
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 1m53s
Create release / Create release from merged PR (pull_request) Has been skipped
dabbe6bc98
PMS-481 shipped the standalone /approvals queue; PMS-486 lands the
two remaining surfaces that touch existing high-traffic chrome.

Top-bar pending-approvals chip (ApprovalsBadge in components/layout.rs):
- Polls `GET /approvals/pending` on mount + on every active-org switch.
- Collapses to an empty span when count == 0 so non-approver users see
  no extra chrome.
- Otherwise renders a yellow rounded chip ("Approvals N") linking to
  the /approvals page; carries an aria-label so screen readers
  announce the count.

Ticket-detail Approvals section (ApprovalsSection in pages/tickets.rs):
- Self-contained component invoked once from TicketDetailPage above
  the Activity timeline; owns its own fetch
  (`GET /tickets/{id}/approvals`), modal state, and refresh cycle so
  the diff to TicketDetailPage stays at one line.
- Lists every approval row with a state Badge, approver scope
  ("To: name" / "Role: role"), requester, requested-at, optional
  notes, and decision + decided-at + decision_notes once decided.
- "Request approval" button opens a Modal with a user-picker Select
  (mutually exclusive with) a free-text role Input, plus an optional
  notes Textarea. Submit POSTs `/tickets/{id}/approvals` and refreshes
  the list on success; the server's XOR validator surfaces inline if
  both or neither are filled.
- Rendered as a Card rather than a tab: the ticket-detail page has no
  Tabs primitive in use today, so a tab would have meant introducing
  a new component just for one section. A Card matches every other
  ticket-detail section (Details, Activity, etc.).

#PMS-486
YousifShkara deleted branch feat/PMS-486-approvals-tab-and-badge 2026-06-25 08:04:50 +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!334
No description provided.