Parcourir la source

Sort meetings by scheduled date

Tyler Mandry il y a 1 an
Parent
commit
70cc40ba8f
2 fichiers modifiés avec 42 ajouts et 21 suppressions
  1. 32 5
      github-graphql/src/lib.rs
  2. 10 16
      src/github.rs

+ 32 - 5
github-graphql/src/lib.rs

@@ -7,8 +7,10 @@
 pub mod queries {
     use super::schema;
 
+    pub type Date = chrono::NaiveDate;
     pub type DateTime = chrono::DateTime<chrono::Utc>;
 
+    cynic::impl_scalar!(Date, schema::Date);
     cynic::impl_scalar!(DateTime, schema::DateTime);
 
     #[derive(cynic::QueryVariables, Debug, Clone)]
@@ -272,8 +274,8 @@ mod schema {
 }
 
 #[cynic::schema_for_derives(file = "src/github.graphql", module = "schema")]
-pub mod project_items_by_status {
-    use super::queries::{PageInfo, Uri};
+pub mod project_items {
+    use super::queries::{Date, PageInfo, Uri};
     use super::schema;
 
     #[derive(cynic::QueryVariables, Debug, Clone)]
@@ -312,13 +314,25 @@ pub mod project_items_by_status {
     #[derive(cynic::QueryFragment, Debug)]
     pub struct ProjectV2Item {
         pub content: Option<ProjectV2ItemContent>,
+
+        // Currently we hard code the field names we care about here.
+        #[cynic(rename = "fieldValueByName")]
         #[arguments(name = "Status")]
-        pub field_value_by_name: Option<ProjectV2ItemFieldValue>,
+        pub status: Option<ProjectV2ItemFieldValue>,
+        #[cynic(rename = "fieldValueByName")]
+        #[arguments(name = "Date")]
+        pub date: Option<ProjectV2ItemFieldValue>,
     }
 
     impl ProjectV2Item {
-        pub fn status(&self) -> &Option<ProjectV2ItemFieldValue> {
-            &self.field_value_by_name
+        pub fn status(&self) -> Option<&str> {
+            let Some(ref status) = self.status else { return None };
+            status.as_str()
+        }
+
+        pub fn date(&self) -> Option<Date> {
+            let Some(ref date) = self.date else { return None };
+            date.as_date()
         }
     }
 
@@ -333,6 +347,7 @@ pub mod project_items_by_status {
     #[derive(cynic::InlineFragments, Debug)]
     pub enum ProjectV2ItemFieldValue {
         ProjectV2ItemFieldSingleSelectValue(ProjectV2ItemFieldSingleSelectValue),
+        ProjectV2ItemFieldDateValue(ProjectV2ItemFieldDateValue),
 
         #[cynic(fallback)]
         Other,
@@ -345,6 +360,13 @@ pub mod project_items_by_status {
                 _ => return None,
             })
         }
+
+        pub fn as_date(&self) -> Option<Date> {
+            match self {
+                Self::ProjectV2ItemFieldDateValue(val) => val.date,
+                _ => None,
+            }
+        }
     }
 
     #[derive(cynic::QueryFragment, Debug)]
@@ -358,4 +380,9 @@ pub mod project_items_by_status {
     pub struct ProjectV2ItemFieldSingleSelectValue {
         pub name: Option<String>,
     }
+
+    #[derive(cynic::QueryFragment, Debug)]
+    pub struct ProjectV2ItemFieldDateValue {
+        pub date: Option<Date>,
+    }
 }

+ 10 - 16
src/github.rs

@@ -2116,23 +2116,23 @@ impl IssuesQuery for LeastRecentlyReviewedPullRequests {
 async fn project_items_by_status(
     client: &GithubClient,
     status_filter: impl Fn(Option<&str>) -> bool,
-) -> anyhow::Result<Vec<github_graphql::project_items_by_status::ProjectV2ItemContent>> {
+) -> anyhow::Result<Vec<github_graphql::project_items::ProjectV2Item>> {
     use cynic::QueryBuilder;
-    use github_graphql::project_items_by_status;
+    use github_graphql::project_items;
 
     const DESIGN_MEETING_PROJECT: i32 = 31;
-    let mut args = project_items_by_status::Arguments {
+    let mut args = project_items::Arguments {
         project_number: DESIGN_MEETING_PROJECT,
         after: None,
     };
 
     let mut all_items = vec![];
     loop {
-        let query = project_items_by_status::Query::build(args.clone());
+        let query = project_items::Query::build(args.clone());
         let req = client.post(Repository::GITHUB_GRAPHQL_API_URL);
         let req = req.json(&query);
 
-        let data: cynic::GraphQlResponse<project_items_by_status::Query> = client.json(req).await?;
+        let data: cynic::GraphQlResponse<project_items::Query> = client.json(req).await?;
         if let Some(errors) = data.errors {
             anyhow::bail!("There were graphql errors. {:?}", errors);
         }
@@ -2149,14 +2149,7 @@ async fn project_items_by_status(
             .ok_or_else(|| anyhow!("Malformed response."))?
             .into_iter()
             .flatten()
-            .filter(|item| {
-                status_filter(
-                    item.field_value_by_name
-                        .as_ref()
-                        .and_then(|status| status.as_str()),
-                )
-            })
-            .flat_map(|item| item.content);
+            .filter(|item| status_filter(item.status()));
         all_items.extend(filtered);
 
         let page_info = items.page_info;
@@ -2166,6 +2159,7 @@ async fn project_items_by_status(
         args.after = page_info.end_cursor;
     }
 
+    all_items.sort_by_key(|item| item.date());
     Ok(all_items)
 }
 
@@ -2199,15 +2193,15 @@ impl IssuesQuery for DesignMeetings {
         _include_fcp_details: bool,
         client: &'a GithubClient,
     ) -> anyhow::Result<Vec<crate::actions::IssueDecorator>> {
-        use github_graphql::project_items_by_status::ProjectV2ItemContent;
+        use github_graphql::project_items::ProjectV2ItemContent;
 
         let items =
             project_items_by_status(client, |status| status == self.with_status.query_str())
                 .await?;
         Ok(items
             .into_iter()
-            .flat_map(|item| match item {
-                ProjectV2ItemContent::Issue(issue) => Some(crate::actions::IssueDecorator {
+            .flat_map(|item| match item.content {
+                Some(ProjectV2ItemContent::Issue(issue)) => Some(crate::actions::IssueDecorator {
                     assignees: String::new(),
                     number: issue.number.try_into().unwrap(),
                     fcp_details: None,