feat: fj-dash TUI dashboard implementation #1

Merged
bryan merged 16 commits from get-started into main 2026-03-08 03:35:45 +00:00
Owner

Summary

Transforms the skeleton ratatui app into a working Forgejo PR dashboard.

What it does

  • Multi-instance support — configure multiple Forgejo instances via ~/.config/fj-dash/config.toml, each with its own API token and optional repo filter
  • Tea CLI fallback — auto-discovers credentials from tea's config (XDG, macOS, legacy paths) when no fj-dash config exists
  • Async data fetching — loads PRs concurrently across instances with loading/error states per-instance
  • TUI navigationj/k to navigate, Enter to open PR in browser, Tab to switch instances, r to refresh, q to quit
  • PR table — shows number, repo, title, author, +/- diff stats, and last updated date
  • rustls-tls — replaces native-tls/OpenSSL with rustls for simpler cross-platform builds

New modules

File Purpose
api.rs Forgejo API client — repo listing, PR fetching, response mapping
app.rs Application state — instances, selection, navigation
config.rs TOML config parsing with validation
event.rs Async event loop — keyboard, tick, resize, data events
tea_config.rs Tea CLI YAML config reader (fallback credentials)
ui.rs Ratatui rendering — tabs, PR table, loading/error states

Config format

[[instance]]
name = "my-forgejo"
url = "https://forgejo.example.com"
token = "your-api-token"
repos = ["owner/repo1", "owner/repo2"]  # optional
## Summary Transforms the skeleton ratatui app into a working Forgejo PR dashboard. ### What it does - **Multi-instance support** — configure multiple Forgejo instances via `~/.config/fj-dash/config.toml`, each with its own API token and optional repo filter - **Tea CLI fallback** — auto-discovers credentials from tea's config (XDG, macOS, legacy paths) when no fj-dash config exists - **Async data fetching** — loads PRs concurrently across instances with loading/error states per-instance - **TUI navigation** — `j`/`k` to navigate, `Enter` to open PR in browser, `Tab` to switch instances, `r` to refresh, `q` to quit - **PR table** — shows number, repo, title, author, +/- diff stats, and last updated date - **rustls-tls** — replaces native-tls/OpenSSL with rustls for simpler cross-platform builds ### New modules | File | Purpose | |------|--------| | `api.rs` | Forgejo API client — repo listing, PR fetching, response mapping | | `app.rs` | Application state — instances, selection, navigation | | `config.rs` | TOML config parsing with validation | | `event.rs` | Async event loop — keyboard, tick, resize, data events | | `tea_config.rs` | Tea CLI YAML config reader (fallback credentials) | | `ui.rs` | Ratatui rendering — tabs, PR table, loading/error states | ### Config format ```toml [[instance]] name = "my-forgejo" url = "https://forgejo.example.com" token = "your-api-token" repos = ["owner/repo1", "owner/repo2"] # optional ```
native-tls (macOS Secure Transport) fails with TLS error -9836
against the Forgejo instance. Switch to rustls via feature flag.
Collect per-repo errors during fetch loop instead of sending
individual FetchError events. Only send FetchError when all repos
fail and no PRs were loaded.
If an instance has no repos configured, uses the Forgejo API
(user_current_list_repos) to fetch all repos for the authenticated
user. Makes repos field optional in config with serde default.
Also allows tea CLI fallback to work without manual config.
- Move PullRequest struct from ui.rs to app.rs to fix inverted dependency
- Replace process::exit(1) with anyhow::bail in Config::load()
- Use spawn_blocking for crossterm event polling instead of tokio::spawn
- Surface partial fetch failures via warnings field on InstanceData
- Return Vec<String> from Config::validate() instead of printing to stderr
- Remove duplicate table title block in draw_pr_table
- Filter out mirror and archived repos during auto-discovery
- Add PR number column to table display
- Remove dead code: to_instances(), unused fields, unnecessary allow(dead_code)
bryan merged commit 7565564267 into main 2026-03-08 03:35:45 +00:00
Commenting is not possible because the repository is archived.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bryan/fj-dash-og!1
No description provided.