Merge pull request #3399 from github/koesie10/hide-type-models-non-canary

Hide type models for Ruby by default
This commit is contained in:
Koen Vlaswinkel
2024-02-26 11:58:30 +01:00
committed by GitHub
18 changed files with 157 additions and 9 deletions

View File

@@ -724,6 +724,7 @@ export async function setAutogenerateQlPacks(choice: AutogenerateQLPacks) {
const MODEL_SETTING = new Setting("model", ROOT_SETTING); const MODEL_SETTING = new Setting("model", ROOT_SETTING);
const FLOW_GENERATION = new Setting("flowGeneration", MODEL_SETTING); const FLOW_GENERATION = new Setting("flowGeneration", MODEL_SETTING);
const LLM_GENERATION = new Setting("llmGeneration", MODEL_SETTING); const LLM_GENERATION = new Setting("llmGeneration", MODEL_SETTING);
const SHOW_TYPE_MODELS = new Setting("showTypeModels", MODEL_SETTING);
const LLM_GENERATION_BATCH_SIZE = new Setting( const LLM_GENERATION_BATCH_SIZE = new Setting(
"llmGenerationBatchSize", "llmGenerationBatchSize",
MODEL_SETTING, MODEL_SETTING,
@@ -743,6 +744,7 @@ const ENABLE_ACCESS_PATH_SUGGESTIONS = new Setting(
export interface ModelConfig { export interface ModelConfig {
flowGeneration: boolean; flowGeneration: boolean;
llmGeneration: boolean; llmGeneration: boolean;
showTypeModels: boolean;
getExtensionsDirectory(languageId: string): string | undefined; getExtensionsDirectory(languageId: string): string | undefined;
enablePython: boolean; enablePython: boolean;
enableAccessPathSuggestions: boolean; enableAccessPathSuggestions: boolean;
@@ -761,6 +763,10 @@ export class ModelConfigListener extends ConfigListener implements ModelConfig {
return !!LLM_GENERATION.getValue<boolean>(); return !!LLM_GENERATION.getValue<boolean>();
} }
public get showTypeModels(): boolean {
return !!SHOW_TYPE_MODELS.getValue<boolean>();
}
/** /**
* Limits the number of candidates we send to the model in each request to avoid long requests. * Limits the number of candidates we send to the model in each request to avoid long requests.
* Note that the model may return fewer than this number of candidates. * Note that the model may return fewer than this number of candidates.

View File

@@ -17,9 +17,37 @@ import type {
import type { BaseLogger } from "../../common/logging"; import type { BaseLogger } from "../../common/logging";
import type { AccessPathSuggestionRow } from "../suggestions"; import type { AccessPathSuggestionRow } from "../suggestions";
// This is a subset of the model config that doesn't import the vscode module.
// It only includes settings that are actually used.
export type ModelConfig = {
showTypeModels: boolean;
};
/**
* This function creates a new model config object from the given model config object.
* The new model config object is a deep copy of the given model config object.
*
* @param modelConfig The model config object to create a new model config object from.
* In most cases, this is a `ModelConfigListener`.
*/
export function createModelConfig(modelConfig: ModelConfig): ModelConfig {
return {
showTypeModels: modelConfig.showTypeModels,
};
}
export const defaultModelConfig: ModelConfig = {
showTypeModels: false,
};
type GenerateMethodDefinition<T> = (method: T) => DataTuple[]; type GenerateMethodDefinition<T> = (method: T) => DataTuple[];
type ReadModeledMethod = (row: DataTuple[]) => ModeledMethod; type ReadModeledMethod = (row: DataTuple[]) => ModeledMethod;
type IsHiddenContext = {
method: MethodDefinition;
config: ModelConfig;
};
export type ModelsAsDataLanguagePredicate<T> = { export type ModelsAsDataLanguagePredicate<T> = {
extensiblePredicate: string; extensiblePredicate: string;
supportedKinds?: string[]; supportedKinds?: string[];
@@ -30,6 +58,14 @@ export type ModelsAsDataLanguagePredicate<T> = {
supportedEndpointTypes?: EndpointType[]; supportedEndpointTypes?: EndpointType[];
generateMethodDefinition: GenerateMethodDefinition<T>; generateMethodDefinition: GenerateMethodDefinition<T>;
readModeledMethod: ReadModeledMethod; readModeledMethod: ReadModeledMethod;
/**
* Controls whether this predicate is hidden for a certain method. This only applies to the UI.
* If not specified, the predicate is visible for all methods.
*
* @param method The method to check if the predicate is hidden for.
*/
isHidden?: (context: IsHiddenContext) => boolean;
}; };
type ParseGenerationResults = ( type ParseGenerationResults = (

View File

@@ -169,6 +169,7 @@ export const ruby: ModelsAsDataLanguage = {
methodParameters: "", methodParameters: "",
}; };
}, },
isHidden: ({ config }) => !config.showTypeModels,
}, },
}, },
modelGeneration: { modelGeneration: {

View File

@@ -15,6 +15,7 @@ import type { DatabaseItem } from "../../databases/local-databases";
import type { ModelingEvents } from "../modeling-events"; import type { ModelingEvents } from "../modeling-events";
import type { QueryLanguage } from "../../common/query-language"; import type { QueryLanguage } from "../../common/query-language";
import { tryGetQueryLanguage } from "../../common/query-language"; import { tryGetQueryLanguage } from "../../common/query-language";
import { createModelConfig } from "../languages";
export class MethodModelingViewProvider extends AbstractWebviewViewProvider< export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
ToMethodModelingMessage, ToMethodModelingMessage,
@@ -46,6 +47,7 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
t: "setMethodModelingPanelViewState", t: "setMethodModelingPanelViewState",
viewState: { viewState: {
language: this.language, language: this.language,
modelConfig: createModelConfig(this.modelConfig),
}, },
}); });
} }

