App Builder recipe: Agent Productivity & Organization Effort Dashboard | The place for Zendesk users to come together and share
Skip to main content

App Builder recipe: Agent Productivity & Organization Effort Dashboard

  • July 14, 2026
  • 0 replies
  • 33 views

MattRussell

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, and assignee:{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 the TicketListModal filtered to the exact tickets making up that metric.

  1. Solved Tickets: Total solved in the period.

  2. Avg Handle Time: Scan the custom_fields array 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".

  3. Total Handle Time for Period: Sum the same [TIME_TRACKING_CUSTOM_FIELD_ID] custom field across solved tickets. Format as "Xh Ym".

  4. Outstanding Tickets: Total unsolved tickets currently assigned.

  5. Actionable Outstanding: Total Outstanding Tickets, excluding tickets with a custom_status_id of [EXCLUDED_STATUS_ID_1] or [EXCLUDED_STATUS_ID_2].

  6. CSAT Score: Look at the satisfaction_rating.score on 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.js tying 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 the TicketListModal showing 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 fallback href formatted as https://[YOUR_SUBDOMAIN][.zendesk.com/agent/tickets/$](https://.zendesk.com/agent/tickets/$){ticket.id} with target="_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, and Math.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_page pagination 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_id exactly 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 name exactly matches: [BOT_NAME_1], [BOT_NAME_2], or [SYSTEM_USER_NAME].