issue-select: Add filter arguments

This commit is contained in:
Erik Kundt
2024-01-30 10:58:45 +01:00
parent 26fae956fa
commit efdfe7b530
2 changed files with 59 additions and 25 deletions
+21 -1
View File
@@ -11,7 +11,7 @@ use anyhow::anyhow;
use radicle_tui as tui;
use tui::cob::issue::{self};
use tui::cob::issue::{self, State};
use tui::{context, log, Window};
use crate::terminal;
@@ -89,6 +89,26 @@ impl Args for Options {
unknown => anyhow::bail!("unknown mode '{}'", unknown),
};
}
Long("all") if op == Some(OperationName::Select) => {
select_opts.filter = select_opts.filter.with_state(None);
}
Long("open") if op == Some(OperationName::Select) => {
select_opts.filter = select_opts.filter.with_state(Some(State::Open));
}
Long("solved") if op == Some(OperationName::Select) => {
select_opts.filter = select_opts.filter.with_state(Some(State::Solved));
}
Long("closed") if op == Some(OperationName::Select) => {
select_opts.filter = select_opts.filter.with_state(Some(State::Closed));
}
Long("assigned") if op == Some(OperationName::Select) => {
if let Ok(val) = parser.value() {
select_opts.filter =
select_opts.filter.with_assginee(terminal::args::did(&val)?);
} else {
select_opts.filter = select_opts.filter.with_assgined(true);
}
}
Value(val) if op.is_none() => match val.to_string_lossy().as_ref() {
"select" => op = Some(OperationName::Select),
+38 -24
View File
@@ -3,6 +3,7 @@ use std::fmt::Display;
use anyhow::Result;
use radicle::cob::issue::{Issue, IssueId, Issues};
use radicle::cob::Label;
use radicle::issue::CloseReason;
use radicle::prelude::{Did, Signer};
use radicle::storage::git::Repository;
use radicle::{issue, Profile};
@@ -13,6 +14,7 @@ use super::format;
pub enum State {
#[default]
Open,
Solved,
Closed,
}
@@ -20,6 +22,7 @@ impl Display for State {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let state = match self {
State::Open => "open",
State::Solved => "solved",
State::Closed => "closed",
};
f.write_str(state)
@@ -29,8 +32,8 @@ impl Display for State {
#[derive(Clone, Default, Debug, Eq, PartialEq)]
pub struct Filter {
state: Option<State>,
authored: bool,
authors: Vec<Did>,
assigned: bool,
assignees: Vec<Did>,
}
impl Filter {
@@ -39,37 +42,48 @@ impl Filter {
self
}
pub fn with_authored(mut self, authored: bool) -> Self {
self.authored = authored;
pub fn with_assgined(mut self, assigned: bool) -> Self {
self.assigned = assigned;
self
}
pub fn with_author(mut self, author: Did) -> Self {
self.authors.push(author);
pub fn with_assginee(mut self, assignee: Did) -> Self {
self.assignees.push(assignee);
self
}
pub fn matches(&self, profile: &Profile, issue: &Issue) -> bool {
let matches_state = match self.state {
Some(State::Open) => matches!(issue.state(), issue::State::Open),
Some(State::Solved) => matches!(
issue.state(),
issue::State::Closed {
reason: CloseReason::Solved
}
),
Some(State::Closed) => matches!(issue.state(), issue::State::Closed { .. }),
None => true,
};
let matches_authored = self
.authored
.then(|| *issue.author().id() == profile.did())
.unwrap_or(true);
let matches_authors = (!self.authors.is_empty())
let matches_assgined = self
.assigned
.then(|| {
self.authors
.iter()
.any(|other| *issue.author().id() == *other)
issue
.assignees()
.collect::<Vec<_>>()
.contains(&&profile.did())
})
.unwrap_or(true);
matches_state && matches_authored && matches_authors
let matches_assignees = (!self.assignees.is_empty())
.then(|| {
self.assignees
.iter()
.any(|other| issue.assignees().collect::<Vec<_>>().contains(&other))
})
.unwrap_or(true);
matches_state && matches_assgined && matches_assignees
}
}
@@ -82,19 +96,19 @@ impl ToString for Filter {
filter.push_str(&format!("is:{}", state));
filter.push(' ');
}
if self.authored {
filter.push_str("is:authored");
if self.assigned {
filter.push_str("is:assgined");
filter.push(' ');
}
if !self.authors.is_empty() {
filter.push_str("authors:");
if !self.assignees.is_empty() {
filter.push_str("assignees:");
filter.push('[');
let mut authors = self.authors.iter().peekable();
while let Some(author) = authors.next() {
filter.push_str(&format::did(author));
let mut assignees = self.assignees.iter().peekable();
while let Some(assignee) = assignees.next() {
filter.push_str(&format::did(assignee));
if authors.peek().is_some() {
if assignees.peek().is_some() {
filter.push(',');
}
}