View File

@@ -50,7 +50,7 @@ import { telemetryListener } from "../common/vscode/telemetry";
import type { ModelingStore } from "./modeling-store"; import type { ModelingStore } from "./modeling-store";
import type { ModelingEvents } from "./modeling-events"; import type { ModelingEvents } from "./modeling-events";
import type { ModelsAsDataLanguage } from "./languages"; import type { ModelsAsDataLanguage } from "./languages";
import { getModelsAsDataLanguage } from "./languages"; import { createModelConfig, getModelsAsDataLanguage } from "./languages";
import { runGenerateQueries } from "./generate"; import { runGenerateQueries } from "./generate";
import { ResponseError } from "vscode-jsonrpc"; import { ResponseError } from "vscode-jsonrpc";
import { LSPErrorCodes } from "vscode-languageclient"; import { LSPErrorCodes } from "vscode-languageclient";
@@ -456,6 +456,7 @@ export class ModelEditorView extends AbstractWebview<
mode: this.modelingStore.getMode(this.databaseItem), mode: this.modelingStore.getMode(this.databaseItem),
showModeSwitchButton, showModeSwitchButton,
sourceArchiveAvailable, sourceArchiveAvailable,
modelConfig: createModelConfig(this.modelConfig),
}, },
}); });
} }

View File

@@ -1,6 +1,7 @@
import type { ExtensionPack } from "./extension-pack"; import type { ExtensionPack } from "./extension-pack";
import type { Mode } from "./mode"; import type { Mode } from "./mode";
import type { QueryLanguage } from "../../common/query-language"; import type { QueryLanguage } from "../../common/query-language";
import type { ModelConfig } from "../languages";
export interface ModelEditorViewState { export interface ModelEditorViewState {
extensionPack: ExtensionPack; extensionPack: ExtensionPack;
@@ -11,8 +12,10 @@ export interface ModelEditorViewState {
mode: Mode; mode: Mode;
showModeSwitchButton: boolean; showModeSwitchButton: boolean;
sourceArchiveAvailable: boolean; sourceArchiveAvailable: boolean;
modelConfig: ModelConfig;
} }
export interface MethodModelingPanelViewState { export interface MethodModelingPanelViewState {
language: QueryLanguage | undefined; language: QueryLanguage | undefined;
modelConfig: ModelConfig;
} }

View File

@@ -6,6 +6,7 @@ import { createSinkModeledMethod } from "../../../test/factories/model-editor/mo
import { useState } from "react"; import { useState } from "react";
import type { ModeledMethod } from "../../model-editor/modeled-method"; import type { ModeledMethod } from "../../model-editor/modeled-method";
import { QueryLanguage } from "../../common/query-language"; import { QueryLanguage } from "../../common/query-language";
import { defaultModelConfig } from "../../model-editor/languages";
export default { export default {
title: "Method Modeling/Method Modeling Inputs", title: "Method Modeling/Method Modeling Inputs",
@@ -34,6 +35,7 @@ const Template: StoryFn<typeof MethodModelingInputsComponent> = (args) => {
language={QueryLanguage.Java} language={QueryLanguage.Java}
modeledMethod={m} modeledMethod={m}
onChange={onChange} onChange={onChange}
modelConfig={defaultModelConfig}
/> />
); );
}; };

