From 5a3fe318691d0ed104b039014efbb89da5fe8f03 Mon Sep 17 00:00:00 2001 From: ognjeeen Date: Mon, 14 Sep 2026 15:54:09 +0200 Subject: [PATCH 1/2] Show creation timestamps in Inbox details --- src-tauri/src/fs.rs | 28 ++++++++++++++++++++++++---- src/lib/githubTasks.ts | 1 + src/surfaces/InboxView.test.ts | 11 +++++++++++ src/surfaces/InboxView.tsx | 11 +++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/fs.rs b/src-tauri/src/fs.rs index 94638b6e..22c81c12 100644 --- a/src-tauri/src/fs.rs +++ b/src-tauri/src/fs.rs @@ -538,6 +538,7 @@ pub struct GitHubWorkItem { pub title: String, pub url: String, pub state: String, + pub created_at: String, pub updated_at: String, pub labels: Vec, pub assignees: Vec, @@ -1704,9 +1705,9 @@ fn git_github_work_items_for( }; let limit = limit.clamp(1, 100).to_string(); let fields = if kind == "pr" { - "number,title,url,state,updatedAt,labels,assignees,isDraft" + "number,title,url,state,createdAt,updatedAt,labels,assignees,isDraft" } else { - "number,title,url,state,updatedAt,labels,assignees" + "number,title,url,state,createdAt,updatedAt,labels,assignees" }; let mut args = vec![ kind.to_string(), @@ -1750,9 +1751,9 @@ fn git_github_work_item_for( let repo = format!("{owner}/{name}"); let number = number.to_string(); let fields = if kind == "pr" { - "number,title,url,state,updatedAt,labels,assignees,isDraft" + "number,title,url,state,createdAt,updatedAt,labels,assignees,isDraft" } else { - "number,title,url,state,updatedAt,labels,assignees" + "number,title,url,state,createdAt,updatedAt,labels,assignees" }; let json = gh_checked( root, @@ -2721,6 +2722,8 @@ fn parse_github_work_items( url: String, state: String, #[serde(default)] + created_at: String, + #[serde(default)] updated_at: String, #[serde(default)] labels: Vec, @@ -2738,6 +2741,7 @@ fn parse_github_work_items( title: row.title, url: row.url, state: row.state.to_lowercase(), + created_at: row.created_at, updated_at: row.updated_at, labels: row .labels @@ -5363,6 +5367,22 @@ mod tests { assert_eq!(items[0].repo, "acme/web"); } + #[test] + fn github_pr_creation_time_reaches_frontend() { + let json = r#"{ + "number": 12, + "title": "Checkout", + "url": "https://github.com/acme/web/pull/12", + "state": "OPEN", + "createdAt": "2026-09-01T08:00:00Z", + "updatedAt": "2026-09-11T08:00:00Z" + }"#; + let item = parse_github_work_item(json, "pr", "acme/web").unwrap(); + let payload = serde_json::to_value(item).unwrap(); + assert_eq!(payload["createdAt"], "2026-09-01T08:00:00Z"); + assert_eq!(payload["updatedAt"], "2026-09-11T08:00:00Z"); + } + #[test] fn parse_github_work_item_reads_view_shape() { let json = r#"{ diff --git a/src/lib/githubTasks.ts b/src/lib/githubTasks.ts index 9889f8f2..34bfc733 100644 --- a/src/lib/githubTasks.ts +++ b/src/lib/githubTasks.ts @@ -41,6 +41,7 @@ export type GithubWorkItem = { title: string; url: string; state: string; + createdAt?: string; updatedAt: string; labels: GithubLabel[]; assignees: GithubAssignee[]; diff --git a/src/surfaces/InboxView.test.ts b/src/surfaces/InboxView.test.ts index 871f5298..84c1062a 100644 --- a/src/surfaces/InboxView.test.ts +++ b/src/surfaces/InboxView.test.ts @@ -41,6 +41,17 @@ function renderDetail( } describe("InboxDetail layout", () => { + it("shows when a PR was created alongside its last update", () => { + const markup = renderDetail({ + ...item({ kind: "pr" }), + createdAt: "2026-09-01T08:00:00Z", + }); + expect(markup).toContain("Created "); + expect(markup).toContain('dateTime="2026-09-01T08:00:00Z"'); + expect(markup).toContain("Updated "); + expect(renderDetail(item({ kind: "pr" }))).not.toContain("Created "); + }); + it("keeps issue identity and actions outside the body scroller", () => { const markup = renderDetail(item({ projectPath: "/tmp/local-project" })); const headerIndex = markup.indexOf("data-inbox-detail-header"); diff --git a/src/surfaces/InboxView.tsx b/src/surfaces/InboxView.tsx index 55da668c..08bf664c 100644 --- a/src/surfaces/InboxView.tsx +++ b/src/surfaces/InboxView.tsx @@ -1685,6 +1685,17 @@ export function InboxDetail({ )} ) : null} + {item.createdAt && formatRelativeTime(item.createdAt) ? ( + <> + · + + + ) : null} {formatRelativeTime(item.updatedAt) ? ( <> · From deea415f8dfc0e6bbb7c9b4dae78427f6a6d515f Mon Sep 17 00:00:00 2001 From: ognjeeen Date: Mon, 14 Sep 2026 16:07:01 +0200 Subject: [PATCH 2/2] Test creation timestamps for GitHub issues --- src-tauri/src/fs.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src-tauri/src/fs.rs b/src-tauri/src/fs.rs index 22c81c12..ad04806c 100644 --- a/src-tauri/src/fs.rs +++ b/src-tauri/src/fs.rs @@ -5332,6 +5332,7 @@ mod tests { "title": "Promo codes fail to apply", "url": "https://github.com/acme/web/issues/5138", "state": "OPEN", + "createdAt": "2026-08-20T09:00:00Z", "updatedAt": "2026-08-27T08:00:00Z", "labels": [{"name": "bug", "color": "d73a4a"}], "assignees": [{"login": "maya"}] @@ -5349,6 +5350,9 @@ mod tests { "https://avatars.githubusercontent.com/maya?s=64" ); assert!(!items[0].draft); + let payload = serde_json::to_value(&items[0]).unwrap(); + assert_eq!(payload["createdAt"], "2026-08-20T09:00:00Z"); + assert_eq!(payload["updatedAt"], "2026-08-27T08:00:00Z"); } #[test] @@ -5368,8 +5372,9 @@ mod tests { } #[test] - fn github_pr_creation_time_reaches_frontend() { - let json = r#"{ + fn github_work_item_creation_time_reaches_frontend() { + for (kind, resource) in [("pr", "pull"), ("issue", "issues")] { + let json = r#"{ "number": 12, "title": "Checkout", "url": "https://github.com/acme/web/pull/12", @@ -5377,10 +5382,13 @@ mod tests { "createdAt": "2026-09-01T08:00:00Z", "updatedAt": "2026-09-11T08:00:00Z" }"#; - let item = parse_github_work_item(json, "pr", "acme/web").unwrap(); - let payload = serde_json::to_value(item).unwrap(); - assert_eq!(payload["createdAt"], "2026-09-01T08:00:00Z"); - assert_eq!(payload["updatedAt"], "2026-09-11T08:00:00Z"); + let json = json.replace("/pull/", &format!("/{resource}/")); + let item = parse_github_work_item(&json, kind, "acme/web").unwrap(); + let payload = serde_json::to_value(item).unwrap(); + assert_eq!(payload["kind"], kind); + assert_eq!(payload["createdAt"], "2026-09-01T08:00:00Z"); + assert_eq!(payload["updatedAt"], "2026-09-11T08:00:00Z"); + } } #[test]