feat: consolidate PMC client UI PRs (PMC-2..PMC-119) #41
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pmc-merge"
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?
Consolidates the 15 open PMC client-UI PRs (#26-#40) into a single branch so they can be reviewed and merged as one unit instead of 15 interdependent PRs.
What this branch contains
All 15 PMC branches merged into
feat/pmc-mergeoffmainwith real merge commits (git merge --no-ff), preserving every PR's individual commits:Merge conflict resolved
One textual conflict, in
src/pages/admin.rs(PMC-2 vs PMC-88): both branches edited the component import block. Resolved by keeping PMC-88's removal of the decorative "Add Tenant" button together with PMC-2's live-tenant data fetch; the merged import set dropsButton/ButtonVariant/IconSize/PlusIcon, which are unused once the button is gone.CI cleanup
The source branches carried pre-existing rustfmt drift and clippy warnings (their CI was already red). To land this branch green, two extra commits were added on top of the merges: a
cargo fmt --allnormalization, and a clippy pass that resolves everycargo clippy --all-targets -- -D warningsfinding, including warnings pre-existing inmain'ssrc/modules/*.Verification
Run in the local dev container (rust 1.94.1):
cargo check --target wasm32-unknown-unknown- passescargo clippy --all-targets -- -D warnings- passescargo test --lib- 47 passedcargo fmt --all --check- cleanSupersedes
Replaces #26, #27, #28, #29, #30, #31, #32, #33, #34, #35, #36, #37, #38, #39, #40 - those PRs are closed in favour of this one.
Adds an `ApiError` enum (`Network`, `Status { code, message }`, `Decode`) alongside the existing string-returning fetch helpers, plus `_typed` variants of get_authed/post_authed/put_authed/delete_authed that decode the server's `ErrorResponse` envelope so callers can react to 401/403/404/422/etc. without re-parsing strings. `ApiError::user_message` produces the copy that gets dropped straight into a toast. The toast surface is a `GlobalSignal<Vec<Toast>>` driven by `push_toast`/`push_toast_with_title` plus a `push_api_error` convenience that maps an `ApiError` to an Error-variant toast. `ToastRoot` mounts once inside `AppLayout` so every authed page is already wired; no per-page plumbing needed. The existing `Result<T, String>` helpers stay so live callers (companies, calendar, system version) keep compiling. New call sites should prefer the typed variants going forward. #PMC-10 State DoneReplace the hardcoded "TKT-1234: Email server not responding" header with "Ticket {props.id}" so every detail-page URL gets a distinct title and the browser tab/back-button history reflect the route the user actually navigated to. Real ticket numbers and subjects will replace the bare id once the detail-page fetch lands (tracked under the API client story). #PMC-28 State DoneThe Add Note modal on TicketDetailPage was a UI shell: the Select and Textarea fed no signals, and the footer Add Note button had no onclick. Bind `note_type` / `note_content` signals to the inputs, wire the footer button to POST `/api/v1/tickets/{id}/notes` (using the route's `props.id`), close the modal and clear the textarea on success. Empty-content submissions short-circuit instead of round-tripping. POST failures log to the browser console; the toast surface from PMC-10 isn't on this branch yet so we keep the modal open and let the user retry. #PMC-25 State DoneProjectDetailPage hardcoded the title "Network Infrastructure Upgrade" so every project URL rendered the same header. Switch the title and tab title to "Project {props.id}" so navigation history reflects the route. Real project names will replace the bare id once the server's projects module ships. The Add Task header button had no onclick and no server destination; per the F5 pattern (audit P1-05 "decorative detail-page buttons") hide it until the projects module lands so the affordance stops lying. Live wiring is tracked under PMC-39 alongside the other Add Task surface. #PMC-40 State Done #PMC-38 State DoneProjectTasksPage had a header Add Task button with no onclick and no destination (server projects module is still stubbed at 501). Per the F5 pattern, hide it until the server lands so the affordance stops promising a flow that doesn't exist. Also switches the page header to "Project {props.id} - Tasks" so it reflects the route. #PMC-39 State DoneCompanyDetailPage and ContactDetailPage hardcoded "Acme Corp" / "Bob Johnson" headers regardless of the route, and the Edit header button had no onclick. Switch the headers to "Company {props.id}" / "Contact {props.id}" so navigation reflects the route, and hide the Edit affordance per the F5 pattern until the contacts mutation surface ships. The Open Tickets statistic on CompanyDetailPage was styled link-blue but was a bare span, so it looked clickable and wasn't. There's no /tickets?company=:id filter to wire it to yet, so drop the blue styling and render it as a plain stat. PMC-47: the contacts and recent-tickets sub-tables on CompanyDetailPage already wrap names in Link components pointing to ContactDetail / TicketDetail (lines 388-422 / 447-468). ContactDetailPage's sidebar already links its Company back to CompanyDetail. No remaining dead row clicks; sub-task validated as resolved in main. #PMC-46 State Done #PMC-47 State Done #PMC-48 State Done #PMC-49 State DoneInvoiceDetailPage hardcoded "Invoice INV-2025-001" so every invoice URL rendered the same header. Switch the title and tab title to "Invoice {props.id}" so navigation reflects the route. Real invoice numbers replace the bare id once the billing module ships server-side. #PMC-65 State DoneKBArticleNewPage was a placeholder. Scaffolds a real editor with title / category / visibility / Markdown body. WYSIWYG is deferred (a comment notes that); submit stubs to navigate until the KB module ships. KBArticleDetailPage hardcoded a "How to Reset a User's Password" header and the Edit button had no onclick. Switch header to "Article {props.id}" and hide Edit per F5. Related Articles links wired to Route::KBArticleDetail with slug placeholders (real ids land with the KB module). #PMC-73 State Done #PMC-75 State Done #PMC-77 State Done- PMC-95: PortalTicketListPage rows extracted into PortalTicketRow with Link + clickable navigation to PortalTicketDetail. No more inert TKT-#### spans. - PMC-96: PortalInvoiceDetailPage now renders a read-only invoice view (bill-to / line items / total / payment-pending note) instead of the literal "Invoice details would be displayed here" placeholder. Live data lands when the portal billing endpoint ships. - PMC-97: PortalKBPage article items wrap in Link to Route::KBArticleDetail with slug placeholder ids so clicks actually go somewhere. - PMC-98: Replace the no-input "drag and drop" zone on the portal ticket form with a real `<input type=file multiple>`. Styled drag-drop with upload progress lands alongside the portal attachments endpoint. - PMC-99: PortalTicketDetailPage uses "Ticket {props.id}" for both the layout title and the header h1. The audit noted "decorative header buttons" but this page has no header button bar; the only buttons are the inline Send Reply at the bottom of the Reply form. The route-param title fixes the practical effect (every URL got the same header) covered by this issue. #PMC-95 State Done #PMC-96 State Done #PMC-97 State Done #PMC-98 State Done #PMC-99 State DoneAssetDetailPage and ContractDetailPage were the two remaining detail surfaces still rendering hardcoded sample headers ("Exchange Server 01", "Managed Services Agreement"). Switch them to "Asset {props.id}" / "Contract {props.id}" to complete the F10 sweep; the other detail pages were already done in their per-story PRs. #PMC-104 State Done`assets/styles.css` is a gitignored Tailwind build artifact, so a clean CI checkout does not have it, and `cargo check`/`clippy`/`test` fail on the `asset!("/assets/styles.css")` macro in src/main.rs. This workflow only compile-validates and never renders CSS, so an empty file is sufficient; the real Tailwind build stays in oci-build/Dockerfile for deployment. Pre-existing main bug, unrelated to the consolidated PMC branches. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>