Skip to content

Commit c7a8c5d

Browse files
adrianviquezandrewshie-sentry
authored andcommitted
feat(Codecov): add Codecov repository picker (#92068)
This PR adds the RepoPicker and RepoSelector components as well as adding them to the Test page.
1 parent 3ba33a5 commit c7a8c5d

File tree

4 files changed

+135
-8
lines changed

4 files changed

+135
-8
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {useSearchParams} from 'react-router-dom';
2+
3+
import {useCodecovContext} from 'sentry/components/codecov/context/codecovContext';
4+
import {RepoSelector} from 'sentry/components/codecov/repoPicker/repoSelector';
5+
6+
export function RepoPicker() {
7+
const {repository} = useCodecovContext();
8+
const [searchParams, setSearchParams] = useSearchParams();
9+
10+
return (
11+
<RepoSelector
12+
repository={repository}
13+
onChange={newRepository => {
14+
const currentParams = Object.fromEntries(searchParams.entries());
15+
const updatedParams = {
16+
...currentParams,
17+
repository: newRepository,
18+
};
19+
setSearchParams(updatedParams);
20+
}}
21+
/>
22+
);
23+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import {useCallback, useMemo} from 'react';
2+
import styled from '@emotion/styled';
3+
4+
import type {SelectOption, SingleSelectProps} from 'sentry/components/core/compactSelect';
5+
import {CompactSelect} from 'sentry/components/core/compactSelect';
6+
import DropdownButton from 'sentry/components/dropdownButton';
7+
import {t} from 'sentry/locale';
8+
9+
const CODECOV_PLACEHOLDER_REPOS = ['test repo 1', 'test-repo-2', 'Test Repo 3'];
10+
11+
export interface RepoSelectorProps {
12+
onChange: (data: string) => void;
13+
/**
14+
* Repository value
15+
*/
16+
repository: string | null;
17+
/**
18+
* Optional trigger for the assignee selector. If nothing passed in,
19+
* the default trigger will be used
20+
*/
21+
trigger?: (
22+
props: Omit<React.HTMLAttributes<HTMLElement>, 'children'>,
23+
isOpen: boolean
24+
) => React.ReactNode;
25+
}
26+
27+
export function RepoSelector({onChange, trigger, repository}: RepoSelectorProps) {
28+
const options = useMemo((): Array<SelectOption<string>> => {
29+
// TODO: When API is ready, replace placeholder w/ api response
30+
const repoSet = new Set([
31+
...(repository ? [repository] : []),
32+
...(CODECOV_PLACEHOLDER_REPOS.length ? CODECOV_PLACEHOLDER_REPOS : []),
33+
]);
34+
35+
return [...repoSet].map((value): SelectOption<string> => {
36+
return {
37+
// TODO: ideally this has a unique id, possibly adjust set to an
38+
// object when you have backend response
39+
value,
40+
label: <OptionLabel>{value}</OptionLabel>,
41+
textValue: value,
42+
};
43+
});
44+
}, [repository]);
45+
46+
const handleChange = useCallback<NonNullable<SingleSelectProps<string>['onChange']>>(
47+
newSelected => {
48+
onChange(newSelected.value);
49+
},
50+
[onChange]
51+
);
52+
53+
return (
54+
<CompactSelect
55+
options={options}
56+
value={repository ?? ''}
57+
onChange={handleChange}
58+
menuWidth={'16rem'}
59+
trigger={
60+
trigger ??
61+
((triggerProps, isOpen) => {
62+
const defaultLabel = options.some(item => item.value === repository)
63+
? repository?.toUpperCase()
64+
: t('Select Repo');
65+
66+
return (
67+
<DropdownButton
68+
isOpen={isOpen}
69+
data-test-id="page-filter-codecov-repository-selector"
70+
{...triggerProps}
71+
>
72+
<TriggerLabelWrap>
73+
<TriggerLabel>{defaultLabel}</TriggerLabel>
74+
</TriggerLabelWrap>
75+
</DropdownButton>
76+
);
77+
})
78+
}
79+
/>
80+
);
81+
}
82+
83+
const TriggerLabelWrap = styled('span')`
84+
position: relative;
85+
min-width: 0;
86+
`;
87+
88+
const TriggerLabel = styled('span')`
89+
${p => p.theme.overflowEllipsis}
90+
width: auto;
91+
`;
92+
93+
const OptionLabel = styled('span')`
94+
div {
95+
margin: 0;
96+
}
97+
`;

static/app/views/codecov/tests/tests.spec.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import {OrganizationFixture} from 'sentry-fixture/organization';
2-
31
import {render, screen} from 'sentry-test/reactTestingLibrary';
42

53
import TestsPage from 'sentry/views/codecov/tests/tests';
64

7-
const COVERAGE_FEATURE = 'codecov-ui';
8-
95
describe('CoveragePageWrapper', () => {
106
describe('when the wrapper is used', () => {
11-
it('renders the passed children', () => {
7+
it('renders the passed children', async () => {
128
render(<TestsPage />, {
13-
organization: OrganizationFixture({features: [COVERAGE_FEATURE]}),
9+
initialRouterConfig: {
10+
location: {
11+
pathname: '/codecov/tests',
12+
query: {codecovPeriod: '7d'},
13+
},
14+
},
1415
});
1516

16-
const testsAnalytics = screen.getByText('Test Analytics');
17+
const testsAnalytics = await screen.findByText('Test Analytics');
1718
expect(testsAnalytics).toBeInTheDocument();
1819
});
1920
});

static/app/views/codecov/tests/tests.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import styled from '@emotion/styled';
22

3+
import CodecovProvider from 'sentry/components/codecov/container/codecovParamsProvider';
34
import {DatePicker} from 'sentry/components/codecov/datePicker/datePicker';
4-
// import TestAnalyticsTable from 'sentry/components/codecov/testAnalytics/testAnalyticsTable';
5+
import {RepoPicker} from 'sentry/components/codecov/repoPicker/repoPicker';
56
import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
67
import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
78
import {space} from 'sentry/styles/space';
@@ -72,6 +73,11 @@ export default function TestsPage() {
7273
<DatePicker />
7374
</PageFilterBar>
7475
</PageFiltersContainer>
76+
<CodecovProvider>
77+
<PageFilterBar condensed>
78+
<RepoPicker />
79+
</PageFilterBar>
80+
</CodecovProvider>
7581
{/* TODO: Conditionally show these if the branch we're in is the main branch */}
7682
<Summaries />
7783
<TestAnalyticsTable response={fakeApiResponse} sort={sorts[0]} />

0 commit comments

Comments
 (0)