mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-11-12 06:30:40 +08:00
issue-select: Add filter arguments
This commit is contained in:
+21
-1
@@ -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
@@ -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(',');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user