feat(settings): ticket lookup editors in the Settings hub (MAPPS-172) #150

Merged
nrupard merged 4 commits from feat/mapps-172-ticket-lookup-editors into main 2026-06-15 17:22:58 +02:00
Owner

What

MAPPS-172: client editors for the five ticket lookup tables, wired to the management CRUD that shipped in PMS-321. Completes the "anything with a standard type" part of the MAPPS-169 Settings hub for tickets.

A new Tickets group on the /settings hub links to five sub-routes, each a paginated list + create/edit/delete modal following the existing Work Types / Task Statuses / Asset Types pattern (admin-gated, refetches on tenant switch, shared SettingFormModal chrome):

  • Ticket Statuses -> /api/v1/tickets/statuses (/settings/ticket-statuses)
  • Ticket Priorities -> /api/v1/tickets/priorities (/settings/ticket-priorities)
  • Ticket Types -> /api/v1/tickets/types (/settings/ticket-types)
  • Ticket Queues -> /api/v1/tickets/queues (/settings/ticket-queues)
  • Ticket Categories -> /api/v1/tickets/categories (/settings/ticket-categories)

Contract

Fields mirror the as-built PMS-321 DTOs verbatim (verified against crates/mokosh-types/src/tickets.rs and src/modules/tickets/routes.rs on server main):

  • status: name, color, is_closed, is_default, sort_order
  • priority: name, color, icon, sla_multiplier (f64), is_default, sort_order
  • type: name, description, icon, is_active, sort_order
  • queue: name, description, color, icon, is_default, sort_order
  • category: name, description, parent_id, is_active, sort_order

Lists consume PaginatedResponse (page/per_page params). Mutations are admin-gated server-side; the client also hides the editors behind use_is_admin.

Category specifics

The category editor offers a parent picker populated from the category list, excluding the row being edited. The server independently rejects self-parenting and deeper cycles (400), so the UI restriction is just a convenience. The list table resolves parent names from the same fetch.

Refactor

Per-modal save/delete logic is factored into shared helpers (save_lookup = POST-or-PUT, confirm_delete, opt_str, non_empty_color) plus small ColorSwatch / ActiveBadge view helpers, used by the new editors (and a couple of the existing ones for the color/active cells).

Notes

  • No mokosh-server changes; depends on PMS-321 (merged).
  • Not compiled locally (no Rust toolchain here). Mirrors established settings.rs idioms; gated by CI (cargo clippy --all-targets -- -D warnings).

Test plan

  • As an admin, open /settings: a "Tickets" group shows five cards.
  • Each editor: create, edit, delete a row; list refreshes; non-admins get the admin-only notice.
  • Category: create a child under a parent; confirm the parent picker excludes the row being edited; confirm the server rejects a cycle with a surfaced error.
  • Priority: set an sla_multiplier like 1.5; confirm it round-trips and renders as 1.50x.
## What MAPPS-172: client editors for the five ticket lookup tables, wired to the management CRUD that shipped in PMS-321. Completes the "anything with a standard type" part of the MAPPS-169 Settings hub for tickets. A new **Tickets** group on the `/settings` hub links to five sub-routes, each a paginated list + create/edit/delete modal following the existing Work Types / Task Statuses / Asset Types pattern (admin-gated, refetches on tenant switch, shared `SettingFormModal` chrome): - **Ticket Statuses** -> `/api/v1/tickets/statuses` (`/settings/ticket-statuses`) - **Ticket Priorities** -> `/api/v1/tickets/priorities` (`/settings/ticket-priorities`) - **Ticket Types** -> `/api/v1/tickets/types` (`/settings/ticket-types`) - **Ticket Queues** -> `/api/v1/tickets/queues` (`/settings/ticket-queues`) - **Ticket Categories** -> `/api/v1/tickets/categories` (`/settings/ticket-categories`) ## Contract Fields mirror the as-built PMS-321 DTOs verbatim (verified against `crates/mokosh-types/src/tickets.rs` and `src/modules/tickets/routes.rs` on server main): - status: name, color, is_closed, is_default, sort_order - priority: name, color, icon, sla_multiplier (f64), is_default, sort_order - type: name, description, icon, is_active, sort_order - queue: name, description, color, icon, is_default, sort_order - category: name, description, parent_id, is_active, sort_order Lists consume `PaginatedResponse` (`page`/`per_page` params). Mutations are admin-gated server-side; the client also hides the editors behind `use_is_admin`. ## Category specifics The category editor offers a parent picker populated from the category list, excluding the row being edited. The server independently rejects self-parenting and deeper cycles (400), so the UI restriction is just a convenience. The list table resolves parent names from the same fetch. ## Refactor Per-modal save/delete logic is factored into shared helpers (`save_lookup` = POST-or-PUT, `confirm_delete`, `opt_str`, `non_empty_color`) plus small `ColorSwatch` / `ActiveBadge` view helpers, used by the new editors (and a couple of the existing ones for the color/active cells). ## Notes - No mokosh-server changes; depends on PMS-321 (merged). - Not compiled locally (no Rust toolchain here). Mirrors established settings.rs idioms; gated by CI (`cargo clippy --all-targets -- -D warnings`). ## Test plan - As an admin, open `/settings`: a "Tickets" group shows five cards. - Each editor: create, edit, delete a row; list refreshes; non-admins get the admin-only notice. - Category: create a child under a parent; confirm the parent picker excludes the row being edited; confirm the server rejects a cycle with a surfaced error. - Priority: set an `sla_multiplier` like `1.5`; confirm it round-trips and renders as `1.50x`.
feat(settings): ticket status/type/priority/queue/category editors
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 6s
6dd11f177c
MAPPS-172. Adds the client editors for the five ticket lookup tables to the centralized Settings hub, wired to the management CRUD shipped by PMS-321.

