test-crud
Version:
es una prueba acerca de como publicar un package name
190 lines (171 loc) • 5.08 kB
JSX
import React, { useState, useEffect } from "react";
import { useFormikContext } from "formik";
import SearchInput from "../inputs/searchInput";
function AppSearchCustom({
name,
label,
valueProperty = "id",
labelProperty,
asyncData,
asyncParameters,
onSelect,
onClose,
onChangeInput,
endAdornment = null,
startAdornment = null,
defaultValue = null,
data = null,
setValue = null, // (string) Selecciona el valor del select, no solo cuando se inicializa el componente.
size = "normal",
variant = "outlined",
...rest
}) {
const [open, setOpen] = useState(false);
const [options, setOptions] = useState([]);
const [inputValue, setInputValue] = useState("");
const [startIcon, setStartIcon] = useState("");
const loading = open && options.length === 0;
const {
setFieldValue,
setFieldTouched,
errors,
touched,
values,
initialValues,
} = useFormikContext();
useEffect(() => {
let active = true;
if (!loading) return undefined;
asyncData(asyncParameters).then((res) => {
if (res.data) {
if (active) setOptions(res.data);
}
});
return () => {
active = false;
};
}, [loading, data]);
useEffect(() => {
if (!open) {
setOptions([]);
setStartIcon(null);
startAdornment = null;
}
setStartIcon(null);
startAdornment = null;
}, [open]);
useEffect(() => {
let newItem = null;
setFieldValue(name, values[name], false);
if (Object.keys(values).length !== 0 && !data) {
asyncData(asyncParameters).then((res) => {
if (res.data) {
setOptions(res.data);
newItem = res.data.find((item) => {
return item?.[valueProperty] === values[name];
});
if (newItem) {
setInputValue(newItem[labelProperty]);
setFieldValue(name, newItem[valueProperty]);
onSelect && onSelect(newItem);
}
}
});
} else if (Object.keys(values).length !== 0 && data) {
setOptions(data);
newItem = data.find((item) => item?.[valueProperty] === values[name]);
if (newItem) {
setInputValue(newItem[labelProperty]);
setFieldValue(name, newItem[valueProperty]);
onSelect && onSelect(newItem);
}
}
if (newItem) {
setInputValue(newItem[labelProperty]);
setFieldValue(name, newItem[valueProperty]);
onSelect && onSelect(newItem);
}
}, [initialValues, data]);
useEffect(() => {
if (values) {
if (!onChangeInput) {
setFieldValue(name, "");
setInputValue("");
if (onSelect) onSelect();
}
asyncData(asyncParameters).then((res) => {
if (res.data) {
setOptions(res.data);
const newItem = res.data.find(
(item) => item?.[valueProperty] === values[name]
);
if (newItem) {
setInputValue(newItem[labelProperty].toString());
setFieldValue(name, newItem[valueProperty]);
onSelect && onSelect(newItem);
}
if (defaultValue || setValue) {
const defaultItem = res.data.find(
(item) =>
item?.[valueProperty] === defaultValue ||
item?.[valueProperty] === setValue
);
if (defaultItem) {
setInputValue(defaultItem[labelProperty].toString());
setFieldValue(name, defaultItem[valueProperty]);
}
}
}
});
}
}, [asyncParameters, setValue]);
useEffect(() => {
startAdornment && setStartIcon(startAdornment);
}, [startAdornment, endAdornment]);
const handleSelect = (item) => {
if (!item) {
setInputValue("");
setFieldValue(name, "");
onSelect && onSelect(item);
setStartIcon(null);
startAdornment = null;
return;
}
setFieldValue(name, item[valueProperty]);
onSelect && onSelect(item);
};
return (
<div>
<SearchInput
name={name}
label={label}
value={values && values[name]}
inputValue={inputValue}
options={options}
getOptionLabel={(option) => option?.[labelProperty] || ""}
isOptionEqualToValue={(option, value) =>
option?.[valueProperty] === value ||
option?.[valueProperty] === value[valueProperty]
}
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
loading={loading}
onBlur={() => setFieldTouched(name)}
onChange={(event, newValue) => handleSelect(newValue)}
onInputChange={(event, newValue) => {
event && onChangeInput && onChangeInput(newValue.toString());
event && setInputValue(newValue.toString());
}}
touched={touched[name]}
errorMessage={errors[name]}
endAdornment={endAdornment}
startAdornment={startIcon && startIcon}
size={size}
variant={variant}
{...rest}
/>
</div>
);
}
export default AppSearchCustom;