Add issue label and milestone filters

This commit is contained in:
Georg Bauer
2026-07-31 13:42:06 +02:00
parent 6374636b04
commit 6eb27537e8
9 changed files with 492 additions and 18 deletions

View File

@@ -3,7 +3,8 @@ use gotcha_gitea::models;
use crate::{
activity,
domain::{
HistoryCommit, HomeData, IssueDetails, MilestoneDetails, PullDetails, RepositoryData,
HistoryCommit, HomeData, IssueDetails, IssueFilter, MilestoneDetails, PullDetails,
RepositoryData,
},
};
@@ -66,6 +67,14 @@ pub struct IssuePage {
pub comments: Vec<CommentRow>,
}
#[derive(Clone, uniffi::Record)]
pub struct IssueFilterOptions {
pub milestones: Vec<String>,
pub labels: Vec<String>,
pub selected_milestone: String,
pub selected_labels: Vec<String>,
}
#[derive(Clone, uniffi::Record)]
pub struct MilestoneRow {
pub id: i64,
@@ -219,6 +228,31 @@ pub fn issue_rows(issues: &[models::Issue]) -> Vec<IssueRow> {
.collect()
}
pub fn issue_filter_options(
labels: &[models::Label],
milestones: &[models::Milestone],
filter: &IssueFilter,
) -> IssueFilterOptions {
let mut labels: Vec<_> = labels
.iter()
.filter_map(|label| label.name.clone())
.collect();
labels.sort_by_key(|label| label.to_lowercase());
labels.dedup();
let mut milestones: Vec<_> = milestones
.iter()
.filter_map(|milestone| milestone.title.clone())
.collect();
milestones.sort_by_key(|milestone| milestone.to_lowercase());
milestones.dedup();
IssueFilterOptions {
milestones,
labels,
selected_milestone: filter.milestone.clone(),
selected_labels: filter.labels.iter().cloned().collect(),
}
}
pub fn milestone_rows(milestones: &[models::Milestone]) -> Vec<MilestoneRow> {
let mut milestones = milestones.to_vec();
milestones.sort_by_key(|milestone| {
@@ -879,4 +913,40 @@ mod tests {
assert_eq!(page.state, "closed");
}
#[test]
fn builds_sorted_issue_filter_options() {
let filter = IssueFilter {
milestone: "v2".into(),
labels: ["bug".into(), "critical".into()].into(),
};
let options = issue_filter_options(
&[
models::Label {
name: Some("critical".into()),
..Default::default()
},
models::Label {
name: Some("bug".into()),
..Default::default()
},
],
&[
models::Milestone {
title: Some("v2".into()),
..Default::default()
},
models::Milestone {
title: Some("v1".into()),
..Default::default()
},
],
&filter,
);
assert_eq!(options.labels, ["bug", "critical"]);
assert_eq!(options.milestones, ["v1", "v2"]);
assert_eq!(options.selected_labels, ["bug", "critical"]);
assert_eq!(options.selected_milestone, "v2");
}
}