소스 검색

Add a filter to the triage dashboard

Takayuki Nakata 3 년 전
부모
커밋
7656c322f1
3개의 변경된 파일57개의 추가작업 그리고 3개의 파일을 삭제
  1. 8 1
      src/main.rs
  2. 45 2
      src/triage.rs
  3. 4 0
      templates/triage/pulls.html

+ 8 - 1
src/main.rs

@@ -21,7 +21,14 @@ async fn serve_req(req: Request<Body>, ctx: Arc<Context>) -> Result<Response<Bod
             let params = matcher.params();
             let owner = params.find("owner");
             let repo = params.find("repo");
-            return triagebot::triage::pulls(ctx, owner.unwrap(), repo.unwrap()).await;
+            let filter = if let Some(q) = req.uri.query() {
+                let pair = url::form_urlencoded::parse(q.as_bytes()).find(|(k, _)| k == "q");
+                pair.map(|(_, filter)| filter.to_string())
+            } else {
+                None
+            };
+
+            return triagebot::triage::pulls(ctx, owner.unwrap(), repo.unwrap(), filter).await;
         } else {
             return triagebot::triage::index();
         }

+ 45 - 2
src/triage.rs

@@ -21,6 +21,7 @@ pub async fn pulls(
     ctx: Arc<Context>,
     owner: &str,
     repo: &str,
+    filter: Option<String>,
 ) -> Result<Response<Body>, hyper::Error> {
     let octocrab = &ctx.octocrab;
     let res = octocrab
@@ -51,6 +52,24 @@ pub async fn pulls(
         next_page = page.next;
     }
 
+    let mut label_filter = Vec::new();
+    let mut author_filter = Vec::new();
+    let mut assignee_filter = Vec::new();
+    if let Some(filter) = filter.clone() {
+        let kvs: Vec<&str> = filter.split_whitespace().collect();
+        for kv in kvs {
+            match kv.split_once(':') {
+                Some((k, v)) if !v.is_empty() => match k {
+                    "label" => label_filter.push(v.to_string()),
+                    "author" => author_filter.push(v.to_string()),
+                    "assignee" => assignee_filter.push(v.to_string()),
+                    _ => {}
+                },
+                _ => {}
+            }
+        }
+    }
+
     let mut pulls: Vec<Value> = Vec::new();
     for base_pull in base_pulls.into_iter() {
         let assignee = base_pull.assignee.map_or("".to_string(), |v| v.login);
@@ -71,13 +90,25 @@ pub async fn pulls(
             (Utc::now() - base_pull.created_at).num_days()
         };
 
-        let labels = base_pull.labels.map_or("".to_string(), |labels| {
+        let labels = base_pull.labels.map_or(Vec::new(), |labels| {
             labels
                 .iter()
                 .map(|label| label.name.clone())
                 .collect::<Vec<_>>()
-                .join(", ")
         });
+        if !label_filter.is_empty() {
+            let mut flg = false;
+            for filter in label_filter.iter() {
+                if !labels.iter().any(|label| *label == *filter) {
+                    flg = true;
+                }
+            }
+            if flg {
+                continue;
+            }
+        }
+
+        let labels = labels.join(", ");
         let wait_for_author = labels.contains("S-waiting-on-author");
         let wait_for_review = labels.contains("S-waiting-on-review");
         let html_url = base_pull.html_url;
@@ -85,6 +116,13 @@ pub async fn pulls(
         let title = base_pull.title;
         let author = base_pull.user.login;
 
+        if !author_filter.is_empty() && !author_filter.iter().all(|s| *s == author) {
+            continue;
+        }
+        if !assignee_filter.is_empty() && !assignee_filter.iter().all(|s| *s == assignee) {
+            continue;
+        }
+
         let pull = PullRequest {
             html_url,
             number,
@@ -105,6 +143,11 @@ pub async fn pulls(
     context.insert("pulls", &pulls);
     context.insert("owner", &owner);
     context.insert("repo", &repo);
+    if let Some(filter) = filter {
+        context.insert("filter", &filter);
+    } else {
+        context.insert("filter", "");
+    }
 
     let tera = tera::Tera::new("templates/triage/**/*").unwrap();
     let body = Body::from(tera.render("pulls.html", &context).unwrap());

+ 4 - 0
templates/triage/pulls.html

@@ -42,6 +42,10 @@
 
     <body>
         <h1>Triage dashboard - <a href="https://github.com/{{ owner }}/{{ repo }}">{{ owner }}/{{ repo }}</a></h1>
+        <form action="/triage/{{ owner }}/{{ repo }}" method="get">
+            <input type="search" name="q" value="{{ filter }}" style="width: 400px;">
+            <input type="submit" value="filter">
+        </form>
         <table>
             <thead>
                 <tr>