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

View File

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