Fix execute sproc pane textfield focus issue (#1170)

* Fix execute sproc pane textfield focus issue

* Update snapshot
This commit is contained in:
victor-meng 2021-12-08 15:41:27 -08:00 committed by GitHub
parent 8a8c023d7b
commit ada95eae1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 5050 additions and 5059 deletions

View File

@ -1,6 +1,6 @@
import { IDropdownOption, IImageProps, Image, Stack, Text } from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks";
import React, { FunctionComponent, useState } from "react";
import React, { FunctionComponent, useRef, useState } from "react";
import AddPropertyIcon from "../../../../images/Add-property.svg";
import { useSidePanel } from "../../../hooks/useSidePanel";
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
@ -25,19 +25,16 @@ interface UnwrappedExecuteSprocParam {
export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPaneProps> = ({
storedProcedure,
}: ExecuteSprocParamsPaneProps): JSX.Element => {
const paramKeyValuesRef = useRef<UnwrappedExecuteSprocParam[]>([{ key: "string", text: "" }]);
const partitionValueRef = useRef<string>();
const partitionKeyRef = useRef<string>("string");
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
const [numberOfParams, setNumberOfParams] = useState<number>(1);
const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false);
const [paramKeyValues, setParamKeyValues] = useState<UnwrappedExecuteSprocParam[]>([{ key: "string", text: "" }]);
const [partitionValue, setPartitionValue] = useState<string>(); // Defaulting to undefined here is important. It is not the same partition key as ""
const [selectedKey, setSelectedKey] = React.useState<IDropdownOption>({ key: "string", text: "" });
const [formError, setFormError] = useState<string>("");
const onPartitionKeyChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
setSelectedKey(item);
};
const validateUnwrappedParams = (): boolean => {
const unwrappedParams: UnwrappedExecuteSprocParam[] = paramKeyValues;
const unwrappedParams: UnwrappedExecuteSprocParam[] = paramKeyValuesRef.current;
for (let i = 0; i < unwrappedParams.length; i++) {
const { key: paramType, text: paramValue } = unwrappedParams[i];
if (paramType === "custom" && (paramValue === "" || paramValue === undefined)) {
@ -53,8 +50,9 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
};
const submit = (): void => {
const wrappedSprocParams: UnwrappedExecuteSprocParam[] = paramKeyValues;
const { key: partitionKey } = selectedKey;
const wrappedSprocParams: UnwrappedExecuteSprocParam[] = paramKeyValuesRef.current;
const partitionValue: string = partitionValueRef.current;
const partitionKey: string = partitionKeyRef.current;
if (partitionKey === "custom" && (partitionValue === "" || partitionValue === undefined)) {
setInvalidParamError(partitionValue);
return;
@ -78,37 +76,21 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
};
const deleteParamAtIndex = (indexToRemove: number): void => {
const cloneParamKeyValue = [...paramKeyValues];
cloneParamKeyValue.splice(indexToRemove, 1);
setParamKeyValues(cloneParamKeyValue);
paramKeyValuesRef.current.splice(indexToRemove, 1);
setNumberOfParams(numberOfParams - 1);
};
const addNewParamAtIndex = (indexToAdd: number): void => {
const cloneParamKeyValue = [...paramKeyValues];
cloneParamKeyValue.splice(indexToAdd, 0, { key: "string", text: "" });
setParamKeyValues(cloneParamKeyValue);
};
const paramValueChange = (value: string, indexOfInput: number): void => {
const cloneParamKeyValue = [...paramKeyValues];
cloneParamKeyValue[indexOfInput].text = value;
setParamKeyValues(cloneParamKeyValue);
};
const paramKeyChange = (
_event: React.FormEvent<HTMLDivElement>,
selectedParam: IDropdownOption,
indexOfParam: number
): void => {
const cloneParamKeyValue = [...paramKeyValues];
cloneParamKeyValue[indexOfParam].key = selectedParam.key.toString();
setParamKeyValues(cloneParamKeyValue);
paramKeyValuesRef.current.splice(indexToAdd, 0, { key: "string", text: "" });
setNumberOfParams(numberOfParams + 1);
};
const addNewParamAtLastIndex = (): void => {
const cloneParamKeyValue = [...paramKeyValues];
cloneParamKeyValue.splice(cloneParamKeyValue.length, 0, { key: "string", text: "" });
setParamKeyValues(cloneParamKeyValue);
paramKeyValuesRef.current.push({
key: "string",
text: "",
});
setNumberOfParams(numberOfParams + 1);
};
const props: RightPaneFormProps = {
@ -118,47 +100,53 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
onSubmit: () => submit(),
};
const getInputParameterComponent = (): JSX.Element[] => {
const inputParameters: JSX.Element[] = [];
for (let i = 0; i < numberOfParams; i++) {
const paramKeyValue = paramKeyValuesRef.current[i];
inputParameters.push(
<InputParameter
key={paramKeyValue.text + i}
dropdownLabel={i === 0 ? "Key" : ""}
inputParameterTitle={i === 0 ? "Enter input parameters (if any)" : ""}
inputLabel={i === 0 ? "Param" : ""}
isAddRemoveVisible={true}
onDeleteParamKeyPress={() => deleteParamAtIndex(i)}
onAddNewParamKeyPress={() => addNewParamAtIndex(i + 1)}
onParamValueChange={(_event, newInput?: string) => (paramKeyValuesRef.current[i].text = newInput)}
onParamKeyChange={(_event, selectedParam: IDropdownOption) =>
(paramKeyValuesRef.current[i].key = selectedParam.key.toString())
}
paramValue={paramKeyValue.text}
selectedKey={paramKeyValue.key}
/>
);
}
return inputParameters;
};
return (
<RightPaneForm {...props}>
<div className="panelFormWrapper">
<div className="panelMainContent">
<InputParameter
dropdownLabel="Key"
inputParameterTitle="Partition key value"
inputLabel="Value"
isAddRemoveVisible={false}
onParamValueChange={(_event, newInput?: string) => {
setPartitionValue(newInput);
}}
onParamKeyChange={onPartitionKeyChange}
paramValue={partitionValue}
selectedKey={selectedKey.key}
onParamValueChange={(_event, newInput?: string) => (partitionValueRef.current = newInput)}
onParamKeyChange={(_event: React.FormEvent<HTMLDivElement>, item: IDropdownOption) =>
(partitionKeyRef.current = item.key.toString())
}
paramValue={partitionValueRef.current}
selectedKey={partitionKeyRef.current}
/>
{paramKeyValues.map((paramKeyValue, index) => (
<InputParameter
key={paramKeyValue && paramKeyValue.text + index}
dropdownLabel={!index && "Key"}
inputParameterTitle={!index && "Enter input parameters (if any)"}
inputLabel={!index && "Param"}
isAddRemoveVisible={true}
onDeleteParamKeyPress={() => deleteParamAtIndex(index)}
onAddNewParamKeyPress={() => addNewParamAtIndex(index + 1)}
onParamValueChange={(event, newInput?: string) => {
paramValueChange(newInput, index);
}}
onParamKeyChange={(event: React.FormEvent<HTMLDivElement>, selectedParam: IDropdownOption) => {
paramKeyChange(event, selectedParam, index);
}}
paramValue={paramKeyValue && paramKeyValue.text}
selectedKey={paramKeyValue && paramKeyValue.key}
/>
))}
<Stack horizontal onClick={addNewParamAtLastIndex} tabIndex={0}>
{getInputParameterComponent()}
<Stack horizontal onClick={() => addNewParamAtLastIndex()} tabIndex={0}>
<Image {...imageProps} src={AddPropertyIcon} alt="Add param" />
<Text className="addNewParamStyle">Add New Param</Text>
</Stack>
</div>
</div>
</RightPaneForm>
);
};

View File

@ -55,7 +55,7 @@ export const InputParameter: FunctionComponent<InputParameterProps> = ({
<Stack horizontal>
<Dropdown
label={dropdownLabel && dropdownLabel}
selectedKey={selectedKey}
defaultSelectedKey={selectedKey}
onChange={onParamKeyChange}
options={options}
styles={dropdownStyles}
@ -64,8 +64,9 @@ export const InputParameter: FunctionComponent<InputParameterProps> = ({
<TextField
label={inputLabel && inputLabel}
id="confirmCollectionId"
value={paramValue}
defaultValue={paramValue}
onChange={onParamValueChange}
tabIndex={0}
/>
{isAddRemoveVisible && (
<>

View File

@ -15,9 +15,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
<form
className="panelFormWrapper"
onSubmit={[Function]}
>
<div
className="panelFormWrapper"
>
<div
className="panelMainContent"
@ -322,6 +319,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
className="ms-Stack css-54"
>
<Dropdown
defaultSelectedKey="string"
key=".0:$.0"
label="Key"
onChange={[Function]}
@ -337,7 +335,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
},
]
}
selectedKey="string"
styles={
Object {
"dropdown": Object {
@ -348,6 +345,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
tabIndex={0}
>
<DropdownBase
defaultSelectedKey="string"
label="Key"
onChange={[Function]}
options={
@ -362,7 +360,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
},
]
}
selectedKey="string"
styles={[Function]}
tabIndex={0}
theme={
@ -640,6 +637,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}
>
<DropdownInternal
defaultSelectedKey="string"
hoisted={
Object {
"rootRef": [Function],
@ -664,7 +662,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
]
}
responsiveMode={3}
selectedKey="string"
styles={[Function]}
tabIndex={0}
theme={
@ -1569,6 +1566,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
key=".0:$.1"
label="Value"
onChange={[Function]}
tabIndex={0}
>
<TextFieldBase
deferredValidationTime={200}
@ -1577,6 +1575,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
onChange={[Function]}
resizable={true}
styles={[Function]}
tabIndex={0}
theme={
Object {
"disableGlobalClassNames": false,
@ -2162,6 +2161,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
onChange={[Function]}
onFocus={[Function]}
onInput={[Function]}
tabIndex={0}
type="text"
value=""
/>
@ -2477,6 +2477,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
className="ms-Stack css-54"
>
<Dropdown
defaultSelectedKey="string"
key=".0:$.0"
label="Key"
onChange={[Function]}
@ -2492,7 +2493,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
},
]
}
selectedKey="string"
styles={
Object {
"dropdown": Object {
@ -2503,6 +2503,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
tabIndex={0}
>
<DropdownBase
defaultSelectedKey="string"
label="Key"
onChange={[Function]}
options={
@ -2517,7 +2518,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
},
]
}
selectedKey="string"
styles={[Function]}
tabIndex={0}
theme={
@ -2795,6 +2795,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}
>
<DropdownInternal
defaultSelectedKey="string"
hoisted={
Object {
"rootRef": [Function],
@ -2819,7 +2820,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
]
}
responsiveMode={3}
selectedKey="string"
styles={[Function]}
tabIndex={0}
theme={
@ -3720,19 +3720,22 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</DropdownBase>
</Dropdown>
<StyledTextFieldBase
defaultValue=""
id="confirmCollectionId"
key=".0:$.1"
label="Param"
onChange={[Function]}
value=""
tabIndex={0}
>
<TextFieldBase
defaultValue=""
deferredValidationTime={200}
id="confirmCollectionId"
label="Param"
onChange={[Function]}
resizable={true}
styles={[Function]}
tabIndex={0}
theme={
Object {
"disableGlobalClassNames": false,
@ -4007,7 +4010,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
}
}
validateOnLoad={true}
value=""
>
<div
className="ms-TextField root-75"
@ -4319,6 +4321,7 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
onChange={[Function]}
onFocus={[Function]}
onInput={[Function]}
tabIndex={0}
type="text"
value=""
/>
@ -5302,7 +5305,6 @@ exports[`Excute Sproc Param Pane should render Default properly 1`] = `
</div>
</Stack>
</div>
</div>
<PanelFooterComponent
buttonLabel="Execute"
isButtonDisabled={false}