KW Knowledge base

Helpdesk

The helpdesk is where staff handle support tickets. Every ticket carries a `source`, one of three values:

Mitch Wigham
Updated 24 June 2026 · 8 views

03 · Helpdesk

The helpdesk is where staff handle support tickets. Every ticket carries a source, one of three values:

  • EMAIL — created from an inbound email
  • PORTAL — raised by a customer at support.kwgroup.uk
  • AGENT — created internally by staff (the default for tickets raised from the portal + New form)

Where to find it

Sidebar → Helpdesk or /helpdesk. Any staff role (SUPER_ADMIN, ADMIN, MANAGER, AGENT) can open it.

Layout

+--------------------------------------------------------------+
| Helpdesk.                                  [Reports] [+ New]  |
| [Tickets open] [SLA breached] [Avg open] [Avg close] [Avg rsp]|
|--------------------------------------------------------------|
| [All][OPEN][IN PROGRESS][RESOLVED][CLOSED]  🔍search  N total |
|--------------------------------------------------------------|
| ☐  Subject     Type    Status   Pri  SLA  Assignee  Age      |
| ☐  Server down 🎫 Inc. OPEN     HIGH ⚠   Mitch     2h       |
| ☐  Email bounce —      RESOLVED LOW  met  —         4d       |
+--------------------------------------------------------------+

The page opens with a stat strip of five tabular metrics — tickets open, SLA breached, average time open, average time to close, average response. The Tickets open and SLA breached cards are clickable and filter the queue below; the three averages are informational only.

The Type column shows the ticket's ticket-type chip (icon + colour-coded label) when one is set, or when untyped. Status pulls the per-type status name when one's defined; legacy enum-only tickets fall back to the OPEN/IN_PROGRESS/RESOLVED/CLOSED labels. Above the table a status pill row (All / OPEN / IN PROGRESS / RESOLVED / CLOSED) filters by the legacy enum status.

📷 Screenshot placeholder: screenshots/helpdesk-list.png

The platform sidebar's Helpdesk section carries five built-in views, each a /helpdesk?filter=<id> link with a live count badge:

  • All open — every OPEN/IN_PROGRESS ticket
  • Assigned to me (filter=mine) — open tickets assigned to you
  • SLA breached (filter=sla) — open tickets past their SLA resolution deadline and not yet met
  • Awaiting reply (filter=awaiting) — open tickets where the most recent public comment is unauthored (an email/portal intake), or that have no staff reply yet
  • Closed · 7d (filter=closed) — RESOLVED/CLOSED in the last 7 days

Below those, two kinds of saved views appear, each linking to /helpdesk?view=<slug>:

  • Shared views — admins create these at /admin/helpdesk/views. They show up in every operator's sidebar.
  • Personal views — you create these at /profile/settings/views. Only you see them.

A saved view bundles a base view + status + priority + assignee + customer + project + ticket type + free-text search. Click one to apply all filters at once. The status pill row disables while a named view is active so the two filter sets don't fight.

📷 Screenshot placeholder: screenshots/helpdesk-views.png

Ticket detail view

The detail page uses a three-zone layout. Top bar runs full-width across the page; everything else splits into a wider left column for the conversation and a right sidebar for linkage and metadata.

