Skip to content

Commit c442ff5

Browse files
Implement skipped repositories tabs
1 parent 110d930 commit c442ff5

11 files changed

Lines changed: 462 additions & 30 deletions

extensions/ql-vscode/src/remote-queries/shared/variant-analysis.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,13 @@ export interface VariantAnalysisSkippedRepositories {
7272

7373
export interface VariantAnalysisSkippedRepositoryGroup {
7474
repositoryCount: number,
75-
repositories: Array<{
76-
id?: number,
77-
fullName: string
78-
}>
75+
repositories: Array<VariantAnalysisSkippedRepository>,
76+
}
77+
78+
export interface VariantAnalysisSkippedRepository {
79+
id?: number,
80+
fullName: string,
81+
private?: boolean,
7982
}
8083

8184
/**
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React from 'react';
2+
3+
import { ComponentMeta, ComponentStory } from '@storybook/react';
4+
5+
import { VariantAnalysisContainer } from '../../view/variant-analysis/VariantAnalysisContainer';
6+
import { VariantAnalysisSkippedRepositoriesTab } from '../../view/variant-analysis/VariantAnalysisSkippedRepositoriesTab';
7+
8+
export default {
9+
title: 'Variant Analysis/Variant Analysis Skipped Repositories Tab',
10+
component: VariantAnalysisSkippedRepositoriesTab,
11+
decorators: [
12+
(Story) => (
13+
<VariantAnalysisContainer>
14+
<Story />
15+
</VariantAnalysisContainer>
16+
)
17+
],
18+
} as ComponentMeta<typeof VariantAnalysisSkippedRepositoriesTab>;
19+
20+
const Template: ComponentStory<typeof VariantAnalysisSkippedRepositoriesTab> = (args) => (
21+
<VariantAnalysisSkippedRepositoriesTab {...args} />
22+
);
23+
24+
export const NoAccessNoOmissions = Template.bind({});
25+
NoAccessNoOmissions.args = {
26+
reason: 'no_access',
27+
skippedRepositoryGroup: {
28+
repositoryCount: 2,
29+
repositories: [
30+
{
31+
fullName: 'octodemo/hello-globe',
32+
},
33+
{
34+
fullName: 'octodemo/hello-planet',
35+
},
36+
],
37+
},
38+
};
39+
40+
export const NoAccessWithOmissions = Template.bind({});
41+
NoAccessWithOmissions.args = {
42+
reason: 'no_access',
43+
skippedRepositoryGroup: {
44+
repositoryCount: 12345,
45+
repositories: [
46+
{
47+
fullName: 'octodemo/hello-globe',
48+
},
49+
{
50+
fullName: 'octodemo/hello-planet',
51+
},
52+
{
53+
fullName: 'octodemo/hello-universe',
54+
},
55+
],
56+
},
57+
};
58+
59+
export const NoDatabaseNoOmissions = Template.bind({});
60+
NoDatabaseNoOmissions.args = {
61+
reason: 'no_database',
62+
skippedRepositoryGroup: {
63+
repositoryCount: 2,
64+
repositories: [
65+
{
66+
id: 1,
67+
fullName: 'octodemo/hello-globe',
68+
private: false,
69+
},
70+
{
71+
id: 2,
72+
fullName: 'octodemo/hello-planet',
73+
private: true,
74+
},
75+
],
76+
},
77+
};
78+
79+
export const NoDatabaseWithOmissions = Template.bind({});
80+
NoDatabaseWithOmissions.args = {
81+
reason: 'no_database',
82+
skippedRepositoryGroup: {
83+
repositoryCount: 12345,
84+
repositories: [
85+
{
86+
id: 1,
87+
fullName: 'octodemo/hello-globe',
88+
private: false,
89+
},
90+
{
91+
id: 2,
92+
fullName: 'octodemo/hello-planet',
93+
private: true,
94+
},
95+
{
96+
id: 3,
97+
fullName: 'octodemo/hello-universe',
98+
private: false,
99+
},
100+
],
101+
},
102+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
3+
import { ComponentMeta, ComponentStory } from '@storybook/react';
4+
5+
import { VariantAnalysisContainer } from '../../view/variant-analysis/VariantAnalysisContainer';
6+
import { VariantAnalysisSkippedRepositoryRow } from '../../view/variant-analysis/VariantAnalysisSkippedRepositoryRow';
7+
8+
export default {
9+
title: 'Variant Analysis/Variant Analysis Skipped Repository',
10+
component: VariantAnalysisSkippedRepositoryRow,
11+
decorators: [
12+
(Story) => (
13+
<VariantAnalysisContainer>
14+
<Story />
15+
</VariantAnalysisContainer>
16+
)
17+
],
18+
} as ComponentMeta<typeof VariantAnalysisSkippedRepositoryRow>;
19+
20+
const Template: ComponentStory<typeof VariantAnalysisSkippedRepositoryRow> = (args) => (
21+
<VariantAnalysisSkippedRepositoryRow {...args} />
22+
);
23+
24+
export const OnlyFullName = Template.bind({});
25+
OnlyFullName.args = {
26+
repository: {
27+
fullName: 'octodemo/hello-globe',
28+
}
29+
};
30+
31+
export const Public = Template.bind({});
32+
Public.args = {
33+
repository: {
34+
fullName: 'octodemo/hello-globe',
35+
private: false,
36+
}
37+
};
38+
39+
export const Private = Template.bind({});
40+
Private.args = {
41+
repository: {
42+
fullName: 'octodemo/hello-globe',
43+
private: true,
44+
}
45+
};

extensions/ql-vscode/src/view/variant-analysis/VariantAnalysis.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const variantAnalysis: VariantAnalysisDomainModel = {
106106
],
107107
skippedRepos: {
108108
notFoundRepos: {
109-
repositoryCount: 2,
109+
repositoryCount: 9999,
110110
repositories: [
111111
{
112112
fullName: 'octodemo/hello-globe'
@@ -121,19 +121,23 @@ const variantAnalysis: VariantAnalysisDomainModel = {
121121
repositories: [
122122
{
123123
id: 100,
124-
fullName: 'octodemo/no-db-1'
124+
fullName: 'octodemo/no-db-1',
125+
private: false,
125126
},
126127
{
127128
id: 101,
128-
fullName: 'octodemo/no-db-2'
129+
fullName: 'octodemo/no-db-2',
130+
private: true,
129131
},
130132
{
131133
id: 102,
132-
fullName: 'octodemo/no-db-3'
134+
fullName: 'octodemo/no-db-3',
135+
private: true,
133136
},
134137
{
135138
id: 103,
136-
fullName: 'octodemo/no-db-4'
139+
fullName: 'octodemo/no-db-4',
140+
private: false,
137141
}
138142
]
139143
},

extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisNoCodeqlDbRepos.tsx

Lines changed: 0 additions & 5 deletions
This file was deleted.

extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisNotFoundRepos.tsx

Lines changed: 0 additions & 5 deletions
This file was deleted.

extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisOutcomePanels.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import { VSCodeBadge, VSCodePanels, VSCodePanelTab, VSCodePanelView } from '@vsc
44
import { formatDecimal } from '../../pure/number';
55
import { VariantAnalysis } from '../../remote-queries/shared/variant-analysis';
66
import { VariantAnalysisAnalyzedRepos } from './VariantAnalysisAnalyzedRepos';
7-
import { VariantAnalysisNotFoundRepos } from './VariantAnalysisNotFoundRepos';
8-
import { VariantAnalysisNoCodeqlDbRepos } from './VariantAnalysisNoCodeqlDbRepos';
97
import { Alert } from '../common';
8+
import { VariantAnalysisSkippedRepositoriesTab } from './VariantAnalysisSkippedRepositoriesTab';
109

1110
export type VariantAnalysisOutcomePanelProps = {
1211
variantAnalysis: VariantAnalysis;
@@ -35,8 +34,8 @@ const WarningsContainer = styled.div`
3534
export const VariantAnalysisOutcomePanels = ({
3635
variantAnalysis
3736
}: VariantAnalysisOutcomePanelProps) => {
38-
const noCodeqlDbRepositoryCount = variantAnalysis.skippedRepos?.noCodeqlDbRepos?.repositoryCount ?? 0;
39-
const notFoundRepositoryCount = variantAnalysis.skippedRepos?.notFoundRepos?.repositoryCount ?? 0;
37+
const noCodeqlDbRepos = variantAnalysis.skippedRepos?.noCodeqlDbRepos;
38+
const notFoundRepos = variantAnalysis.skippedRepos?.notFoundRepos;
4039
const overLimitRepositoryCount = variantAnalysis.skippedRepos?.overLimitRepos?.repositoryCount ?? 0;
4140
const accessMismatchRepositoryCount = variantAnalysis.skippedRepos?.accessMismatchRepos?.repositoryCount ?? 0;
4241

@@ -59,7 +58,7 @@ export const VariantAnalysisOutcomePanels = ({
5958
</WarningsContainer>
6059
);
6160

62-
if (noCodeqlDbRepositoryCount === 0 && notFoundRepositoryCount === 0) {
61+
if (!noCodeqlDbRepos?.repositoryCount && !notFoundRepos?.repositoryCount) {
6362
return (
6463
<>
6564
{warnings}
@@ -76,21 +75,31 @@ export const VariantAnalysisOutcomePanels = ({
7675
Analyzed
7776
<VSCodeBadge appearance="secondary">{formatDecimal(variantAnalysis.scannedRepos?.length ?? 0)}</VSCodeBadge>
7877
</Tab>
79-
{notFoundRepositoryCount > 0 && (
78+
{notFoundRepos?.repositoryCount && (
8079
<Tab>
8180
No access
82-
<VSCodeBadge appearance="secondary">{formatDecimal(notFoundRepositoryCount)}</VSCodeBadge>
81+
<VSCodeBadge appearance="secondary">{formatDecimal(notFoundRepos.repositoryCount)}</VSCodeBadge>
8382
</Tab>
8483
)}
85-
{noCodeqlDbRepositoryCount > 0 && (
84+
{noCodeqlDbRepos?.repositoryCount && (
8685
<Tab>
8786
No database
88-
<VSCodeBadge appearance="secondary">{formatDecimal(noCodeqlDbRepositoryCount)}</VSCodeBadge>
87+
<VSCodeBadge appearance="secondary">{formatDecimal(noCodeqlDbRepos.repositoryCount)}</VSCodeBadge>
8988
</Tab>
9089
)}
9190
<VSCodePanelView><VariantAnalysisAnalyzedRepos /></VSCodePanelView>
92-
{notFoundRepositoryCount > 0 && <VSCodePanelView><VariantAnalysisNotFoundRepos /></VSCodePanelView>}
93-
{noCodeqlDbRepositoryCount > 0 && <VSCodePanelView><VariantAnalysisNoCodeqlDbRepos /></VSCodePanelView>}
91+
{notFoundRepos?.repositoryCount &&
92+
<VSCodePanelView>
93+
<VariantAnalysisSkippedRepositoriesTab
94+
reason='no_access'
95+
skippedRepositoryGroup={notFoundRepos} />
96+
</VSCodePanelView>}
97+
{noCodeqlDbRepos?.repositoryCount &&
98+
<VSCodePanelView>
99+
<VariantAnalysisSkippedRepositoriesTab
100+
reason='no_database'
101+
skippedRepositoryGroup={noCodeqlDbRepos} />
102+
</VSCodePanelView>}
94103
</VSCodePanels>
95104
</>
96105
);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import * as React from 'react';
2+
import styled from 'styled-components';
3+
import { VariantAnalysisSkippedRepositoryGroup } from '../../remote-queries/shared/variant-analysis';
4+
import { Alert } from '../common';
5+
import { VariantAnalysisSkippedRepositoryRow } from './VariantAnalysisSkippedRepositoryRow';
6+
7+
export type SkippedRepositoriesReason = 'no_access' | 'no_database';
8+
9+
export type VariantAnalysisSkippedRepositoriesTabProps = {
10+
reason: SkippedRepositoriesReason,
11+
skippedRepositoryGroup: VariantAnalysisSkippedRepositoryGroup,
12+
};
13+
14+
function getSkipReasonAlertTitle(reason: SkippedRepositoriesReason): string {
15+
switch (reason) {
16+
case 'no_access':
17+
return 'No access';
18+
case 'no_database':
19+
return 'No database';
20+
}
21+
}
22+
23+
function getSkipReasonAlertMessage(
24+
reason: SkippedRepositoriesReason,
25+
repos: VariantAnalysisSkippedRepositoryGroup
26+
): string {
27+
const repositoriesOmittedText = repos.repositoryCount > repos.repositories.length
28+
? ` (Only the first ${repos.repositories.length} ${repos.repositories.length > 1 ? 'repositories are' : 'repository is'} shown.)`
29+
: '';
30+
switch (reason) {
31+
case 'no_access':
32+
return `The following repositories could not be scanned because you do not have read access.${repositoriesOmittedText}`;
33+
case 'no_database':
34+
return `The following repositories could not be scanned because they do not have an available CodeQL database.${repositoriesOmittedText}`;
35+
}
36+
}
37+
38+
function getSkipReasonAlert(
39+
reason: SkippedRepositoriesReason,
40+
repos: VariantAnalysisSkippedRepositoryGroup
41+
) {
42+
return (
43+
<Alert
44+
key='alert'
45+
type='warning'
46+
title={getSkipReasonAlertTitle(reason)}
47+
message={getSkipReasonAlertMessage(reason, repos)}
48+
/>
49+
);
50+
}
51+
52+
const Container = styled.div`
53+
display: flex;
54+
flex-direction: column;
55+
gap: 0.5em;
56+
width: 100%;
57+
`;
58+
59+
export const VariantAnalysisSkippedRepositoriesTab = ({
60+
reason,
61+
skippedRepositoryGroup,
62+
}: VariantAnalysisSkippedRepositoriesTabProps) => {
63+
return (
64+
<Container>
65+
{getSkipReasonAlert(reason, skippedRepositoryGroup)}
66+
{skippedRepositoryGroup.repositories.map((repo) =>
67+
<VariantAnalysisSkippedRepositoryRow key={`repo/${repo.fullName}`} repository={repo} />
68+
)}
69+
</Container>
70+
);
71+
};

0 commit comments

Comments
 (0)