Skip to content

Repository files navigation

Jira Team Management Dashboard

A Streamlit application that fetches Jira tickets via JQL and renders delivery analytics dashboards for team leads and engineering managers.

Features

  • Delayed Tasks Trend — weekly count of tickets past their ETA per user
  • Total Delay per User — cumulative delay days per user per week (bar or area chart)
  • Delivery Velocity — tickets completed per user per week
  • Status Distribution — ticket breakdown by workflow status (pie + bar + per-user stacked bar)
  • Cycle Time Analysis — median/mean creation-to-resolution time per user with weekly trend
  • Priority Breakdown — tickets by priority over time and per user
  • Unassigned Tasks — tickets with no assignee; supports assigning a team member in-app
  • Workload Overview — active tasks and story point share per person
  • Team Members — directory of configured Jira users with names and emails

Requirements

  • Python 3.10+
  • A Jira Cloud instance with API access
  • An Atlassian API token — generate one at https://id.atlassian.com/manage-profile/security/api-tokens

Setup

1. Install dependencies

pip install -r requirements.txt

2. Configure credentials

cp .env.example .env

Edit .env and fill in:

Variable Description
JIRA_BASE_URL Your Atlassian instance URL, e.g. https://your-domain.atlassian.net
JIRA_EMAIL Your Atlassian account email
JIRA_API_TOKEN API token from Atlassian (the app encodes it automatically)
JIRA_USERS Comma-separated Jira account IDs to track, e.g. accountId1,accountId2
JQL_FILTER Default JQL shown in the sidebar, e.g. type = "Story" ORDER BY created DESC
MAX_RESULTS Tickets per page — pagination is automatic (default: 100)
ETA_FIELD Jira field used as the deadline for delay calculation (default: duedate)
PORT Streamlit server port (default: 8501)

To find a user's account ID: open any ticket in Jira, click the assignee avatar — the profile URL ends with the account ID.

3. Run the app

./run.sh

The script reads PORT from .env and starts Streamlit. Open http://localhost:8501 in your browser.

Project Structure

app.py                      # Sidebar nav, data fetch, page routing
config.py                   # Loads .env into constants
jira_client.py              # Paginated Jira POST /search client (cached 5 min)
logger.py                   # Application logger → application_output.log
utils/
  data_processing.py        # Shared helpers: delay calc, week bucketing, cycle days
  pdf_export.py             # PDF download button for charts
dashboards/
  delayed_tasks.py          # Delayed Tasks Trend
  total_delay.py            # Total Delay per User
  delivery_velocity.py      # Delivery Velocity
  status_distribution.py    # Status Distribution
  cycle_time.py             # Cycle Time Analysis
  priority_breakdown.py     # Priority Breakdown
  unassigned_tasks.py       # Unassigned Tasks
  workload.py               # Workload Overview
  users.py                  # Team Members
tests/
  conftest.py               # Shared fixtures and sample data factory
  test_data_processing.py   # Unit tests for utils/data_processing.py
  test_dashboard_logic.py   # Unit tests for dashboard business logic
  test_ui.py                # End-to-end Playwright UI tests

Running Tests

Unit tests (no app needed)

pytest tests/test_data_processing.py tests/test_dashboard_logic.py -v

UI tests (requires running app)

./run.sh &
pytest tests/test_ui.py -v --browser chromium

UI tests use the MCP Playwright server in headed mode. See tests/TEST_CASES.md for a full description of every test case.

How It Works

Sidebar JQL input
  → jira_client.fetch_tickets(jql)    # paginated POST /rest/api/3/search
  → data_processing.to_df(tickets)    # normalise + parse date columns
  → st.session_state.df               # shared across all dashboards
  → dashboards/<name>.render(df)      # each dashboard filters/groups independently

Data is cached for 5 minutes. Click Fetch Data again to force a refresh.

Security

  • .env is gitignored and never read directly by any dashboard or test.
  • All credentials are accessed through config.py constants only.
  • A pre-tool hook (check_secrets.py) actively blocks any attempt to read .env files directly.
  • The app encodes JIRA_EMAIL:JIRA_API_TOKEN to Base64 automatically — no manual step needed.
  • No Jira write operations are performed except the optional "Update in Jira" action on the Unassigned Tasks dashboard (requires explicit user interaction).

About

Streamlit dashboard for Jira team delivery analytics

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages