Extract external api usage name component and reuse it (#2765)

This commit is contained in:
Charis Kyriakou
2023-08-31 10:12:19 +01:00
committed by GitHub
parent e61f619f8f
commit 26b602399a
8 changed files with 99 additions and 32 deletions

View File

@@ -0,0 +1,18 @@
import * as React from "react";
import { Meta, StoryFn } from "@storybook/react";
import { ExternalApiUsageName as ExternalApiUsageNameComponent } from "../../view/model-editor/ExternalApiUsageName";
import { createExternalApiUsage } from "../../../test/factories/data-extension/external-api-factories";
export default {
title: "CodeQL Model Editor/External API Usage Name",
component: ExternalApiUsageNameComponent,
} as Meta<typeof ExternalApiUsageNameComponent>;
const Template: StoryFn<typeof ExternalApiUsageNameComponent> = (args) => (
<ExternalApiUsageNameComponent {...args} />
);
export const ExternalApiUsageName = Template.bind({});
ExternalApiUsageName.args = createExternalApiUsage();

View File

@@ -4,6 +4,8 @@ import {
ModelingStatus, ModelingStatus,
ModelingStatusIndicator, ModelingStatusIndicator,
} from "../model-editor/ModelingStatusIndicator"; } from "../model-editor/ModelingStatusIndicator";
import { ExternalApiUsage } from "../../model-editor/external-api-usage";
import { ExternalApiUsageName } from "../model-editor/ExternalApiUsageName";
const Container = styled.div` const Container = styled.div`
background-color: var(--vscode-peekViewResult-background); background-color: var(--vscode-peekViewResult-background);
@@ -21,21 +23,20 @@ const DependencyContainer = styled.div`
justify-content: space-between; justify-content: space-between;
`; `;
const DependencyName = styled.span`
font-family: var(--vscode-editor-font-family);
`;
export type MethodModelingProps = { export type MethodModelingProps = {
modelingStatus: ModelingStatus; modelingStatus: ModelingStatus;
externalApiUsage: ExternalApiUsage;
}; };
export const MethodModeling = (props: MethodModelingProps) => { export const MethodModeling = ({
const { modelingStatus } = props; modelingStatus,
externalApiUsage,
}: MethodModelingProps): JSX.Element => {
return ( return (
<Container> <Container>
<Title>API or Method</Title> <Title>API or Method</Title>
<DependencyContainer> <DependencyContainer>
<DependencyName>that.dependency.THENAME</DependencyName> <ExternalApiUsageName {...externalApiUsage} />
<ModelingStatusIndicator status={modelingStatus} /> <ModelingStatusIndicator status={modelingStatus} />
</DependencyContainer> </DependencyContainer>
</Container> </Container>

View File

@@ -2,6 +2,7 @@ import * as React from "react";
import { useEffect } from "react"; import { useEffect } from "react";
import { MethodModeling } from "./MethodModeling"; import { MethodModeling } from "./MethodModeling";
import { ModelingStatus } from "../model-editor/ModelingStatusIndicator"; import { ModelingStatus } from "../model-editor/ModelingStatusIndicator";
import { ExternalApiUsage } from "../../model-editor/external-api-usage";
export function MethodModelingView(): JSX.Element { export function MethodModelingView(): JSX.Element {
useEffect(() => { useEffect(() => {
@@ -22,5 +23,22 @@ export function MethodModelingView(): JSX.Element {
}, []); }, []);
const modelingStatus: ModelingStatus = "saved"; const modelingStatus: ModelingStatus = "saved";
return <MethodModeling modelingStatus={modelingStatus} />; const externalApiUsage: ExternalApiUsage = {
library: "sql2o",
libraryVersion: "1.6.0",
signature: "org.sql2o.Connection#createQuery(String)",
packageName: "org.sql2o",
typeName: "Connection",
methodName: "createQuery",
methodParameters: "(String)",
supported: true,
supportedType: "summary",
usages: [],
};
return (
<MethodModeling
modelingStatus={modelingStatus}
externalApiUsage={externalApiUsage}
/>
);
} }

View File

@@ -1,14 +1,18 @@
import * as React from "react"; import * as React from "react";
import { render as reactRender, screen } from "@testing-library/react"; import { render as reactRender, screen } from "@testing-library/react";
import { MethodModeling, MethodModelingProps } from "../MethodModeling"; import { MethodModeling, MethodModelingProps } from "../MethodModeling";
import { createExternalApiUsage } from "../../../../test/factories/data-extension/external-api-factories";
describe(MethodModeling.name, () => { describe(MethodModeling.name, () => {
const render = (props: MethodModelingProps) => const render = (props: MethodModelingProps) =>
reactRender(<MethodModeling {...props} />); reactRender(<MethodModeling {...props} />);
it("renders method name", () => { it("renders method modeling panel", () => {
render({ modelingStatus: "saved" }); render({
modelingStatus: "saved",
externalApiUsage: createExternalApiUsage(),
});
expect(screen.getByText("that.dependency.THENAME")).toBeInTheDocument(); expect(screen.getByText("API or Method")).toBeInTheDocument();
}); });
}); });

View File

@@ -0,0 +1,19 @@
import * as React from "react";
import { styled } from "styled-components";
import { ExternalApiUsage } from "../../model-editor/external-api-usage";
const Name = styled.span`
font-family: var(--vscode-editor-font-family);
`;
export const ExternalApiUsageName = (
externalApiUsage: ExternalApiUsage,
): JSX.Element => {
return (
<Name>
{externalApiUsage.packageName && <>{externalApiUsage.packageName}.</>}
{externalApiUsage.typeName}.{externalApiUsage.methodName}
{externalApiUsage.methodParameters}
</Name>
);
};

View File

@@ -25,6 +25,7 @@ import {
ModelingStatusIndicator, ModelingStatusIndicator,
} from "./ModelingStatusIndicator"; } from "./ModelingStatusIndicator";
import { InProgressDropdown } from "./InProgressDropdown"; import { InProgressDropdown } from "./InProgressDropdown";
import { ExternalApiUsageName } from "./ExternalApiUsageName";
const ApiOrMethodCell = styled(VSCodeDataGridCell)` const ApiOrMethodCell = styled(VSCodeDataGridCell)`
display: flex; display: flex;
@@ -218,7 +219,7 @@ function ModelableMethodRow(props: Props) {
<ApiOrMethodCell gridColumn={1}> <ApiOrMethodCell gridColumn={1}>
<ModelingStatusIndicator status={modelingStatus} /> <ModelingStatusIndicator status={modelingStatus} />
<MethodClassifications externalApiUsage={externalApiUsage} /> <MethodClassifications externalApiUsage={externalApiUsage} />
<ExternalApiUsageName {...props} /> <ExternalApiUsageName {...props.externalApiUsage} />
{mode === Mode.Application && ( {mode === Mode.Application && (
<UsagesButton onClick={jumpToUsage}> <UsagesButton onClick={jumpToUsage}>
{externalApiUsage.usages.length} {externalApiUsage.usages.length}
@@ -294,7 +295,7 @@ function UnmodelableMethodRow(props: Props) {
<VSCodeDataGridRow> <VSCodeDataGridRow>
<ApiOrMethodCell gridColumn={1}> <ApiOrMethodCell gridColumn={1}>
<ModelingStatusIndicator status="saved" /> <ModelingStatusIndicator status="saved" />
<ExternalApiUsageName {...props} /> <ExternalApiUsageName {...props.externalApiUsage} />
{mode === Mode.Application && ( {mode === Mode.Application && (
<UsagesButton onClick={jumpToUsage}> <UsagesButton onClick={jumpToUsage}>
{externalApiUsage.usages.length} {externalApiUsage.usages.length}
@@ -310,18 +311,6 @@ function UnmodelableMethodRow(props: Props) {
); );
} }
function ExternalApiUsageName(props: { externalApiUsage: ExternalApiUsage }) {
return (
<span>
{props.externalApiUsage.packageName && (
<>{props.externalApiUsage.packageName}.</>
)}
{props.externalApiUsage.typeName}.{props.externalApiUsage.methodName}
{props.externalApiUsage.methodParameters}
</span>
);
}
function sendJumpToUsageMessage(externalApiUsage: ExternalApiUsage) { function sendJumpToUsageMessage(externalApiUsage: ExternalApiUsage) {
vscode.postMessage({ vscode.postMessage({
t: "jumpToUsage", t: "jumpToUsage",

View File

@@ -0,0 +1,18 @@
import * as React from "react";
import { render as reactRender, screen } from "@testing-library/react";
import { ExternalApiUsageName } from "../ExternalApiUsageName";
import { ExternalApiUsage } from "../../../model-editor/external-api-usage";
import { createExternalApiUsage } from "../../../../test/factories/data-extension/external-api-factories";
describe(ExternalApiUsageName.name, () => {
const render = (props: ExternalApiUsage) =>
reactRender(<ExternalApiUsageName {...props} />);
it("renders method name", () => {
const apiUsage = createExternalApiUsage();
render(apiUsage);
const name = `${apiUsage.packageName}.${apiUsage.typeName}.${apiUsage.methodName}${apiUsage.methodParameters}`;
expect(screen.getByText(name)).toBeInTheDocument();
});
});

View File

@@ -7,15 +7,15 @@ import { ModeledMethodType } from "../../../src/model-editor/modeled-method";
import { ResolvableLocationValue } from "../../../src/common/bqrs-cli-types"; import { ResolvableLocationValue } from "../../../src/common/bqrs-cli-types";
export function createExternalApiUsage({ export function createExternalApiUsage({
library = "test", library = "sql2o-1.6.0.jar",
supported = true, supported = true,
supportedType = "none" as ModeledMethodType, supportedType = "summary" as ModeledMethodType,
usages = [], usages = [],
signature = "test", signature = "org.sql2o.Sql2o#open()",
packageName = "test", packageName = "org.sql2o",
typeName = "test", typeName = "Sql2o",
methodName = "test", methodName = "open",
methodParameters = "test", methodParameters = "()",
}: { }: {
library?: string; library?: string;
supported?: boolean; supported?: boolean;