Don't show Bucket Name input error until field is touched (#2316)
This commit is contained in:
@@ -45,6 +45,8 @@ import { selDistSet, selSiteRep } from "../../../../../systemSlice";
|
||||
import {
|
||||
resetForm,
|
||||
setEnableObjectLocking,
|
||||
setIsDirty,
|
||||
setName,
|
||||
setQuota,
|
||||
setQuotaSize,
|
||||
setQuotaUnit,
|
||||
@@ -119,6 +121,7 @@ const AddBucket = ({ classes }: IsetProps) => {
|
||||
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(.|$)){4}$"
|
||||
);
|
||||
const bucketName = useSelector((state: AppState) => state.addBucket.name);
|
||||
const isDirty = useSelector((state: AppState) => state.addBucket.isDirty);
|
||||
const [validationResult, setValidationResult] = useState<boolean[]>([]);
|
||||
const errorList = validationResult.filter((v) => !v);
|
||||
const hasErrors = errorList.length > 0;
|
||||
@@ -166,7 +169,7 @@ const AddBucket = ({ classes }: IsetProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
const bucketNameErrors = [
|
||||
!(bucketName.length < 3 || bucketName.length > 63),
|
||||
!(isDirty && (bucketName.length < 3 || bucketName.length > 63)),
|
||||
validBucketCharacters.test(bucketName),
|
||||
!(
|
||||
bucketName.includes(".-") ||
|
||||
@@ -180,9 +183,11 @@ const AddBucket = ({ classes }: IsetProps) => {
|
||||
];
|
||||
setValidationResult(bucketNameErrors);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [bucketName]);
|
||||
}, [bucketName, isDirty]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(setName(""));
|
||||
dispatch(setIsDirty(false));
|
||||
const fetchRecords = () => {
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets`)
|
||||
@@ -475,7 +480,12 @@ const AddBucket = ({ classes }: IsetProps) => {
|
||||
type="submit"
|
||||
variant="callAction"
|
||||
color="primary"
|
||||
disabled={addLoading || invalidFields.length > 0 || hasErrors}
|
||||
disabled={
|
||||
addLoading ||
|
||||
invalidFields.length > 0 ||
|
||||
!isDirty ||
|
||||
hasErrors
|
||||
}
|
||||
label={"Create Bucket"}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import { setName } from "./addBucketsSlice";
|
||||
import { setName, setIsDirty } from "./addBucketsSlice";
|
||||
import InputBoxWrapper from "../../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import { useSelector } from "react-redux";
|
||||
import { AppState, useAppDispatch } from "../../../../../store";
|
||||
@@ -28,8 +28,10 @@ const AddBucketName = ({ hasErrors }: { hasErrors: boolean }) => {
|
||||
<InputBoxWrapper
|
||||
id="bucket-name"
|
||||
name="bucket-name"
|
||||
error={hasErrors ? "Invalid bucket Name" : ""}
|
||||
autoFocus={true}
|
||||
error={hasErrors ? "Invalid bucket name" : ""}
|
||||
onFocus={() => {
|
||||
dispatch(setIsDirty(true));
|
||||
}}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
dispatch(setName(event.target.value));
|
||||
}}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { addBucketAsync } from "./addBucketThunks";
|
||||
|
||||
export interface AddBucketState {
|
||||
loading: boolean;
|
||||
isDirty: boolean;
|
||||
invalidFields: string[];
|
||||
name: string;
|
||||
versioningEnabled: boolean;
|
||||
@@ -36,7 +37,8 @@ export interface AddBucketState {
|
||||
|
||||
const initialState: AddBucketState = {
|
||||
loading: false,
|
||||
invalidFields: ["name"],
|
||||
isDirty: false,
|
||||
invalidFields: [],
|
||||
name: "",
|
||||
versioningEnabled: false,
|
||||
lockingEnabled: false,
|
||||
@@ -55,6 +57,9 @@ export const addBucketsSlice = createSlice({
|
||||
name: "addBuckets",
|
||||
initialState,
|
||||
reducers: {
|
||||
setIsDirty: (state, action: PayloadAction<boolean>) => {
|
||||
state.isDirty = action.payload;
|
||||
},
|
||||
setName: (state, action: PayloadAction<string>) => {
|
||||
state.name = action.payload;
|
||||
|
||||
@@ -177,6 +182,7 @@ export const addBucketsSlice = createSlice({
|
||||
|
||||
export const {
|
||||
setName,
|
||||
setIsDirty,
|
||||
setVersioning,
|
||||
setEnableObjectLocking,
|
||||
setQuota,
|
||||
|
||||
@@ -41,6 +41,7 @@ interface InputBoxProps {
|
||||
classes: any;
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
onKeyPress?: (e: any) => void;
|
||||
onFocus?: () => void;
|
||||
value: string | boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -133,6 +134,7 @@ const InputBoxWrapper = ({
|
||||
classes,
|
||||
className = "",
|
||||
onKeyPress,
|
||||
onFocus,
|
||||
}: InputBoxProps) => {
|
||||
let inputProps: any = { "data-index": index, ...extraInputProps };
|
||||
|
||||
@@ -198,6 +200,7 @@ const InputBoxWrapper = ({
|
||||
placeholder={placeholder}
|
||||
className={classes.inputRebase}
|
||||
onKeyPress={onKeyPress}
|
||||
onFocus={onFocus}
|
||||
/>
|
||||
{overlayIcon && (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user