feat(portal): render ticket comment thread + send-reply form (PMS-480) #327
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/mokosh-apps!327
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/PMS-480-portal-comment-thread"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PMS-449 phase 1 shipped the portal ticket-comments server surface (
GET / POST /api/v1/portal/tickets/{id}/notes) and PMS-468 then exposedcreated_by_contact_idon the wire shape so a portal SPA can distinguish Customer vs Agent comments without the lossy name-equality heuristic. The portal ticket-detail page never consumed either of those. PMS-480 lands the consumer: a "Conversation" card below the existing detail card that lists the public-note thread oldest-first and accepts a new reply.What landed:
New
PortalTicketCommentscomponent nested underPortalTicketDetailPage. FetchesGET /portal/tickets/{id}/notes?page=1&per_page=200viause_resourcewith aversionsignal that bumps on every successful POST so the thread refreshes without a page reload.Each note row renders the author name, a Customer / Agent badge driven by
created_by_contact_id.is_some()(PMS-468), the formatted timestamp, and the content (whitespace-preserved so multi-line replies don't collapse). The author label falls back to "You" / "Agent" when the server omitted a display name (deleted user, missing first+last).Send-reply form below the thread: textarea + Primary button that POSTs
{ "content": "..." }to/portal/tickets/{id}/notes, clears the draft on success, bumpsversion, andnotes_resource.restart()s. Submit button disabled while the request is in flight so a customer who clicks twice can't double-post; empty-content is rejected client-side with an inline error. Server-side fields the same validation, this just keeps the round-trip honest.Loading / failed / empty states all render distinct messages so an empty fresh ticket reads differently from a 500 on the GET.
Agent SPA already surfaces customer comments via the existing tickets/notes panel - the server reads the same
ticket_notestable from both sides, so no agent-side change is needed.#PMS-480
PMS-449 phase 1 shipped the portal ticket-comments server surface (`GET / POST /api/v1/portal/tickets/{id}/notes`) and PMS-468 then exposed `created_by_contact_id` on the wire shape so a portal SPA can distinguish Customer vs Agent comments without the lossy name-equality heuristic. The portal ticket-detail page never consumed either of those. PMS-480 lands the consumer: a "Conversation" card below the existing detail card that lists the public-note thread oldest-first and accepts a new reply. What landed: * New `PortalTicketComments` component nested under `PortalTicketDetailPage`. Fetches `GET /portal/tickets/{id}/notes?page=1&per_page=200` via `use_resource` with a `version` signal that bumps on every successful POST so the thread refreshes without a page reload. * Each note row renders the author name, a Customer / Agent badge driven by `created_by_contact_id.is_some()` (PMS-468), the formatted timestamp, and the content (whitespace-preserved so multi-line replies don't collapse). The author label falls back to "You" / "Agent" when the server omitted a display name (deleted user, missing first+last). * Send-reply form below the thread: textarea + Primary button that POSTs `{ "content": "..." }` to `/portal/tickets/{id}/notes`, clears the draft on success, bumps `version`, and `notes_resource.restart()`s. Submit button disabled while the request is in flight so a customer who clicks twice can't double-post; empty-content is rejected client-side with an inline error. Server-side fields the same validation, this just keeps the round-trip honest. * Loading / failed / empty states all render distinct messages so an empty fresh ticket reads differently from a 500 on the GET. Agent SPA already surfaces customer comments via the existing tickets/notes panel - the server reads the same `ticket_notes` table from both sides, so no agent-side change is needed. #PMS-480