+----------------------------------------------------------+
| #A1B2C3D4  Server down — Acme Ltd     [OPEN] [HIGH] [🎫] |
| Linked: [🏢 Acme] [👤 John Doe] [📁 SNAG-014]            |
+--------------------------------+-------------------------+
| 📨 Original message            | 🏷 Classification       |
|   "Server is unreachable…"     |   Type [Incident ▾]    |
|                                |   Status [Open ▾]      |
| ┌────────┬────────┐            |   Priority [HIGH ▾]    |
| │ 📧Pub. │ 🔒Int. │ ◀ chooser  +-------------------------+
| └────────┴────────┘            | ⏱ SLA                   |
| [textarea — sends to picked]   |   Resolution: 35m left  |
| [Send] [⏱ Log time]            +-------------------------+
|                                | 👥 People               |
| 💬 Conversation (4) ⬇ Newest   |   Assignee  Mitch       |
|   ─ John, 11:14 — public       |   Customer  [Acme ▾]    |
|   ─ Mitch, 10:30 — internal    |   Contact   [John ▾]    |
|   ─ John, 10:05 — public       +-------------------------+
|                                | 📁 Linkage              |
|                                |   Project [SNAG-014 ▾]  |
|                                |   Contract [Gold ▾]     |
|                                +-------------------------+
|                                | 🔗 Linked items         |
|                                |   🔐 Open vault →       |
|                                |   📦 Customer assets →  |
|                                +-------------------------+
| 📎 Attachments                  | ⏱ Time on this ticket   |
+--------------------------------+-------------------------+

📷 Screenshot placeholder: screenshots/helpdesk-ticket.png

