Repository navigation
RivetMSP 26.10.21 — multi-select ticket filters and a default Service Desk view
The Service Desk ticket filters took one value each (one priority, one agent, one board). Every filter is now a group of checkboxes, so a saved view can be "High + Medium priority, assigned to Alex or Bo, on boards Network and Email", and an agent or an administrator can choose the view Tickets opens with.
Deploy notes: back up the database, pull this tag, php scripts/update_cli.php --update_db (2.6.92 to 2.6.93: ONE new table, ticket_view_defaults, CREATE TABLE IF NOT EXISTS, nothing existing altered; the code works before it runs, only choosing a default needs the table). No new cron line, no nginx change, no new composer package. Existing saved views and bookmarked URLs keep working unchanged.
- Checkbox filters, OR inside a group and AND across groups. Assigned to (me / unassigned / any agents, any combination), Priority (Low / Medium / High), Board, Category, On-site / Remote (both ticked = no filter), Due (Overdue and Due today are independent; both ticked matches either) and Status (All open / All closed / Everything, or specific statuses). Each group is a fieldset with a legend, a count badge ("Any" when nothing is ticked) and Select all / Clear; every box has a label and works from the keyboard. The Save View form and the live quick-filter panel on the Tickets page use the same groups (the toolbar buttons open a checkbox menu; closing it or pressing Apply runs the filter; "More Filters" holds Assigned to, On-site / Remote and Due).
- Old and new URLs.
assigned=me,priority=High,board=5,onsite=1,status=Closed,status=7,overdue=1and the dashboard'sassigned=0(nobody) still work and mean the same as the one-item lists. The canonical form isassigned[]=me&assigned[]=7&priority[]=High&priority[]=Medium. A stored view of either form opens as the canonical URL, and the highlighted view in the sidebar is decided by what the filters mean, not how the URL spells them. The viewer's own id andmeare the same choice.status=All(the "All Tickets" box) now really shows every ticket. - One validator.
ticketFiltersNormalize()turns any input into integers, enum members and fixed tokens (hostile values, nested arrays and oversized values are dropped; a group keeps at most 50 values),ticketFiltersSql()builds the conditions from that, and the list, the pagination and sort links, the kanban board, the client ticket lists and the API all read it. Kanban now honours Priority, Board, On-site, Due and Tags too (it used to ignore them).ticketViewDescribe()reads naturally ("Open tickets · Assigned to Alex, Bo or me · Medium or High priority · Board: Network or Email · Overdue or Due today"). - Default view. Add / Edit view: Make this my default view. A star beside every view in the Ticket Views list sets or clears it in one click. Opening Tickets with no filter in the URL loads the default (as a redirect to the same page with the view's filters in the address bar, keeping the list / kanban display mode). Any filter in the URL, or a view link, wins. The list offers Reset to my default (
?default=1) and Show all open (?status=Open). One personal default per agent and one shared default (set by an agent with support level 3, Make shared default in the view's menu, or the extra checkbox in the form) for agents who have no personal default; the order is personal, then shared, then the old behaviour. A default that was deleted, un-shared or can no longer be used is skipped gracefully; deleting a view forgets the defaults that point at it. Setting, replacing and clearing a default is audit-logged (type "Ticket View"). A client's own ticket list never gets the default. - Permissions tightened on the way. The Save View and Edit View modals now require write access to the support module, and the edit modal only opens for a view the agent owns (or a shared view for support level 3);
/api/v1/ticket-viewsrequires support read access and refuses a key locked to one client. Client portal logins never reach any of it (agent pages sign them out; API tokens are agents only). - API.
GET /api/v1/ticketstakes several values forpriority,onsite,assigned(me / unassigned / ids),status_id,category_id,board_idandtag_id(comma list or repeatedname[]; OR inside a filter, AND between filters;mine=1andpriority=highwork as before;overdue+due_todaytogether match either).GET /api/v1/ticket-viewstranslates a multi-value view into those comma lists (all values still strings) and marks the agent's default withis_default.api/v1/openapi.yamlanddocs/API.mdupdated. - Not changed. The CSV export (an unfiltered export of all tickets, as before), the sidebar counters and the stat boxes (whole-desk numbers), and the per-ticket live stream (
sse_ticket_stream.php, which follows one ticket, not a list) do not take list filters.
DB and tests: DB 2.6.93; db.sql gains ticket_view_defaults (a fresh import and the 2.6.92-to-2.6.93 update produce the same schema, 301 tables compared, no uca1400; the step is idempotent). Tests: new tests/ticket_views.php (171 checks: old / new forms and the canonical round trip, hostile and capped values, every filter combination against an independent PHP filter on 24 seeded tickets, the form validator, descriptions, default resolution / set / clear / replace / archived / un-shared / deleted fallbacks, the real Tickets page, pagination and sort links, kanban, the redirect and its escapes, handler permissions, audit lines, CSRF, the modals, the API, client portal and client-locked key refusals) and a browser smoke tests/browser/ticket_views_smoke.mjs (14 checks: two priorities and two agents by checkbox, save as default, Tickets opens with it, an explicit filter overrides, Reset to my default, Show all open, kanban, the star toggle, Select all / Clear, keyboard, phone width, dark theme). tests/wave1_integration.php and tests/endpoint_agent_module.php follow the new step.