mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(agents): add PR title, draft, and status icons to sidebar (#22952)
Adds `pull_request_title` and `pull_request_draft` to the chat diff status pipeline (DB → provider → SDK → frontend). The GitHub provider now fetches the PR title alongside existing status fields. The agents sidebar now displays PR-state-aware icons for chats that have a linked pull request (when the chat is in waiting/completed state): - **Open PR**: `GitPullRequestArrow` (green) - **Draft PR**: `GitPullRequestDraft` (gray) - **Merged PR**: `GitMerge` (purple) - **Closed PR**: `GitPullRequestClosed` (red) Running/pending/paused/error chats keep their existing activity icons (spinner, pause, error triangle). ### Changes **Database migration** (`000432`): Adds `pull_request_title TEXT` and `pull_request_draft BOOLEAN` columns to `chat_diff_statuses`. **Backend pipeline**: - `gitprovider.PRStatus` gains a `Title` field - GitHub provider decodes the `title` from the API response - `gitsync` and `coderd/chats.go` pass title + draft through to the DB upsert - `codersdk.ChatDiffStatus` exposes both new fields in the API response **Frontend** (`AgentsSidebar.tsx`): New `getPRIconConfig()` function resolves the appropriate Lucide git icon based on `pull_request_state` and `pull_request_draft`. Only applies when the chat is in a terminal state (waiting/completed). **Real-time sync**: No changes needed — the existing `diff_status_change` pubsub event already propagates the full `ChatDiffStatus` including the new fields.
This commit is contained in:
@@ -1534,6 +1534,8 @@ func (api *API) refreshChatDiffStatus(
|
||||
String: string(status.State),
|
||||
Valid: status.State != "",
|
||||
},
|
||||
PullRequestTitle: status.Title,
|
||||
PullRequestDraft: status.Draft,
|
||||
ChangesRequested: status.ChangesRequested,
|
||||
Additions: status.DiffStats.Additions,
|
||||
Deletions: status.DiffStats.Deletions,
|
||||
@@ -2314,6 +2316,8 @@ func convertChatDiffStatus(chatID uuid.UUID, status *database.ChatDiffStatus) co
|
||||
result.PullRequestState = &pullRequestState
|
||||
}
|
||||
}
|
||||
result.PullRequestTitle = status.PullRequestTitle
|
||||
result.PullRequestDraft = status.PullRequestDraft
|
||||
result.ChangesRequested = status.ChangesRequested
|
||||
result.Additions = status.Additions
|
||||
result.Deletions = status.Deletions
|
||||
|
||||
Generated
+3
-1
@@ -1187,7 +1187,9 @@ CREATE TABLE chat_diff_statuses (
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
git_branch text DEFAULT ''::text NOT NULL,
|
||||
git_remote_origin text DEFAULT ''::text NOT NULL
|
||||
git_remote_origin text DEFAULT ''::text NOT NULL,
|
||||
pull_request_title text DEFAULT ''::text NOT NULL,
|
||||
pull_request_draft boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE chat_files (
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE chat_diff_statuses DROP COLUMN pull_request_title;
|
||||
ALTER TABLE chat_diff_statuses DROP COLUMN pull_request_draft;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE chat_diff_statuses ADD COLUMN pull_request_title TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE chat_diff_statuses ADD COLUMN pull_request_draft BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
@@ -3924,6 +3924,8 @@ type ChatDiffStatus struct {
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
GitBranch string `db:"git_branch" json:"git_branch"`
|
||||
GitRemoteOrigin string `db:"git_remote_origin" json:"git_remote_origin"`
|
||||
PullRequestTitle string `db:"pull_request_title" json:"pull_request_title"`
|
||||
PullRequestDraft bool `db:"pull_request_draft" json:"pull_request_draft"`
|
||||
}
|
||||
|
||||
type ChatFile struct {
|
||||
|
||||
@@ -3056,10 +3056,10 @@ WITH acquired AS (
|
||||
LIMIT
|
||||
$1::int
|
||||
)
|
||||
RETURNING chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin
|
||||
RETURNING chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin, pull_request_title, pull_request_draft
|
||||
)
|
||||
SELECT
|
||||
acquired.chat_id, acquired.url, acquired.pull_request_state, acquired.changes_requested, acquired.additions, acquired.deletions, acquired.changed_files, acquired.refreshed_at, acquired.stale_at, acquired.created_at, acquired.updated_at, acquired.git_branch, acquired.git_remote_origin,
|
||||
acquired.chat_id, acquired.url, acquired.pull_request_state, acquired.changes_requested, acquired.additions, acquired.deletions, acquired.changed_files, acquired.refreshed_at, acquired.stale_at, acquired.created_at, acquired.updated_at, acquired.git_branch, acquired.git_remote_origin, acquired.pull_request_title, acquired.pull_request_draft,
|
||||
c.owner_id
|
||||
FROM
|
||||
acquired
|
||||
@@ -3081,6 +3081,8 @@ type AcquireStaleChatDiffStatusesRow struct {
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
GitBranch string `db:"git_branch" json:"git_branch"`
|
||||
GitRemoteOrigin string `db:"git_remote_origin" json:"git_remote_origin"`
|
||||
PullRequestTitle string `db:"pull_request_title" json:"pull_request_title"`
|
||||
PullRequestDraft bool `db:"pull_request_draft" json:"pull_request_draft"`
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
}
|
||||
|
||||
@@ -3107,6 +3109,8 @@ func (q *sqlQuerier) AcquireStaleChatDiffStatuses(ctx context.Context, limitVal
|
||||
&i.UpdatedAt,
|
||||
&i.GitBranch,
|
||||
&i.GitRemoteOrigin,
|
||||
&i.PullRequestTitle,
|
||||
&i.PullRequestDraft,
|
||||
&i.OwnerID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
@@ -3266,7 +3270,7 @@ func (q *sqlQuerier) GetChatByIDForUpdate(ctx context.Context, id uuid.UUID) (Ch
|
||||
|
||||
const getChatDiffStatusByChatID = `-- name: GetChatDiffStatusByChatID :one
|
||||
SELECT
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin, pull_request_title, pull_request_draft
|
||||
FROM
|
||||
chat_diff_statuses
|
||||
WHERE
|
||||
@@ -3290,13 +3294,15 @@ func (q *sqlQuerier) GetChatDiffStatusByChatID(ctx context.Context, chatID uuid.
|
||||
&i.UpdatedAt,
|
||||
&i.GitBranch,
|
||||
&i.GitRemoteOrigin,
|
||||
&i.PullRequestTitle,
|
||||
&i.PullRequestDraft,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getChatDiffStatusesByChatIDs = `-- name: GetChatDiffStatusesByChatIDs :many
|
||||
SELECT
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin, pull_request_title, pull_request_draft
|
||||
FROM
|
||||
chat_diff_statuses
|
||||
WHERE
|
||||
@@ -3326,6 +3332,8 @@ func (q *sqlQuerier) GetChatDiffStatusesByChatIDs(ctx context.Context, chatIds [
|
||||
&i.UpdatedAt,
|
||||
&i.GitBranch,
|
||||
&i.GitRemoteOrigin,
|
||||
&i.PullRequestTitle,
|
||||
&i.PullRequestDraft,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -4272,6 +4280,8 @@ INSERT INTO chat_diff_statuses (
|
||||
chat_id,
|
||||
url,
|
||||
pull_request_state,
|
||||
pull_request_title,
|
||||
pull_request_draft,
|
||||
changes_requested,
|
||||
additions,
|
||||
deletions,
|
||||
@@ -4282,17 +4292,21 @@ INSERT INTO chat_diff_statuses (
|
||||
$1::uuid,
|
||||
$2::text,
|
||||
$3::text,
|
||||
$4::boolean,
|
||||
$5::integer,
|
||||
$6::integer,
|
||||
$4::text,
|
||||
$5::boolean,
|
||||
$6::boolean,
|
||||
$7::integer,
|
||||
$8::timestamptz,
|
||||
$9::timestamptz
|
||||
$8::integer,
|
||||
$9::integer,
|
||||
$10::timestamptz,
|
||||
$11::timestamptz
|
||||
)
|
||||
ON CONFLICT (chat_id) DO UPDATE
|
||||
SET
|
||||
url = EXCLUDED.url,
|
||||
pull_request_state = EXCLUDED.pull_request_state,
|
||||
pull_request_title = EXCLUDED.pull_request_title,
|
||||
pull_request_draft = EXCLUDED.pull_request_draft,
|
||||
changes_requested = EXCLUDED.changes_requested,
|
||||
additions = EXCLUDED.additions,
|
||||
deletions = EXCLUDED.deletions,
|
||||
@@ -4301,13 +4315,15 @@ SET
|
||||
stale_at = EXCLUDED.stale_at,
|
||||
updated_at = NOW()
|
||||
RETURNING
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin, pull_request_title, pull_request_draft
|
||||
`
|
||||
|
||||
type UpsertChatDiffStatusParams struct {
|
||||
ChatID uuid.UUID `db:"chat_id" json:"chat_id"`
|
||||
Url sql.NullString `db:"url" json:"url"`
|
||||
PullRequestState sql.NullString `db:"pull_request_state" json:"pull_request_state"`
|
||||
PullRequestTitle string `db:"pull_request_title" json:"pull_request_title"`
|
||||
PullRequestDraft bool `db:"pull_request_draft" json:"pull_request_draft"`
|
||||
ChangesRequested bool `db:"changes_requested" json:"changes_requested"`
|
||||
Additions int32 `db:"additions" json:"additions"`
|
||||
Deletions int32 `db:"deletions" json:"deletions"`
|
||||
@@ -4321,6 +4337,8 @@ func (q *sqlQuerier) UpsertChatDiffStatus(ctx context.Context, arg UpsertChatDif
|
||||
arg.ChatID,
|
||||
arg.Url,
|
||||
arg.PullRequestState,
|
||||
arg.PullRequestTitle,
|
||||
arg.PullRequestDraft,
|
||||
arg.ChangesRequested,
|
||||
arg.Additions,
|
||||
arg.Deletions,
|
||||
@@ -4343,6 +4361,8 @@ func (q *sqlQuerier) UpsertChatDiffStatus(ctx context.Context, arg UpsertChatDif
|
||||
&i.UpdatedAt,
|
||||
&i.GitBranch,
|
||||
&i.GitRemoteOrigin,
|
||||
&i.PullRequestTitle,
|
||||
&i.PullRequestDraft,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -4378,7 +4398,7 @@ SET
|
||||
stale_at = EXCLUDED.stale_at,
|
||||
updated_at = NOW()
|
||||
RETURNING
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin
|
||||
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin, pull_request_title, pull_request_draft
|
||||
`
|
||||
|
||||
type UpsertChatDiffStatusReferenceParams struct {
|
||||
@@ -4412,6 +4432,8 @@ func (q *sqlQuerier) UpsertChatDiffStatusReference(ctx context.Context, arg Upse
|
||||
&i.UpdatedAt,
|
||||
&i.GitBranch,
|
||||
&i.GitRemoteOrigin,
|
||||
&i.PullRequestTitle,
|
||||
&i.PullRequestDraft,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
@@ -378,6 +378,8 @@ INSERT INTO chat_diff_statuses (
|
||||
chat_id,
|
||||
url,
|
||||
pull_request_state,
|
||||
pull_request_title,
|
||||
pull_request_draft,
|
||||
changes_requested,
|
||||
additions,
|
||||
deletions,
|
||||
@@ -388,6 +390,8 @@ INSERT INTO chat_diff_statuses (
|
||||
@chat_id::uuid,
|
||||
sqlc.narg('url')::text,
|
||||
sqlc.narg('pull_request_state')::text,
|
||||
@pull_request_title::text,
|
||||
@pull_request_draft::boolean,
|
||||
@changes_requested::boolean,
|
||||
@additions::integer,
|
||||
@deletions::integer,
|
||||
@@ -399,6 +403,8 @@ ON CONFLICT (chat_id) DO UPDATE
|
||||
SET
|
||||
url = EXCLUDED.url,
|
||||
pull_request_state = EXCLUDED.pull_request_state,
|
||||
pull_request_title = EXCLUDED.pull_request_title,
|
||||
pull_request_draft = EXCLUDED.pull_request_draft,
|
||||
changes_requested = EXCLUDED.changes_requested,
|
||||
additions = EXCLUDED.additions,
|
||||
deletions = EXCLUDED.deletions,
|
||||
|
||||
@@ -258,6 +258,7 @@ func (g *githubProvider) FetchPullRequestStatus(
|
||||
)
|
||||
|
||||
var pull struct {
|
||||
Title string `json:"title"`
|
||||
State string `json:"state"`
|
||||
Merged bool `json:"merged"`
|
||||
Draft bool `json:"draft"`
|
||||
@@ -298,6 +299,7 @@ func (g *githubProvider) FetchPullRequestStatus(
|
||||
}
|
||||
|
||||
return &PRStatus{
|
||||
Title: pull.Title,
|
||||
State: state,
|
||||
Draft: pull.Draft,
|
||||
HeadSHA: pull.Head.SHA,
|
||||
|
||||
@@ -66,6 +66,8 @@ type DiffStats struct {
|
||||
// PRStatus is the complete status of a pull/merge request.
|
||||
// This is the universal return type that all providers populate.
|
||||
type PRStatus struct {
|
||||
// Title is the PR's title/subject line.
|
||||
Title string
|
||||
// State is the PR's lifecycle state.
|
||||
State PRState
|
||||
// Draft indicates the PR is marked as draft/WIP.
|
||||
|
||||
@@ -218,6 +218,8 @@ func (r *Refresher) refreshOne(
|
||||
String: string(status.State),
|
||||
Valid: status.State != "",
|
||||
},
|
||||
PullRequestTitle: status.Title,
|
||||
PullRequestDraft: status.Draft,
|
||||
ChangesRequested: status.ChangesRequested,
|
||||
Additions: status.DiffStats.Additions,
|
||||
Deletions: status.DiffStats.Deletions,
|
||||
|
||||
@@ -465,6 +465,8 @@ type ChatDiffStatus struct {
|
||||
ChatID uuid.UUID `json:"chat_id" format:"uuid"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
PullRequestState *string `json:"pull_request_state,omitempty"`
|
||||
PullRequestTitle string `json:"pull_request_title"`
|
||||
PullRequestDraft bool `json:"pull_request_draft"`
|
||||
ChangesRequested bool `json:"changes_requested"`
|
||||
Additions int32 `json:"additions"`
|
||||
Deletions int32 `json:"deletions"`
|
||||
|
||||
Generated
+2
@@ -1091,6 +1091,8 @@ export interface ChatDiffStatus {
|
||||
readonly chat_id: string;
|
||||
readonly url?: string;
|
||||
readonly pull_request_state?: string;
|
||||
readonly pull_request_title: string;
|
||||
readonly pull_request_draft: boolean;
|
||||
readonly changes_requested: boolean;
|
||||
readonly additions: number;
|
||||
readonly deletions: number;
|
||||
|
||||
@@ -144,6 +144,8 @@ const buildQueries = (
|
||||
data: {
|
||||
chat_id: CHAT_ID,
|
||||
url: opts?.diffUrl,
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: opts?.diffUrl ? 4 : 0,
|
||||
deletions: opts?.diffUrl ? 1 : 0,
|
||||
|
||||
@@ -475,6 +475,8 @@ export const WithDiffStats: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-both",
|
||||
url: "https://github.com/coder/coder/pull/1",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 42,
|
||||
deletions: 7,
|
||||
@@ -488,6 +490,8 @@ export const WithDiffStats: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-add-only",
|
||||
url: "https://github.com/coder/coder/pull/2",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 120,
|
||||
deletions: 0,
|
||||
@@ -501,6 +505,8 @@ export const WithDiffStats: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-del-only",
|
||||
url: "https://github.com/coder/coder/pull/3",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 0,
|
||||
deletions: 35,
|
||||
@@ -514,6 +520,8 @@ export const WithDiffStats: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-none",
|
||||
url: "https://github.com/coder/coder/pull/4",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 0,
|
||||
deletions: 0,
|
||||
@@ -558,6 +566,8 @@ export const WithDiffStatsLight: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-both-light",
|
||||
url: "https://github.com/coder/coder/pull/1",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 42,
|
||||
deletions: 7,
|
||||
@@ -571,6 +581,8 @@ export const WithDiffStatsLight: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-add-only-light",
|
||||
url: "https://github.com/coder/coder/pull/2",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 120,
|
||||
deletions: 0,
|
||||
@@ -584,6 +596,8 @@ export const WithDiffStatsLight: Story = {
|
||||
diff_status: {
|
||||
chat_id: "diff-del-only-light",
|
||||
url: "https://github.com/coder/coder/pull/3",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 0,
|
||||
deletions: 35,
|
||||
@@ -607,6 +621,98 @@ export const WithDiffStatsLight: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const WithPRStateIcons: Story = {
|
||||
args: {
|
||||
chats: [
|
||||
buildChat({
|
||||
id: "pr-open",
|
||||
title: "Open pull request",
|
||||
updated_at: todayTimestamp,
|
||||
diff_status: {
|
||||
chat_id: "pr-open",
|
||||
url: "https://github.com/coder/coder/pull/100",
|
||||
pull_request_state: "open",
|
||||
pull_request_title: "feat: add new feature",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 50,
|
||||
deletions: 10,
|
||||
changed_files: 4,
|
||||
},
|
||||
}),
|
||||
buildChat({
|
||||
id: "pr-draft",
|
||||
title: "Draft pull request",
|
||||
updated_at: todayTimestamp,
|
||||
diff_status: {
|
||||
chat_id: "pr-draft",
|
||||
url: "https://github.com/coder/coder/pull/101",
|
||||
pull_request_state: "open",
|
||||
pull_request_title: "wip: draft changes",
|
||||
pull_request_draft: true,
|
||||
changes_requested: false,
|
||||
additions: 20,
|
||||
deletions: 5,
|
||||
changed_files: 2,
|
||||
},
|
||||
}),
|
||||
buildChat({
|
||||
id: "pr-merged",
|
||||
title: "Merged pull request",
|
||||
updated_at: todayTimestamp,
|
||||
diff_status: {
|
||||
chat_id: "pr-merged",
|
||||
url: "https://github.com/coder/coder/pull/102",
|
||||
pull_request_state: "merged",
|
||||
pull_request_title: "feat: completed feature",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 200,
|
||||
deletions: 80,
|
||||
changed_files: 12,
|
||||
},
|
||||
}),
|
||||
buildChat({
|
||||
id: "pr-closed",
|
||||
title: "Closed pull request",
|
||||
updated_at: todayTimestamp,
|
||||
diff_status: {
|
||||
chat_id: "pr-closed",
|
||||
url: "https://github.com/coder/coder/pull/103",
|
||||
pull_request_state: "closed",
|
||||
pull_request_title: "fix: abandoned approach",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 15,
|
||||
deletions: 3,
|
||||
changed_files: 1,
|
||||
},
|
||||
}),
|
||||
buildChat({
|
||||
id: "pr-no-state",
|
||||
title: "No PR state (branch only)",
|
||||
updated_at: todayTimestamp,
|
||||
diff_status: {
|
||||
chat_id: "pr-no-state",
|
||||
url: "https://github.com/coder/coder/tree/my-branch",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 10,
|
||||
deletions: 2,
|
||||
changed_files: 1,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
parameters: {
|
||||
reactRouter: reactRouterParameters({
|
||||
location: { path: "/agents" },
|
||||
routing: agentsRouting,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
export const ArchivedAgentUnarchiveOption: Story = {
|
||||
args: {
|
||||
chats: [
|
||||
|
||||
@@ -33,6 +33,10 @@ import {
|
||||
ChevronDownIcon,
|
||||
ChevronRightIcon,
|
||||
EllipsisIcon,
|
||||
GitMergeIcon,
|
||||
GitPullRequestArrowIcon,
|
||||
GitPullRequestClosedIcon,
|
||||
GitPullRequestDraftIcon,
|
||||
Loader2Icon,
|
||||
PanelLeftCloseIcon,
|
||||
PauseIcon,
|
||||
@@ -98,6 +102,37 @@ const getStatusConfig = (status: ChatStatus) => {
|
||||
return statusConfig[status] ?? statusConfig.completed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the icon and className to use for a PR state, or undefined
|
||||
* if there is no PR linked. Only overrides the icon when the chat
|
||||
* is not actively executing (pending/running/paused/error).
|
||||
*/
|
||||
const getPRIconConfig = (
|
||||
diffStatus: ChatDiffStatus | undefined,
|
||||
): { icon: typeof CheckIcon; className: string } | undefined => {
|
||||
const state = diffStatus?.pull_request_state;
|
||||
if (!state) {
|
||||
return undefined;
|
||||
}
|
||||
if (state === "merged") {
|
||||
return { icon: GitMergeIcon, className: "text-purple-500" };
|
||||
}
|
||||
if (state === "closed") {
|
||||
return {
|
||||
icon: GitPullRequestClosedIcon,
|
||||
className: "text-content-destructive",
|
||||
};
|
||||
}
|
||||
// state === "open"
|
||||
if (diffStatus?.pull_request_draft) {
|
||||
return {
|
||||
icon: GitPullRequestDraftIcon,
|
||||
className: "text-content-secondary",
|
||||
};
|
||||
}
|
||||
return { icon: GitPullRequestArrowIcon, className: "text-green-500" };
|
||||
};
|
||||
|
||||
const asNonEmptyString = (value: unknown): string | undefined => {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
@@ -309,8 +344,6 @@ const ChatTreeNode = memo<ChatTreeNodeProps>(({ chat, isChildNode }) => {
|
||||
);
|
||||
const hasChildren = childIDs.length > 0;
|
||||
const isDelegated = Boolean(getParentChatID(chat));
|
||||
const config = getStatusConfig(chat.status);
|
||||
const StatusIcon = config.icon;
|
||||
const isDelegatedExecuting =
|
||||
isDelegated && (chat.status === "pending" || chat.status === "running");
|
||||
const modelName = getModelDisplayName(
|
||||
@@ -324,6 +357,13 @@ const ChatTreeNode = memo<ChatTreeNodeProps>(({ chat, isChildNode }) => {
|
||||
: undefined;
|
||||
const subtitle = errorReason || modelName;
|
||||
const diffStatus = getChatDiffStatus(chat);
|
||||
const baseConfig = getStatusConfig(chat.status);
|
||||
const prConfig =
|
||||
chat.status === "waiting" || chat.status === "completed"
|
||||
? getPRIconConfig(diffStatus)
|
||||
: undefined;
|
||||
const config = prConfig ?? baseConfig;
|
||||
const StatusIcon = config.icon;
|
||||
const hasLinkedDiffStatus = Boolean(diffStatus?.url);
|
||||
const changedFiles = diffStatus?.changed_files ?? 0;
|
||||
const additions = diffStatus?.additions ?? 0;
|
||||
|
||||
@@ -226,6 +226,8 @@ index 1234567..abcdef0 100644
|
||||
|
||||
const defaultDiffStatus: ChatDiffStatusResponse = {
|
||||
chat_id: "test-chat",
|
||||
pull_request_title: "",
|
||||
pull_request_draft: false,
|
||||
changes_requested: false,
|
||||
additions: 0,
|
||||
deletions: 0,
|
||||
|
||||
Reference in New Issue
Block a user