feat: add persistent pull request sort and filter menus

This commit is contained in:
Valdemar Lorenzen
2026-10-21 13:30:38 +02:00
parent 37b47ebc8a
commit fbcb519e13
22 changed files with 1557 additions and 181 deletions
+75 -4
View File
@@ -3514,8 +3514,11 @@ fn pull_request_picker_renders_all_rows_without_a_pinned_offset() {
Category::Open
},
},
format!("2026-01-{:02}T00:00:00Z", 20 - index),
crate::diff::PullRequestReviewState::None,
crate::diff::PullRequestMetadata {
created_at: format!("2026-01-{:02}T00:00:00Z", 20 - index),
updated_at: format!("2026-01-{:02}T00:00:00Z", 20 - index),
..Default::default()
},
)
})
.collect(),
@@ -3560,6 +3563,70 @@ fn pull_request_picker_renders_all_rows_without_a_pinned_offset() {
assert!(!text.contains("#00 Pull request") && !text.contains("#19 Pull request"));
}
}
#[test]
fn pull_request_menus_replace_picker_contents_and_show_explicit_choices() {
for (width, height) in [(100, 24), (44, 12)] {
let mut diff = DiffState::pull_requests("origin".into());
let mut terminal =
Terminal::new(ratatui::backend::TestBackend::new(width, height)).unwrap();
let mut panels = WheelPanels::default();
diff.handle(Input::Ctrl('s'));
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
assert!(text.contains("Sort pull requests"));
assert!(text.contains("[–] Requested from me"));
assert!(text.contains("Updated at") && text.contains("Created at"));
assert!(text.contains("newest first"));
assert!(!text.contains("Loading pull requests") && !text.contains("[partial]"));
assert!(text.contains("Enter Apply") && text.contains("Esc Cancel"));
diff.handle(Input::Char('3'));
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
let row = |label: &str| text.lines().position(|line| line.contains(label)).unwrap();
assert!(row("Updated at") < row("Approved by me"));
assert!(row("Approved by me") < row("Requested from me"));
assert!(row("Requested from me") < row("Created at"));
assert!(text.contains("> [3] Requested from me"));
diff.handle(Input::Backspace);
render_diff(&mut terminal, &diff, &mut panels);
assert!(screen_text(&terminal).contains("> [–] Requested from me"));
diff.handle(Input::Down);
diff.handle(Input::Char('4'));
diff.handle(Input::Left);
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
assert!(text.contains("> [4] Updated at · oldest first"));
let row = |label: &str| text.lines().position(|line| line.contains(label)).unwrap();
assert!(row("Requested from me") < row("Approved by me"));
assert!(row("Approved by me") < row("Created at"));
assert!(row("Created at") < row("Updated at"));
diff.handle(Input::Backspace);
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
assert!(text.contains("> [–] Updated at · oldest first"));
let row = |label: &str| text.lines().position(|line| line.contains(label)).unwrap();
assert!(row("Requested from me") < row("Updated at"));
assert!(row("Updated at") < row("Approved by me"));
assert!(row("Approved by me") < row("Created at"));
diff.handle(Input::Right);
render_diff(&mut terminal, &diff, &mut panels);
assert!(screen_text(&terminal).contains("> [–] Updated at · newest first"));
diff.handle(Input::Ctrl('f'));
diff.handle(Input::Char(' '));
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
assert!(text.contains("Filter pull requests"));
assert!(text.contains("[ ] Requested from me"));
assert!(text.contains("[x] Approved by me"));
assert!(text.contains("[x] Other / unavailable"));
assert!(!text.contains("Updated at"));
diff.handle(Input::Escape);
render_diff(&mut terminal, &diff, &mut panels);
assert!(screen_text(&terminal).contains("Pull requests"));
assert!(screen_text(&terminal).contains("[partial]"));
}
}
#[test]
fn pull_request_review_symbols_use_terminal_cells_and_keep_the_selection_arrow_independent() {
use crate::diff::{
@@ -3594,8 +3661,12 @@ fn pull_request_review_symbols_use_terminal_cells_and_keep_the_selection_arrow_i
description: format!("metadata{index}"),
category: Category::Open,
},
(3 - index).to_string(),
state,
crate::diff::PullRequestMetadata {
created_at: (3 - index).to_string(),
updated_at: (3 - index).to_string(),
requested: state == PullRequestReviewState::Requested,
approved: state != PullRequestReviewState::None,
},
)
})
.collect(),