View File

@@ -8,6 +8,7 @@ import { VSCodeTag } from "@vscode/webview-ui-toolkit/react";
import { ReviewInEditorButton } from "./ReviewInEditorButton"; import { ReviewInEditorButton } from "./ReviewInEditorButton";
import { MultipleModeledMethodsPanel } from "./MultipleModeledMethodsPanel"; import { MultipleModeledMethodsPanel } from "./MultipleModeledMethodsPanel";
import type { QueryLanguage } from "../../common/query-language"; import type { QueryLanguage } from "../../common/query-language";
import type { ModelConfig } from "../../model-editor/languages";
const Container = styled.div` const Container = styled.div`
padding-top: 0.5rem; padding-top: 0.5rem;
@@ -50,6 +51,7 @@ const UnsavedTag = ({ modelingStatus }: { modelingStatus: ModelingStatus }) => (
export type MethodModelingProps = { export type MethodModelingProps = {
language: QueryLanguage; language: QueryLanguage;
modelConfig: ModelConfig;
modelingStatus: ModelingStatus; modelingStatus: ModelingStatus;
method: Method; method: Method;
modeledMethods: ModeledMethod[]; modeledMethods: ModeledMethod[];
@@ -60,6 +62,7 @@ export type MethodModelingProps = {
export const MethodModeling = ({ export const MethodModeling = ({
language, language,
modelConfig,
modelingStatus, modelingStatus,
modeledMethods, modeledMethods,
method, method,
@@ -80,6 +83,7 @@ export const MethodModeling = ({
</DependencyContainer> </DependencyContainer>
<MultipleModeledMethodsPanel <MultipleModeledMethodsPanel
language={language} language={language}
modelConfig={modelConfig}
method={method} method={method}
modeledMethods={modeledMethods} modeledMethods={modeledMethods}
isModelingInProgress={isModelingInProgress} isModelingInProgress={isModelingInProgress}

View File

@@ -7,6 +7,7 @@ import { ModelOutputDropdown } from "../model-editor/ModelOutputDropdown";
import { ModelKindDropdown } from "../model-editor/ModelKindDropdown"; import { ModelKindDropdown } from "../model-editor/ModelKindDropdown";
import { InProgressDropdown } from "../model-editor/InProgressDropdown"; import { InProgressDropdown } from "../model-editor/InProgressDropdown";
import type { QueryLanguage } from "../../common/query-language"; import type { QueryLanguage } from "../../common/query-language";
import type { ModelConfig } from "../../model-editor/languages";
const Container = styled.div` const Container = styled.div`
padding-top: 0.5rem; padding-top: 0.5rem;
@@ -24,6 +25,7 @@ const Name = styled.span`
export type MethodModelingInputsProps = { export type MethodModelingInputsProps = {
language: QueryLanguage; language: QueryLanguage;
modelConfig: ModelConfig;
method: Method; method: Method;
modeledMethod: ModeledMethod | undefined; modeledMethod: ModeledMethod | undefined;
modelPending: boolean; modelPending: boolean;
@@ -33,6 +35,7 @@ export type MethodModelingInputsProps = {
export const MethodModelingInputs = ({ export const MethodModelingInputs = ({
language, language,
modelConfig,
method, method,
modeledMethod, modeledMethod,
modelPending, modelPending,
@@ -55,7 +58,7 @@ export const MethodModelingInputs = ({
{isModelingInProgress ? ( {isModelingInProgress ? (
<InProgressDropdown /> <InProgressDropdown />
) : ( ) : (
<ModelTypeDropdown {...inputProps} /> <ModelTypeDropdown modelConfig={modelConfig} {...inputProps} />
)} )}
</Input> </Input>
</Container> </Container>

View File

@@ -11,6 +11,7 @@ import { NotInModelingMode } from "./NotInModelingMode";
import { NoMethodSelected } from "./NoMethodSelected"; import { NoMethodSelected } from "./NoMethodSelected";
import type { MethodModelingPanelViewState } from "../../model-editor/shared/view-state"; import type { MethodModelingPanelViewState } from "../../model-editor/shared/view-state";
import { MethodAlreadyModeled } from "./MethodAlreadyModeled"; import { MethodAlreadyModeled } from "./MethodAlreadyModeled";
import { defaultModelConfig } from "../../model-editor/languages";
type Props = { type Props = {
initialViewState?: MethodModelingPanelViewState; initialViewState?: MethodModelingPanelViewState;
@@ -116,6 +117,7 @@ export function MethodModelingView({
return ( return (
<MethodModeling <MethodModeling
language={viewState?.language} language={viewState?.language}
modelConfig={viewState?.modelConfig ?? defaultModelConfig}
modelingStatus={modelingStatus} modelingStatus={modelingStatus}
method={method} method={method}
modeledMethods={modeledMethods} modeledMethods={modeledMethods}

View File

@@ -16,9 +16,11 @@ import type { QueryLanguage } from "../../common/query-language";
import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empty"; import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empty";
import { sendTelemetry } from "../common/telemetry"; import { sendTelemetry } from "../common/telemetry";
import type { ModelingStatus } from "../../model-editor/shared/modeling-status"; import type { ModelingStatus } from "../../model-editor/shared/modeling-status";
import type { ModelConfig } from "../../model-editor/languages";
export type MultipleModeledMethodsPanelProps = { export type MultipleModeledMethodsPanelProps = {
language: QueryLanguage; language: QueryLanguage;
modelConfig: ModelConfig;
method: Method; method: Method;
modeledMethods: ModeledMethod[]; modeledMethods: ModeledMethod[];
modelingStatus: ModelingStatus; modelingStatus: ModelingStatus;
@@ -61,6 +63,7 @@ const ModificationActions = styled.div`
export const MultipleModeledMethodsPanel = ({ export const MultipleModeledMethodsPanel = ({
language, language,
modelConfig,
method, method,
modeledMethods, modeledMethods,
modelingStatus, modelingStatus,
@@ -157,6 +160,7 @@ export const MultipleModeledMethodsPanel = ({
{modeledMethods.length > 0 ? ( {modeledMethods.length > 0 ? (
<MethodModelingInputs <MethodModelingInputs
language={language} language={language}
modelConfig={modelConfig}
method={method} method={method}
modeledMethod={modeledMethods[selectedIndex]} modeledMethod={modeledMethods[selectedIndex]}
modelPending={isModelPending( modelPending={isModelPending(
@@ -170,6 +174,7 @@ export const MultipleModeledMethodsPanel = ({
) : ( ) : (
<MethodModelingInputs <MethodModelingInputs
language={language} language={language}
modelConfig={modelConfig}
method={method} method={method}
modeledMethod={undefined} modeledMethod={undefined}
modelPending={isModelPending( modelPending={isModelPending(

View File

@@ -4,6 +4,7 @@ import { MethodModeling } from "../MethodModeling";
import { createMethod } from "../../../../test/factories/model-editor/method-factories"; import { createMethod } from "../../../../test/factories/model-editor/method-factories";
import { createSinkModeledMethod } from "../../../../test/factories/model-editor/modeled-method-factories"; import { createSinkModeledMethod } from "../../../../test/factories/model-editor/modeled-method-factories";
import { QueryLanguage } from "../../../common/query-language"; import { QueryLanguage } from "../../../common/query-language";
import { defaultModelConfig } from "../../../model-editor/languages";
describe(MethodModeling.name, () => { describe(MethodModeling.name, () => {
const render = (props: MethodModelingProps) => const render = (props: MethodModelingProps) =>
@@ -18,6 +19,7 @@ describe(MethodModeling.name, () => {
render({ render({
language: QueryLanguage.Java, language: QueryLanguage.Java,
modelConfig: defaultModelConfig,
modelingStatus: "saved", modelingStatus: "saved",
method, method,
modeledMethods: [modeledMethod], modeledMethods: [modeledMethod],

View File

@@ -9,6 +9,7 @@ import {
} from "../../../../test/factories/model-editor/modeled-method-factories"; } from "../../../../test/factories/model-editor/modeled-method-factories";
import { QueryLanguage } from "../../../common/query-language"; import { QueryLanguage } from "../../../common/query-language";
import { createEmptyModeledMethod } from "../../../model-editor/modeled-method-empty"; import { createEmptyModeledMethod } from "../../../model-editor/modeled-method-empty";
import { defaultModelConfig } from "../../../model-editor/languages";
describe(MethodModelingInputs.name, () => { describe(MethodModelingInputs.name, () => {
const render = (props: MethodModelingInputsProps) => const render = (props: MethodModelingInputsProps) =>
@@ -19,6 +20,7 @@ describe(MethodModelingInputs.name, () => {
const modeledMethod = createSinkModeledMethod(); const modeledMethod = createSinkModeledMethod();
const modelPending = false; const modelPending = false;
const isModelingInProgress = false; const isModelingInProgress = false;
const modelConfig = defaultModelConfig;
const onChange = jest.fn(); const onChange = jest.fn();
it("renders the method modeling inputs", () => { it("renders the method modeling inputs", () => {
@@ -28,6 +30,7 @@ describe(MethodModelingInputs.name, () => {
modeledMethod, modeledMethod,
modelPending, modelPending,
isModelingInProgress, isModelingInProgress,
modelConfig,
onChange, onChange,
}); });
@@ -55,6 +58,7 @@ describe(MethodModelingInputs.name, () => {
modeledMethod, modeledMethod,
modelPending, modelPending,
isModelingInProgress, isModelingInProgress,
modelConfig,
onChange, onChange,
}); });
@@ -78,6 +82,7 @@ describe(MethodModelingInputs.name, () => {
modeledMethod, modeledMethod,
modelPending, modelPending,
isModelingInProgress, isModelingInProgress,
modelConfig,
onChange, onChange,
}); });
@@ -93,6 +98,7 @@ describe(MethodModelingInputs.name, () => {
modeledMethod={updatedModeledMethod} modeledMethod={updatedModeledMethod}
modelPending={modelPending} modelPending={modelPending}
isModelingInProgress={isModelingInProgress} isModelingInProgress={isModelingInProgress}
modelConfig={modelConfig}
onChange={onChange} onChange={onChange}
/>, />,
); );
@@ -123,6 +129,7 @@ describe(MethodModelingInputs.name, () => {
modeledMethod, modeledMethod,
modelPending, modelPending,
isModelingInProgress: true, isModelingInProgress: true,
modelConfig,
onChange, onChange,
}); });

View File

@@ -11,6 +11,7 @@ import { userEvent } from "@testing-library/user-event";
import type { ModeledMethod } from "../../../model-editor/modeled-method"; import type { ModeledMethod } from "../../../model-editor/modeled-method";
import { QueryLanguage } from "../../../common/query-language"; import { QueryLanguage } from "../../../common/query-language";
import type { ModelingStatus } from "../../../model-editor/shared/modeling-status"; import type { ModelingStatus } from "../../../model-editor/shared/modeling-status";
import { defaultModelConfig } from "../../../model-editor/languages";
describe(MultipleModeledMethodsPanel.name, () => { describe(MultipleModeledMethodsPanel.name, () => {
const language = QueryLanguage.Java; const language = QueryLanguage.Java;
@@ -19,12 +20,14 @@ describe(MultipleModeledMethodsPanel.name, () => {
const isProcessedByAutoModel = false; const isProcessedByAutoModel = false;
const modelingStatus: ModelingStatus = "unmodeled"; const modelingStatus: ModelingStatus = "unmodeled";
const onChange = jest.fn<void, [string, ModeledMethod[]]>(); const onChange = jest.fn<void, [string, ModeledMethod[]]>();
const modelConfig = defaultModelConfig;
const baseProps = { const baseProps = {
language, language,
method, method,
modelingStatus, modelingStatus,
isModelingInProgress, isModelingInProgress,
modelConfig,
isProcessedByAutoModel, isProcessedByAutoModel,
onChange, onChange,
}; };

View File

@@ -37,6 +37,7 @@ import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empt
import type { AccessPathOption } from "../../model-editor/suggestions"; import type { AccessPathOption } from "../../model-editor/suggestions";
import { ModelInputSuggestBox } from "./ModelInputSuggestBox"; import { ModelInputSuggestBox } from "./ModelInputSuggestBox";
import { ModelOutputSuggestBox } from "./ModelOutputSuggestBox"; import { ModelOutputSuggestBox } from "./ModelOutputSuggestBox";
import { getModelsAsDataLanguage } from "../../model-editor/languages";
const ApiOrMethodRow = styled.div` const ApiOrMethodRow = styled.div`
min-height: calc(var(--input-height) * 1px); min-height: calc(var(--input-height) * 1px);
@@ -192,9 +193,37 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
[method], [method],
); );
const modelingStatus = getModelingStatus(modeledMethods, methodIsUnsaved); // Only show modeled methods that are non-hidden. These are also the ones that are
// used for determining the modeling status.
const shownModeledMethods = useMemo(() => {
const modelsAsDataLanguage = getModelsAsDataLanguage(viewState.language);
const addModelButtonDisabled = !canAddNewModeledMethod(modeledMethods); return modeledMethodsToDisplay(
modeledMethods.filter((modeledMethod) => {
if (modeledMethod.type === "none") {
return true;
}
const predicate = modelsAsDataLanguage.predicates[modeledMethod.type];
if (!predicate) {
return true;
}
return !predicate.isHidden?.({
method,
config: viewState.modelConfig,
});
}),
method,
);
}, [method, modeledMethods, viewState]);
const modelingStatus = getModelingStatus(
shownModeledMethods,
methodIsUnsaved,
);
const addModelButtonDisabled = !canAddNewModeledMethod(shownModeledMethods);
return ( return (
<DataGridRow <DataGridRow
@@ -206,7 +235,7 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
}} }}
> >
<DataGridCell <DataGridCell
gridRow={`span ${modeledMethods.length + validationErrors.length}`} gridRow={`span ${shownModeledMethods.length + validationErrors.length}`}
ref={ref} ref={ref}
> >
<ApiOrMethodRow> <ApiOrMethodRow>
@@ -257,7 +286,7 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
)} )}
{!props.modelingInProgress && ( {!props.modelingInProgress && (
<> <>
{modeledMethods.map((modeledMethod, index) => { {shownModeledMethods.map((modeledMethod, index) => {
const modelPending = isModelPending( const modelPending = isModelPending(
modeledMethod, modeledMethod,
modelingStatus, modelingStatus,
@@ -269,6 +298,7 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
<DataGridCell> <DataGridCell>
<ModelTypeDropdown <ModelTypeDropdown
language={viewState.language} language={viewState.language}
modelConfig={viewState.modelConfig}
method={method} method={method}
modeledMethod={modeledMethod} modeledMethod={modeledMethod}
modelPending={modelPending} modelPending={modelPending}

View File

@@ -10,12 +10,16 @@ import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empt
import type { Mutable } from "../../common/mutable"; import type { Mutable } from "../../common/mutable";
import { ReadonlyDropdown } from "../common/ReadonlyDropdown"; import { ReadonlyDropdown } from "../common/ReadonlyDropdown";
import type { QueryLanguage } from "../../common/query-language"; import type { QueryLanguage } from "../../common/query-language";
import type { ModelsAsDataLanguagePredicates } from "../../model-editor/languages"; import type {
ModelConfig,
ModelsAsDataLanguagePredicates,
} from "../../model-editor/languages";
import { getModelsAsDataLanguage } from "../../model-editor/languages"; import { getModelsAsDataLanguage } from "../../model-editor/languages";
import { InputDropdown } from "./InputDropdown"; import { InputDropdown } from "./InputDropdown";
type Props = { type Props = {
language: QueryLanguage; language: QueryLanguage;
modelConfig: ModelConfig;
method: Method; method: Method;
modeledMethod: ModeledMethod | undefined; modeledMethod: ModeledMethod | undefined;
modelPending: boolean; modelPending: boolean;
@@ -34,6 +38,7 @@ type Option = { value: ModeledMethodType; label: string };
export const ModelTypeDropdown = ({ export const ModelTypeDropdown = ({
language, language,
modelConfig,
method, method,
modeledMethod, modeledMethod,
modelPending, modelPending,
@@ -55,6 +60,13 @@ export const ModelTypeDropdown = ({
return null; return null;
} }
if (
predicate.isHidden &&
predicate.isHidden({ method, config: modelConfig })
) {
return null;
}
return { return {
value: type, value: type,
label: typeLabels[type], label: typeLabels[type],
@@ -64,7 +76,7 @@ export const ModelTypeDropdown = ({
]; ];
return baseOptions; return baseOptions;
}, [language, method.endpointType]); }, [language, modelConfig, method]);
const handleChange = useCallback( const handleChange = useCallback(
(e: ChangeEvent<HTMLSelectElement>) => { (e: ChangeEvent<HTMLSelectElement>) => {

View File

@@ -4,6 +4,7 @@ import { createNoneModeledMethod } from "../../../../test/factories/model-editor
import { QueryLanguage } from "../../../common/query-language"; import { QueryLanguage } from "../../../common/query-language";
import { ModelTypeDropdown } from "../ModelTypeDropdown"; import { ModelTypeDropdown } from "../ModelTypeDropdown";
import { createMethod } from "../../../../test/factories/model-editor/method-factories"; import { createMethod } from "../../../../test/factories/model-editor/method-factories";
import { defaultModelConfig } from "../../../model-editor/languages";
describe(ModelTypeDropdown.name, () => { describe(ModelTypeDropdown.name, () => {
const onChange = jest.fn(); const onChange = jest.fn();
@@ -23,6 +24,7 @@ describe(ModelTypeDropdown.name, () => {
modelPending={false} modelPending={false}
onChange={onChange} onChange={onChange}
method={method} method={method}
modelConfig={defaultModelConfig}
/>, />,
); );
@@ -34,7 +36,7 @@ describe(ModelTypeDropdown.name, () => {
); );
}); });
it("allows changing the type to 'Type' for Ruby", async () => { it("allows changing the type to 'Type' for Ruby when type models are shown", async () => {
const method = createMethod(); const method = createMethod();
const modeledMethod = createNoneModeledMethod(); const modeledMethod = createNoneModeledMethod();
@@ -45,6 +47,10 @@ describe(ModelTypeDropdown.name, () => {
modelPending={false} modelPending={false}
onChange={onChange} onChange={onChange}
method={method} method={method}
modelConfig={{
...defaultModelConfig,
showTypeModels: true,
}}
/>, />,
); );
@@ -56,6 +62,26 @@ describe(ModelTypeDropdown.name, () => {
); );
}); });
it("does not allow changing the type to 'Type' for Ruby when type models are not shown", async () => {
const method = createMethod();
const modeledMethod = createNoneModeledMethod();
render(
<ModelTypeDropdown
language={QueryLanguage.Ruby}
modeledMethod={modeledMethod}
modelPending={false}
onChange={onChange}
method={method}
modelConfig={defaultModelConfig}
/>,
);
expect(
screen.queryByRole("option", { name: "Type" }),
).not.toBeInTheDocument();
});
it("does not allow changing the type to 'Type' for Java", async () => { it("does not allow changing the type to 'Type' for Java", async () => {
const method = createMethod(); const method = createMethod();
const modeledMethod = createNoneModeledMethod(); const modeledMethod = createNoneModeledMethod();
@@ -67,6 +93,7 @@ describe(ModelTypeDropdown.name, () => {
modelPending={false} modelPending={false}
onChange={onChange} onChange={onChange}
method={method} method={method}
modelConfig={defaultModelConfig}
/>, />,
); );

View File

@@ -2,6 +2,7 @@ import type { ModelEditorViewState } from "../../../src/model-editor/shared/view
import { Mode } from "../../../src/model-editor/shared/mode"; import { Mode } from "../../../src/model-editor/shared/mode";
import { createMockExtensionPack } from "./extension-pack"; import { createMockExtensionPack } from "./extension-pack";
import { QueryLanguage } from "../../../src/common/query-language"; import { QueryLanguage } from "../../../src/common/query-language";
import { defaultModelConfig } from "../../../src/model-editor/languages";
export function createMockModelEditorViewState( export function createMockModelEditorViewState(
data: Partial<ModelEditorViewState> = {}, data: Partial<ModelEditorViewState> = {},
@@ -15,6 +16,7 @@ export function createMockModelEditorViewState(
showModeSwitchButton: true, showModeSwitchButton: true,
extensionPack: createMockExtensionPack(), extensionPack: createMockExtensionPack(),
sourceArchiveAvailable: true, sourceArchiveAvailable: true,
modelConfig: defaultModelConfig,
...data, ...data,
}; };
} }