diff --git a/src/__mocks__/state-mocks.ts b/src/__mocks__/state-mocks.ts index 118e11bbe..13dc08529 100644 --- a/src/__mocks__/state-mocks.ts +++ b/src/__mocks__/state-mocks.ts @@ -71,4 +71,5 @@ export const mockSettings: SettingsState = { markAsDoneOnOpen: false, showAccountHostname: false, delayNotificationState: false, + showPills: true, }; diff --git a/src/components/NotificationRow.test.tsx b/src/components/NotificationRow.test.tsx index 1f9e6f0c8..515386923 100644 --- a/src/components/NotificationRow.test.tsx +++ b/src/components/NotificationRow.test.tsx @@ -26,7 +26,11 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); @@ -43,7 +47,11 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); @@ -60,11 +68,42 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); describe('notification pills / metrics', () => { + describe('showPills disabled', () => { + it('should not render any pills when showPills is disabled', async () => { + jest + .spyOn(global.Date, 'now') + .mockImplementation(() => new Date('2024').valueOf()); + + const mockNotification = mockSingleNotification; + mockNotification.subject.linkedIssues = ['#1']; + + const props = { + notification: mockNotification, + hostname: 'github.com', + }; + + const tree = render( + + + , + ); + expect(tree).toMatchSnapshot(); + }); + }); + describe('linked issue pills', () => { it('should render issues pill when linked to one issue/pr', async () => { jest @@ -79,7 +118,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); @@ -96,7 +143,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); }); @@ -115,7 +170,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); @@ -132,7 +195,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); @@ -149,7 +220,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); }); @@ -168,7 +247,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); }); @@ -190,7 +277,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); @@ -210,7 +305,15 @@ describe('components/NotificationRow.tsx', () => { hostname: 'github.com', }; - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); }); @@ -304,12 +407,10 @@ describe('components/NotificationRow.tsx', () => { - - - + , ); @@ -327,14 +428,9 @@ describe('components/NotificationRow.tsx', () => { render( - - - + , ); @@ -352,7 +448,9 @@ describe('components/NotificationRow.tsx', () => { render( - + , diff --git a/src/components/NotificationRow.tsx b/src/components/NotificationRow.tsx index 18e0585ab..f4f726a37 100644 --- a/src/components/NotificationRow.tsx +++ b/src/components/NotificationRow.tsx @@ -153,86 +153,88 @@ export const NotificationRow: FC = ({ notification, hostname }) => { )} {reason.title} {updatedAt} - - {notification.subject?.linkedIssues?.length > 0 && ( - - - - )} - {notification.subject.reviews - ? notification.subject.reviews.map((review) => { - const icon = getPullRequestReviewIcon(review); - if (!icon) { - return null; - } - - return ( - - - - ); - }) - : null} - {notification.subject?.comments > 0 && ( - - - - )} - {notification.subject?.labels?.length > 0 && ( - - - - )} - {notification.subject.milestone && ( - - + + )} + {notification.subject.reviews + ? notification.subject.reviews.map((review) => { + const icon = getPullRequestReviewIcon(review); + if (!icon) { + return null; } - aria-label={notification.subject.milestone.title} - /> - - - )} - + + return ( + + + + ); + }) + : null} + {notification.subject?.comments > 0 && ( + + + + )} + {notification.subject?.labels?.length > 0 && ( + + + + )} + {notification.subject.milestone && ( + + + + )} + + )} diff --git a/src/components/__snapshots__/NotificationRow.test.tsx.snap b/src/components/__snapshots__/NotificationRow.test.tsx.snap index b9cab2c6d..7cf6e5b80 100644 --- a/src/components/__snapshots__/NotificationRow.test.tsx.snap +++ b/src/components/__snapshots__/NotificationRow.test.tsx.snap @@ -4552,6 +4552,347 @@ exports[`components/NotificationRow.tsx notification pills / metrics milestone p } `; +exports[`components/NotificationRow.tsx notification pills / metrics showPills disabled should not render any pills when showPills is disabled 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+ + + + +
+
+
+ I am a robot and this is a test! +
+
+ + + + + + Updated + + + over 6 years ago + + +
+
+
+ + + +
+
+
+ , + "container":
+
+
+ + + + +
+
+
+ I am a robot and this is a test! +
+
+ + + + + + Updated + + + over 6 years ago + + +
+
+
+ + + +
+
+
, + "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[`components/NotificationRow.tsx should render itself & its children 1`] = ` { "asFragment": [Function], diff --git a/src/context/App.test.tsx b/src/context/App.test.tsx index 71dc830d9..8d20babc1 100644 --- a/src/context/App.test.tsx +++ b/src/context/App.test.tsx @@ -371,7 +371,12 @@ describe('context/App.tsx', () => { }); expect(saveStateMock).toHaveBeenCalledWith({ - auth: { accounts: [], enterpriseAccounts: [], token: null, user: null }, + auth: { + accounts: [], + enterpriseAccounts: [], + token: null, + user: null, + } as AuthState, settings: { participating: true, playSound: true, @@ -384,7 +389,8 @@ describe('context/App.tsx', () => { markAsDoneOnOpen: false, showAccountHostname: false, delayNotificationState: false, - }, + showPills: true, + } as SettingsState, }); }); @@ -416,7 +422,12 @@ describe('context/App.tsx', () => { expect(setAutoLaunchMock).toHaveBeenCalledWith(true); expect(saveStateMock).toHaveBeenCalledWith({ - auth: { accounts: [], enterpriseAccounts: [], token: null, user: null }, + auth: { + accounts: [], + enterpriseAccounts: [], + token: null, + user: null, + } as AuthState, settings: { participating: false, playSound: true, @@ -429,7 +440,8 @@ describe('context/App.tsx', () => { markAsDoneOnOpen: false, showAccountHostname: false, delayNotificationState: false, - }, + showPills: true, + } as SettingsState, }); }); }); diff --git a/src/context/App.tsx b/src/context/App.tsx index b84c8b3ec..74517daea 100644 --- a/src/context/App.tsx +++ b/src/context/App.tsx @@ -53,6 +53,7 @@ export const defaultSettings: SettingsState = { markAsDoneOnOpen: false, showAccountHostname: false, delayNotificationState: false, + showPills: true, }; interface AppContextState { diff --git a/src/routes/Settings.test.tsx b/src/routes/Settings.test.tsx index 2edc874b2..be80c903d 100644 --- a/src/routes/Settings.test.tsx +++ b/src/routes/Settings.test.tsx @@ -127,6 +127,31 @@ describe('routes/Settings.tsx', () => { ); }); + it('should toggle metric pills checkbox', async () => { + await act(async () => { + render( + + + + + , + ); + }); + + await screen.findByLabelText('Show notification metric pills'); + + fireEvent.click(screen.getByLabelText('Show notification metric pills')); + + expect(updateSetting).toHaveBeenCalledTimes(1); + expect(updateSetting).toHaveBeenCalledWith('showPills', false); + }); + it('should toggle account hostname checkbox', async () => { await act(async () => { render( diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx index 25bfdb35d..d5ffc3f91 100644 --- a/src/routes/Settings.tsx +++ b/src/routes/Settings.tsx @@ -1,9 +1,14 @@ import { ArrowLeftIcon, + CheckIcon, + CommentIcon, + IssueClosedIcon, KeyIcon, + MilestoneIcon, PersonIcon, PlusIcon, SignOutIcon, + TagIcon, XCircleIcon, } from '@primer/octicons-react'; import { ipcRenderer } from 'electron'; @@ -150,6 +155,41 @@ export const SettingsRoute: FC = () => { } /> + updateSetting('showPills', evt.target.checked)} + tooltip={ +
+
Show notification metric pills for:
+
+
    +
  • + + linked issues +
  • +
  • + pr reviews +
  • +
  • + + comments +
  • + +
  • + + labels +
  • +
  • + + milestones +
  • +
+
+
+ } + /> +
+
+
+ +
+
+ +
+
+
diff --git a/src/types.ts b/src/types.ts index a3e62104f..b9688f535 100644 --- a/src/types.ts +++ b/src/types.ts @@ -41,6 +41,7 @@ interface AppearanceSettingsState { theme: Theme; detailedNotifications: boolean; showAccountHostname: boolean; + showPills: boolean; } interface NotificationSettingsState {