diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index e5fd97f52..9f7f3694c 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -7,9 +7,9 @@ import { useLocation, } from 'react-router-dom'; -import { BaseStyles, Box, ThemeProvider } from '@primer/react'; +import { BaseStyles, ThemeProvider } from '@primer/react'; -import { Sidebar } from './components/Sidebar'; +import { AppLayout } from './components/layout/AppLayout'; import { AppContext, AppProvider } from './context/App'; import { AccountsRoute } from './routes/Accounts'; import { FiltersRoute } from './routes/Filters'; @@ -38,8 +38,7 @@ export const App = () => { - - + { element={} /> - + diff --git a/src/renderer/components/fields/Checkbox.tsx b/src/renderer/components/fields/Checkbox.tsx index 578904836..d7e55dc64 100644 --- a/src/renderer/components/fields/Checkbox.tsx +++ b/src/renderer/components/fields/Checkbox.tsx @@ -1,8 +1,8 @@ +import { Stack } from '@primer/react'; import type { FC, ReactNode } from 'react'; -import { CounterLabel, Stack } from '@primer/react'; - import { cn } from '../../utils/cn'; +import { CustomCounter } from '../primitives/CustomCounter'; import { Tooltip } from './Tooltip'; export interface ICheckbox { @@ -20,7 +20,7 @@ export const Checkbox: FC = ({ visible = true, ...props }: ICheckbox) => { - const counter = props.counter > 0 ? props.counter : undefined; + const counter = props?.counter === 0 ? '0' : props.counter; return ( visible && ( @@ -54,11 +54,12 @@ export const Checkbox: FC = ({ )} - {counter ? ( - - {counter} - - ) : null} + {counter && ( + + )} ) ); diff --git a/src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap b/src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap index 6218f5afb..7a2c09b83 100644 --- a/src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap +++ b/src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap @@ -200,18 +200,9 @@ exports[`renderer/components/fields/Checkbox.tsx should render - positive counte Appearance - -  ( 5 - ) @@ -240,18 +231,9 @@ exports[`renderer/components/fields/Checkbox.tsx should render - positive counte Appearance - -  ( 5 - ) , @@ -336,18 +318,9 @@ exports[`renderer/components/fields/Checkbox.tsx should render - positive counte Appearance - -  ( 5 - ) @@ -375,18 +348,9 @@ exports[`renderer/components/fields/Checkbox.tsx should render - positive counte Appearance - -  ( 5 - ) , @@ -735,6 +699,11 @@ exports[`renderer/components/fields/Checkbox.tsx should render - zero counter 1` > Appearance + + 0 + , @@ -761,6 +730,11 @@ exports[`renderer/components/fields/Checkbox.tsx should render - zero counter 1` > Appearance + + 0 + , "debug": [Function], diff --git a/src/renderer/components/filters/ReasonFilter.tsx b/src/renderer/components/filters/ReasonFilter.tsx index 44950c649..96fd4d740 100644 --- a/src/renderer/components/filters/ReasonFilter.tsx +++ b/src/renderer/components/filters/ReasonFilter.tsx @@ -17,8 +17,9 @@ export const ReasonFilter: FC = () => { const { updateFilter, settings, notifications } = useContext(AppContext); return ( -
+
Reason + {Object.keys(FORMATTED_REASONS).map((reason: Reason) => { const reasonDetails = getReasonDetails(reason); diff --git a/src/renderer/components/filters/StateFilter.tsx b/src/renderer/components/filters/StateFilter.tsx index 4a453035d..2d0ec9a20 100644 --- a/src/renderer/components/filters/StateFilter.tsx +++ b/src/renderer/components/filters/StateFilter.tsx @@ -19,8 +19,8 @@ export const StateFilter: FC = () => { const { updateFilter, settings, notifications } = useContext(AppContext); return ( -
- +
+ State { const { updateFilter, settings, notifications } = useContext(AppContext); return ( -
+
Type { }; return ( -
+
Handles { const { updateFilter, settings, notifications } = useContext(AppContext); return ( -
- +
+ User Type + + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 + `; @@ -742,6 +817,11 @@ exports[`renderer/components/filters/ReasonFilter.tsx should be able to toggle r /> + + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 + `; @@ -1383,7 +1533,6 @@ exports[`renderer/components/filters/ReasonFilter.tsx should render itself & its "baseElement":
@@ -1478,6 +1627,11 @@ exports[`renderer/components/filters/ReasonFilter.tsx should render itself & its />
+ + 0 +
+ + 0 +
- -  ( 1 - )
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
- -  ( 3 - )
+ + 0 +
@@ -2143,7 +2339,6 @@ exports[`renderer/components/filters/ReasonFilter.tsx should render itself & its , "container":
@@ -2238,6 +2433,11 @@ exports[`renderer/components/filters/ReasonFilter.tsx should render itself & its />
+ + 0 +
+ + 0 +
- -  ( 1 - )
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
- -  ( 3 - )
+ + 0 +
diff --git a/src/renderer/components/filters/__snapshots__/StateFilter.test.tsx.snap b/src/renderer/components/filters/__snapshots__/StateFilter.test.tsx.snap index ea0c2df73..20482a468 100644 --- a/src/renderer/components/filters/__snapshots__/StateFilter.test.tsx.snap +++ b/src/renderer/components/filters/__snapshots__/StateFilter.test.tsx.snap @@ -31,6 +31,11 @@ exports[`renderer/components/filters/StateFilter.tsx should be able to toggle us > Draft + + 0 +
+ + 0 +
Merged + + 0 +
+ + 0 +
+ + 0 + `; @@ -223,6 +248,11 @@ exports[`renderer/components/filters/StateFilter.tsx should be able to toggle us > Draft + + 0 +
+ + 0 +
Merged + + 0 +
+ + 0 +
+ + 0 + `; @@ -391,12 +441,11 @@ exports[`renderer/components/filters/StateFilter.tsx should render itself & its "baseElement":
Draft + + 0 +
- -  ( - 1 - ) -
Merged + + 0 +
+ + 0 +
- -  ( - 3 - ) -
@@ -696,12 +742,11 @@ exports[`renderer/components/filters/StateFilter.tsx should render itself & its , "container":
Draft + + 0 +
- -  ( 1 - )
Merged + + 0 +
+ + 0 +
- -  ( 3 - ) @@ -1058,12 +1100,11 @@ exports[`renderer/components/filters/StateFilter.tsx should render itself & its "baseElement":
Draft + + 0 +
- -  ( - 1 - ) -
Merged + + 0 +
+ + 0 +
- -  ( - 3 - ) -
@@ -1358,12 +1396,11 @@ exports[`renderer/components/filters/StateFilter.tsx should render itself & its , "container":
Draft + + 0 +
- -  ( 1 - )
Merged + + 0 +
+ + 0 +
- -  ( 3 - ) diff --git a/src/renderer/components/filters/__snapshots__/SubjectTypeFilter.test.tsx.snap b/src/renderer/components/filters/__snapshots__/SubjectTypeFilter.test.tsx.snap index d219a727a..81cf00169 100644 --- a/src/renderer/components/filters/__snapshots__/SubjectTypeFilter.test.tsx.snap +++ b/src/renderer/components/filters/__snapshots__/SubjectTypeFilter.test.tsx.snap @@ -31,6 +31,11 @@ exports[`renderer/components/filters/SubjectTypeFilter.tsx should be able to tog > Check Suite + + 0 +
Commit + + 0 +
Discussion + + 0 +
Issue + + 0 +
Pull Request + + 0 +
Release + + 0 +
Dependabot Alert + + 0 +
Invitation + + 0 +
Vulnerability Alert + + 0 +
Workflow Run + + 0 +
`; @@ -264,6 +314,11 @@ exports[`renderer/components/filters/SubjectTypeFilter.tsx should be able to tog > Check Suite + + 0 +
Commit + + 0 +
Discussion + + 0 +
Issue + + 0 +
Pull Request + + 0 +
Release + + 0 +
Dependabot Alert + + 0 +
Invitation + + 0 +
Vulnerability Alert + + 0 +
Workflow Run + + 0 +
`; @@ -473,7 +573,6 @@ exports[`renderer/components/filters/SubjectTypeFilter.tsx should render itself "baseElement":
Check Suite + + 0 +
Commit + + 0 +
Discussion + + 0 +
- -  ( 2 - )
- -  ( - 1 - ) -
- -  ( - 1 - ) -
Dependabot Alert + + 0 +
Invitation + + 0 +
Vulnerability Alert + + 0 +
Workflow Run + + 0 +
@@ -825,7 +932,6 @@ exports[`renderer/components/filters/SubjectTypeFilter.tsx should render itself , "container":
Check Suite + + 0 +
Commit + + 0 +
Discussion + + 0 +
- -  ( 2 - )
- -  ( 1 - )
- -  ( 1 - )
Dependabot Alert + + 0 +
Invitation + + 0 +
Vulnerability Alert + + 0 +
Workflow Run + + 0 +
diff --git a/src/renderer/components/filters/__snapshots__/UserHandleFilter.test.tsx.snap b/src/renderer/components/filters/__snapshots__/UserHandleFilter.test.tsx.snap index 266a158f8..db4435a12 100644 --- a/src/renderer/components/filters/__snapshots__/UserHandleFilter.test.tsx.snap +++ b/src/renderer/components/filters/__snapshots__/UserHandleFilter.test.tsx.snap @@ -6,7 +6,6 @@ exports[`renderer/components/filters/UserHandleFilter.tsx should render itself & "baseElement":
, "container":
, "container":
User + + 0 +
+ + 0 +
Organization + + 0 +
`; @@ -134,6 +149,11 @@ exports[`renderer/components/filters/UserTypeFilter.tsx should be able to toggle > User + + 0 +
+ + 0 +
Organization + + 0 +
`; @@ -211,12 +241,11 @@ exports[`renderer/components/filters/UserTypeFilter.tsx should render itself & i "baseElement":
- -  ( - 1 - ) -
+ + 0 +
Organization + + 0 +
@@ -407,12 +437,11 @@ exports[`renderer/components/filters/UserTypeFilter.tsx should render itself & i , "container":
- -  ( - 1 - ) -
+ + 0 +
Organization + + 0 +
@@ -660,12 +690,11 @@ exports[`renderer/components/filters/UserTypeFilter.tsx should render itself & i "baseElement":
- -  ( 1 - )
+ + 0 +
Organization + + 0 +
@@ -853,12 +883,11 @@ exports[`renderer/components/filters/UserTypeFilter.tsx should render itself & i , "container":
- -  ( 1 - )
+ + 0 +
Organization + + 0 +
diff --git a/src/renderer/components/layout/AppLayout.test.tsx b/src/renderer/components/layout/AppLayout.test.tsx new file mode 100644 index 000000000..2a41945d2 --- /dev/null +++ b/src/renderer/components/layout/AppLayout.test.tsx @@ -0,0 +1,26 @@ +import { render } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; + +import { mockAuth, mockSettings } from '../../__mocks__/state-mocks'; +import { AppContext } from '../../context/App'; +import { AppLayout } from './AppLayout'; + +describe('renderer/components/layout/AppLayout.tsx', () => { + it('should render itself & its children', () => { + const tree = render( + + + Test + + , + ); + + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/src/renderer/components/layout/AppLayout.tsx b/src/renderer/components/layout/AppLayout.tsx new file mode 100644 index 000000000..048ecffab --- /dev/null +++ b/src/renderer/components/layout/AppLayout.tsx @@ -0,0 +1,22 @@ +import { Box } from '@primer/react'; +import type { FC, ReactNode } from 'react'; + +import { Sidebar } from '../Sidebar'; + +interface IAppLayout { + children: ReactNode; +} + +/** + * AppLayout is the main container for the application. + * It handles the basic layout with sidebar and content area. + */ +export const AppLayout: FC = ({ children }) => { + return ( + + + {/* Content area with left padding to make space for the sidebar */} + {children} + + ); +}; diff --git a/src/renderer/components/layout/Contents.tsx b/src/renderer/components/layout/Contents.tsx index b50b08272..682315d1c 100644 --- a/src/renderer/components/layout/Contents.tsx +++ b/src/renderer/components/layout/Contents.tsx @@ -1,14 +1,31 @@ import { Box } from '@primer/react'; import type { FC, ReactNode } from 'react'; +import { cn } from '../../utils/cn'; interface IContents { children: ReactNode; + paddingHorizontal?: boolean; + paddingBottom?: boolean; } -export const Contents: FC = (props: IContents) => { +/** + * Contents component holds the main content of a page. + * It provides proper padding and handles scrolling. + */ +export const Contents: FC = ({ + children, + paddingHorizontal = true, + paddingBottom = false, +}) => { return ( - - {props.children} + + {children} ); }; diff --git a/src/renderer/components/layout/Page.tsx b/src/renderer/components/layout/Page.tsx index 123ccdac0..34f077325 100644 --- a/src/renderer/components/layout/Page.tsx +++ b/src/renderer/components/layout/Page.tsx @@ -6,10 +6,15 @@ interface IPage { id: string; } -export const Page: FC = (props: IPage) => { +/** + * Page component represents a single page view. + * It creates a column layout for header, content, and footer. + * The height is 100% to fill the parent container. + */ +export const Page: FC = ({ children, id }) => { return ( - - {props.children} + + {children} ); }; diff --git a/src/renderer/components/layout/__snapshots__/AppLayout.test.tsx.snap b/src/renderer/components/layout/__snapshots__/AppLayout.test.tsx.snap new file mode 100644 index 000000000..06272ae28 --- /dev/null +++ b/src/renderer/components/layout/__snapshots__/AppLayout.test.tsx.snap @@ -0,0 +1,582 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renderer/components/layout/AppLayout.tsx should render itself & its children 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+ +
+ Test +
+
+
+ , + "container":
+
+ +
+ Test +
+
+
, + "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/layout/__snapshots__/Contents.test.tsx.snap b/src/renderer/components/layout/__snapshots__/Contents.test.tsx.snap index ef2f6fb2f..b9d0969b3 100644 --- a/src/renderer/components/layout/__snapshots__/Contents.test.tsx.snap +++ b/src/renderer/components/layout/__snapshots__/Contents.test.tsx.snap @@ -6,7 +6,7 @@ exports[`renderer/components/layout/Contents.tsx should render itself & its chil "baseElement":
Test
@@ -14,7 +14,7 @@ exports[`renderer/components/layout/Contents.tsx should render itself & its chil , "container":
Test
diff --git a/src/renderer/components/primitives/CustomCounter.test.tsx b/src/renderer/components/primitives/CustomCounter.test.tsx new file mode 100644 index 000000000..60239b859 --- /dev/null +++ b/src/renderer/components/primitives/CustomCounter.test.tsx @@ -0,0 +1,10 @@ +import { render } from '@testing-library/react'; +import { CustomCounter } from './CustomCounter'; + +describe('renderer/components/primitives/CustomCounter.tsx', () => { + it('should render itself & its children', () => { + const tree = render(); + + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/src/renderer/components/primitives/CustomCounter.tsx b/src/renderer/components/primitives/CustomCounter.tsx new file mode 100644 index 000000000..c9a9e5943 --- /dev/null +++ b/src/renderer/components/primitives/CustomCounter.tsx @@ -0,0 +1,37 @@ +import type { FC } from 'react'; + +import { Text } from '@primer/react'; + +import { cn } from '../../utils/cn'; + +type CounterScheme = 'primary' | 'secondary' | 'empty'; + +interface ICustomCounter { + /** The content to display within the counter */ + value: string | number; + /** The visual style of the counter */ + scheme?: CounterScheme; +} + +/** + * CustomCounter is a component that displays a small count or numeric indicator, + * similar to CounterLabel from @primer/react but with customizable styling. + * + * Created due to odd behavior with CounterLabel: + * - would show screen vertical scrollbar which is undesirable. + * - would not render '0' within a counter. + */ +export const CustomCounter: FC = ({ + value, + scheme = 'secondary', +}) => { + const baseStyles = + 'px-1.5 py-0.75 rounded-full text-[10px] font-medium leading-none min-w-[16px] text-gitify-counter-text'; + + const schemeStyles = { + primary: 'bg-gitify-counter-primary', + secondary: 'bg-gitify-counter-secondary', + }; + + return {value}; +}; diff --git a/src/renderer/components/primitives/Footer.tsx b/src/renderer/components/primitives/Footer.tsx index 99fff8479..5388f0149 100644 --- a/src/renderer/components/primitives/Footer.tsx +++ b/src/renderer/components/primitives/Footer.tsx @@ -6,11 +6,15 @@ interface IFooter { justify: 'end' | 'space-between'; } -export const Footer: FC = (props: IFooter) => { +/** + * Footer component displays actions at the bottom of the page. + * It is fixed to the viewport bottom. + */ +export const Footer: FC = ({ children, justify }) => { return ( - - - {props.children} + + + {children} ); diff --git a/src/renderer/components/primitives/Header.test.tsx b/src/renderer/components/primitives/Header.test.tsx index 0a2eececb..50ad7c581 100644 --- a/src/renderer/components/primitives/Header.test.tsx +++ b/src/renderer/components/primitives/Header.test.tsx @@ -37,7 +37,7 @@ describe('renderer/components/primitives/Header.tsx', () => { fetchNotifications, }} > -
+
Test Header
, diff --git a/src/renderer/components/primitives/__snapshots__/CustomCounter.test.tsx.snap b/src/renderer/components/primitives/__snapshots__/CustomCounter.test.tsx.snap new file mode 100644 index 000000000..9ae36cf61 --- /dev/null +++ b/src/renderer/components/primitives/__snapshots__/CustomCounter.test.tsx.snap @@ -0,0 +1,74 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renderer/components/primitives/CustomCounter.tsx should render itself & its children 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+ + 100 + +
+ , + "container":
+ + 100 + +
, + "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/primitives/__snapshots__/Footer.test.tsx.snap b/src/renderer/components/primitives/__snapshots__/Footer.test.tsx.snap index dfb9c4efb..7a529f34b 100644 --- a/src/renderer/components/primitives/__snapshots__/Footer.test.tsx.snap +++ b/src/renderer/components/primitives/__snapshots__/Footer.test.tsx.snap @@ -6,7 +6,7 @@ exports[`renderer/components/primitives/Footer.tsx should render itself & its ch "baseElement":
Check Suite + + 0 +
Commit + + 0 +
Discussion + + 0 +
Issue + + 0 +
Pull Request + + 0 +
Release + + 0 +
Dependabot Alert + + 0 +
Invitation + + 0 +
Vulnerability Alert + + 0 +
Workflow Run + + 0 +
Draft + + 0 +
+ + 0 +
Merged + + 0 +
+ + 0 +
+ + 0 +
@@ -1170,6 +1255,11 @@ exports[`renderer/routes/Filters.tsx General should render itself & its children /> + + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +
+ + 0 +