Show in-progress state in method modeling panel (#2979)

This commit is contained in:
Charis Kyriakou
2023-10-16 11:47:31 +01:00
committed by GitHub
parent b1a4586791
commit b87dfa4471
14 changed files with 169 additions and 6 deletions

View File

@@ -583,6 +583,11 @@ interface SetInModelingModeMessage {
inModelingMode: boolean;
}
interface SetInProgressMessage {
t: "setInProgress";
inProgress: boolean;
}
interface RevealMethodMessage {
t: "revealMethod";
methodSignature: string;
@@ -646,6 +651,7 @@ interface SetSelectedMethodMessage {
method: Method;
modeledMethods: ModeledMethod[];
isModified: boolean;
isInProgress: boolean;
}
export type ToMethodModelingMessage =
@@ -654,4 +660,5 @@ export type ToMethodModelingMessage =
| SetMultipleModeledMethodsMessage
| SetMethodModifiedMessage
| SetSelectedMethodMessage
| SetInModelingModeMessage;
| SetInModelingModeMessage
| SetInProgressMessage;

View File

@@ -14,6 +14,7 @@ import { assertNever } from "../../common/helpers-pure";
import { ModelEditorViewTracker } from "../model-editor-view-tracker";
import { ModelConfigListener } from "../../config";
import { DatabaseItem } from "../../databases/local-databases";
import { hasInProgressMethodSignature } from "../shared/in-progress-methods";
export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
ToMethodModelingMessage,
@@ -75,6 +76,7 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
method: selectedMethod.method,
modeledMethods: selectedMethod.modeledMethods,
isModified: selectedMethod.isModified,
isInProgress: selectedMethod.isInProgress,
});
}
@@ -188,6 +190,7 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
method: e.method,
modeledMethods: e.modeledMethods,
isModified: e.isModified,
isInProgress: e.isInProgress,
});
}
}),
@@ -216,6 +219,24 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
}
}),
);
this.push(
this.modelingStore.onInProgressMethodsChanged(async (e) => {
if (this.method && this.databaseItem) {
const dbUri = this.databaseItem.databaseUri.toString();
if (e.dbUri === dbUri) {
const inProgress = hasInProgressMethodSignature(
e.methods,
this.method.signature,
);
await this.postMessage({
t: "setInProgress",
inProgress,
});
}
}
}),
);
}
private registerToModelConfigEvents(): void {

View File

@@ -5,7 +5,10 @@ import { DatabaseItem } from "../databases/local-databases";
import { Method, Usage } from "./method";
import { ModeledMethod } from "./modeled-method";
import { INITIAL_HIDE_MODELED_METHODS_VALUE } from "./shared/hide-modeled-methods";
import { InProgressMethods } from "./shared/in-progress-methods";
import {
InProgressMethods,
hasInProgressMethodSignature,
} from "./shared/in-progress-methods";
import { INITIAL_MODE, Mode } from "./shared/mode";
interface InternalDbModelingState {
@@ -37,6 +40,7 @@ interface SelectedMethodDetails {
readonly usage: Usage | undefined;
readonly modeledMethods: readonly ModeledMethod[];
readonly isModified: boolean;
readonly isInProgress: boolean;
}
interface MethodsChangedEvent {
@@ -73,6 +77,7 @@ interface SelectedMethodChangedEvent {
readonly usage: Usage;
readonly modeledMethods: readonly ModeledMethod[];
readonly isModified: boolean;
readonly isInProgress: boolean;
}
interface InProgressMethodsChangedEvent {
@@ -420,6 +425,10 @@ export class ModelingStore extends DisposableObject {
usage,
modeledMethods: dbState.modeledMethods[method.signature] ?? [],
isModified: dbState.modifiedMethodSignatures.has(method.signature),
isInProgress: hasInProgressMethodSignature(
dbState.inProgressMethods,
method.signature,
),
});
}
@@ -460,6 +469,10 @@ export class ModelingStore extends DisposableObject {
isModified: dbState.modifiedMethodSignatures.has(
selectedMethod.signature,
),
isInProgress: hasInProgressMethodSignature(
dbState.inProgressMethods,
selectedMethod.signature,
),
};
}

View File

@@ -15,3 +15,16 @@ export function hasInProgressMethod(
return false;
}
export function hasInProgressMethodSignature(
inProgressMethods: InProgressMethods,
signature: string,
): boolean {
for (const methods of Object.values(inProgressMethods)) {
if (methods.includes(signature)) {
return true;
}
}
return false;
}

View File

@@ -51,3 +51,10 @@ FullyModeledMethod.args = {
method,
modeledMethod,
};
export const ModelingInProgress = Template.bind({});
ModelingInProgress.args = {
method,
modeledMethod,
isModelingInProgress: true,
};

View File

@@ -52,6 +52,7 @@ export type MethodModelingProps = {
modelingStatus: ModelingStatus;
method: Method;
modeledMethods: ModeledMethod[];
isModelingInProgress: boolean;
showMultipleModels?: boolean;
onChange: (methodSignature: string, modeledMethods: ModeledMethod[]) => void;
};
@@ -60,6 +61,7 @@ export const MethodModeling = ({
modelingStatus,
modeledMethods,
method,
isModelingInProgress,
showMultipleModels = false,
onChange,
}: MethodModelingProps): JSX.Element => {
@@ -78,6 +80,7 @@ export const MethodModeling = ({
method={method}
modeledMethods={modeledMethods}
showMultipleModels={showMultipleModels}
isModelingInProgress={isModelingInProgress}
onChange={onChange}
/>
<ReviewInEditorButton method={method} />

View File

@@ -6,6 +6,7 @@ import { ModelTypeDropdown } from "../model-editor/ModelTypeDropdown";
import { ModelInputDropdown } from "../model-editor/ModelInputDropdown";
import { ModelOutputDropdown } from "../model-editor/ModelOutputDropdown";
import { ModelKindDropdown } from "../model-editor/ModelKindDropdown";
import { InProgressDropdown } from "../model-editor/InProgressDropdown";
const Container = styled.div`
padding-top: 0.5rem;
@@ -24,12 +25,14 @@ const Name = styled.span`
export type MethodModelingInputsProps = {
method: Method;
modeledMethod: ModeledMethod | undefined;
isModelingInProgress: boolean;
onChange: (modeledMethod: ModeledMethod) => void;
};
export const MethodModelingInputs = ({
method,
modeledMethod,
isModelingInProgress,
onChange,
}: MethodModelingInputsProps): JSX.Element => {
const inputProps = {
@@ -43,25 +46,41 @@ export const MethodModelingInputs = ({
<Container>
<Input>
<Name>Model Type</Name>
<ModelTypeDropdown {...inputProps} />
{isModelingInProgress ? (
<InProgressDropdown />
) : (
<ModelTypeDropdown {...inputProps} />
)}
</Input>
</Container>
<Container>
<Input>
<Name>Input</Name>
<ModelInputDropdown {...inputProps} />
{isModelingInProgress ? (
<InProgressDropdown />
) : (
<ModelInputDropdown {...inputProps} />
)}
</Input>
</Container>
<Container>
<Input>
<Name>Output</Name>
<ModelOutputDropdown {...inputProps} />
{isModelingInProgress ? (
<InProgressDropdown />
) : (
<ModelOutputDropdown {...inputProps} />
)}
</Input>
</Container>
<Container>
<Input>
<Name>Kind</Name>
<ModelKindDropdown {...inputProps} />
{isModelingInProgress ? (
<InProgressDropdown />
) : (
<ModelKindDropdown {...inputProps} />
)}
</Input>
</Container>
</>

View File

@@ -28,6 +28,9 @@ export function MethodModelingView({ initialViewState }: Props): JSX.Element {
const [isMethodModified, setIsMethodModified] = useState<boolean>(false);
const [isModelingInProgress, setIsModelingInProgress] =
useState<boolean>(false);
const modelingStatus = useMemo(
() => getModelingStatus(modeledMethods, isMethodModified),
[modeledMethods, isMethodModified],
@@ -58,6 +61,9 @@ export function MethodModelingView({ initialViewState }: Props): JSX.Element {
setModeledMethods(msg.modeledMethods);
setIsMethodModified(msg.isModified);
break;
case "setInProgress":
setIsModelingInProgress(msg.inProgress);
break;
default:
assertNever(msg);
}
@@ -102,6 +108,7 @@ export function MethodModelingView({ initialViewState }: Props): JSX.Element {
modelingStatus={modelingStatus}
method={method}
modeledMethods={modeledMethods}
isModelingInProgress={isModelingInProgress}
showMultipleModels={viewState?.showMultipleModels}
onChange={onChange}
/>

View File

@@ -10,6 +10,7 @@ import { convertToLegacyModeledMethod } from "../../model-editor/shared/modeled-
export type ModeledMethodsPanelProps = {
method: Method;
modeledMethods: ModeledMethod[];
isModelingInProgress: boolean;
showMultipleModels: boolean;
onChange: (methodSignature: string, modeledMethods: ModeledMethod[]) => void;
};
@@ -21,6 +22,7 @@ const SingleMethodModelingInputs = styled(MethodModelingInputs)`
export const ModeledMethodsPanel = ({
method,
modeledMethods,
isModelingInProgress,
showMultipleModels,
onChange,
}: ModeledMethodsPanelProps) => {
@@ -36,6 +38,7 @@ export const ModeledMethodsPanel = ({
<SingleMethodModelingInputs
method={method}
modeledMethod={convertToLegacyModeledMethod(modeledMethods)}
isModelingInProgress={isModelingInProgress}
onChange={handleSingleChange}
/>
);
@@ -45,6 +48,7 @@ export const ModeledMethodsPanel = ({
<MultipleModeledMethodsPanel
method={method}
modeledMethods={modeledMethods}
isModelingInProgress={isModelingInProgress}
onChange={onChange}
/>
);

View File

@@ -16,6 +16,7 @@ import { ModeledMethodAlert } from "./ModeledMethodAlert";
export type MultipleModeledMethodsPanelProps = {
method: Method;
modeledMethods: ModeledMethod[];
isModelingInProgress: boolean;
onChange: (methodSignature: string, modeledMethods: ModeledMethod[]) => void;
};
@@ -54,6 +55,7 @@ const ModificationActions = styled.div`
export const MultipleModeledMethodsPanel = ({
method,
modeledMethods,
isModelingInProgress,
onChange,
}: MultipleModeledMethodsPanelProps) => {
const [selectedIndex, setSelectedIndex] = useState<number>(0);
@@ -134,12 +136,14 @@ export const MultipleModeledMethodsPanel = ({
<MethodModelingInputs
method={method}
modeledMethod={modeledMethods[selectedIndex]}
isModelingInProgress={isModelingInProgress}
onChange={handleChange}
/>
) : (
<MethodModelingInputs
method={method}
modeledMethod={undefined}
isModelingInProgress={isModelingInProgress}
onChange={handleChange}
/>
)}

View File

@@ -11,12 +11,14 @@ describe(MethodModeling.name, () => {
it("renders method modeling panel", () => {
const method = createMethod();
const modeledMethod = createModeledMethod();
const isModelingInProgress = false;
const onChange = jest.fn();
render({
modelingStatus: "saved",
method,
modeledMethods: [modeledMethod],
isModelingInProgress,
onChange,
});

View File

@@ -14,12 +14,14 @@ describe(MethodModelingInputs.name, () => {
const method = createMethod();
const modeledMethod = createModeledMethod();
const isModelingInProgress = false;
const onChange = jest.fn();
it("renders the method modeling inputs", () => {
render({
method,
modeledMethod,
isModelingInProgress,
onChange,
});
@@ -44,6 +46,7 @@ describe(MethodModelingInputs.name, () => {
render({
method,
modeledMethod,
isModelingInProgress,
onChange,
});
@@ -64,6 +67,7 @@ describe(MethodModelingInputs.name, () => {
const { rerender } = render({
method,
modeledMethod,
isModelingInProgress,
onChange,
});
@@ -75,6 +79,7 @@ describe(MethodModelingInputs.name, () => {
<MethodModelingInputs
method={method}
modeledMethod={updatedModeledMethod}
isModelingInProgress={isModelingInProgress}
onChange={onChange}
/>,
);
@@ -97,4 +102,29 @@ describe(MethodModelingInputs.name, () => {
expect(modelOutputDropdown).toHaveValue("ReturnValue");
expect(modelKindDropdown).toHaveValue("local");
});
it("sets in progress dropdowns when modeling is in progress", () => {
render({
method,
modeledMethod,
isModelingInProgress: true,
onChange,
});
// Check that all the labels are rendered.
expect(screen.getByText("Model Type")).toBeInTheDocument();
expect(screen.getByText("Input")).toBeInTheDocument();
expect(screen.getByText("Output")).toBeInTheDocument();
expect(screen.getByText("Kind")).toBeInTheDocument();
// Check that all the dropdowns are rendered.
const dropdowns = screen.getAllByRole("combobox");
expect(dropdowns.length).toBe(4);
// Check that all the dropdowns are disabled and indicate have the value "Thinking...".
dropdowns.forEach((dropdown) => {
expect(dropdown).toBeDisabled();
expect(dropdown).toHaveValue("Thinking...");
});
});
});

View File

@@ -13,6 +13,7 @@ describe(ModeledMethodsPanel.name, () => {
const method = createMethod();
const modeledMethods = [createModeledMethod(), createModeledMethod()];
const isModelingInProgress = false;
const onChange = jest.fn();
describe("when show multiple models is disabled", () => {
@@ -22,6 +23,7 @@ describe(ModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
showMultipleModels,
});
@@ -33,6 +35,7 @@ describe(ModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
showMultipleModels,
});
@@ -51,6 +54,7 @@ describe(ModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
showMultipleModels,
});
@@ -62,6 +66,7 @@ describe(ModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
showMultipleModels,
});

View File

@@ -14,6 +14,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
reactRender(<MultipleModeledMethodsPanel {...props} />);
const method = createMethod();
const isModelingInProgress = false;
const onChange = jest.fn<void, [string, ModeledMethod[]]>();
describe("with no modeled methods", () => {
@@ -23,6 +24,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -38,6 +40,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -57,6 +60,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -86,6 +90,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -101,6 +106,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -119,6 +125,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -133,6 +140,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -178,6 +186,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -193,6 +202,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -205,6 +215,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -222,6 +233,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -256,6 +268,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -266,6 +279,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -296,6 +310,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -328,6 +343,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -343,6 +359,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -369,6 +386,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
const { rerender } = render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -380,6 +398,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
modeledMethods={
onChange.mock.calls[onChange.mock.calls.length - 1][1]
}
isModelingInProgress={isModelingInProgress}
onChange={onChange}
/>,
);
@@ -396,6 +415,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
modeledMethods={
onChange.mock.calls[onChange.mock.calls.length - 1][1]
}
isModelingInProgress={isModelingInProgress}
onChange={onChange}
/>,
);
@@ -436,6 +456,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -543,6 +564,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -555,6 +577,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -570,6 +593,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -586,6 +610,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
const { rerender } = render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -601,6 +626,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
<MultipleModeledMethodsPanel
method={method}
modeledMethods={modeledMethods.slice(0, 1)}
isModelingInProgress={isModelingInProgress}
onChange={onChange}
/>,
);
@@ -640,6 +666,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});
@@ -650,6 +677,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
render({
method,
modeledMethods,
isModelingInProgress,
onChange,
});