A new "Tickets" group on the Settings hub links to five sub-routes under /settings/ticket-*, each a paginated list with a create/edit/delete modal following the existing Work Types / Task Statuses / Asset Types pattern (page-local Deserialize row struct, Paginated<T>, active_tenant_generation() inside use_resource, admin-gated via use_is_admin, shared SettingFormModal chrome).

Fields mirror the as-built server DTOs verbatim: status (name, color, is_closed, is_default, sort_order); priority (name, color, icon, sla_multiplier, is_default, sort_order); type (name, description, icon, is_active, sort_order); queue (name, description, color, icon, is_default, sort_order); category (name, description, parent_id, is_active, sort_order). The category editor offers a parent picker populated from the category list (excluding self; the server also rejects self-parenting and deeper cycles), and the table resolves parent names.

Refactors the per-modal save/delete into shared helpers (save_lookup POST-or-PUT, confirm_delete, opt_str, non_empty_color) plus small ColorSwatch / ActiveBadge view helpers, used by both the new and a couple of the existing editors.

Not compiled locally (no Rust toolchain in this environment); mirrors the established settings.rs idioms and is gated by CI (cargo clippy --all-targets -- -D warnings).

#MAPPS-172

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs(settings): refresh module comment now that ticket editors exist
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 5s
6832e60423
The module doc still said the ticket lookup editors were deferred and blocked on backend work. They ship in this branch (MAPPS-172, wired to PMS-321). Update the comment to reflect that and to point at the remaining project-type editor follow-up (MAPPS-173).

#MAPPS-172

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
style(settings): apply cargo fmt to satisfy CI check
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 56s
a5947232bf
The check.yml rustfmt step failed on this branch: an import block in src/pages/settings.rs exceeded the line width and a multi-line format! call inside TicketStatusFormModal was not wrapped per rustfmt. Run cargo fmt to reflow the import list at line 33 and the delete_authed format! call at line 1408 so cargo fmt --all --check passes.

#MAPPS-175
#MAPPS-172

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
refactor(settings): address code-review findings on the ticket editors
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 55s
Create release / Create release from merged PR (pull_request) Has been skipped
1f72bed919
Fixes from review of the MAPPS-172 editors:

1. (correctness) Ticket Categories parent picker and the table's Parent column only saw the current page (per_page=25), so a parent on another page was unselectable and rendered blank. Added a second fetch of the full category set (per_page=100, the server cap) feeding both the name lookup and the picker, independent of the table page; restart it after a save.

2. (correctness) Priority sla_multiplier had no client-side guard - an out-of-range or non-numeric entry produced a raw 400, and an empty field silently became 1.0. Validate against 0.0..=9.99 before saving with a clear message.

3. (correctness) Bounded every sort_order number input with min=0 / max=2147483647 (server stores i32) so the widget rejects negatives and overflow.

4. (cleanup) Extracted delete_lookup (confirm + DELETE) mirroring save_lookup, and routed all eight editor delete handlers through it.

5. (cleanup) Back-applied the new shared helpers (save_lookup, delete_lookup, opt_str, ColorSwatch, ActiveBadge) to the three pre-existing editors (work types, task statuses, asset types) so one spelling of each rule lives in the file.

6. (efficiency) The category page now clones the full set into the modal only when it is open, instead of unconditionally every render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch feat/mapps-172-ticket-lookup-editors 2026-06-15 17:22:59 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
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!150
No description provided.