Top bar (full width)

  • Ticket number (short ID, e.g. #A1B2C3D4)
  • Title
  • Inline pills for status / priority / type / merged-into status
  • Quick links — chips for any linked record. Only renders the chips that exist: customer, contact, project, contract. Hidden entirely if none are linked. Each chip is a hyperlink to the linked record's page.

Left column

  1. 📨 Original message — the description from the original email / form submission. Displayed as a card with the contact's email address shown in the header.
  2. Reply box — two full-width buttons at the top covering 50/50 of the reply card width:
    • 📧 Public reply — blue. The customer sees the message; it's emailed via the inbound-email reply alias.
    • 🔒 Internal note — amber. Staff-only. The textarea background flips to amber so it's impossible to confuse with a public reply. The textarea, send button, and ⏱ Log time affordance are below the toggle. The send button colour matches the active mode so sender + receive intent stay in sync.
  3. 💬 Conversation — every comment in the ticket. By default newest-first; toggle ⬇ Newest first⬆ Oldest first from the card header. Each comment has a clear PUBLIC / INTERNAL pill so the audience is unambiguous, plus the author and timestamp.
  4. 📎 Attachments — drag-drop file uploads bound to the ticket.

Right column

  • 🏷 Classification — Ticket type / Status / Priority. When a ticket type is set, the status dropdown filters to that type's configured statuses (otherwise falls back to the legacy enum).
  • ⏱ SLA — current response + resolution status with countdown. Hidden when the ticket has no SLA deadlines set.
  • 👥 People — Customer and Contact pickers, plus a read-only Assignee line (name + email, or "Unassigned") and the contact email when one is set. The customer and contact rows each get a small ↗ Open link.
  • 📁 Linkage — Project + Contract pickers.
  • 🔗 Linked items — quick deep-links to the vault and, when a customer is linked, the customer's assets, devices, and contacts. The customer page is the single source of truth for those — the ticket doesn't try to embed them.
  • ⏱ Time on this ticket — last 8 entries with totals. Log an entry from the ⏱ Log time affordance under the reply box.

Creating a ticket

Click + New ticket on the helpdesk dashboard (or open /helpdesk/new). The form has two cards:

  • BasicsTitle (required), Description, Type (defaults to "— default —", i.e. untyped), and Priority chosen from a LOW / MEDIUM / HIGH / URGENT pill group.
  • ScopeCustomer, Project, Assignee, and Support contract, all optional dropdowns. The contract dropdown filters to contracts belonging to the chosen customer. A Contact email field records where reply emails should go.

Then click Create ticket.

The ticket fires the SLA clock as soon as it's created — deadlines are computed from the org's SLA policy for the chosen priority. Tickets created from this form have source = AGENT.

Replying

Two reply modes — pick the full-width tab at the top of the reply box:

  • 📧 Public reply (blue) — the customer sees this. The send button reads 📧 Send reply.
  • 🔒 Internal note (amber) — staff-only. The textarea background turns amber and the send button reads 🔒 Add note.

The send button is disabled until the textarea has content. Attach files to the ticket from the 📎 Attachments card.

Status, priority, type

Field Notes
Type Tenant-defined (Incident, Change, Quote, …)
Status The set of options depends on the type — each type owns its own status list
Priority LOW / MEDIUM / HIGH / URGENT (fixed)

When you pick a type at ticket-creation time, the status dropdown filters to the statuses configured on that type. So a Change ticket might cycle through Submitted → Approved → Implemented → Closed, while an Incident moves through Open → Investigating → Resolved → Closed — without bleeding statuses across types.

Configure types and per-type statuses in Admin → Ticket types.

SLA

When a ticket is created, the platform looks up the org's SLA policy for the ticket's priority and stamps a response deadline and a resolution deadline onto the ticket. (The policy is keyed on org + priority — there is one policy row per LOW / MEDIUM / HIGH / URGENT.) If no policy is configured for that priority, the ticket simply has no SLA deadlines.

  • Response — marked met on the first public (non-internal) reply, comparing the reply time against the response deadline.
  • Resolution — marked met when the ticket moves to RESOLVED or CLOSED, comparing the close time against the resolution deadline.

The SLA card and the queue's SLA column show, for an open ticket, "Nh remaining" / "⚠ Overdue", and for a closed ticket, "SLA met" / "SLA breached". There is no pause/resume — the deadlines are fixed absolute timestamps set at creation time.

→ Configure: Helpdesk admin → SLA

Linking projects and customers

The right sidebar of a ticket lets you link:

  • Customer — a CRM company. Optional, but it drives the Linked-items deep links and surfaces the ticket on the customer record.
  • Contact — the person on the other side of the conversation.
  • Project — links the ticket to a project.
  • Contract — a support contract, used for time-entry billing.

All four are dropdowns in the right sidebar and can be changed at any time. There is no device (RMM) picker on the ticket itself.

Attachments

The 📎 Attachments card sits below the conversation thread. Click + Attach file to pick one or more files; they upload to object storage and are listed on the card with size and type, where you can download or delete them. The card is bound to the ticket, not to an individual reply.

Search

The search box at the top of the queue does a case-insensitive contains search across title, description body, and contact email, debounced 300 ms. Hits show with a "X matches" indicator next to the box. Tickets that have been merged into another are hidden by default — pass ?includeMerged=1 on the API if you want them back.

Multi-select & merge

Each row has a checkbox; the header has a select-all-visible. With 2 or more selected, an action bar appears at the top with 🔀 Merge selected….

Clicking it opens a modal where you pick the survivor — the oldest selected ticket is pre-selected because it's usually the original report. The other tickets' comments and time entries are moved into the survivor (an internal "🔀 Merged from …" note marks each insertion point), the originals are flipped to CLOSED with mergedIntoId set, and the queue refreshes.

⚠️ Caution. The merge is one-way and atomic (it runs in a single database transaction). There's no "unmerge" button — by design, you'd have to manually re-create the source ticket. Each source ticket gets a 🔀 Merged from … internal note in the survivor, authored by the operator who performed the merge.

Email handover

Replies are sent from helpdesk@<your-domain> and Reply-To is set to a ticket-specific alias so customer replies thread back automatically.

→ Configure email under Admin → Email settings.

Public customer view

Customers can see their own tickets at support.kwgroup.uk. They see only the Reply stream — internal notes are hidden.

Common workflows

Triage incoming inbox

  1. Open the helpdesk and click the OPEN status pill, or use the sidebar's Awaiting reply view to find tickets the customer last touched.
  2. Skim subjects, open each ticket, set the assignee, type, and priority from the right sidebar.

Resolve and close

  1. Send a public reply with the resolution.
  2. Set the status to RESOLVED (or CLOSED). Both stamp resolvedAt and evaluate the resolution SLA.
  3. If a SCHEDULED rule is configured, RESOLVED tickets can be auto-closed after a delay — see Helpdesk rules.

See also

Still need help?

Log a support ticket and the team will pick it up from this page.