Fix validation in "Add Entry" components (#1625)

This commit is contained in:
Florian Scholdei
2021-04-21 14:36:52 +02:00
committed by GitHub
parent b6018280ed
commit 05ef203038
4 changed files with 115 additions and 146 deletions

View File

@@ -21,24 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { MouseEvent } from "react";
import React, { FC, useState, MouseEvent } from "react";
import styled from "styled-components";
import Level from "../layout/Level";
import InputField from "./InputField";
import AddButton from "../buttons/AddButton";
import InputField from "./InputField";
type Props = {
addEntry: (p: string) => void;
disabled: boolean;
disabled?: boolean;
buttonLabel: string;
fieldLabel: string;
errorMessage: string;
helpText?: string;
validateEntry?: (p: string) => boolean;
};
type State = {
entryToAdd: string;
errorMessage: string;
};
const StyledLevel = styled(Level)`
@@ -46,83 +42,77 @@ const StyledLevel = styled(Level)`
margin-bottom: 1rem !important; // same margin as field
`;
const StyledInputField = styled(InputField)`
const FullWidthInputField = styled(InputField)`
width: 100%;
margin-right: 1.5rem;
`;
const StyledField = styled.div.attrs(props => ({
const StyledField = styled.div.attrs(() => ({
className: "field"
}))`
align-self: flex-end;
`;
class AddEntryToTableField extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
entryToAdd: ""
};
}
const AddEntryToTableField: FC<Props> = ({
addEntry,
disabled,
buttonLabel,
fieldLabel,
helpText,
validateEntry,
errorMessage
}) => {
const [entryToAdd, setEntryToAdd] = useState("");
isValid = () => {
const { validateEntry } = this.props;
if (!this.state.entryToAdd || this.state.entryToAdd === "" || !validateEntry) {
return true;
} else {
return validateEntry(this.state.entryToAdd);
const handleAddEntryChange = (entryName: string) => {
setEntryToAdd(entryName);
};
const addButtonClicked = (event: MouseEvent) => {
event.preventDefault();
appendEntry();
};
const appendEntry = () => {
if (!disabled && entryToAdd !== "" && isValid()) {
addEntry(entryToAdd);
setEntryToAdd("");
}
};
render() {
const { disabled, buttonLabel, fieldLabel, errorMessage, helpText } = this.props;
return (
<StyledLevel
children={
<StyledInputField
label={fieldLabel}
errorMessage={errorMessage}
onChange={this.handleAddEntryChange}
validationError={!this.isValid()}
value={this.state.entryToAdd}
onReturnPressed={this.appendEntry}
disabled={disabled}
helpText={helpText}
const isValid = () => {
if (entryToAdd === "" || !validateEntry) {
return true;
} else {
return validateEntry(entryToAdd);
}
};
return (
<StyledLevel
children={
<FullWidthInputField
label={fieldLabel}
errorMessage={errorMessage}
onChange={handleAddEntryChange}
validationError={!isValid()}
value={entryToAdd}
onReturnPressed={appendEntry}
disabled={disabled}
helpText={helpText}
/>
}
right={
<StyledField>
<AddButton
label={buttonLabel}
action={addButtonClicked}
disabled={disabled || entryToAdd === "" || !isValid()}
/>
}
right={
<StyledField>
<AddButton
label={buttonLabel}
action={this.addButtonClicked}
disabled={disabled || this.state.entryToAdd === "" || !this.isValid()}
/>
</StyledField>
}
/>
);
}
addButtonClicked = (event: MouseEvent) => {
event.preventDefault();
this.appendEntry();
};
appendEntry = () => {
const { entryToAdd } = this.state;
this.props.addEntry(entryToAdd);
this.setState({
...this.state,
entryToAdd: ""
});
};
handleAddEntryChange = (entryname: string) => {
this.setState({
...this.state,
entryToAdd: entryname
});
};
}
</StyledField>
}
/>
);
};
export default AddEntryToTableField;

View File

@@ -21,16 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { MouseEvent } from "react";
import React, { FC, useState, MouseEvent } from "react";
import styled from "styled-components";
import { SelectValue } from "@scm-manager/ui-types";
import Level from "../layout/Level";
import Autocomplete from "../Autocomplete";
import AddButton from "../buttons/AddButton";
import Autocomplete from "../Autocomplete";
type Props = {
addEntry: (p: SelectValue) => void;
disabled: boolean;
disabled?: boolean;
buttonLabel: string;
fieldLabel: string;
helpText?: string;
@@ -40,86 +40,63 @@ type Props = {
noOptionsMessage?: string;
};
type State = {
selectedValue?: SelectValue;
};
const StyledAutocomplete = styled(Autocomplete)`
const FullWidthAutocomplete = styled(Autocomplete)`
width: 100%;
margin-right: 1.5rem;
`;
class AutocompleteAddEntryToTableField extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
selectedValue: undefined
};
}
render() {
const {
disabled,
buttonLabel,
fieldLabel,
helpText,
loadSuggestions,
placeholder,
loadingMessage,
noOptionsMessage
} = this.props;
const AutocompleteAddEntryToTableField: FC<Props> = ({
addEntry,
disabled,
buttonLabel,
fieldLabel,
helpText,
loadSuggestions,
placeholder,
loadingMessage,
noOptionsMessage
}) => {
const [selectedValue, setSelectedValue] = useState<SelectValue | undefined>(undefined);
const { selectedValue } = this.state;
return (
<Level
children={
<StyledAutocomplete
label={fieldLabel}
loadSuggestions={loadSuggestions}
valueSelected={this.handleAddEntryChange}
helpText={helpText}
value={selectedValue}
placeholder={placeholder}
loadingMessage={loadingMessage}
noOptionsMessage={noOptionsMessage}
creatable={true}
/>
}
right={
<div className="field">
<AddButton label={buttonLabel} action={this.addButtonClicked} disabled={disabled} />
</div>
}
/>
);
}
addButtonClicked = (event: MouseEvent) => {
event.preventDefault();
this.appendEntry();
const handleAddEntryChange = (selection: SelectValue) => {
setSelectedValue(selection);
};
appendEntry = () => {
const { selectedValue } = this.state;
if (!selectedValue) {
const addButtonClicked = (event: MouseEvent) => {
event.preventDefault();
appendEntry();
};
const appendEntry = () => {
if (disabled || !selectedValue) {
return;
}
this.setState(
// @ts-ignore
{
...this.state,
// @ts-ignore null is needed to clear the selection; undefined does not work
selectedValue: null
},
() => this.props.addEntry(selectedValue)
);
addEntry(selectedValue);
setSelectedValue(undefined);
};
handleAddEntryChange = (selection: SelectValue) => {
this.setState({
...this.state,
selectedValue: selection
});
};
}
return (
<Level
children={
<FullWidthAutocomplete
label={fieldLabel}
loadSuggestions={loadSuggestions}
valueSelected={handleAddEntryChange}
helpText={helpText}
value={selectedValue}
placeholder={placeholder}
loadingMessage={loadingMessage}
noOptionsMessage={noOptionsMessage}
creatable={true}
/>
}
right={
<div className="field">
<AddButton label={buttonLabel} action={addButtonClicked} disabled={disabled} />
</div>
}
/>
);
};
export default AutocompleteAddEntryToTableField;