From d545d668a0d585da16a636a68b6a137208eeb46e Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 10:57:01 -0500 Subject: [PATCH 1/9] feat: primer label component Signed-off-by: Adam Setch --- .../components/metrics/LabelsPill.test.tsx | 13 ++- .../components/metrics/LabelsPill.tsx | 41 +++++++-- .../components/metrics/MetricPill.tsx | 4 +- .../components/metrics/MilestonePill.tsx | 9 +- .../components/metrics/ReactionsPill.tsx | 9 +- src/renderer/types.ts | 7 +- src/renderer/utils/api/graphql/common.graphql | 5 ++ .../utils/api/graphql/discussion.graphql | 2 +- .../utils/api/graphql/generated/gql.ts | 24 ++--- .../utils/api/graphql/generated/graphql.ts | 88 ++++++++++++++----- src/renderer/utils/api/graphql/issue.graphql | 2 +- src/renderer/utils/api/graphql/pull.graphql | 2 +- .../notifications/handlers/discussion.test.ts | 3 +- .../notifications/handlers/discussion.ts | 6 +- .../notifications/handlers/issue.test.ts | 4 +- .../utils/notifications/handlers/issue.ts | 6 +- .../handlers/pullRequest.test.ts | 3 +- .../notifications/handlers/pullRequest.ts | 6 +- 18 files changed, 160 insertions(+), 74 deletions(-) diff --git a/src/renderer/components/metrics/LabelsPill.test.tsx b/src/renderer/components/metrics/LabelsPill.test.tsx index 9e0b0207f..0bf9541b0 100644 --- a/src/renderer/components/metrics/LabelsPill.test.tsx +++ b/src/renderer/components/metrics/LabelsPill.test.tsx @@ -1,17 +1,22 @@ +import { screen } from '@testing-library/react'; + import { renderWithAppContext } from '../../__helpers__/test-utils'; import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; import { LabelsPill } from './LabelsPill'; describe('renderer/components/metrics/LabelsPill.tsx', () => { - it('renders labels pill', () => { + it('renders labels pill count', () => { const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.labels = ['enhancement', 'good-first-issue']; + mockNotification.subject.labels = [ + { name: 'enhancement', color: 'a2eeef' }, + { name: 'good-first-issue', color: '7057ff' }, + ]; - const tree = renderWithAppContext( + renderWithAppContext( , ); - expect(tree).toMatchSnapshot(); + expect(screen.getByText('2')).toBeInTheDocument(); }); }); diff --git a/src/renderer/components/metrics/LabelsPill.tsx b/src/renderer/components/metrics/LabelsPill.tsx index 42443a1b2..30c15fb9b 100644 --- a/src/renderer/components/metrics/LabelsPill.tsx +++ b/src/renderer/components/metrics/LabelsPill.tsx @@ -1,14 +1,15 @@ import type { FC } from 'react'; import { TagIcon } from '@primer/octicons-react'; +import { IssueLabelToken } from '@primer/react'; -import { IconColor } from '../../types'; +import { type GitifyLabels, IconColor } from '../../types'; import { formatMetricDescription } from '../../utils/notifications/formatters'; import { MetricPill } from './MetricPill'; export interface LabelsPillProps { - labels: string[]; + labels: GitifyLabels[]; } export const LabelsPill: FC = ({ labels }) => { @@ -19,19 +20,45 @@ export const LabelsPill: FC = ({ labels }) => { const description = formatMetricDescription( labels.length, 'label', - (count, noun) => { - const formatted = labels.map((label) => `🏷️ ${label}`).join(', '); + (count, noun) => `${count} ${noun}`, + ); - return `${count} ${noun}: ${formatted}`; - }, + const tooltipContent = ( +
+ {description} +
+ {labels.map((label) => { + const safeColor = label.color + ? `#${String(label.color).replace(/^#/, '')}` + : undefined; + return ( + + + + ); + })} +
+
); return ( ); }; diff --git a/src/renderer/components/metrics/MetricPill.tsx b/src/renderer/components/metrics/MetricPill.tsx index 9371fe6aa..13454728b 100644 --- a/src/renderer/components/metrics/MetricPill.tsx +++ b/src/renderer/components/metrics/MetricPill.tsx @@ -1,4 +1,4 @@ -import type { FC } from 'react'; +import type { FC, ReactNode } from 'react'; import type { Icon } from '@primer/octicons-react'; import { Label, Stack, Text, Tooltip } from '@primer/react'; @@ -10,6 +10,7 @@ export interface MetricPillProps { metric?: number; icon: Icon; color: IconColor; + content?: ReactNode; } export const MetricPill: FC = (props: MetricPillProps) => { @@ -31,6 +32,7 @@ export const MetricPill: FC = (props: MetricPillProps) => { ) : null} + {props.content} ); diff --git a/src/renderer/components/metrics/MilestonePill.tsx b/src/renderer/components/metrics/MilestonePill.tsx index 431693fb0..341a1526f 100644 --- a/src/renderer/components/metrics/MilestonePill.tsx +++ b/src/renderer/components/metrics/MilestonePill.tsx @@ -2,17 +2,12 @@ import type { FC } from 'react'; import { MilestoneIcon } from '@primer/octicons-react'; -import { IconColor } from '../../types'; +import { type GitifyMilestone, IconColor } from '../../types'; import { MetricPill } from './MetricPill'; -export interface Milestone { - title: string; - state: string; -} - export interface MilestonePillProps { - milestone: Milestone; + milestone: GitifyMilestone; } export const MilestonePill: FC = ({ milestone }) => { diff --git a/src/renderer/components/metrics/ReactionsPill.tsx b/src/renderer/components/metrics/ReactionsPill.tsx index 3fd4552c6..7333f011b 100644 --- a/src/renderer/components/metrics/ReactionsPill.tsx +++ b/src/renderer/components/metrics/ReactionsPill.tsx @@ -2,19 +2,14 @@ import type { FC } from 'react'; import { SmileyIcon } from '@primer/octicons-react'; -import { IconColor } from '../../types'; +import { type GitifyReactionGroup, IconColor } from '../../types'; import { formatMetricDescription } from '../../utils/notifications/formatters'; import { MetricPill } from './MetricPill'; -export interface ReactionGroup { - content: string; - reactors: { totalCount: number }; -} - export interface ReactionsPillProps { reactionsCount: number; - reactionGroups: ReactionGroup[]; + reactionGroups: GitifyReactionGroup[]; } const reactionEmojiMap: Record = { diff --git a/src/renderer/types.ts b/src/renderer/types.ts index 9a2c8663b..41bcccd2c 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -8,6 +8,7 @@ import type { DiscussionStateReason, IssueState, IssueStateReason, + LabelFieldsFragment, MilestoneFieldsFragment, PullRequestReviewState, PullRequestState, @@ -333,8 +334,8 @@ export interface GitifySubject { linkedIssues?: string[]; /** Total comment count */ commentCount?: number; - /** Label names */ - labels?: string[]; + /** Labels names and colors */ + labels?: GitifyLabels[]; /** Milestone state/title */ milestone?: GitifyMilestone; /** Deep link to notification thread */ @@ -408,6 +409,8 @@ export type GitifyMilestone = MilestoneFieldsFragment; export type GitifyReactionGroup = ReactionGroupFieldsFragment; +export type GitifyLabels = LabelFieldsFragment; + export interface GitifyPullRequestReview { state: PullRequestReviewState; users: string[]; diff --git a/src/renderer/utils/api/graphql/common.graphql b/src/renderer/utils/api/graphql/common.graphql index 1ebdda615..a031db794 100644 --- a/src/renderer/utils/api/graphql/common.graphql +++ b/src/renderer/utils/api/graphql/common.graphql @@ -16,3 +16,8 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } + +fragment LabelFields on Label { + name + color +} diff --git a/src/renderer/utils/api/graphql/discussion.graphql b/src/renderer/utils/api/graphql/discussion.graphql index 788019024..b3826d477 100644 --- a/src/renderer/utils/api/graphql/discussion.graphql +++ b/src/renderer/utils/api/graphql/discussion.graphql @@ -34,7 +34,7 @@ fragment DiscussionDetails on Discussion { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { diff --git a/src/renderer/utils/api/graphql/generated/gql.ts b/src/renderer/utils/api/graphql/generated/gql.ts index 5d8e406bd..2e6ace7e9 100644 --- a/src/renderer/utils/api/graphql/generated/gql.ts +++ b/src/renderer/utils/api/graphql/generated/gql.ts @@ -15,32 +15,32 @@ import * as types from './graphql'; * Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size */ type Documents = { - "fragment AuthorFields on Actor {\n login\n htmlUrl: url\n avatarUrl: avatarUrl\n type: __typename\n}\n\nfragment MilestoneFields on Milestone {\n state\n title\n}\n\nfragment ReactionGroupFields on ReactionGroup {\n content\n reactors {\n totalCount\n }\n}": typeof types.AuthorFieldsFragmentDoc, - "query FetchDiscussionByNumber($owner: String!, $name: String!, $number: Int!, $lastThreadedComments: Int, $lastReplies: Int, $firstLabels: Int, $includeIsAnswered: Boolean!) {\n repository(owner: $owner, name: $name) {\n discussion(number: $number) {\n ...DiscussionDetails\n }\n }\n}\n\nfragment DiscussionDetails on Discussion {\n __typename\n number\n title\n stateReason\n isAnswered @include(if: $includeIsAnswered)\n url\n author {\n ...AuthorFields\n }\n comments(last: $lastThreadedComments) {\n totalCount\n nodes {\n ...DiscussionCommentFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment CommentFields on DiscussionComment {\n databaseId\n createdAt\n author {\n ...AuthorFields\n }\n url\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment DiscussionCommentFields on DiscussionComment {\n ...CommentFields\n replies(last: $lastReplies) {\n totalCount\n nodes {\n ...CommentFields\n }\n }\n}": typeof types.FetchDiscussionByNumberDocument, - "query FetchIssueByNumber($owner: String!, $name: String!, $number: Int!, $lastComments: Int, $firstLabels: Int) {\n repository(owner: $owner, name: $name) {\n issue(number: $number) {\n ...IssueDetails\n }\n }\n}\n\nfragment IssueDetails on Issue {\n __typename\n number\n title\n url\n state\n stateReason\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}": typeof types.FetchIssueByNumberDocument, + "fragment AuthorFields on Actor {\n login\n htmlUrl: url\n avatarUrl: avatarUrl\n type: __typename\n}\n\nfragment MilestoneFields on Milestone {\n state\n title\n}\n\nfragment ReactionGroupFields on ReactionGroup {\n content\n reactors {\n totalCount\n }\n}\n\nfragment LabelFields on Label {\n name\n color\n}": typeof types.AuthorFieldsFragmentDoc, + "query FetchDiscussionByNumber($owner: String!, $name: String!, $number: Int!, $lastThreadedComments: Int, $lastReplies: Int, $firstLabels: Int, $includeIsAnswered: Boolean!) {\n repository(owner: $owner, name: $name) {\n discussion(number: $number) {\n ...DiscussionDetails\n }\n }\n}\n\nfragment DiscussionDetails on Discussion {\n __typename\n number\n title\n stateReason\n isAnswered @include(if: $includeIsAnswered)\n url\n author {\n ...AuthorFields\n }\n comments(last: $lastThreadedComments) {\n totalCount\n nodes {\n ...DiscussionCommentFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment CommentFields on DiscussionComment {\n databaseId\n createdAt\n author {\n ...AuthorFields\n }\n url\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment DiscussionCommentFields on DiscussionComment {\n ...CommentFields\n replies(last: $lastReplies) {\n totalCount\n nodes {\n ...CommentFields\n }\n }\n}": typeof types.FetchDiscussionByNumberDocument, + "query FetchIssueByNumber($owner: String!, $name: String!, $number: Int!, $lastComments: Int, $firstLabels: Int) {\n repository(owner: $owner, name: $name) {\n issue(number: $number) {\n ...IssueDetails\n }\n }\n}\n\nfragment IssueDetails on Issue {\n __typename\n number\n title\n url\n state\n stateReason\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}": typeof types.FetchIssueByNumberDocument, "query FetchMergedDetailsTemplate($ownerINDEX: String!, $nameINDEX: String!, $numberINDEX: Int!, $isDiscussionNotificationINDEX: Boolean!, $isIssueNotificationINDEX: Boolean!, $isPullRequestNotificationINDEX: Boolean!, $lastComments: Int, $lastThreadedComments: Int, $lastReplies: Int, $lastReviews: Int, $firstLabels: Int, $firstClosingIssues: Int, $includeIsAnswered: Boolean!) {\n ...MergedDetailsQueryTemplate\n}\n\nfragment MergedDetailsQueryTemplate on Query {\n repository(owner: $ownerINDEX, name: $nameINDEX) {\n discussion(number: $numberINDEX) @include(if: $isDiscussionNotificationINDEX) {\n ...DiscussionDetails\n }\n issue(number: $numberINDEX) @include(if: $isIssueNotificationINDEX) {\n ...IssueDetails\n }\n pullRequest(number: $numberINDEX) @include(if: $isPullRequestNotificationINDEX) {\n ...PullRequestDetails\n }\n }\n}": typeof types.FetchMergedDetailsTemplateDocument, - "query FetchPullRequestByNumber($owner: String!, $name: String!, $number: Int!, $firstLabels: Int, $lastComments: Int, $lastReviews: Int, $firstClosingIssues: Int) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $number) {\n ...PullRequestDetails\n }\n }\n}\n\nfragment PullRequestDetails on PullRequest {\n __typename\n number\n title\n url\n state\n merged\n isDraft\n isInMergeQueue\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n reviews(last: $lastReviews) {\n totalCount\n nodes {\n ...PullRequestReviewFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n closingIssuesReferences(first: $firstClosingIssues) {\n nodes {\n number\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment PullRequestReviewFields on PullRequestReview {\n state\n author {\n login\n }\n}": typeof types.FetchPullRequestByNumberDocument, + "query FetchPullRequestByNumber($owner: String!, $name: String!, $number: Int!, $firstLabels: Int, $lastComments: Int, $lastReviews: Int, $firstClosingIssues: Int) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $number) {\n ...PullRequestDetails\n }\n }\n}\n\nfragment PullRequestDetails on PullRequest {\n __typename\n number\n title\n url\n state\n merged\n isDraft\n isInMergeQueue\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n reviews(last: $lastReviews) {\n totalCount\n nodes {\n ...PullRequestReviewFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n closingIssuesReferences(first: $firstClosingIssues) {\n nodes {\n number\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment PullRequestReviewFields on PullRequestReview {\n state\n author {\n login\n }\n}": typeof types.FetchPullRequestByNumberDocument, }; const documents: Documents = { - "fragment AuthorFields on Actor {\n login\n htmlUrl: url\n avatarUrl: avatarUrl\n type: __typename\n}\n\nfragment MilestoneFields on Milestone {\n state\n title\n}\n\nfragment ReactionGroupFields on ReactionGroup {\n content\n reactors {\n totalCount\n }\n}": types.AuthorFieldsFragmentDoc, - "query FetchDiscussionByNumber($owner: String!, $name: String!, $number: Int!, $lastThreadedComments: Int, $lastReplies: Int, $firstLabels: Int, $includeIsAnswered: Boolean!) {\n repository(owner: $owner, name: $name) {\n discussion(number: $number) {\n ...DiscussionDetails\n }\n }\n}\n\nfragment DiscussionDetails on Discussion {\n __typename\n number\n title\n stateReason\n isAnswered @include(if: $includeIsAnswered)\n url\n author {\n ...AuthorFields\n }\n comments(last: $lastThreadedComments) {\n totalCount\n nodes {\n ...DiscussionCommentFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment CommentFields on DiscussionComment {\n databaseId\n createdAt\n author {\n ...AuthorFields\n }\n url\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment DiscussionCommentFields on DiscussionComment {\n ...CommentFields\n replies(last: $lastReplies) {\n totalCount\n nodes {\n ...CommentFields\n }\n }\n}": types.FetchDiscussionByNumberDocument, - "query FetchIssueByNumber($owner: String!, $name: String!, $number: Int!, $lastComments: Int, $firstLabels: Int) {\n repository(owner: $owner, name: $name) {\n issue(number: $number) {\n ...IssueDetails\n }\n }\n}\n\nfragment IssueDetails on Issue {\n __typename\n number\n title\n url\n state\n stateReason\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}": types.FetchIssueByNumberDocument, + "fragment AuthorFields on Actor {\n login\n htmlUrl: url\n avatarUrl: avatarUrl\n type: __typename\n}\n\nfragment MilestoneFields on Milestone {\n state\n title\n}\n\nfragment ReactionGroupFields on ReactionGroup {\n content\n reactors {\n totalCount\n }\n}\n\nfragment LabelFields on Label {\n name\n color\n}": types.AuthorFieldsFragmentDoc, + "query FetchDiscussionByNumber($owner: String!, $name: String!, $number: Int!, $lastThreadedComments: Int, $lastReplies: Int, $firstLabels: Int, $includeIsAnswered: Boolean!) {\n repository(owner: $owner, name: $name) {\n discussion(number: $number) {\n ...DiscussionDetails\n }\n }\n}\n\nfragment DiscussionDetails on Discussion {\n __typename\n number\n title\n stateReason\n isAnswered @include(if: $includeIsAnswered)\n url\n author {\n ...AuthorFields\n }\n comments(last: $lastThreadedComments) {\n totalCount\n nodes {\n ...DiscussionCommentFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment CommentFields on DiscussionComment {\n databaseId\n createdAt\n author {\n ...AuthorFields\n }\n url\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment DiscussionCommentFields on DiscussionComment {\n ...CommentFields\n replies(last: $lastReplies) {\n totalCount\n nodes {\n ...CommentFields\n }\n }\n}": types.FetchDiscussionByNumberDocument, + "query FetchIssueByNumber($owner: String!, $name: String!, $number: Int!, $lastComments: Int, $firstLabels: Int) {\n repository(owner: $owner, name: $name) {\n issue(number: $number) {\n ...IssueDetails\n }\n }\n}\n\nfragment IssueDetails on Issue {\n __typename\n number\n title\n url\n state\n stateReason\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}": types.FetchIssueByNumberDocument, "query FetchMergedDetailsTemplate($ownerINDEX: String!, $nameINDEX: String!, $numberINDEX: Int!, $isDiscussionNotificationINDEX: Boolean!, $isIssueNotificationINDEX: Boolean!, $isPullRequestNotificationINDEX: Boolean!, $lastComments: Int, $lastThreadedComments: Int, $lastReplies: Int, $lastReviews: Int, $firstLabels: Int, $firstClosingIssues: Int, $includeIsAnswered: Boolean!) {\n ...MergedDetailsQueryTemplate\n}\n\nfragment MergedDetailsQueryTemplate on Query {\n repository(owner: $ownerINDEX, name: $nameINDEX) {\n discussion(number: $numberINDEX) @include(if: $isDiscussionNotificationINDEX) {\n ...DiscussionDetails\n }\n issue(number: $numberINDEX) @include(if: $isIssueNotificationINDEX) {\n ...IssueDetails\n }\n pullRequest(number: $numberINDEX) @include(if: $isPullRequestNotificationINDEX) {\n ...PullRequestDetails\n }\n }\n}": types.FetchMergedDetailsTemplateDocument, - "query FetchPullRequestByNumber($owner: String!, $name: String!, $number: Int!, $firstLabels: Int, $lastComments: Int, $lastReviews: Int, $firstClosingIssues: Int) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $number) {\n ...PullRequestDetails\n }\n }\n}\n\nfragment PullRequestDetails on PullRequest {\n __typename\n number\n title\n url\n state\n merged\n isDraft\n isInMergeQueue\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n reviews(last: $lastReviews) {\n totalCount\n nodes {\n ...PullRequestReviewFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n closingIssuesReferences(first: $firstClosingIssues) {\n nodes {\n number\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment PullRequestReviewFields on PullRequestReview {\n state\n author {\n login\n }\n}": types.FetchPullRequestByNumberDocument, + "query FetchPullRequestByNumber($owner: String!, $name: String!, $number: Int!, $firstLabels: Int, $lastComments: Int, $lastReviews: Int, $firstClosingIssues: Int) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $number) {\n ...PullRequestDetails\n }\n }\n}\n\nfragment PullRequestDetails on PullRequest {\n __typename\n number\n title\n url\n state\n merged\n isDraft\n isInMergeQueue\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n reviews(last: $lastReviews) {\n totalCount\n nodes {\n ...PullRequestReviewFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n closingIssuesReferences(first: $firstClosingIssues) {\n nodes {\n number\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment PullRequestReviewFields on PullRequestReview {\n state\n author {\n login\n }\n}": types.FetchPullRequestByNumberDocument, }; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "fragment AuthorFields on Actor {\n login\n htmlUrl: url\n avatarUrl: avatarUrl\n type: __typename\n}\n\nfragment MilestoneFields on Milestone {\n state\n title\n}\n\nfragment ReactionGroupFields on ReactionGroup {\n content\n reactors {\n totalCount\n }\n}"): typeof import('./graphql').AuthorFieldsFragmentDoc; +export function graphql(source: "fragment AuthorFields on Actor {\n login\n htmlUrl: url\n avatarUrl: avatarUrl\n type: __typename\n}\n\nfragment MilestoneFields on Milestone {\n state\n title\n}\n\nfragment ReactionGroupFields on ReactionGroup {\n content\n reactors {\n totalCount\n }\n}\n\nfragment LabelFields on Label {\n name\n color\n}"): typeof import('./graphql').AuthorFieldsFragmentDoc; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query FetchDiscussionByNumber($owner: String!, $name: String!, $number: Int!, $lastThreadedComments: Int, $lastReplies: Int, $firstLabels: Int, $includeIsAnswered: Boolean!) {\n repository(owner: $owner, name: $name) {\n discussion(number: $number) {\n ...DiscussionDetails\n }\n }\n}\n\nfragment DiscussionDetails on Discussion {\n __typename\n number\n title\n stateReason\n isAnswered @include(if: $includeIsAnswered)\n url\n author {\n ...AuthorFields\n }\n comments(last: $lastThreadedComments) {\n totalCount\n nodes {\n ...DiscussionCommentFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment CommentFields on DiscussionComment {\n databaseId\n createdAt\n author {\n ...AuthorFields\n }\n url\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment DiscussionCommentFields on DiscussionComment {\n ...CommentFields\n replies(last: $lastReplies) {\n totalCount\n nodes {\n ...CommentFields\n }\n }\n}"): typeof import('./graphql').FetchDiscussionByNumberDocument; +export function graphql(source: "query FetchDiscussionByNumber($owner: String!, $name: String!, $number: Int!, $lastThreadedComments: Int, $lastReplies: Int, $firstLabels: Int, $includeIsAnswered: Boolean!) {\n repository(owner: $owner, name: $name) {\n discussion(number: $number) {\n ...DiscussionDetails\n }\n }\n}\n\nfragment DiscussionDetails on Discussion {\n __typename\n number\n title\n stateReason\n isAnswered @include(if: $includeIsAnswered)\n url\n author {\n ...AuthorFields\n }\n comments(last: $lastThreadedComments) {\n totalCount\n nodes {\n ...DiscussionCommentFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment CommentFields on DiscussionComment {\n databaseId\n createdAt\n author {\n ...AuthorFields\n }\n url\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment DiscussionCommentFields on DiscussionComment {\n ...CommentFields\n replies(last: $lastReplies) {\n totalCount\n nodes {\n ...CommentFields\n }\n }\n}"): typeof import('./graphql').FetchDiscussionByNumberDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query FetchIssueByNumber($owner: String!, $name: String!, $number: Int!, $lastComments: Int, $firstLabels: Int) {\n repository(owner: $owner, name: $name) {\n issue(number: $number) {\n ...IssueDetails\n }\n }\n}\n\nfragment IssueDetails on Issue {\n __typename\n number\n title\n url\n state\n stateReason\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}"): typeof import('./graphql').FetchIssueByNumberDocument; +export function graphql(source: "query FetchIssueByNumber($owner: String!, $name: String!, $number: Int!, $lastComments: Int, $firstLabels: Int) {\n repository(owner: $owner, name: $name) {\n issue(number: $number) {\n ...IssueDetails\n }\n }\n}\n\nfragment IssueDetails on Issue {\n __typename\n number\n title\n url\n state\n stateReason\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}"): typeof import('./graphql').FetchIssueByNumberDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -48,7 +48,7 @@ export function graphql(source: "query FetchMergedDetailsTemplate($ownerINDEX: S /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query FetchPullRequestByNumber($owner: String!, $name: String!, $number: Int!, $firstLabels: Int, $lastComments: Int, $lastReviews: Int, $firstClosingIssues: Int) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $number) {\n ...PullRequestDetails\n }\n }\n}\n\nfragment PullRequestDetails on PullRequest {\n __typename\n number\n title\n url\n state\n merged\n isDraft\n isInMergeQueue\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n reviews(last: $lastReviews) {\n totalCount\n nodes {\n ...PullRequestReviewFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n name\n }\n }\n closingIssuesReferences(first: $firstClosingIssues) {\n nodes {\n number\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment PullRequestReviewFields on PullRequestReview {\n state\n author {\n login\n }\n}"): typeof import('./graphql').FetchPullRequestByNumberDocument; +export function graphql(source: "query FetchPullRequestByNumber($owner: String!, $name: String!, $number: Int!, $firstLabels: Int, $lastComments: Int, $lastReviews: Int, $firstClosingIssues: Int) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $number) {\n ...PullRequestDetails\n }\n }\n}\n\nfragment PullRequestDetails on PullRequest {\n __typename\n number\n title\n url\n state\n merged\n isDraft\n isInMergeQueue\n milestone {\n ...MilestoneFields\n }\n author {\n ...AuthorFields\n }\n comments(last: $lastComments) {\n totalCount\n nodes {\n url\n author {\n ...AuthorFields\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n }\n }\n reviews(last: $lastReviews) {\n totalCount\n nodes {\n ...PullRequestReviewFields\n }\n }\n labels(first: $firstLabels) {\n nodes {\n ...LabelFields\n }\n }\n closingIssuesReferences(first: $firstClosingIssues) {\n nodes {\n number\n }\n }\n reactions {\n totalCount\n }\n reactionGroups {\n ...ReactionGroupFields\n }\n}\n\nfragment PullRequestReviewFields on PullRequestReview {\n state\n author {\n login\n }\n}"): typeof import('./graphql').FetchPullRequestByNumberDocument; export function graphql(source: string) { diff --git a/src/renderer/utils/api/graphql/generated/graphql.ts b/src/renderer/utils/api/graphql/generated/graphql.ts index e21b6c025..e628c6e8a 100644 --- a/src/renderer/utils/api/graphql/generated/graphql.ts +++ b/src/renderer/utils/api/graphql/generated/graphql.ts @@ -35608,6 +35608,8 @@ export type MilestoneFieldsFragment = { __typename?: 'Milestone', state: Milesto export type ReactionGroupFieldsFragment = { __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }; +export type LabelFieldsFragment = { __typename?: 'Label', name: string, color: string }; + export type FetchDiscussionByNumberQueryVariables = Exact<{ owner: Scalars['String']['input']; name: Scalars['String']['input']; @@ -35637,7 +35639,7 @@ export type FetchDiscussionByNumberQuery = { __typename?: 'Query', repository?: | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; export type DiscussionDetailsFragment = { __typename: 'Discussion', number: number, title: string, stateReason?: DiscussionStateReason | null, isAnswered?: boolean | null, url: any, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } @@ -35657,7 +35659,7 @@ export type DiscussionDetailsFragment = { __typename: 'Discussion', number: numb | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null }; + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null }; export type CommentFieldsFragment = { __typename?: 'DiscussionComment', databaseId?: number | null, createdAt: any, url: any, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } @@ -35702,7 +35704,7 @@ export type FetchIssueByNumberQuery = { __typename?: 'Query', repository?: { __t | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; export type IssueDetailsFragment = { __typename: 'Issue', number: number, title: string, url: any, state: IssueState, stateReason?: IssueStateReason | null, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } @@ -35716,7 +35718,7 @@ export type IssueDetailsFragment = { __typename: 'Issue', number: number, title: | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null }; + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null }; export type FetchMergedDetailsTemplateQueryVariables = Exact<{ ownerINDEX: Scalars['String']['input']; @@ -35753,7 +35755,7 @@ export type FetchMergedDetailsTemplateQuery = { __typename?: 'Query', repository | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, issue?: { __typename: 'Issue', number: number, title: string, url: any, state: IssueState, stateReason?: IssueStateReason | null, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, issue?: { __typename: 'Issue', number: number, title: string, url: any, state: IssueState, stateReason?: IssueStateReason | null, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } | { __typename?: 'EnterpriseUserAccount', login: string, htmlUrl: any, avatarUrl: any, type: 'EnterpriseUserAccount' } | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } @@ -35765,7 +35767,7 @@ export type FetchMergedDetailsTemplateQuery = { __typename?: 'Query', repository | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, pullRequest?: { __typename: 'PullRequest', number: number, title: string, url: any, state: PullRequestState, merged: boolean, isDraft: boolean, isInMergeQueue: boolean, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, pullRequest?: { __typename: 'PullRequest', number: number, title: string, url: any, state: PullRequestState, merged: boolean, isDraft: boolean, isInMergeQueue: boolean, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } | { __typename?: 'EnterpriseUserAccount', login: string, htmlUrl: any, avatarUrl: any, type: 'EnterpriseUserAccount' } | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } @@ -35783,7 +35785,7 @@ export type FetchMergedDetailsTemplateQuery = { __typename?: 'Query', repository | { __typename?: 'Mannequin', login: string } | { __typename?: 'Organization', login: string } | { __typename?: 'User', login: string } - | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; + | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; export type MergedDetailsQueryTemplateFragment = { __typename?: 'Query', repository?: { __typename?: 'Repository', discussion?: { __typename: 'Discussion', number: number, title: string, stateReason?: DiscussionStateReason | null, isAnswered?: boolean | null, url: any, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } @@ -35803,7 +35805,7 @@ export type MergedDetailsQueryTemplateFragment = { __typename?: 'Query', reposit | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, issue?: { __typename: 'Issue', number: number, title: string, url: any, state: IssueState, stateReason?: IssueStateReason | null, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, issue?: { __typename: 'Issue', number: number, title: string, url: any, state: IssueState, stateReason?: IssueStateReason | null, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } | { __typename?: 'EnterpriseUserAccount', login: string, htmlUrl: any, avatarUrl: any, type: 'EnterpriseUserAccount' } | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } @@ -35815,7 +35817,7 @@ export type MergedDetailsQueryTemplateFragment = { __typename?: 'Query', reposit | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } | { __typename?: 'Organization', login: string, htmlUrl: any, avatarUrl: any, type: 'Organization' } | { __typename?: 'User', login: string, htmlUrl: any, avatarUrl: any, type: 'User' } - | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, pullRequest?: { __typename: 'PullRequest', number: number, title: string, url: any, state: PullRequestState, merged: boolean, isDraft: boolean, isInMergeQueue: boolean, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: + | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null> | null }, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null, pullRequest?: { __typename: 'PullRequest', number: number, title: string, url: any, state: PullRequestState, merged: boolean, isDraft: boolean, isInMergeQueue: boolean, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } | { __typename?: 'EnterpriseUserAccount', login: string, htmlUrl: any, avatarUrl: any, type: 'EnterpriseUserAccount' } | { __typename?: 'Mannequin', login: string, htmlUrl: any, avatarUrl: any, type: 'Mannequin' } @@ -35833,7 +35835,7 @@ export type MergedDetailsQueryTemplateFragment = { __typename?: 'Query', reposit | { __typename?: 'Mannequin', login: string } | { __typename?: 'Organization', login: string } | { __typename?: 'User', login: string } - | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; + | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; export type FetchPullRequestByNumberQueryVariables = Exact<{ owner: Scalars['String']['input']; @@ -35864,7 +35866,7 @@ export type FetchPullRequestByNumberQuery = { __typename?: 'Query', repository?: | { __typename?: 'Mannequin', login: string } | { __typename?: 'Organization', login: string } | { __typename?: 'User', login: string } - | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; + | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null } | null } | null }; export type PullRequestDetailsFragment = { __typename: 'PullRequest', number: number, title: string, url: any, state: PullRequestState, merged: boolean, isDraft: boolean, isInMergeQueue: boolean, milestone?: { __typename?: 'Milestone', state: MilestoneState, title: string } | null, author?: | { __typename?: 'Bot', login: string, htmlUrl: any, avatarUrl: any, type: 'Bot' } @@ -35884,7 +35886,7 @@ export type PullRequestDetailsFragment = { __typename: 'PullRequest', number: nu | { __typename?: 'Mannequin', login: string } | { __typename?: 'Organization', login: string } | { __typename?: 'User', login: string } - | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null }; + | null } | null> | null } | null, labels?: { __typename?: 'LabelConnection', nodes?: Array<{ __typename?: 'Label', name: string, color: string } | null> | null } | null, closingIssuesReferences?: { __typename?: 'IssueConnection', nodes?: Array<{ __typename?: 'Issue', number: number } | null> | null } | null, reactions: { __typename?: 'ReactionConnection', totalCount: number }, reactionGroups?: Array<{ __typename?: 'ReactionGroup', content: ReactionContent, reactors: { __typename?: 'ReactorConnection', totalCount: number } }> | null }; export type PullRequestReviewFieldsFragment = { __typename?: 'PullRequestReview', state: PullRequestReviewState, author?: | { __typename?: 'Bot', login: string } @@ -35991,6 +35993,12 @@ fragment CommentFields on DiscussionComment { ...ReactionGroupFields } }`, {"fragmentName":"DiscussionCommentFields"}) as unknown as TypedDocumentString; +export const LabelFieldsFragmentDoc = new TypedDocumentString(` + fragment LabelFields on Label { + name + color +} + `, {"fragmentName":"LabelFields"}) as unknown as TypedDocumentString; export const DiscussionDetailsFragmentDoc = new TypedDocumentString(` fragment DiscussionDetails on Discussion { __typename @@ -36010,7 +36018,7 @@ export const DiscussionDetailsFragmentDoc = new TypedDocumentString(` } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36032,6 +36040,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment CommentFields on DiscussionComment { databaseId createdAt @@ -36092,7 +36104,7 @@ export const IssueDetailsFragmentDoc = new TypedDocumentString(` } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36117,6 +36129,10 @@ fragment ReactionGroupFields on ReactionGroup { reactors { totalCount } +} +fragment LabelFields on Label { + name + color }`, {"fragmentName":"IssueDetails"}) as unknown as TypedDocumentString; export const PullRequestReviewFieldsFragmentDoc = new TypedDocumentString(` fragment PullRequestReviewFields on PullRequestReview { @@ -36165,7 +36181,7 @@ export const PullRequestDetailsFragmentDoc = new TypedDocumentString(` } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } closingIssuesReferences(first: $firstClosingIssues) { @@ -36196,6 +36212,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment PullRequestReviewFields on PullRequestReview { state author { @@ -36232,6 +36252,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment DiscussionDetails on Discussion { __typename number @@ -36250,7 +36274,7 @@ fragment DiscussionDetails on Discussion { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36313,7 +36337,7 @@ fragment IssueDetails on Issue { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36361,7 +36385,7 @@ fragment PullRequestDetails on PullRequest { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } closingIssuesReferences(first: $firstClosingIssues) { @@ -36402,6 +36426,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment DiscussionDetails on Discussion { __typename number @@ -36420,7 +36448,7 @@ fragment DiscussionDetails on Discussion { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36477,6 +36505,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment IssueDetails on Issue { __typename number @@ -36507,7 +36539,7 @@ fragment IssueDetails on Issue { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36537,6 +36569,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment DiscussionDetails on Discussion { __typename number @@ -36555,7 +36591,7 @@ fragment DiscussionDetails on Discussion { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36618,7 +36654,7 @@ fragment IssueDetails on Issue { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { @@ -36679,7 +36715,7 @@ fragment PullRequestDetails on PullRequest { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } closingIssuesReferences(first: $firstClosingIssues) { @@ -36724,6 +36760,10 @@ fragment ReactionGroupFields on ReactionGroup { totalCount } } +fragment LabelFields on Label { + name + color +} fragment PullRequestDetails on PullRequest { __typename number @@ -36762,7 +36802,7 @@ fragment PullRequestDetails on PullRequest { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } closingIssuesReferences(first: $firstClosingIssues) { diff --git a/src/renderer/utils/api/graphql/issue.graphql b/src/renderer/utils/api/graphql/issue.graphql index 4c36aac4b..34743d0f3 100644 --- a/src/renderer/utils/api/graphql/issue.graphql +++ b/src/renderer/utils/api/graphql/issue.graphql @@ -44,7 +44,7 @@ fragment IssueDetails on Issue { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } reactions { diff --git a/src/renderer/utils/api/graphql/pull.graphql b/src/renderer/utils/api/graphql/pull.graphql index 89b86fd53..0302ecb27 100644 --- a/src/renderer/utils/api/graphql/pull.graphql +++ b/src/renderer/utils/api/graphql/pull.graphql @@ -54,7 +54,7 @@ fragment PullRequestDetails on PullRequest { } labels(first: $firstLabels) { nodes { - name + ...LabelFields } } closingIssuesReferences(first: $firstClosingIssues) { diff --git a/src/renderer/utils/notifications/handlers/discussion.test.ts b/src/renderer/utils/notifications/handlers/discussion.test.ts index 969f95c5e..f53b39b95 100644 --- a/src/renderer/utils/notifications/handlers/discussion.test.ts +++ b/src/renderer/utils/notifications/handlers/discussion.test.ts @@ -150,6 +150,7 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { nodes: [ { name: 'enhancement', + color: '0e8a16', }, ], }; @@ -175,7 +176,7 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { type: mockAuthor.type, }, commentCount: 0, - labels: ['enhancement'], + labels: [{ name: 'enhancement', color: '0e8a16' }], htmlUrl: 'https://github.com/gitify-app/notifications-test/discussions/123' as Link, reactionsCount: 0, diff --git a/src/renderer/utils/notifications/handlers/discussion.ts b/src/renderer/utils/notifications/handlers/discussion.ts index 0c4c2a919..875b5aa14 100644 --- a/src/renderer/utils/notifications/handlers/discussion.ts +++ b/src/renderer/utils/notifications/handlers/discussion.ts @@ -71,7 +71,11 @@ class DiscussionHandler extends DefaultHandler { discussion.author, ]), commentCount: discussion.comments.totalCount, - labels: discussion.labels?.nodes.map((label) => label.name) ?? [], + labels: + discussion.labels?.nodes.map((label) => ({ + name: label.name, + color: (label as any).color, + })) ?? [], htmlUrl: latestDiscussionComment?.url ?? discussion.url, reactionsCount: discussionReactionCount, reactionGroups: discussionReactionGroup, diff --git a/src/renderer/utils/notifications/handlers/issue.test.ts b/src/renderer/utils/notifications/handlers/issue.test.ts index 35c1249ea..621386851 100644 --- a/src/renderer/utils/notifications/handlers/issue.test.ts +++ b/src/renderer/utils/notifications/handlers/issue.test.ts @@ -151,7 +151,7 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { state: 'OPEN', }); mockIssue.labels = { - nodes: [{ name: 'enhancement' }], + nodes: [{ name: 'enhancement', color: '0e8a16' }], }; fetchIssueByNumberSpy.mockResolvedValue({ @@ -174,7 +174,7 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { commentCount: 0, htmlUrl: 'https://github.com/gitify-app/notifications-test/issues/123' as Link, - labels: ['enhancement'], + labels: [{ name: 'enhancement', color: '0e8a16' }], milestone: undefined, reactionsCount: 0, reactionGroups: noReactionGroups, diff --git a/src/renderer/utils/notifications/handlers/issue.ts b/src/renderer/utils/notifications/handlers/issue.ts index 7b50592c6..0297ebe8b 100644 --- a/src/renderer/utils/notifications/handlers/issue.ts +++ b/src/renderer/utils/notifications/handlers/issue.ts @@ -54,7 +54,11 @@ class IssueHandler extends DefaultHandler { state: issueState, user: issueUser, commentCount: issue.comments.totalCount, - labels: issue.labels?.nodes.map((label) => label.name) ?? [], + labels: + issue.labels?.nodes.map((label) => ({ + name: label.name, + color: (label as any).color, + })) ?? [], milestone: issue.milestone ?? undefined, htmlUrl: issueComment?.url ?? issue.url, reactionsCount: issueReactionCount, diff --git a/src/renderer/utils/notifications/handlers/pullRequest.test.ts b/src/renderer/utils/notifications/handlers/pullRequest.test.ts index 8f0e26d42..f34764afd 100644 --- a/src/renderer/utils/notifications/handlers/pullRequest.test.ts +++ b/src/renderer/utils/notifications/handlers/pullRequest.test.ts @@ -248,6 +248,7 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { nodes: [ { name: 'enhancement', + color: '0e8a16', }, ], }; @@ -273,7 +274,7 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { type: mockAuthor.type, }, reviews: null, - labels: ['enhancement'], + labels: [{ name: 'enhancement', color: '0e8a16' }], linkedIssues: [], commentCount: 0, milestone: null, diff --git a/src/renderer/utils/notifications/handlers/pullRequest.ts b/src/renderer/utils/notifications/handlers/pullRequest.ts index d8c8b5400..34da1041e 100644 --- a/src/renderer/utils/notifications/handlers/pullRequest.ts +++ b/src/renderer/utils/notifications/handlers/pullRequest.ts @@ -65,7 +65,11 @@ class PullRequestHandler extends DefaultHandler { user: prUser, reviews: reviews, commentCount: pr.comments.totalCount, - labels: pr.labels?.nodes.map((label) => label.name) ?? [], + labels: + pr.labels?.nodes.map((label) => ({ + name: label.name, + color: (label as any).color, + })) ?? [], linkedIssues: pr.closingIssuesReferences?.nodes.map((issue) => formatGitHubNumber(issue.number), ), From 58a6df06810a296cba5f31d2e9fdc360046781e2 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 11:15:59 -0500 Subject: [PATCH 2/9] feat: primer label component Signed-off-by: Adam Setch --- .../components/metrics/LabelsPill.tsx | 63 +++++-------------- .../components/metrics/MetricGroup.tsx | 4 +- 2 files changed, 18 insertions(+), 49 deletions(-) diff --git a/src/renderer/components/metrics/LabelsPill.tsx b/src/renderer/components/metrics/LabelsPill.tsx index 30c15fb9b..a79202e31 100644 --- a/src/renderer/components/metrics/LabelsPill.tsx +++ b/src/renderer/components/metrics/LabelsPill.tsx @@ -1,12 +1,8 @@ import type { FC } from 'react'; -import { TagIcon } from '@primer/octicons-react'; import { IssueLabelToken } from '@primer/react'; -import { type GitifyLabels, IconColor } from '../../types'; - -import { formatMetricDescription } from '../../utils/notifications/formatters'; -import { MetricPill } from './MetricPill'; +import type { GitifyLabels } from '../../types'; export interface LabelsPillProps { labels: GitifyLabels[]; @@ -17,48 +13,21 @@ export const LabelsPill: FC = ({ labels }) => { return null; } - const description = formatMetricDescription( - labels.length, - 'label', - (count, noun) => `${count} ${noun}`, - ); - - const tooltipContent = ( -
- {description} -
- {labels.map((label) => { - const safeColor = label.color - ? `#${String(label.color).replace(/^#/, '')}` - : undefined; - return ( - - - - ); - })} -
-
+ const labelsContent = ( + <> + {labels.map((label) => { + return ( + + ); + })} + ); - return ( - - ); + return labelsContent; }; diff --git a/src/renderer/components/metrics/MetricGroup.tsx b/src/renderer/components/metrics/MetricGroup.tsx index 7661be473..1dde4cdca 100644 --- a/src/renderer/components/metrics/MetricGroup.tsx +++ b/src/renderer/components/metrics/MetricGroup.tsx @@ -37,9 +37,9 @@ export const MetricGroup: FC = ({ notification }) => { - - + + ); }; From c1ba50eb088b1ff2cacbc8825c51b1bffb09f02a Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 11:27:19 -0500 Subject: [PATCH 3/9] feat: primer label component Signed-off-by: Adam Setch --- src/renderer/components/metrics/LabelsPill.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/metrics/LabelsPill.tsx b/src/renderer/components/metrics/LabelsPill.tsx index a79202e31..54f2454f3 100644 --- a/src/renderer/components/metrics/LabelsPill.tsx +++ b/src/renderer/components/metrics/LabelsPill.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; -import { IssueLabelToken } from '@primer/react'; +import { IssueLabelToken, LabelGroup } from '@primer/react'; import type { GitifyLabels } from '../../types'; @@ -14,7 +14,7 @@ export const LabelsPill: FC = ({ labels }) => { } const labelsContent = ( - <> + {labels.map((label) => { return ( = ({ labels }) => { /> ); })} - + ); return labelsContent; From cd64bdf8e81e3331a0d2db2ce1cea5d838a814fd Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 11:37:03 -0500 Subject: [PATCH 4/9] feat: primer label component Signed-off-by: Adam Setch --- src/renderer/components/metrics/LabelsPill.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/components/metrics/LabelsPill.tsx b/src/renderer/components/metrics/LabelsPill.tsx index 54f2454f3..bae716f81 100644 --- a/src/renderer/components/metrics/LabelsPill.tsx +++ b/src/renderer/components/metrics/LabelsPill.tsx @@ -18,7 +18,6 @@ export const LabelsPill: FC = ({ labels }) => { {labels.map((label) => { return ( Date: Fri, 30 Jan 2026 12:06:42 -0500 Subject: [PATCH 5/9] feat: primer label component Signed-off-by: Adam Setch --- .../components/metrics/CommentsPill.test.tsx | 28 +- .../components/metrics/LabelsPill.test.tsx | 32 +- .../metrics/LinkedIssuesPill.test.tsx | 28 +- .../components/metrics/MetricGroup.test.tsx | 31 +- .../components/metrics/MilestonePill.test.tsx | 45 +-- .../components/metrics/ReactionsPill.test.tsx | 71 ++-- .../components/metrics/ReviewsPill.test.tsx | 15 +- .../__snapshots__/LabelsPill.test.tsx.snap | 114 +------ .../LinkedIssuesPill.test.tsx.snap | 83 +++++ .../__snapshots__/MetricGroup.test.tsx.snap | 307 +++++++++++++++++- .../__snapshots__/MilestonePill.test.tsx.snap | 83 +++++ .../__snapshots__/ReactionsPill.test.tsx.snap | 274 ++++++++++++++++ src/renderer/utils/api/graphql/utils.test.ts | 9 +- 13 files changed, 889 insertions(+), 231 deletions(-) diff --git a/src/renderer/components/metrics/CommentsPill.test.tsx b/src/renderer/components/metrics/CommentsPill.test.tsx index 58d0eaa6d..2b4180c88 100644 --- a/src/renderer/components/metrics/CommentsPill.test.tsx +++ b/src/renderer/components/metrics/CommentsPill.test.tsx @@ -1,38 +1,32 @@ import { renderWithAppContext } from '../../__helpers__/test-utils'; -import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; -import { CommentsPill } from './CommentsPill'; +import { CommentsPill, type CommentsPillProps } from './CommentsPill'; describe('renderer/components/metrics/CommentsPill.tsx', () => { it('renders with no comments (null)', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.commentCount = null; + const props: CommentsPillProps = null; - const tree = renderWithAppContext( - , - ); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); it('renders with 1 comment', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.commentCount = 1; + const props: CommentsPillProps = { + commentCount: 1, + }; - const tree = renderWithAppContext( - , - ); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); it('renders with multiple comments', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.commentCount = 2; + const props: CommentsPillProps = { + commentCount: 2, + }; - const tree = renderWithAppContext( - , - ); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); diff --git a/src/renderer/components/metrics/LabelsPill.test.tsx b/src/renderer/components/metrics/LabelsPill.test.tsx index 0bf9541b0..02c39ca9b 100644 --- a/src/renderer/components/metrics/LabelsPill.test.tsx +++ b/src/renderer/components/metrics/LabelsPill.test.tsx @@ -1,22 +1,26 @@ -import { screen } from '@testing-library/react'; - import { renderWithAppContext } from '../../__helpers__/test-utils'; -import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; -import { LabelsPill } from './LabelsPill'; +import { LabelsPill, type LabelsPillProps } from './LabelsPill'; describe('renderer/components/metrics/LabelsPill.tsx', () => { - it('renders labels pill count', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.labels = [ - { name: 'enhancement', color: 'a2eeef' }, - { name: 'good-first-issue', color: '7057ff' }, - ]; + it('renders without labels', () => { + const props: LabelsPillProps = { labels: [] }; + + const tree = renderWithAppContext(); + + expect(tree).toMatchSnapshot(); + }); + + it('renders with labels', () => { + const props: LabelsPillProps = { + labels: [ + { name: 'enhancement', color: 'a2eeef' }, + { name: 'good-first-issue', color: '7057ff' }, + ], + }; - renderWithAppContext( - , - ); + const tree = renderWithAppContext(); - expect(screen.getByText('2')).toBeInTheDocument(); + expect(tree).toMatchSnapshot(); }); }); diff --git a/src/renderer/components/metrics/LinkedIssuesPill.test.tsx b/src/renderer/components/metrics/LinkedIssuesPill.test.tsx index 8b2d90d2f..3f50254ad 100644 --- a/src/renderer/components/metrics/LinkedIssuesPill.test.tsx +++ b/src/renderer/components/metrics/LinkedIssuesPill.test.tsx @@ -1,27 +1,31 @@ import { renderWithAppContext } from '../../__helpers__/test-utils'; -import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; -import { LinkedIssuesPill } from './LinkedIssuesPill'; +import { + LinkedIssuesPill, + type LinkedIssuesPillProps, +} from './LinkedIssuesPill'; describe('renderer/components/metrics/LinkedIssuesPill.tsx', () => { + it('renders when no linked issues/prs', () => { + const props: LinkedIssuesPillProps = { linkedIssues: [] }; + + const tree = renderWithAppContext(); + + expect(tree).toMatchSnapshot(); + }); + it('renders when linked to one issue/pr', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.linkedIssues = ['#1']; + const props: LinkedIssuesPillProps = { linkedIssues: ['#1'] }; - const tree = renderWithAppContext( - , - ); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); it('renders when linked to multiple issues/prs', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.linkedIssues = ['#1', '#2']; + const props: LinkedIssuesPillProps = { linkedIssues: ['#1', '#2'] }; - const tree = renderWithAppContext( - , - ); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); diff --git a/src/renderer/components/metrics/MetricGroup.test.tsx b/src/renderer/components/metrics/MetricGroup.test.tsx index e94a216cc..4450d8a1f 100644 --- a/src/renderer/components/metrics/MetricGroup.test.tsx +++ b/src/renderer/components/metrics/MetricGroup.test.tsx @@ -5,18 +5,29 @@ import { mockSettings } from '../../__mocks__/state-mocks'; import { MetricGroup, type MetricGroupProps } from './MetricGroup'; describe('renderer/components/metrics/MetricGroup.tsx', () => { - describe('showPills disabled', () => { - it('should not render any pills when showPills is disabled', async () => { - const mockNotification = mockGitifyNotification; - const props: MetricGroupProps = { - notification: mockNotification, - }; + it('should not render any pills when showPills is disabled', async () => { + const mockNotification = mockGitifyNotification; + const props: MetricGroupProps = { + notification: mockNotification, + }; - const tree = renderWithAppContext(, { - settings: { ...mockSettings, showPills: false }, - }); + const tree = renderWithAppContext(, { + settings: { ...mockSettings, showPills: false }, + }); + + expect(tree).toMatchSnapshot(); + }); - expect(tree).toMatchSnapshot(); + it('should render pills when showPills is enabled', async () => { + const mockNotification = mockGitifyNotification; + const props: MetricGroupProps = { + notification: mockNotification, + }; + + const tree = renderWithAppContext(, { + settings: { ...mockSettings, showPills: true }, }); + + expect(tree).toMatchSnapshot(); }); }); diff --git a/src/renderer/components/metrics/MilestonePill.test.tsx b/src/renderer/components/metrics/MilestonePill.test.tsx index 4d9c65f01..672d2cf74 100644 --- a/src/renderer/components/metrics/MilestonePill.test.tsx +++ b/src/renderer/components/metrics/MilestonePill.test.tsx @@ -1,35 +1,38 @@ import { renderWithAppContext } from '../../__helpers__/test-utils'; -import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; -import type { GitifyMilestone } from '../../types'; - -import { MilestonePill } from './MilestonePill'; +import { MilestonePill, type MilestonePillProps } from './MilestonePill'; describe('renderer/components/metrics/MilestonePill.tsx', () => { + it('renders with no milestone', () => { + const props: MilestonePillProps = { milestone: null }; + + const tree = renderWithAppContext(); + + expect(tree).toMatchSnapshot(); + }); + it('renders open milestone pill', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.milestone = { - title: 'Milestone 1', - state: 'OPEN', - } as GitifyMilestone; + const props: MilestonePillProps = { + milestone: { + title: 'Milestone 1', + state: 'OPEN', + }, + }; - const tree = renderWithAppContext( - , - ); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); it('renders closed milestone pill', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.milestone = { - title: 'Milestone 1', - state: 'CLOSED', - } as GitifyMilestone; - - const tree = renderWithAppContext( - , - ); + const props: MilestonePillProps = { + milestone: { + title: 'Milestone 1', + state: 'CLOSED', + }, + }; + + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); diff --git a/src/renderer/components/metrics/ReactionsPill.test.tsx b/src/renderer/components/metrics/ReactionsPill.test.tsx index eca202c1a..060ae724c 100644 --- a/src/renderer/components/metrics/ReactionsPill.test.tsx +++ b/src/renderer/components/metrics/ReactionsPill.test.tsx @@ -1,49 +1,48 @@ import { renderWithAppContext } from '../../__helpers__/test-utils'; -import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; -import { ReactionsPill } from './ReactionsPill'; +import { ReactionsPill, type ReactionsPillProps } from './ReactionsPill'; describe('renderer/components/metrics/ReactionsPill.tsx', () => { + it('renders with no reactions', () => { + const props: ReactionsPillProps = { reactionGroups: [], reactionsCount: 0 }; + + const tree = renderWithAppContext(); + + expect(tree).toMatchSnapshot(); + }); + it('renders when one reaction', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.reactionsCount = 1; - mockNotification.subject.reactionGroups = [ - { - content: 'ROCKET', - reactors: { totalCount: 1 }, - }, - ]; - - const tree = renderWithAppContext( - , - ); + const props: ReactionsPillProps = { + reactionGroups: [ + { + content: 'ROCKET', + reactors: { totalCount: 1 }, + }, + ], + reactionsCount: 1, + }; + + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); it('renders when multiple reactions', () => { - const mockNotification = { ...mockGitifyNotification }; - mockNotification.subject.reactionsCount = 53; - mockNotification.subject.reactionGroups = [ - { content: 'THUMBS_UP', reactors: { totalCount: 1 } }, - { content: 'THUMBS_DOWN', reactors: { totalCount: 1 } }, - { content: 'LAUGH', reactors: { totalCount: 2 } }, - { content: 'HOORAY', reactors: { totalCount: 3 } }, - { content: 'CONFUSED', reactors: { totalCount: 5 } }, - { content: 'ROCKET', reactors: { totalCount: 8 } }, - { content: 'EYES', reactors: { totalCount: 13 } }, - { content: 'HEART', reactors: { totalCount: 21 } }, - ]; - - const tree = renderWithAppContext( - , - ); + const props: ReactionsPillProps = { + reactionGroups: [ + { content: 'THUMBS_UP', reactors: { totalCount: 1 } }, + { content: 'THUMBS_DOWN', reactors: { totalCount: 1 } }, + { content: 'LAUGH', reactors: { totalCount: 2 } }, + { content: 'HOORAY', reactors: { totalCount: 3 } }, + { content: 'CONFUSED', reactors: { totalCount: 5 } }, + { content: 'ROCKET', reactors: { totalCount: 8 } }, + { content: 'EYES', reactors: { totalCount: 13 } }, + { content: 'HEART', reactors: { totalCount: 21 } }, + ], + reactionsCount: 54, + }; + + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); diff --git a/src/renderer/components/metrics/ReviewsPill.test.tsx b/src/renderer/components/metrics/ReviewsPill.test.tsx index b75cef4b8..7c0f7e4e3 100644 --- a/src/renderer/components/metrics/ReviewsPill.test.tsx +++ b/src/renderer/components/metrics/ReviewsPill.test.tsx @@ -1,20 +1,25 @@ import { renderWithAppContext } from '../../__helpers__/test-utils'; import { mockGitifyNotification } from '../../__mocks__/notifications-mocks'; -import { ReviewsPill } from './ReviewsPill'; +import { ReviewsPill, type ReviewsPillProps } from './ReviewsPill'; describe('renderer/components/metrics/ReviewsPill.tsx', () => { it('renders review pills when reviews exist', () => { - const mockNotification = { ...mockGitifyNotification }; - const reviews = mockNotification.subject.reviews; + const props: ReviewsPillProps = { + reviews: mockGitifyNotification.subject.reviews, + }; - const tree = renderWithAppContext(); + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); it('renders nothing when no reviews', () => { - const tree = renderWithAppContext(); + const props: ReviewsPillProps = { + reviews: [], + }; + + const tree = renderWithAppContext(); expect(tree).toMatchSnapshot(); }); diff --git a/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap index 4599aca25..cc3ff00b0 100644 --- a/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`renderer/components/metrics/LabelsPill.tsx renders labels pill 1`] = ` +exports[`renderer/components/metrics/LabelsPill.tsx renders without labels 1`] = ` { "asFragment": [Function], "baseElement": @@ -13,61 +13,7 @@ exports[`renderer/components/metrics/LabelsPill.tsx renders labels pill 1`] = `
- - -
+ /> , @@ -80,61 +26,7 @@ exports[`renderer/components/metrics/LabelsPill.tsx renders labels pill 1`] = `
- - -
+ /> , "debug": [Function], diff --git a/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap index 7b2c0d270..52487a426 100644 --- a/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap @@ -393,3 +393,86 @@ exports[`renderer/components/metrics/LinkedIssuesPill.tsx renders when linked to "unmount": [Function], } `; + +exports[`renderer/components/metrics/LinkedIssuesPill.tsx renders when no linked issues/prs 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
+
+ , + "container":
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/renderer/components/metrics/__snapshots__/MetricGroup.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/MetricGroup.test.tsx.snap index 129cb3ca4..280bfaf60 100644 --- a/src/renderer/components/metrics/__snapshots__/MetricGroup.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/MetricGroup.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`renderer/components/metrics/MetricGroup.tsx showPills disabled should not render any pills when showPills is disabled 1`] = ` +exports[`renderer/components/metrics/MetricGroup.tsx should not render any pills when showPills is disabled 1`] = ` { "asFragment": [Function], "baseElement": @@ -82,3 +82,308 @@ exports[`renderer/components/metrics/MetricGroup.tsx showPills disabled should n "unmount": [Function], } `; + +exports[`renderer/components/metrics/MetricGroup.tsx should render pills when showPills is enabled 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
+ + + + +
+
+
+
+ , + "container":
+
+
+
+ + + + +
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/renderer/components/metrics/__snapshots__/MilestonePill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/MilestonePill.test.tsx.snap index 2e40d9fc1..97b5023c9 100644 --- a/src/renderer/components/metrics/__snapshots__/MilestonePill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/MilestonePill.test.tsx.snap @@ -361,3 +361,86 @@ exports[`renderer/components/metrics/MilestonePill.tsx renders open milestone pi "unmount": [Function], } `; + +exports[`renderer/components/metrics/MilestonePill.tsx renders with no milestone 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
+
+ , + "container":
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap index 0380b66d9..488f9b43f 100644 --- a/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap @@ -381,3 +381,277 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when one reaction "unmount": [Function], } `; + +exports[`renderer/components/metrics/ReactionsPill.tsx renders when one reaction 2`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+ + +
+
+
+ , + "container":
+
+
+ + +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`renderer/components/metrics/ReactionsPill.tsx renders with no reactions 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
+
+ , + "container":
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/renderer/utils/api/graphql/utils.test.ts b/src/renderer/utils/api/graphql/utils.test.ts index 14ae99ff6..86b161ed5 100644 --- a/src/renderer/utils/api/graphql/utils.test.ts +++ b/src/renderer/utils/api/graphql/utils.test.ts @@ -53,17 +53,18 @@ describe('renderer/utils/api/graphql/utils.ts', () => { ); expect(fragments).not.toBeNull(); - expect(fragments.length).toBe(9); - expect(fragments.flatMap((f) => f.typeCondition)).toEqual([ + expect(fragments.length).toBe(10); + expect(fragments.flatMap((f) => f.typeCondition).toSorted()).toEqual([ 'Actor', - 'Milestone', - 'ReactionGroup', 'Discussion', 'DiscussionComment', 'DiscussionComment', 'Issue', + 'Label', + 'Milestone', 'PullRequest', 'PullRequestReview', + 'ReactionGroup', ]); }); }); From 49566a15ccc0eb6e239d42d3836f46c464f6226e Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 12:07:17 -0500 Subject: [PATCH 6/9] feat: primer label component Signed-off-by: Adam Setch --- .../__snapshots__/ReactionsPill.test.tsx.snap | 199 +----------------- 1 file changed, 4 insertions(+), 195 deletions(-) diff --git a/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap index 488f9b43f..342dd1044 100644 --- a/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap @@ -52,7 +52,7 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when multiple rea - 53 + 54
@@ -65,7 +65,7 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when multiple rea popover="auto" role="tooltip" > - 53 reactions: 👍 1 👎 1 😆 2 🎉 3 😕 5 🚀 8 👀 13 ❤️ 21 + 54 reactions: 👍 1 👎 1 😆 2 🎉 3 😕 5 🚀 8 👀 13 ❤️ 21
@@ -119,7 +119,7 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when multiple rea - 53 + 54
@@ -132,7 +132,7 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when multiple rea popover="auto" role="tooltip" > - 53 reactions: 👍 1 👎 1 😆 2 🎉 3 😕 5 🚀 8 👀 13 ❤️ 21 + 54 reactions: 👍 1 👎 1 😆 2 🎉 3 😕 5 🚀 8 👀 13 ❤️ 21
@@ -382,197 +382,6 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when one reaction } `; -exports[`renderer/components/metrics/ReactionsPill.tsx renders when one reaction 2`] = ` -{ - "asFragment": [Function], - "baseElement": -
-
-
- - -
-
-
- , - "container":
-
-
- - -
-
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; - exports[`renderer/components/metrics/ReactionsPill.tsx renders with no reactions 1`] = ` { "asFragment": [Function], From cd661135aca83ced23d213dd9594ef564e124f2b Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 15:56:11 -0500 Subject: [PATCH 7/9] feat: labels Signed-off-by: Adam Setch --- src/renderer/__helpers__/jest.setup.ts | 38 ++++ .../__snapshots__/LabelsPill.test.tsx.snap | 173 ++++++++++++++++++ 2 files changed, 211 insertions(+) diff --git a/src/renderer/__helpers__/jest.setup.ts b/src/renderer/__helpers__/jest.setup.ts index c98149063..76f263eda 100644 --- a/src/renderer/__helpers__/jest.setup.ts +++ b/src/renderer/__helpers__/jest.setup.ts @@ -78,3 +78,41 @@ Object.defineProperty(navigator, 'clipboard', { }, configurable: true, }); + +// Simple IntersectionObserver mock for test environments (jsdom) +class MockIntersectionObserver { + readonly root: Element | Document | null; + readonly rootMargin: string; + readonly thresholds: number | number[]; + + constructor( + // callback unused in this mock + _callback: IntersectionObserverCallback, + options?: IntersectionObserverInit, + ) { + this.root = (options?.root as Element | Document) ?? null; + this.rootMargin = options?.rootMargin ?? ''; + this.thresholds = options?.threshold ?? 0; + } + + observe() { + return null; + } + + unobserve() { + return null; + } + + disconnect() { + return null; + } + + takeRecords(): IntersectionObserverEntry[] { + return []; + } +} + +// Attach to global if not present +if (typeof (globalThis as any).IntersectionObserver === 'undefined') { + (globalThis as any).IntersectionObserver = MockIntersectionObserver; +} diff --git a/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap index cc3ff00b0..dd67cc701 100644 --- a/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap @@ -1,5 +1,178 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +exports[`renderer/components/metrics/LabelsPill.tsx renders with labels 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
    +
  • + + + enhancement + + +
  • +
  • + + + good-first-issue + + +
  • +
  • +
+
+
+
+ , + "container":
+
+
+
    +
  • + + + enhancement + + +
  • +
  • + + + good-first-issue + + +
  • +
  • +
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`renderer/components/metrics/LabelsPill.tsx renders without labels 1`] = ` { "asFragment": [Function], From 0fc4ffb6e72439214723eaf6be66f1c7d60c527e Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 17:31:45 -0500 Subject: [PATCH 8/9] feat: skip fetching if offline Signed-off-by: Adam Setch --- .../components/metrics/CommentsPill.tsx | 2 +- .../components/metrics/LabelsPill.tsx | 16 +- .../components/metrics/LinkedIssuesPill.tsx | 4 +- .../components/metrics/MetricPill.test.tsx | 4 +- .../components/metrics/MetricPill.tsx | 7 +- .../components/metrics/MilestonePill.tsx | 2 +- .../components/metrics/ReactionsPill.tsx | 44 +-- .../components/metrics/ReviewsPill.tsx | 2 +- .../__snapshots__/LabelsPill.test.tsx.snap | 226 +++++++++---- .../LinkedIssuesPill.test.tsx.snap | 8 +- .../__snapshots__/ReactionsPill.test.tsx.snap | 316 +++++++++++++++++- 11 files changed, 521 insertions(+), 110 deletions(-) diff --git a/src/renderer/components/metrics/CommentsPill.tsx b/src/renderer/components/metrics/CommentsPill.tsx index 310883965..9352cfb7e 100644 --- a/src/renderer/components/metrics/CommentsPill.tsx +++ b/src/renderer/components/metrics/CommentsPill.tsx @@ -21,9 +21,9 @@ export const CommentsPill: FC = ({ commentCount }) => { return ( ); }; diff --git a/src/renderer/components/metrics/LabelsPill.tsx b/src/renderer/components/metrics/LabelsPill.tsx index bae716f81..5276c5a1a 100644 --- a/src/renderer/components/metrics/LabelsPill.tsx +++ b/src/renderer/components/metrics/LabelsPill.tsx @@ -1,8 +1,11 @@ import type { FC } from 'react'; +import { TagIcon } from '@primer/octicons-react'; import { IssueLabelToken, LabelGroup } from '@primer/react'; -import type { GitifyLabels } from '../../types'; +import { type GitifyLabels, IconColor } from '../../types'; + +import { MetricPill } from './MetricPill'; export interface LabelsPillProps { labels: GitifyLabels[]; @@ -14,7 +17,7 @@ export const LabelsPill: FC = ({ labels }) => { } const labelsContent = ( - + {labels.map((label) => { return ( = ({ labels }) => { ); - return labelsContent; + return ( + + ); }; diff --git a/src/renderer/components/metrics/LinkedIssuesPill.tsx b/src/renderer/components/metrics/LinkedIssuesPill.tsx index f5c82bc04..22ba7b60a 100644 --- a/src/renderer/components/metrics/LinkedIssuesPill.tsx +++ b/src/renderer/components/metrics/LinkedIssuesPill.tsx @@ -21,15 +21,15 @@ export const LinkedIssuesPill: FC = ({ const description = formatMetricDescription( linkedIssues.length, 'issue', - (count, noun) => `Linked to ${count} ${noun}: ${linkedIssues.join(', ')}`, + (noun) => `Linked to ${noun}: ${linkedIssues.join(', ')}`, ); return ( ); }; diff --git a/src/renderer/components/metrics/MetricPill.test.tsx b/src/renderer/components/metrics/MetricPill.test.tsx index e4abfcf7b..6ca357a46 100644 --- a/src/renderer/components/metrics/MetricPill.test.tsx +++ b/src/renderer/components/metrics/MetricPill.test.tsx @@ -9,7 +9,7 @@ import { MetricPill, type MetricPillProps } from './MetricPill'; describe('renderer/components/metrics/MetricPill.tsx', () => { it('should render with metric', () => { const props: MetricPillProps = { - title: 'Mock Pill', + contents: 'Mock Pill', metric: 1, icon: MarkGithubIcon, color: IconColor.GREEN, @@ -22,7 +22,7 @@ describe('renderer/components/metrics/MetricPill.tsx', () => { it('should render without metric', () => { const props: MetricPillProps = { - title: 'Mock Pill', + contents: 'Mock Pill', icon: MarkGithubIcon, color: IconColor.GREEN, }; diff --git a/src/renderer/components/metrics/MetricPill.tsx b/src/renderer/components/metrics/MetricPill.tsx index 13454728b..ba758a2de 100644 --- a/src/renderer/components/metrics/MetricPill.tsx +++ b/src/renderer/components/metrics/MetricPill.tsx @@ -6,18 +6,18 @@ import { Label, Stack, Text, Tooltip } from '@primer/react'; import { type IconColor, Size } from '../../types'; export interface MetricPillProps { - title: string; + contents: string | ReactNode; metric?: number; icon: Icon; color: IconColor; - content?: ReactNode; } export const MetricPill: FC = (props: MetricPillProps) => { const Icon = props.icon; return ( - + // @ts-expect-error: We overload text with a ReactNode + ); diff --git a/src/renderer/components/metrics/MilestonePill.tsx b/src/renderer/components/metrics/MilestonePill.tsx index 341a1526f..5cbe99eb9 100644 --- a/src/renderer/components/metrics/MilestonePill.tsx +++ b/src/renderer/components/metrics/MilestonePill.tsx @@ -18,8 +18,8 @@ export const MilestonePill: FC = ({ milestone }) => { return ( ); }; diff --git a/src/renderer/components/metrics/ReactionsPill.tsx b/src/renderer/components/metrics/ReactionsPill.tsx index 7333f011b..1f8488609 100644 --- a/src/renderer/components/metrics/ReactionsPill.tsx +++ b/src/renderer/components/metrics/ReactionsPill.tsx @@ -1,10 +1,11 @@ import type { FC } from 'react'; import { SmileyIcon } from '@primer/octicons-react'; +import { IssueLabelToken, LabelGroup } from '@primer/react'; import { type GitifyReactionGroup, IconColor } from '../../types'; -import { formatMetricDescription } from '../../utils/notifications/formatters'; +// import { formatMetricDescription } from '../../utils/notifications/formatters'; import { MetricPill } from './MetricPill'; export interface ReactionsPillProps { @@ -31,33 +32,34 @@ export const ReactionsPill: FC = ({ return null; } - const hasMultipleReactions = - reactionGroups.filter((rg) => rg.reactors.totalCount > 0).length > 1; - - const description = formatMetricDescription( - reactionsCount, - 'reaction', - (count, noun) => { - const formatted = reactionGroups - .map((rg) => { - const emoji = reactionEmojiMap[rg.content]; - if (!emoji || !rg.reactors.totalCount) { - return ''; - } - return `${emoji} ${hasMultipleReactions ? rg.reactors.totalCount : ''}`.trim(); - }) - .filter(Boolean) - .join(' '); - return `${count} ${noun}: ${formatted}`; - }, + const visibleReactionGroups = reactionGroups.filter( + (rg) => !!rg.reactors && rg.reactors.totalCount > 0, + ); + + const reactionsContent = ( + + {visibleReactionGroups.map((rg) => { + const emoji = reactionEmojiMap[rg.content]; + const total = rg.reactors.totalCount; + + return ( + + ); + })} + ); return ( ); }; diff --git a/src/renderer/components/metrics/ReviewsPill.tsx b/src/renderer/components/metrics/ReviewsPill.tsx index e53d9faea..bbfe99983 100644 --- a/src/renderer/components/metrics/ReviewsPill.tsx +++ b/src/renderer/components/metrics/ReviewsPill.tsx @@ -26,10 +26,10 @@ export const ReviewsPill: FC = ({ reviews }) => { return ( ); })} diff --git a/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap index dd67cc701..3a8359793 100644 --- a/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/LabelsPill.test.tsx.snap @@ -13,15 +13,168 @@ exports[`renderer/components/metrics/LabelsPill.tsx renders with labels 1`] = `
+ + +
+ + + , + "container":
+
+
+ +
-
-
- , - "container":
-
-
-
    -
  • - - - enhancement - - -
  • -
  • - - - good-first-issue - - -
  • -
  • -
+
, diff --git a/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap index 52487a426..bd7f32b28 100644 --- a/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/LinkedIssuesPill.test.tsx.snap @@ -68,7 +68,7 @@ exports[`renderer/components/metrics/LinkedIssuesPill.tsx renders when linked to popover="auto" role="tooltip" > - Linked to 2 issues: #1, #2 + Linked to 2: #1, #2 @@ -138,7 +138,7 @@ exports[`renderer/components/metrics/LinkedIssuesPill.tsx renders when linked to popover="auto" role="tooltip" > - Linked to 2 issues: #1, #2 + Linked to 2: #1, #2 @@ -265,7 +265,7 @@ exports[`renderer/components/metrics/LinkedIssuesPill.tsx renders when linked to popover="auto" role="tooltip" > - Linked to 1 issue: #1 + Linked to 1: #1 @@ -335,7 +335,7 @@ exports[`renderer/components/metrics/LinkedIssuesPill.tsx renders when linked to popover="auto" role="tooltip" > - Linked to 1 issue: #1 + Linked to 1: #1 diff --git a/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap b/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap index 342dd1044..38b6567c0 100644 --- a/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap +++ b/src/renderer/components/metrics/__snapshots__/ReactionsPill.test.tsx.snap @@ -65,7 +65,140 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when multiple rea popover="auto" role="tooltip" > - 54 reactions: 👍 1 👎 1 😆 2 🎉 3 😕 5 🚀 8 👀 13 ❤️ 21 +
    +
  • + + + 👍 1 + + +
  • +
  • + + + 👎 1 + + +
  • +
  • + + + 😆 2 + + +
  • +
  • + + + 🎉 3 + + +
  • +
  • + + + 😕 5 + + +
  • +
  • + + + 🚀 8 + + +
  • +
  • + + + 👀 13 + + +
  • +
  • + + + ❤️ 21 + + +
  • +
@@ -132,7 +265,140 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when multiple rea popover="auto" role="tooltip" > - 54 reactions: 👍 1 👎 1 😆 2 🎉 3 😕 5 🚀 8 👀 13 ❤️ 21 +
    +
  • + + + 👍 1 + + +
  • +
  • + + + 👎 1 + + +
  • +
  • + + + 😆 2 + + +
  • +
  • + + + 🎉 3 + + +
  • +
  • + + + 😕 5 + + +
  • +
  • + + + 🚀 8 + + +
  • +
  • + + + 👀 13 + + +
  • +
  • + + + ❤️ 21 + + +
  • +
@@ -256,7 +522,28 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when one reaction popover="auto" role="tooltip" > - 1 reaction: 🚀 +
    +
  • + + + 🚀 1 + + +
  • +
@@ -323,7 +610,28 @@ exports[`renderer/components/metrics/ReactionsPill.tsx renders when one reaction popover="auto" role="tooltip" > - 1 reaction: 🚀 +
    +
  • + + + 🚀 1 + + +
  • +
From 2037d92e50a0f5214ac22487159535e89f0e1738 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Fri, 30 Jan 2026 17:37:05 -0500 Subject: [PATCH 9/9] feat(settings): update metric setting tooltip Signed-off-by: Adam Setch --- src/renderer/components/metrics/ReactionsPill.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/components/metrics/ReactionsPill.tsx b/src/renderer/components/metrics/ReactionsPill.tsx index 1f8488609..ce836fa79 100644 --- a/src/renderer/components/metrics/ReactionsPill.tsx +++ b/src/renderer/components/metrics/ReactionsPill.tsx @@ -5,7 +5,6 @@ import { IssueLabelToken, LabelGroup } from '@primer/react'; import { type GitifyReactionGroup, IconColor } from '../../types'; -// import { formatMetricDescription } from '../../utils/notifications/formatters'; import { MetricPill } from './MetricPill'; export interface ReactionsPillProps {