Se agregan selectores y validación

This commit is contained in:
Germán Enríquez 2023-09-07 01:11:14 -05:00
parent c42ba868e2
commit 307e4344f4
10 changed files with 148 additions and 19 deletions

11
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "@chimera-pe/react-saas",
"version": "0.0.6",
"version": "0.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@chimera-pe/react-saas",
"version": "0.0.6",
"version": "0.1.1",
"license": "ISC",
"dependencies": {
"@emotion/react": "^11.11.1",
@ -22,6 +22,7 @@
"jwt-decode": "^3.1.2",
"mui-rff": "^6.2.3",
"navigator-languages": "^2.0.2",
"node-polyglot": "^2.5.0",
"react": ">=18",
"react-dom": ">=18",
"react-final-form": "^6.5.9",
@ -1815,7 +1816,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/array.prototype.foreach/-/array.prototype.foreach-1.0.4.tgz",
"integrity": "sha512-OYqqGR/56CopyheXNwdlJvFtbSvf2Z9RGvL20X6GvAuKePJ76L/D46BqZn3bITd36QA2Ti7Iy0UwVJaD/YwXZA==",
"peer": true,
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
@ -2248,8 +2248,7 @@
"node_modules/es-array-method-boxes-properly": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
"integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
"peer": true
"integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA=="
},
"node_modules/es-set-tostringtag": {
"version": "2.0.1",
@ -3564,7 +3563,6 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/node-polyglot/-/node-polyglot-2.5.0.tgz",
"integrity": "sha512-zXVwHNhFsG3mls+LKHxoHF70GQOL3FTDT3jH7ldkb95kG76RdU7F/NbvxV7D2hNIL9VpWXW6y78Fz+3KZkatRg==",
"peer": true,
"dependencies": {
"array.prototype.foreach": "^1.0.2",
"has": "^1.0.3",
@ -4617,7 +4615,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"peer": true,
"dependencies": {
"loose-envify": "^1.0.0"
}

View file

@ -1,6 +1,6 @@
{
"name": "@chimera-pe/react-saas",
"version": "0.0.6",
"version": "0.1.2",
"type": "module",
"scripts": {
"dev": "vite",
@ -22,6 +22,7 @@
"jwt-decode": "^3.1.2",
"mui-rff": "^6.2.3",
"navigator-languages": "^2.0.2",
"node-polyglot": "^2.5.0",
"react": ">=18",
"react-dom": ">=18",
"react-final-form": "^6.5.9",

View file

@ -2,7 +2,7 @@ import {Box,Alert,AlertTitle} from "@mui/material";
import {useTranslate} from "react-polyglot";
import PropTypes from "prop-types";
const Error = ({titulo,texto,align = "center",severity = "error"}) => {
const ErrorAlert = ({titulo,texto,align = "center",severity = "error"}) => {
const translate = useTranslate();
return (
@ -28,4 +28,4 @@ Error.propTypes={
severity: PropTypes.string
};
export default Error;
export default ErrorAlert;

View file

@ -22,11 +22,11 @@ const Notificacion=() => {
return (
<Snackbar
open={open}
message={notificacion && notificacion.mensaje && notificacion.tipo === "default" && translate(notificacion.mensaje)}
message={notificacion?.mensaje && notificacion.tipo === "default" && translate(notificacion.mensaje)}
autoHideDuration={5000}
onClose={handleClose}
>
{notificacion && notificacion.mensaje && notificacion.tipo !== "default" &&
{notificacion?.mensaje && notificacion.tipo !== "default" &&
<Alert severity={notificacion.tipo}>{translate(notificacion.mensaje)}</Alert>
}
</Snackbar>

View file

@ -1,12 +1,45 @@
import {SaasApp} from "./components";
import {SaasApp,Cargando,Error} from "./components";
import {useNotificar} from "./hooks";
import {Cargando,Error} from "./components";
import {logout} from "./redux";
import {
logout,
getInstancia,
getPerfiles,
getToken,
getUsuario
} from "./redux";
import {
composeValidators,
required,
requiredNotFalse,
number,
minLength,
maxLength,
min,
max,
regex,
email,
remote
} from "./validacion";
export {
SaasApp,
useNotificar,
Cargando,
Error,
logout
logout,
getInstancia,
getPerfiles,
getToken,
getUsuario,
composeValidators,
required,
requiredNotFalse,
number,
minLength,
maxLength,
min,
max,
regex,
email,
remote
};

View file

@ -1,6 +1,13 @@
import {store} from "./store";
import {inicializar} from "./inicializarSlice";
import {refreshToken,requestToken,logout} from "./loginSlice";
import {inicializar,getInstancia} from "./inicializarSlice";
import {
refreshToken,
requestToken,
logout,
getPerfiles,
getToken,
getUsuario
} from "./loginSlice";
import {mostrarNotificacion,ocultarNotificacion} from "./notificacionSlice";
import {cambiarIdioma,cambiarTema} from "./uiSlice";
@ -13,5 +20,9 @@ export {
mostrarNotificacion,
ocultarNotificacion,
cambiarIdioma,
cambiarTema
cambiarTema,
getInstancia,
getPerfiles,
getToken,
getUsuario
};

View file

@ -54,4 +54,6 @@ export const inicializar = createAsyncThunk("inicializar",async (payload) => {
return response.data;
});
export const getInstancia=state => state.instancia;
export default inicializarSlice.reducer;

View file

@ -91,4 +91,10 @@ export const refreshToken = createAsyncThunk("login/refreshToken",async (devURL,
export const {logout} = loginSlice.actions;
export const getToken=state => state.token;
export const getUsuario=state => state.usuario;
export const getPerfiles=state => state.perfiles;
export default loginSlice.reducer;

77
src/validacion.js Normal file
View file

@ -0,0 +1,77 @@
import lodashMemoize from "lodash/memoize";
const EMAIL_REGEX=/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const isEmpty=(value) =>
typeof value === 'undefined' ||
value === null ||
value === '' ||
(Array.isArray(value) && value.length === 0);
const getMessage=(message,messageArgs,value,values) => (
typeof message === 'function'
? message({args: messageArgs,value,values})
: messageArgs
? {message,args: messageArgs}
: message
);
const memoize=(fn) => lodashMemoize(fn,(...args) => JSON.stringify(args));
export const composeValidators=(...validators) => (value,values,meta) => {
const allValidators = Array.isArray(validators[0]) ? validators[0] : validators;
return allValidators.reduce(
(error,validator) =>
error ||
(typeof validator === 'function' && validator(value,values,meta)),
undefined
);
};
export const required=memoize((message="validacion.obligatorio") => (
Object.assign(
(value,values) => isEmpty(value) ? getMessage(message,undefined,value,values) : undefined,
{isRequired: true}
)
));
export const requiredNotFalse=memoize((message="validacion.obligatorio") => (
Object.assign(
(value,values) => isEmpty(value) || !value ? getMessage(message,undefined,value,values) : undefined,
{isRequired: true}
)
));
export const number=memoize((message="validacion.numero") => (value,values) => (
!isEmpty(value) && isNaN(value) ? getMessage(message,undefined,value,values) : undefined
));
export const minLength=memoize((min,message="validacion.longitud.minima") => (value,values) =>
!isEmpty(value) && value.length < min ? getMessage(message,undefined,value,values) : undefined
);
export const maxLength=memoize((max,message="validacion.longitud.maxima") => (value,values) =>
!isEmpty(value) && value.length > max ? getMessage(message,undefined,value,values) : undefined
);
export const min=memoize((min,message="validacion.minimo") => (value,values) =>
!isEmpty(value) && parseFloat(value) < min ? getMessage(message,undefined,value,values) : undefined
);
export const max=memoize((max,message="validacion.maximo") => (value,values) =>
!isEmpty(value) && parseFloat(value) > max ? getMessage(message,undefined,value,values) : undefined
);
export const regex=lodashMemoize((pattern,message="validacion.regex") => (value,values) =>
!isEmpty(value) && typeof value === "string" && !pattern.test(value) ? getMessage(message,undefined,value,values) : undefined,
(pattern,message) => (pattern.toString() + message)
);
export const email=memoize((message="validacion.correo") => regex(EMAIL_REGEX,message));
export const remote=memoize((call,params,message="validacion.remote") => (value,values,meta) => {
return meta.active && !isEmpty(value) &&
call(value,params)
.then(data => data ? getMessage(message,undefined,value,values) : undefined)
.catch(error => getMessage(error.message,undefined,value,values))
});

View file

@ -32,6 +32,7 @@ export default defineConfig({
"jwt-decode",
"mui-rff",
"navigator-languages",
"node-polyglot",
"react-polyglot",
"react-redux",
"react-router-dom",
@ -61,6 +62,7 @@ export default defineConfig({
"jwt-decode": "JWTDecode",
"mui-rff": "MUIRFF",
"navigator-languages": "NavigatorLanguages",
"node-polyglot": "NodePolyglot",
"react-polyglot": "ReactPolyglot",
"react-redux": "ReactRedux",
"react-router-dom": "ReactRouterDom",