Problem Statement Native reporting tools often require navigating away from the core Zendesk workspace and rely on periodic data refreshes. Support managers and team leads need real-time, interactive insights into agent workloads, handle times, and organization-level support efforts directly within the Zendesk interface, with the ability to instantly drill down into the underlying tickets.
What makes this app special This app bridges the gap between high-level analytics and actionable ticket management. It utilizes the Zendesk Search API to pull real-time data while securely bypassing iframe limitations using native ZAF Client routing. It dynamically calculates team benchmarks based solely on active human agents (filtering out bots and AI integrations), distinctly separates "actionable" tickets from those blocked by engineering or third parties, and provides a dual-axis view of performance by either Agent or Organization.
Prerequisites Before pasting the prompt into the App Builder, replace the bracketed placeholders with your instance-specific data. You will need:
-
Your Zendesk Subdomain
-
The Custom Role IDs for your human agents
-
The exact names of any Bot/System AI agents you wish to exclude
-
The Custom Field ID for your Time Tracking app
-
The Custom Status IDs you want to explicitly track on the chart or exclude from actionable metrics
Core Use Cases
-
Comparing performance metrics (CSAT, Handle Time, Solved Volume) of specific agents against a dynamically calculated team benchmark.
-
Getting a quick overview of an agent’s outstanding tickets to manage reassignments during holidays or unexpected leave.
-
Visually tracking a team’s current ticket load and identifying bottlenecks via the interactive status breakdown chart.
-
Querying the total time spent servicing a specific Organization over a custom date range to gauge customer support cost and effort.
-
Reviewing specific tickets that are negatively impacting CSAT or inflating handle times by clicking directly through the metric cards.
Location of app: Side Navigation, for complex apps that need space
The Recipe (The Prompt)
Copy and paste this into the Zendesk App Builder:
Create a Zendesk Side Navigation app called the "Agent Productivity Dashboard". This app will serve as a reporting tool to track agent workload, efficiency, and ticket statuses.
1. Global Filter Panel (UI & Logic): Create a top filter row using Zendesk Garden components. Ensure all three inputs are horizontally aligned using Flexbox (
display: flex,align-items: flex-end,gap: 16px) so they stretch equally and share the same bottom baseline regardless of label height.
Organization (Autocomplete): Optional. Use Garden's Autocomplete component connected to
/api/v2/organizations/autocomplete.json?name={query}for dynamic searching.Team Members (Dropdown): Optional. Sort the resulting agents alphabetically by name. (See API constraints below for exact filtering logic).
Date Range (Dropdown): Must include "Last 3 Days", "Last 7 Days" (Default), "Last 14 Days", "This Month", "Last Month", and "Custom". If "Custom" is selected, render Start/End date pickers.
Search Logic: Dynamically build the search query based on inputs. Include
organization_id:{id}if an org is selected, andassignee:{email}if an agent is selected. Both can be combined.2. Metric Cards (Layout & Math): Render exactly 6 clickable
<MetricCard>components in this strict left-to-right order. When clicked, they must open theTicketListModalfiltered to the exact tickets making up that metric.
Solved Tickets: Total solved in the period.
Avg Handle Time: Scan the
custom_fieldsarray of the solved tickets for the Time Tracking field ID[TIME_TRACKING_CUSTOM_FIELD_ID](value is in seconds). Average this value across tickets with a >0 value, and format as "Xh Ym".Total Handle Time for Period: Sum the same
[TIME_TRACKING_CUSTOM_FIELD_ID]custom field across solved tickets. Format as "Xh Ym".Outstanding Tickets: Total unsolved tickets currently assigned.
Actionable Outstanding: Total Outstanding Tickets, excluding tickets with a
custom_status_idof[EXCLUDED_STATUS_ID_1]or[EXCLUDED_STATUS_ID_2].CSAT Score: Look at the
satisfaction_rating.scoreon solved tickets. Calculate ("good" / ("good" + "bad")) as a percentage. Ignore "unoffered" or null. Display "N/A" if there are 0 rated tickets.3. Benchmarking Logic (Green/Yellow/Red):
Calculate the average metrics across all human agents in the allowed roles list, completely excluding the currently selected agent. Do not cap this loop at 10 agents.
Apply a visual indicator to the metric cards comparing the selected agent to this benchmark: Green (Better), Yellow (Within 10%), Red (Worse). Note: For CSAT, higher is Green.
Add an info icon tooltip next to the Benchmark label stating: "The benchmark is the average performance of all other active agents during this time period (excluding the currently selected agents)."
Hide Condition: If the user generates a report with an Organization selected but NO Team Member selected, gracefully hide all benchmark UI and math, as comparing an entire org to an individual agent average is invalid.
4. Status Breakdown Chart: Render a Recharts Bar Chart plotting the Actionable Outstanding tickets by Custom Ticket Status.
Strict Exclusions: Filter out tickets with
custom_status_id[EXCLUDED_STATUS_ID_1]and[EXCLUDED_STATUS_ID_2]. They must not appear on the X-axis.Strict Ordering: Enforce a left-to-right X-axis render based on this exact array of
custom_status_ids:[STATUS_ID_1],[STATUS_ID_2],[STATUS_ID_3],[STATUS_ID_4],[STATUS_ID_5].Strict Coloring: Define a color map in
constants.jstying the specific IDs to exact colors (e.g.,[STATUS_ID_1]-> Light Red,[STATUS_ID_2]-> Light Blue).Interactivity: Make individual chart bars/cells clickable (
cursor: pointer). Clicking a bar opens theTicketListModalshowing only tickets in that specific status.5. Ticket List Modal (Drill-Down UI): Use a Zendesk Garden
Table(size="small") with an explicit Header Row and 4 columns:
Ticket ID: Use
window.zafClient.invoke('routeTo', 'ticket', ticket.id)on click to open the ticket natively in the agent workspace. Include a fallbackhrefformatted ashttps://[YOUR_SUBDOMAIN][.zendesk.com/agent/tickets/$](https://.zendesk.com/agent/tickets/$){ticket.id}withtarget="_blank".Subject: Truncate long strings.
Status: Display the human-readable Custom Status Name.
Handle Time (mins): Extract
[TIME_TRACKING_CUSTOM_FIELD_ID], divide by 60, andMath.round()to whole minutes. In the Header Cell for this column, include an info icon with a tooltip stating: "This represents the total time tracked on this ticket by all agents combined (may be more than just the selected agent)."6. Backend API Constraints:
Pagination: When fetching agents, you must handle
next_pagepagination to ensure all users in the instance are evaluated before filtering.Strict Role Filtering: Only populate the Team Members dropdown and Benchmark pool with users whose
custom_role_idexactly matches:[ROLE_ID_1],[ROLE_ID_2], or[ROLE_ID_3].AI/Bot Exclusions: Explicitly exclude users from the dropdown and benchmark math if their
nameexactly matches:[BOT_NAME_1],[BOT_NAME_2], or[SYSTEM_USER_NAME].
