feat: show creation time next to pr title
This commit is contained in:
@@ -5,6 +5,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
chrono = { version = "0.4.44", features = ["serde"] }
|
||||||
futures = "0.3.32"
|
futures = "0.3.32"
|
||||||
futures-lite = "2.6.1"
|
futures-lite = "2.6.1"
|
||||||
gpui = { version = "*" }
|
gpui = { version = "*" }
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"title": "feat(prompts): split context loading from execution workers",
|
"title": "feat(prompts): split context loading from execution workers",
|
||||||
"state": "OPEN",
|
"state": "OPEN",
|
||||||
"is_draft": true,
|
"is_draft": true,
|
||||||
|
"created_at": "2026-04-30T14:22:00Z",
|
||||||
"author": {
|
"author": {
|
||||||
"login": "leaferiksen",
|
"login": "leaferiksen",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/5151?v=4"
|
"avatar_url": "https://avatars.githubusercontent.com/u/5151?v=4"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"title": "chore(tokens): tighten dashboard spacing scale",
|
"title": "chore(tokens): tighten dashboard spacing scale",
|
||||||
"state": "OPEN",
|
"state": "OPEN",
|
||||||
"is_draft": false,
|
"is_draft": false,
|
||||||
|
"created_at": "2026-05-02T11:05:00Z",
|
||||||
"author": {
|
"author": {
|
||||||
"login": "mariahops",
|
"login": "mariahops",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/6161?v=4"
|
"avatar_url": "https://avatars.githubusercontent.com/u/6161?v=4"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"title": "docs(deploy): document manual failover steps",
|
"title": "docs(deploy): document manual failover steps",
|
||||||
"state": "CLOSED",
|
"state": "CLOSED",
|
||||||
"is_draft": false,
|
"is_draft": false,
|
||||||
|
"created_at": "2026-04-24T06:40:00Z",
|
||||||
"author": {
|
"author": {
|
||||||
"login": "kennethnym",
|
"login": "kennethnym",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/4242?v=4"
|
"avatar_url": "https://avatars.githubusercontent.com/u/4242?v=4"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"title": "feat(dashboard): hydrate issue pane from cached query state",
|
"title": "feat(dashboard): hydrate issue pane from cached query state",
|
||||||
"state": "OPEN",
|
"state": "OPEN",
|
||||||
"is_draft": false,
|
"is_draft": false,
|
||||||
|
"created_at": "2026-05-01T09:12:00Z",
|
||||||
"author": {
|
"author": {
|
||||||
"login": "kennethnym",
|
"login": "kennethnym",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/4242?v=4"
|
"avatar_url": "https://avatars.githubusercontent.com/u/4242?v=4"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"title": "feat(repo): add cached repository query for titlebar picker",
|
"title": "feat(repo): add cached repository query for titlebar picker",
|
||||||
"state": "OPEN",
|
"state": "OPEN",
|
||||||
"is_draft": false,
|
"is_draft": false,
|
||||||
|
"created_at": "2026-05-03T07:40:00Z",
|
||||||
"author": {
|
"author": {
|
||||||
"login": "kennethnym",
|
"login": "kennethnym",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/4242?v=4"
|
"avatar_url": "https://avatars.githubusercontent.com/u/4242?v=4"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"title": "feat(calendar): ship release handoff checklist in weekly planner",
|
"title": "feat(calendar): ship release handoff checklist in weekly planner",
|
||||||
"state": "MERGED",
|
"state": "MERGED",
|
||||||
"is_draft": false,
|
"is_draft": false,
|
||||||
|
"created_at": "2026-04-28T10:20:00Z",
|
||||||
"author": {
|
"author": {
|
||||||
"login": "rorycraft",
|
"login": "rorycraft",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/7171?v=4"
|
"avatar_url": "https://avatars.githubusercontent.com/u/7171?v=4"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ query PullRequestQuery($id: ID!) {
|
|||||||
body
|
body
|
||||||
state
|
state
|
||||||
isDraft
|
isDraft
|
||||||
|
createdAt
|
||||||
baseRef {
|
baseRef {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ pub(crate) struct DetailedPullRequest {
|
|||||||
pub(crate) state: PullRequestState,
|
pub(crate) state: PullRequestState,
|
||||||
pub(crate) is_draft: bool,
|
pub(crate) is_draft: bool,
|
||||||
pub(crate) body: String,
|
pub(crate) body: String,
|
||||||
|
pub(crate) created_at: Option<chrono::DateTime<chrono::FixedOffset>>,
|
||||||
pub(crate) author: Option<super::user::Actor>,
|
pub(crate) author: Option<super::user::Actor>,
|
||||||
pub(crate) base_branch_name: Option<String>,
|
pub(crate) base_branch_name: Option<String>,
|
||||||
pub(crate) head_branch_name: Option<String>,
|
pub(crate) head_branch_name: Option<String>,
|
||||||
@@ -368,18 +369,29 @@ impl query::QueryFn for FetchPullRequest {
|
|||||||
"missing 'node' field on PullRequestQuery response".into(),
|
"missing 'node' field on PullRequestQuery response".into(),
|
||||||
))
|
))
|
||||||
.and_then(|n| match n {
|
.and_then(|n| match n {
|
||||||
| PullRequestQueryNode::PullRequest(p) => Ok(DetailedPullRequest {
|
| PullRequestQueryNode::PullRequest(p) => {
|
||||||
title: p.title,
|
let created_at =
|
||||||
state: p.state,
|
chrono::DateTime::parse_from_rfc3339(&p.created_at).map_err(|err| {
|
||||||
is_draft: p.is_draft,
|
api::Error::MalformedResponse(format!(
|
||||||
body: p.body,
|
"invalid pull request createdAt {:?}: {err}",
|
||||||
author: p.author.map(|it| api::user::Actor {
|
p.created_at
|
||||||
login: it.login,
|
))
|
||||||
avatar_url: it.avatar_url,
|
})?;
|
||||||
}),
|
|
||||||
base_branch_name: p.base_ref.map(|r| r.name),
|
Ok(DetailedPullRequest {
|
||||||
head_branch_name: p.head_ref.map(|r| r.name),
|
title: p.title,
|
||||||
}),
|
state: p.state,
|
||||||
|
is_draft: p.is_draft,
|
||||||
|
body: p.body,
|
||||||
|
author: p.author.map(|it| api::user::Actor {
|
||||||
|
login: it.login,
|
||||||
|
avatar_url: it.avatar_url,
|
||||||
|
}),
|
||||||
|
base_branch_name: p.base_ref.map(|r| r.name),
|
||||||
|
head_branch_name: p.head_ref.map(|r| r.name),
|
||||||
|
created_at: Some(created_at),
|
||||||
|
})
|
||||||
|
}
|
||||||
| _ => Err(api::Error::MalformedResponse(
|
| _ => Err(api::Error::MalformedResponse(
|
||||||
"unexpected node type on PullRequestQuery".into(),
|
"unexpected node type on PullRequestQuery".into(),
|
||||||
)),
|
)),
|
||||||
|
|||||||
@@ -151,6 +151,10 @@ mod tests {
|
|||||||
merged.head_branch_name.as_deref(),
|
merged.head_branch_name.as_deref(),
|
||||||
Some("feat/release-handoff-checklist")
|
Some("feat/release-handoff-checklist")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
merged.created_at,
|
||||||
|
Some(chrono::DateTime::parse_from_rfc3339("2026-04-28T10:20:00Z").unwrap())
|
||||||
|
);
|
||||||
assert!(
|
assert!(
|
||||||
documented_failover
|
documented_failover
|
||||||
.body
|
.body
|
||||||
@@ -168,12 +172,20 @@ mod tests {
|
|||||||
documented_failover.head_branch_name.as_deref(),
|
documented_failover.head_branch_name.as_deref(),
|
||||||
Some("docs/manual-failover-steps")
|
Some("docs/manual-failover-steps")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
documented_failover.created_at,
|
||||||
|
Some(chrono::DateTime::parse_from_rfc3339("2026-04-24T06:40:00Z").unwrap())
|
||||||
|
);
|
||||||
assert!(dashboard_markdown.body.contains("```rust"));
|
assert!(dashboard_markdown.body.contains("```rust"));
|
||||||
assert_eq!(dashboard_markdown.base_branch_name.as_deref(), Some("main"));
|
assert_eq!(dashboard_markdown.base_branch_name.as_deref(), Some("main"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dashboard_markdown.head_branch_name.as_deref(),
|
dashboard_markdown.head_branch_name.as_deref(),
|
||||||
Some("feat/cached-issue-pane")
|
Some("feat/cached-issue-pane")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
dashboard_markdown.created_at,
|
||||||
|
Some(chrono::DateTime::parse_from_rfc3339("2026-05-01T09:12:00Z").unwrap())
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cached_repo_picker
|
cached_repo_picker
|
||||||
.author
|
.author
|
||||||
@@ -186,6 +198,10 @@ mod tests {
|
|||||||
cached_repo_picker.head_branch_name.as_deref(),
|
cached_repo_picker.head_branch_name.as_deref(),
|
||||||
Some("feat/cached-repo-picker")
|
Some("feat/cached-repo-picker")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
cached_repo_picker.created_at,
|
||||||
|
Some(chrono::DateTime::parse_from_rfc3339("2026-05-03T07:40:00Z").unwrap())
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
worker_split.author.as_ref().map(|author| author.login.as_str()),
|
worker_split.author.as_ref().map(|author| author.login.as_str()),
|
||||||
Some("leaferiksen")
|
Some("leaferiksen")
|
||||||
@@ -195,6 +211,10 @@ mod tests {
|
|||||||
worker_split.head_branch_name.as_deref(),
|
worker_split.head_branch_name.as_deref(),
|
||||||
Some("feat/worker-context-envelope")
|
Some("feat/worker-context-envelope")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
worker_split.created_at,
|
||||||
|
Some(chrono::DateTime::parse_from_rfc3339("2026-04-30T14:22:00Z").unwrap())
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
spacing_tokens
|
spacing_tokens
|
||||||
.author
|
.author
|
||||||
@@ -207,6 +227,10 @@ mod tests {
|
|||||||
spacing_tokens.head_branch_name.as_deref(),
|
spacing_tokens.head_branch_name.as_deref(),
|
||||||
Some("chore/dashboard-spacing-scale")
|
Some("chore/dashboard-spacing-scale")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
spacing_tokens.created_at,
|
||||||
|
Some(chrono::DateTime::parse_from_rfc3339("2026-05-02T11:05:00Z").unwrap())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -205,7 +205,22 @@ impl PullRequestView {
|
|||||||
.py_3()
|
.py_3()
|
||||||
.border_b_1()
|
.border_b_1()
|
||||||
.border_color(theme.colors.border)
|
.border_color(theme.colors.border)
|
||||||
.child(text(pr.title.clone()).w_full().text_xl().mb_1())
|
.child(
|
||||||
|
div()
|
||||||
|
.w_full()
|
||||||
|
.flex()
|
||||||
|
.flex_row()
|
||||||
|
.justify_between()
|
||||||
|
.items_center()
|
||||||
|
.child(text(pr.title.clone()).w_full().text_xl().mb_1())
|
||||||
|
.when_some(pr.created_at, |it, created_at| {
|
||||||
|
it.child(
|
||||||
|
text(created_at.format("%Y-%m-%d %H:%M").to_string())
|
||||||
|
.opacity(0.5)
|
||||||
|
.text_xs(),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
.child(metadata_line),
|
.child(metadata_line),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
Reference in New Issue
Block a user