Receive setRepoStates message in webview

This commit is contained in:
Koen Vlaswinkel
2022-10-04 16:18:16 +02:00
parent 339fc9a755
commit 7c935b37b0
4 changed files with 84 additions and 47 deletions

View File

@@ -2,7 +2,11 @@ import * as React from 'react';
import { useCallback, useState } from 'react';
import styled from 'styled-components';
import { VSCodeBadge, VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import { isCompletedAnalysisRepoStatus, VariantAnalysisRepoStatus } from '../../remote-queries/shared/variant-analysis';
import {
isCompletedAnalysisRepoStatus,
VariantAnalysisRepoStatus,
VariantAnalysisScannedRepositoryDownloadStatus
} from '../../remote-queries/shared/variant-analysis';
import { formatDecimal } from '../../pure/number';
import { Codicon, ErrorIcon, LoadingIcon, SuccessIcon, WarningIcon } from '../common';
import { Repository } from '../../remote-queries/shared/repository';
@@ -62,6 +66,7 @@ export type RepoRowProps = {
// Only fullName is required
repository: Partial<Repository> & Pick<Repository, 'fullName'>;
status?: VariantAnalysisRepoStatus;
downloadStatus?: VariantAnalysisScannedRepositoryDownloadStatus;
resultCount?: number;
interpretedResults?: AnalysisAlert[];

View File

@@ -5,10 +5,9 @@ import { ToVariantAnalysisMessage } from '../../pure/interface-types';
import {
VariantAnalysis as VariantAnalysisDomainModel,
VariantAnalysisQueryLanguage,
VariantAnalysisRepoStatus, VariantAnalysisScannedRepositoryResult,
VariantAnalysisRepoStatus, VariantAnalysisScannedRepositoryResult, VariantAnalysisScannedRepositoryState,
VariantAnalysisStatus
} from '../../remote-queries/shared/variant-analysis';
import { VariantAnalysisContainer } from './VariantAnalysisContainer';
import { VariantAnalysisHeader } from './VariantAnalysisHeader';
import { VariantAnalysisOutcomePanels } from './VariantAnalysisOutcomePanels';
import { VariantAnalysisLoading } from './VariantAnalysisLoading';
@@ -200,7 +199,46 @@ const repositoryResults: VariantAnalysisScannedRepositoryResult[] = [
}
];
function getContainerContents(variantAnalysis: VariantAnalysisDomainModel, repoResults: VariantAnalysisScannedRepositoryResult[]) {
type Props = {
variantAnalysis?: VariantAnalysisDomainModel;
repoStates?: VariantAnalysisScannedRepositoryState[];
repoResults?: VariantAnalysisScannedRepositoryResult[];
}
export function VariantAnalysis({
variantAnalysis: initialVariantAnalysis = variantAnalysis,
repoStates: initialRepoStates = [],
repoResults: initialRepoResults = repositoryResults,
}: Props): JSX.Element {
const [variantAnalysis, setVariantAnalysis] = useState<VariantAnalysisDomainModel>(initialVariantAnalysis);
const [repoStates, setRepoStates] = useState<VariantAnalysisScannedRepositoryState[]>(initialRepoStates);
const [repoResults, setRepoResults] = useState<VariantAnalysisScannedRepositoryResult[]>(initialRepoResults);
useEffect(() => {
window.addEventListener('message', (evt: MessageEvent) => {
if (evt.origin === window.origin) {
const msg: ToVariantAnalysisMessage = evt.data;
if (msg.t === 'setVariantAnalysis') {
setVariantAnalysis(msg.variantAnalysis);
} else if (msg.t === 'setRepoResults') {
setRepoResults(oldRepoResults => {
const newRepoIds = msg.repoResults.map(r => r.repositoryId);
return [...oldRepoResults.filter(v => !newRepoIds.includes(v.repositoryId)), ...msg.repoResults];
});
} else if (msg.t === 'setRepoStates') {
setRepoStates(oldRepoStates => {
const newRepoIds = msg.repoStates.map(r => r.repositoryId);
return [...oldRepoStates.filter(v => !newRepoIds.includes(v.repositoryId)), ...msg.repoStates];
});
}
} else {
// sanitize origin
const origin = evt.origin.replace(/\n|\r/g, '');
console.error(`Invalid event origin ${origin}`);
}
});
});
if (variantAnalysis.actionsWorkflowRunId === undefined) {
return <VariantAnalysisLoading />;
}
@@ -218,47 +256,9 @@ function getContainerContents(variantAnalysis: VariantAnalysisDomainModel, repoR
/>
<VariantAnalysisOutcomePanels
variantAnalysis={variantAnalysis}
repositoryStates={repoStates}
repositoryResults={repoResults}
/>
</>
);
}
type Props = {
variantAnalysis?: VariantAnalysisDomainModel;
repoResults?: VariantAnalysisScannedRepositoryResult[];
}
export function VariantAnalysis({
variantAnalysis: initialVariantAnalysis = variantAnalysis,
repoResults: initialRepoResults = repositoryResults,
}: Props): JSX.Element {
const [variantAnalysis, setVariantAnalysis] = useState<VariantAnalysisDomainModel>(initialVariantAnalysis);
const [repoResults, setRepoResults] = useState<VariantAnalysisScannedRepositoryResult[]>(initialRepoResults);
useEffect(() => {
window.addEventListener('message', (evt: MessageEvent) => {
if (evt.origin === window.origin) {
const msg: ToVariantAnalysisMessage = evt.data;
if (msg.t === 'setVariantAnalysis') {
setVariantAnalysis(msg.variantAnalysis);
} else if (msg.t === 'setRepoResults') {
setRepoResults(oldRepoResults => {
const newRepoIds = msg.repoResults.map(r => r.repositoryId);
return [...oldRepoResults.filter(v => !newRepoIds.includes(v.repositoryId)), ...msg.repoResults];
});
}
} else {
// sanitize origin
const origin = evt.origin.replace(/\n|\r/g, '');
console.error(`Invalid event origin ${origin}`);
}
});
});
return (
<VariantAnalysisContainer>
{getContainerContents(variantAnalysis, repoResults)}
</VariantAnalysisContainer>
);
}

View File

@@ -1,7 +1,11 @@
import * as React from 'react';
import styled from 'styled-components';
import { VariantAnalysis, VariantAnalysisScannedRepositoryResult } from '../../remote-queries/shared/variant-analysis';
import { RepoRow } from './RepoRow';
import {
VariantAnalysis,
VariantAnalysisScannedRepositoryResult,
VariantAnalysisScannedRepositoryState
} from '../../remote-queries/shared/variant-analysis';
import { useMemo } from 'react';
const Container = styled.div`
@@ -12,13 +16,23 @@ const Container = styled.div`
export type VariantAnalysisAnalyzedReposProps = {
variantAnalysis: VariantAnalysis;
repositoryStates?: VariantAnalysisScannedRepositoryState[];
repositoryResults?: VariantAnalysisScannedRepositoryResult[];
}
export const VariantAnalysisAnalyzedRepos = ({
variantAnalysis,
repositoryStates,
repositoryResults,
}: VariantAnalysisAnalyzedReposProps) => {
const repositoryStateById = useMemo(() => {
const map = new Map<number, VariantAnalysisScannedRepositoryState>();
repositoryStates?.forEach((repository) => {
map.set(repository.repositoryId, repository);
});
return map;
}, [repositoryStates]);
const repositoryResultsById = useMemo(() => {
const map = new Map<number, VariantAnalysisScannedRepositoryResult>();
repositoryResults?.forEach((repository) => {
@@ -30,6 +44,7 @@ export const VariantAnalysisAnalyzedRepos = ({
return (
<Container>
{variantAnalysis.scannedRepos?.map(repository => {
const state = repositoryStateById.get(repository.repository.id);
const results = repositoryResultsById.get(repository.repository.id);
return (
@@ -37,6 +52,7 @@ export const VariantAnalysisAnalyzedRepos = ({
key={repository.repository.id}
repository={repository.repository}
status={repository.analysisStatus}
downloadStatus={state?.downloadStatus}
resultCount={repository.resultCount}
interpretedResults={results?.interpretedResults}
rawResults={results?.rawResults}

View File

@@ -2,13 +2,18 @@ import * as React from 'react';
import styled from 'styled-components';
import { VSCodeBadge, VSCodePanels, VSCodePanelTab, VSCodePanelView } from '@vscode/webview-ui-toolkit/react';
import { formatDecimal } from '../../pure/number';
import { VariantAnalysis, VariantAnalysisScannedRepositoryResult } from '../../remote-queries/shared/variant-analysis';
import {
VariantAnalysis,
VariantAnalysisScannedRepositoryResult,
VariantAnalysisScannedRepositoryState
} from '../../remote-queries/shared/variant-analysis';
import { VariantAnalysisAnalyzedRepos } from './VariantAnalysisAnalyzedRepos';
import { Alert } from '../common';
import { VariantAnalysisSkippedRepositoriesTab } from './VariantAnalysisSkippedRepositoriesTab';
export type VariantAnalysisOutcomePanelProps = {
variantAnalysis: VariantAnalysis;
repositoryStates?: VariantAnalysisScannedRepositoryState[];
repositoryResults?: VariantAnalysisScannedRepositoryResult[];
};
@@ -34,6 +39,7 @@ const WarningsContainer = styled.div`
export const VariantAnalysisOutcomePanels = ({
variantAnalysis,
repositoryStates,
repositoryResults,
}: VariantAnalysisOutcomePanelProps) => {
const noCodeqlDbRepos = variantAnalysis.skippedRepos?.noCodeqlDbRepos;
@@ -64,7 +70,11 @@ export const VariantAnalysisOutcomePanels = ({
return (
<>
{warnings}
<VariantAnalysisAnalyzedRepos variantAnalysis={variantAnalysis} repositoryResults={repositoryResults} />
<VariantAnalysisAnalyzedRepos
variantAnalysis={variantAnalysis}
repositoryStates={repositoryStates}
repositoryResults={repositoryResults}
/>
</>
);
}
@@ -89,7 +99,13 @@ export const VariantAnalysisOutcomePanels = ({
<VSCodeBadge appearance="secondary">{formatDecimal(noCodeqlDbRepos.repositoryCount)}</VSCodeBadge>
</Tab>
)}
<VSCodePanelView><VariantAnalysisAnalyzedRepos variantAnalysis={variantAnalysis} repositoryResults={repositoryResults} /></VSCodePanelView>
<VSCodePanelView>
<VariantAnalysisAnalyzedRepos
variantAnalysis={variantAnalysis}
repositoryStates={repositoryStates}
repositoryResults={repositoryResults}
/>
</VSCodePanelView>
{notFoundRepos?.repositoryCount &&
<VSCodePanelView>
<VariantAnalysisSkippedRepositoriesTab