Add initial multiple modelings panel
This commit is contained in:
@@ -37,8 +37,24 @@ MethodSaved.args = {
|
|||||||
modelingStatus: "saved",
|
modelingStatus: "saved",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MultipleModelings = Template.bind({});
|
export const MultipleModelingsUnmodeled = Template.bind({});
|
||||||
MultipleModelings.args = {
|
MultipleModelingsUnmodeled.args = {
|
||||||
|
method,
|
||||||
|
modeledMethods: [],
|
||||||
|
showMultipleModels: true,
|
||||||
|
modelingStatus: "saved",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MultipleModelingsModeledSingle = Template.bind({});
|
||||||
|
MultipleModelingsModeledSingle.args = {
|
||||||
|
method,
|
||||||
|
modeledMethods: [createModeledMethod(method)],
|
||||||
|
showMultipleModels: true,
|
||||||
|
modelingStatus: "saved",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MultipleModelingsModeledMultiple = Template.bind({});
|
||||||
|
MultipleModelingsModeledMultiple.args = {
|
||||||
method,
|
method,
|
||||||
modeledMethods: [
|
modeledMethods: [
|
||||||
createModeledMethod(method),
|
createModeledMethod(method),
|
||||||
|
|||||||
50
extensions/ql-vscode/src/view/common/icon/CodiconButton.tsx
Normal file
50
extensions/ql-vscode/src/view/common/icon/CodiconButton.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { styled } from "styled-components";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
type Size = "x-small" | "small" | "medium" | "large" | "x-large";
|
||||||
|
|
||||||
|
const StyledButton = styled.button<{ size: Size }>`
|
||||||
|
background: none;
|
||||||
|
color: var(--vscode-textLink-foreground);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: ${(props) => props.size ?? "1em"};
|
||||||
|
padding: 0;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
color: var(--vscode-disabledForeground);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CodiconButton = ({
|
||||||
|
size,
|
||||||
|
onClick,
|
||||||
|
className,
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
disabled,
|
||||||
|
}: {
|
||||||
|
size?: Size;
|
||||||
|
onClick: (e: React.MouseEvent) => void;
|
||||||
|
className?: string;
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}) => (
|
||||||
|
<StyledButton
|
||||||
|
size={size}
|
||||||
|
onClick={onClick}
|
||||||
|
className={className}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
role="img"
|
||||||
|
aria-label={label}
|
||||||
|
title={label}
|
||||||
|
className={classNames("codicon", `codicon-${name}`, className)}
|
||||||
|
/>
|
||||||
|
</StyledButton>
|
||||||
|
);
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from "./Codicon";
|
export * from "./Codicon";
|
||||||
|
export * from "./CodiconButton";
|
||||||
export * from "./ErrorIcon";
|
export * from "./ErrorIcon";
|
||||||
export * from "./LoadingIcon";
|
export * from "./LoadingIcon";
|
||||||
export * from "./SuccessIcon";
|
export * from "./SuccessIcon";
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import { ModelingStatusIndicator } from "../model-editor/ModelingStatusIndicator
|
|||||||
import { Method } from "../../model-editor/method";
|
import { Method } from "../../model-editor/method";
|
||||||
import { MethodName } from "../model-editor/MethodName";
|
import { MethodName } from "../model-editor/MethodName";
|
||||||
import { ModeledMethod } from "../../model-editor/modeled-method";
|
import { ModeledMethod } from "../../model-editor/modeled-method";
|
||||||
import { MethodModelingInputs } from "./MethodModelingInputs";
|
|
||||||
import { VSCodeTag } from "@vscode/webview-ui-toolkit/react";
|
import { VSCodeTag } from "@vscode/webview-ui-toolkit/react";
|
||||||
import { ReviewInEditorButton } from "./ReviewInEditorButton";
|
import { ReviewInEditorButton } from "./ReviewInEditorButton";
|
||||||
|
import { ModeledMethodsPanel } from "./ModeledMethodsPanel";
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
@@ -38,10 +38,6 @@ const DependencyContainer = styled.div`
|
|||||||
margin-bottom: 0.8rem;
|
margin-bottom: 0.8rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledMethodModelingInputs = styled(MethodModelingInputs)`
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledVSCodeTag = styled(VSCodeTag)<{ visible: boolean }>`
|
const StyledVSCodeTag = styled(VSCodeTag)<{ visible: boolean }>`
|
||||||
visibility: ${(props) => (props.visible ? "visible" : "hidden")};
|
visibility: ${(props) => (props.visible ? "visible" : "hidden")};
|
||||||
`;
|
`;
|
||||||
@@ -64,6 +60,7 @@ export const MethodModeling = ({
|
|||||||
modelingStatus,
|
modelingStatus,
|
||||||
modeledMethods,
|
modeledMethods,
|
||||||
method,
|
method,
|
||||||
|
showMultipleModels = false,
|
||||||
onChange,
|
onChange,
|
||||||
}: MethodModelingProps): JSX.Element => {
|
}: MethodModelingProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
@@ -77,11 +74,10 @@ export const MethodModeling = ({
|
|||||||
<ModelingStatusIndicator status={modelingStatus} />
|
<ModelingStatusIndicator status={modelingStatus} />
|
||||||
<MethodName {...method} />
|
<MethodName {...method} />
|
||||||
</DependencyContainer>
|
</DependencyContainer>
|
||||||
<StyledMethodModelingInputs
|
<ModeledMethodsPanel
|
||||||
method={method}
|
method={method}
|
||||||
modeledMethod={
|
modeledMethods={modeledMethods}
|
||||||
modeledMethods.length > 0 ? modeledMethods[0] : undefined
|
showMultipleModels={showMultipleModels}
|
||||||
}
|
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<ReviewInEditorButton method={method} />
|
<ReviewInEditorButton method={method} />
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { ModeledMethod } from "../../model-editor/modeled-method";
|
||||||
|
import { MethodModelingInputs } from "./MethodModelingInputs";
|
||||||
|
import { Method } from "../../model-editor/method";
|
||||||
|
import { styled } from "styled-components";
|
||||||
|
import { MultipleModeledMethodsPanel } from "./MultipleModeledMethodsPanel";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
method: Method;
|
||||||
|
modeledMethods: ModeledMethod[];
|
||||||
|
showMultipleModels: boolean;
|
||||||
|
onChange: (modeledMethod: ModeledMethod) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SingleMethodModelingInputs = styled(MethodModelingInputs)`
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ModeledMethodsPanel = ({
|
||||||
|
method,
|
||||||
|
modeledMethods,
|
||||||
|
showMultipleModels,
|
||||||
|
onChange,
|
||||||
|
}: Props) => {
|
||||||
|
if (!showMultipleModels) {
|
||||||
|
return (
|
||||||
|
<SingleMethodModelingInputs
|
||||||
|
method={method}
|
||||||
|
modeledMethod={
|
||||||
|
modeledMethods.length > 0 ? modeledMethods[0] : undefined
|
||||||
|
}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MultipleModeledMethodsPanel
|
||||||
|
method={method}
|
||||||
|
modeledMethods={modeledMethods}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { Method } from "../../model-editor/method";
|
||||||
|
import { ModeledMethod } from "../../model-editor/modeled-method";
|
||||||
|
import { styled } from "styled-components";
|
||||||
|
import { MethodModelingInputs } from "./MethodModelingInputs";
|
||||||
|
import { CodiconButton } from "../common";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
method: Method;
|
||||||
|
modeledMethods: ModeledMethod[];
|
||||||
|
onChange: (modeledMethod: ModeledMethod) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 0.05rem solid var(--vscode-panelSection-border);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Footer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PaginationActions = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 0.5rem;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const MultipleModeledMethodsPanel = ({
|
||||||
|
method,
|
||||||
|
modeledMethods,
|
||||||
|
onChange,
|
||||||
|
}: Props) => {
|
||||||
|
const [selectedIndex, setSelectedIndex] = useState<number>(0);
|
||||||
|
|
||||||
|
const handlePreviousClick = useCallback(() => {
|
||||||
|
setSelectedIndex((previousIndex) => previousIndex - 1);
|
||||||
|
}, []);
|
||||||
|
const handleNextClick = useCallback(() => {
|
||||||
|
setSelectedIndex((previousIndex) => previousIndex + 1);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
{modeledMethods.length > 0 && (
|
||||||
|
<MethodModelingInputs
|
||||||
|
method={method}
|
||||||
|
modeledMethod={modeledMethods[selectedIndex]}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Footer>
|
||||||
|
<PaginationActions>
|
||||||
|
<CodiconButton
|
||||||
|
name="chevron-left"
|
||||||
|
label="Previous modeling"
|
||||||
|
onClick={handlePreviousClick}
|
||||||
|
disabled={modeledMethods.length < 2 || selectedIndex === 0}
|
||||||
|
/>
|
||||||
|
{modeledMethods.length > 1 && (
|
||||||
|
<div>
|
||||||
|
{selectedIndex + 1}/{modeledMethods.length}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<CodiconButton
|
||||||
|
name="chevron-right"
|
||||||
|
label="Next modeling"
|
||||||
|
onClick={handleNextClick}
|
||||||
|
disabled={
|
||||||
|
modeledMethods.length < 2 ||
|
||||||
|
selectedIndex === modeledMethods.length - 1
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</PaginationActions>
|
||||||
|
</Footer>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user