@acvl/frontend-components 0.0.34 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,13 @@ export interface CSVMenuOptionProps {
6
6
  custom?: string;
7
7
  icon?: any;
8
8
  }
9
+ export interface ExtraCreateOptionProps {
10
+ title: string;
11
+ icon: any;
12
+ onClick: () => void;
13
+ }
9
14
  export interface CreateGridAPIProps {
15
+ extraOptions?: ExtraCreateOptionProps[];
10
16
  csv_upload?: {
11
17
  enable: boolean;
12
18
  extraOptions?: CSVMenuOptionProps[];
@@ -14,5 +14,5 @@ export interface JSONFormProps {
14
14
  useLabel?: boolean;
15
15
  props?: JSONParserProps;
16
16
  }
17
- export declare const formParser: ({ type, submitData, data, useLabel, props, }: JSONFormProps) => any;
17
+ export declare const formParser: ({ type, submitData, data, useLabel, props }: JSONFormProps) => any;
18
18
  export declare const setErrors: (form: any, error: any) => void;
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import type { AutocompleteProps } from "@mui/material";
3
+ import { ComoOpcionesProps } from "../../../types";
4
+ export interface CrudDropdownProps {
5
+ name: string;
6
+ label?: string;
7
+ control: any;
8
+ fieldProps?: Partial<AutocompleteProps<any, any, any, any>>;
9
+ extraProps: {
10
+ queryArgs: ComoOpcionesProps;
11
+ crudExtraArgs?: Record<string, any>;
12
+ /** API field name for the display label. Default: "nombre" */
13
+ labelField?: string;
14
+ disableHT?: boolean;
15
+ };
16
+ }
17
+ declare const CrudDropdown: React.FC<CrudDropdownProps>;
18
+ export default CrudDropdown;
@@ -11,3 +11,4 @@ export { default as ControlledToggleButtons } from "./ControlledToggleButtons";
11
11
  export { default as ControlledTimePicker } from "./ControlledTimePicker";
12
12
  export { default as ControlledFileField } from "./ControlledFileField";
13
13
  export { default as ControlledSimpleSlider } from "./ControlledSimpleSlider";
14
+ export { default as CrudDropdown } from "./CrudDropdown";
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { ReactNode } from "react";
2
2
  export interface APIcontextProps {
3
3
  useLazyGetComoOpcionesQuery: any;
4
4
  useLazyGetHistorialQuery: any;
@@ -6,9 +6,10 @@ export interface APIcontextProps {
6
6
  useValidarCSVMutation: any;
7
7
  useSubirCSVMutation: any;
8
8
  useRemoverCSVMutation: any;
9
+ useGenericCrudMutation: any;
9
10
  }
10
11
  declare const APIContext: import("react").Context<APIcontextProps | null>;
11
- export declare const APIProvider: ({ children, hooks }: {
12
+ export declare const APIProvider: ({ children, hooks, }: {
12
13
  children: ReactNode;
13
14
  hooks: APIcontextProps;
14
15
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Cambia el diseño default de ciertos componentes de Material UI
3
- **/
3
+ **/
4
4
  export default function componentStyleOverrides(theme: any): {
5
5
  MuiAlert: {
6
6
  defaultProps: {
@@ -10,12 +10,12 @@ export default function componentStyleOverrides(theme: any): {
10
10
  MuiListItemButton: {
11
11
  styleOverrides: {
12
12
  root: {
13
- '&:hover': {
13
+ "&:hover": {
14
14
  backgroundColor: string;
15
- '& .MuiTypography-root': {
15
+ "& .MuiTypography-root": {
16
16
  color: string;
17
17
  };
18
- '& .MuiSvgIcon-root': {
18
+ "& .MuiSvgIcon-root": {
19
19
  color: string;
20
20
  };
21
21
  };
@@ -25,35 +25,38 @@ export default function componentStyleOverrides(theme: any): {
25
25
  MuiDataGrid: {
26
26
  styleOverrides: {
27
27
  columnHeader: {
28
- '& .MuiDataGrid-columnHeaderTitle': {
28
+ "& .MuiDataGrid-columnHeaderTitle": {
29
29
  fontWeight: string;
30
30
  };
31
- '&:focus': {
31
+ "&:focus": {
32
32
  outline: string;
33
33
  };
34
34
  };
35
35
  row: {
36
+ "&.row-error": {
37
+ backgroundColor: "#ffcdd2";
38
+ };
36
39
  "&.even": {
37
40
  backgroundColor: "#fafafa";
38
41
  };
39
- '&:hover': {
42
+ "&:hover": {
40
43
  backgroundColor: string;
41
- '@media (hover: none)': {
44
+ "@media (hover: none)": {
42
45
  backgroundColor: string;
43
46
  };
44
47
  };
45
48
  };
46
49
  cell: {
47
- '& .MuiOutlinedInput-notchedOutline': {
50
+ "& .MuiOutlinedInput-notchedOutline": {
48
51
  border: string;
49
52
  };
50
- '&.MuiDataGrid-cell--editing': {
53
+ "&.MuiDataGrid-cell--editing": {
51
54
  backgroundColor: string;
52
- '& .MuiInputBase-root': {
55
+ "& .MuiInputBase-root": {
53
56
  height: string;
54
57
  };
55
58
  };
56
- '& .Mui-error': {
59
+ "& .Mui-error": {
57
60
  backgroundColor: string;
58
61
  color: string;
59
62
  fontWeight: string;
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { useTheme, useMediaQuery, Tooltip, IconButton, Button, Grid, FormGroup, FormHelperText as FormHelperText$1, Drawer, Box, Stack, CircularProgress, Typography as Typography$1, List as List$1, ListItem as ListItem$1, ListSubheader, styled as styled$1, LinearProgress, Autocomplete, Checkbox, Slider, Switch, InputAdornment as InputAdornment$1, ToggleButtonGroup, ToggleButton, Dialog, DialogTitle, DialogContent as DialogContent$1, DialogContentText, DialogActions as DialogActions$1, ButtonGroup, Menu, ListItemIcon, MenuItem as MenuItem$1, Link, Card, CardHeader, Avatar, CardContent, Divider as Divider$1, Popper, Grow as Grow$1, Paper, ClickAwayListener, Badge, TablePagination, NoSsr, tooltipClasses, Collapse, Fade as Fade$1, Slide, Zoom, Snackbar, alpha as alpha$1, lighten, createTheme as createTheme$1, responsiveFontSizes } from '@mui/material';
3
+ import { useTheme, useMediaQuery, Tooltip, IconButton, Button, Grid, FormGroup, FormHelperText as FormHelperText$1, Drawer, Box, Stack, CircularProgress, Typography as Typography$1, List as List$1, ListItem as ListItem$1, ListSubheader, styled as styled$1, LinearProgress, Autocomplete, Checkbox, Slider, Switch, InputAdornment as InputAdornment$1, ToggleButtonGroup, ToggleButton, TextField as TextField$1, Dialog, DialogTitle, DialogContent as DialogContent$1, DialogActions as DialogActions$1, DialogContentText, ButtonGroup, Menu, ListItemIcon, MenuItem as MenuItem$1, Link, Card, CardHeader, Avatar, CardContent, Divider as Divider$1, Popper, Grow as Grow$1, Paper, ClickAwayListener, Badge, TablePagination, NoSsr, tooltipClasses, Collapse, Fade as Fade$1, Slide, Zoom, Snackbar, alpha as alpha$1, lighten, createTheme as createTheme$1, responsiveFontSizes } from '@mui/material';
4
4
  import EditIcon from '@mui/icons-material/Edit';
5
5
  import * as React from 'react';
6
6
  import React__default, { useCallback, useEffect, isValidElement, cloneElement, Children, createContext, useContext, useState, useMemo, useRef, useImperativeHandle, useLayoutEffect, Suspense, forwardRef } from 'react';
@@ -41,7 +41,7 @@ import BaseFocusTrap from '@mui/material/Unstable_TrapFocus';
41
41
  import DialogContent from '@mui/material/DialogContent';
42
42
  import MuiDialog, { dialogClasses } from '@mui/material/Dialog';
43
43
  import debounce from 'lodash/debounce';
44
- import { get, map, find, groupBy, forEach, findIndex, mergeWith, isArray, omit, set as set$1, every, includes, merge as merge$2, countBy, isNumber, isEmpty as isEmpty$1, isBoolean, isEqual as isEqual$1, debounce as debounce$1, some } from 'lodash';
44
+ import { get, map, find, groupBy, forEach, findIndex, mergeWith, isArray, omit, set as set$1, debounce as debounce$1, every, includes, merge as merge$2, countBy, isNumber, isEmpty as isEmpty$1, isBoolean, isEqual as isEqual$1, some } from 'lodash';
45
45
  import { produce } from 'immer';
46
46
  import set from 'lodash/set';
47
47
  import get$1 from 'lodash/get';
@@ -68,8 +68,8 @@ import { Visibility, VisibilityOff } from '@mui/icons-material';
68
68
  import merge$1 from 'lodash/merge';
69
69
  import UploadFileIcon from '@mui/icons-material/UploadFile';
70
70
  import ClearIcon$1 from '@mui/icons-material/Clear';
71
- import SaveIcon from '@mui/icons-material/Save';
72
71
  import AddIcon from '@mui/icons-material/Add';
72
+ import SaveIcon from '@mui/icons-material/Save';
73
73
  import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
74
74
  import LinearProgress$1 from '@mui/material/LinearProgress';
75
75
  import AttachFileIcon from '@mui/icons-material/AttachFile';
@@ -25494,8 +25494,8 @@ const useHasPermission = (path) => {
25494
25494
  };
25495
25495
 
25496
25496
  const APIContext = createContext(null);
25497
- const APIProvider = ({ children, hooks }) => {
25498
- return (jsx(APIContext.Provider, { value: hooks, children: children }));
25497
+ const APIProvider = ({ children, hooks, }) => {
25498
+ return jsx(APIContext.Provider, { value: hooks, children: children });
25499
25499
  };
25500
25500
 
25501
25501
  const useAPI = () => {
@@ -25757,7 +25757,7 @@ const typeSwitch = ({ base_object, base_key, response, submitData, useLabel, dat
25757
25757
  break;
25758
25758
  }
25759
25759
  };
25760
- const formParser = ({ type, submitData, data, useLabel, props, }) => {
25760
+ const formParser = ({ type, submitData, data, useLabel, props }) => {
25761
25761
  const t = type || "json";
25762
25762
  const response = t === "json" ? {} : new FormData();
25763
25763
  Object.entries(submitData).forEach(([key, value]) => {
@@ -25778,9 +25778,27 @@ const formParser = ({ type, submitData, data, useLabel, props, }) => {
25778
25778
  };
25779
25779
  // ==============================|| ERRORS ||============================== //
25780
25780
  const setErrors = (form, error) => {
25781
+ const iterateDeep = (obj) => {
25782
+ if (Array.isArray(obj.reason)) {
25783
+ if (obj.reason.every((item) => typeof item === "object" && item !== null && !Array.isArray(item))) {
25784
+ obj.reason.forEach((obj2, index) => {
25785
+ Object.entries(obj2).forEach(([key3, val3]) => {
25786
+ form.setError(`${obj.name}.${index}.${key3}`, { message: val3.join(", ") });
25787
+ });
25788
+ });
25789
+ }
25790
+ else {
25791
+ form.setError(obj.name, { message: obj.reason.join(", ") });
25792
+ }
25793
+ }
25794
+ else {
25795
+ form.setError(obj.name, { message: obj.reason });
25796
+ }
25797
+ };
25781
25798
  if ("invalid_params" in error.data) {
25782
25799
  Object.values(error.data.invalid_params).forEach((entry) => {
25783
- form.setError(entry.name, { message: entry.reason.join(", ") });
25800
+ iterateDeep(entry);
25801
+ // form.setError(entry.name, { message: entry.reason.join(", ") });
25784
25802
  });
25785
25803
  }
25786
25804
  };
@@ -26514,6 +26532,161 @@ const ControlledSlider = (props) => {
26514
26532
  } }));
26515
26533
  };
26516
26534
 
26535
+ const CREATE_OPTION = { value: "__create__", label: "" };
26536
+ const CrudDropdown = (props) => {
26537
+ const { name, label, control, fieldProps, extraProps: { queryArgs, crudExtraArgs = {}, labelField = "nombre", disableHT }, } = props;
26538
+ const [inputValue, setInputValue] = useState("");
26539
+ const [options, setOptions] = useState([]);
26540
+ const [open, setOpen] = useState(false);
26541
+ const [createOpen, setCreateOpen] = useState(false);
26542
+ const [editOpen, setEditOpen] = useState(false);
26543
+ const [deleteOpen, setDeleteOpen] = useState(false);
26544
+ const [activeOption, setActiveOption] = useState(null);
26545
+ const [dialogInput, setDialogInput] = useState("");
26546
+ const formValueRef = useRef(null);
26547
+ const formOnChangeRef = useRef(() => { });
26548
+ const api = useAPI();
26549
+ const [getOpciones, { isLoading, isFetching, isError }] = api.useLazyGetComoOpcionesQuery();
26550
+ const [genericCrud, { isLoading: isMutating }] = api.useGenericCrudMutation();
26551
+ const notifications = useNotifications();
26552
+ const args = useMemo(() => ({
26553
+ ...queryArgs,
26554
+ filters: { ...queryArgs.filters, nombre__icontains: inputValue },
26555
+ }), [inputValue, queryArgs]);
26556
+ const fetchOptions = useCallback(debounce$1((fetchArgs, cb) => {
26557
+ setOptions([]);
26558
+ getOpciones(fetchArgs)
26559
+ .unwrap()
26560
+ .then(cb)
26561
+ .catch(() => { });
26562
+ }, 500), []);
26563
+ const refreshOptions = () => {
26564
+ getOpciones(args, false)
26565
+ .unwrap()
26566
+ .then((fresh) => setOptions(fresh))
26567
+ .catch(() => { });
26568
+ };
26569
+ React__default.useEffect(() => {
26570
+ if (open)
26571
+ fetchOptions(args, setOptions);
26572
+ }, [args, fetchOptions, open]);
26573
+ const handleCreate = () => {
26574
+ genericCrud({
26575
+ endpoint: props.extraProps.queryArgs.endpoint,
26576
+ method: "POST",
26577
+ body: { [labelField]: dialogInput, ...crudExtraArgs },
26578
+ })
26579
+ .unwrap()
26580
+ .then(() => {
26581
+ notifications.show("Opción creada.", { severity: "success" });
26582
+ setCreateOpen(false);
26583
+ setDialogInput("");
26584
+ refreshOptions();
26585
+ })
26586
+ .catch(() => notifications.show("Error al crear.", { severity: "error" }));
26587
+ };
26588
+ const handleEdit = () => {
26589
+ if (!activeOption)
26590
+ return;
26591
+ genericCrud({
26592
+ endpoint: props.extraProps.queryArgs.endpoint,
26593
+ method: "PATCH",
26594
+ id: activeOption.value,
26595
+ body: { [labelField]: dialogInput, ...crudExtraArgs },
26596
+ })
26597
+ .unwrap()
26598
+ .then(() => {
26599
+ if (formValueRef.current?.value === activeOption.value) {
26600
+ formOnChangeRef.current({ value: activeOption.value, label: dialogInput });
26601
+ }
26602
+ notifications.show("Opción actualizada.", { severity: "success" });
26603
+ setEditOpen(false);
26604
+ setDialogInput("");
26605
+ setActiveOption(null);
26606
+ refreshOptions();
26607
+ })
26608
+ .catch(() => notifications.show("Error al actualizar.", { severity: "error" }));
26609
+ };
26610
+ const handleDelete = () => {
26611
+ if (!activeOption)
26612
+ return;
26613
+ genericCrud({
26614
+ endpoint: props.extraProps.queryArgs.endpoint,
26615
+ method: "DELETE",
26616
+ id: activeOption.value,
26617
+ })
26618
+ .unwrap()
26619
+ .then(() => {
26620
+ if (formValueRef.current?.value === activeOption.value) {
26621
+ formOnChangeRef.current(null);
26622
+ }
26623
+ notifications.show("Opción eliminada.", { severity: "success" });
26624
+ setDeleteOpen(false);
26625
+ setActiveOption(null);
26626
+ refreshOptions();
26627
+ })
26628
+ .catch(() => notifications.show("Error al eliminar.", { severity: "error" }));
26629
+ };
26630
+ return (jsxs(Fragment, { children: [jsx(Controller, { name: name, control: control, render: ({ field: { value, onChange }, fieldState: { error } }) => {
26631
+ formValueRef.current = value;
26632
+ formOnChangeRef.current = onChange;
26633
+ const handleChange = (_event, newValue) => {
26634
+ if (newValue?.value === "__create__") {
26635
+ setDialogInput("");
26636
+ setCreateOpen(true);
26637
+ return;
26638
+ }
26639
+ onChange(newValue);
26640
+ };
26641
+ return (jsx(Autocomplete, { id: name, open: open, onOpen: () => setOpen(true), onClose: () => setOpen(false), options: options, loading: isLoading || isFetching, value: value, onChange: handleChange, inputValue: inputValue, onInputChange: (_event, newInputValue) => setInputValue(newInputValue), isOptionEqualToValue: (option, val) => option.value === val.value, filterOptions: (x) => [CREATE_OPTION, ...x], getOptionLabel: (option) => option.value === "__create__" ? "" : option.label || "", fullWidth: true, size: "small", disabled: isError, renderOption: (optionProps, option) => {
26642
+ const { key, ...rest } = optionProps;
26643
+ if (option.value === "__create__") {
26644
+ return (jsxs(Box, { component: "li", ...rest, onClick: () => {
26645
+ setDialogInput("");
26646
+ setCreateOpen(true);
26647
+ }, sx: {
26648
+ justifyContent: "center !important",
26649
+ color: "primary.main",
26650
+ borderBottom: "1px solid",
26651
+ borderColor: "divider",
26652
+ py: "6px !important",
26653
+ gap: 0.5,
26654
+ }, children: [jsx(AddIcon, { fontSize: "small" }), jsx(Typography$1, { variant: "body2", children: "Agregar nuevo" })] }, key));
26655
+ }
26656
+ return (jsxs(Box, { component: "li", ...rest, sx: {
26657
+ display: "flex",
26658
+ alignItems: "center",
26659
+ pr: "4px !important",
26660
+ }, children: [jsx(Box, { sx: {
26661
+ flex: 1,
26662
+ overflow: "hidden",
26663
+ textOverflow: "ellipsis",
26664
+ }, children: option.label }), jsx(IconButton, { size: "small", tabIndex: -1, onMouseDown: (e) => {
26665
+ e.stopPropagation();
26666
+ e.preventDefault();
26667
+ }, onClick: (e) => {
26668
+ e.stopPropagation();
26669
+ setActiveOption(option);
26670
+ setDialogInput(option.label);
26671
+ setEditOpen(true);
26672
+ }, children: jsx(EditIcon, { fontSize: "inherit" }) }), jsx(IconButton, { size: "small", tabIndex: -1, onMouseDown: (e) => {
26673
+ e.stopPropagation();
26674
+ e.preventDefault();
26675
+ }, onClick: (e) => {
26676
+ e.stopPropagation();
26677
+ setActiveOption(option);
26678
+ setDeleteOpen(true);
26679
+ }, children: jsx(DeleteIcon, { fontSize: "inherit" }) })] }, key));
26680
+ }, renderInput: (params) => (jsx(TextField$1, { ...params, label: label, error: !!error, helperText: error ? error.message : disableHT ? "" : " ", slotProps: {
26681
+ input: {
26682
+ ...params.InputProps,
26683
+ endAdornment: (jsxs(Fragment, { children: [isLoading || isFetching ? (jsx(CircularProgress, { color: "inherit", size: 20 })) : null, params.InputProps.endAdornment] })),
26684
+ },
26685
+ } })), ...fieldProps }));
26686
+ } }), jsxs(Dialog, { open: createOpen, onClose: () => setCreateOpen(false), maxWidth: "xs", fullWidth: true, children: [jsx(DialogTitle, { children: "Agregar opci\u00F3n" }), jsx(DialogContent$1, { children: jsx(TextField$1, { autoFocus: true, fullWidth: true, size: "small", label: label, value: dialogInput, onChange: (e) => setDialogInput(e.target.value), onKeyDown: (e) => e.key === "Enter" && !!dialogInput && handleCreate(), sx: { mt: 1 } }) }), jsxs(DialogActions$1, { children: [jsx(Button, { color: "error", onClick: () => setCreateOpen(false), children: "Cancelar" }), jsx(Button, { color: "secondary", disabled: !dialogInput, loading: isMutating, onClick: handleCreate, children: "Guardar" })] })] }), jsxs(Dialog, { open: editOpen, onClose: () => setEditOpen(false), maxWidth: "xs", fullWidth: true, children: [jsx(DialogTitle, { children: "Editar opci\u00F3n" }), jsx(DialogContent$1, { children: jsx(TextField$1, { autoFocus: true, fullWidth: true, size: "small", label: label, value: dialogInput, onChange: (e) => setDialogInput(e.target.value), onKeyDown: (e) => e.key === "Enter" && !!dialogInput && handleEdit(), sx: { mt: 1 } }) }), jsxs(DialogActions$1, { children: [jsx(Button, { color: "error", onClick: () => setEditOpen(false), children: "Cancelar" }), jsx(Button, { color: "secondary", disabled: !dialogInput, loading: isMutating, onClick: handleEdit, children: "Guardar" })] })] }), jsxs(Dialog, { open: deleteOpen, onClose: () => setDeleteOpen(false), maxWidth: "xs", fullWidth: true, children: [jsx(DialogTitle, { children: "Eliminar opci\u00F3n" }), jsx(DialogContent$1, { children: jsxs(Typography$1, { children: ["\u00BFEliminar ", jsx("strong", { children: activeOption?.label }), "?"] }) }), jsxs(DialogActions$1, { children: [jsx(Button, { onClick: () => setDeleteOpen(false), children: "Cancelar" }), jsx(Button, { color: "error", loading: isMutating, onClick: handleDelete, children: "Eliminar" })] })] })] }));
26687
+ };
26688
+ CrudDropdown.displayName = "CrudDropdown";
26689
+
26517
26690
  const DeleteConfirmationDialog = (props) => {
26518
26691
  const notifications = useNotifications();
26519
26692
  const { pathname } = useLocation();
@@ -27637,7 +27810,12 @@ const CreateGridWrapper = (props) => {
27637
27810
  }), jsxs(MenuItem, { onClick: () => {
27638
27811
  navigate(props.navigation ? `${props.navigation}crear` : `crear`);
27639
27812
  handleClose();
27640
- }, disableRipple: true, children: [jsx(ListItemIcon, { children: jsx(DrawIcon, {}) }), "Manual"] })] }), props.csv_upload?.enable && (jsx(CSVUpload, { open: csv.open, drawerToggle: handleToggleClose, data: csv.data })), props.renderFunction({ dataGridProps: createGridProps })] }));
27813
+ }, disableRipple: true, children: [jsx(ListItemIcon, { children: jsx(DrawIcon, {}) }), "Manual"] }), props.extraOptions?.map((option, index) => {
27814
+ return (jsxs(MenuItem, { onClick: () => {
27815
+ option.onClick();
27816
+ handleClose();
27817
+ }, disableRipple: true, children: [jsx(ListItemIcon, { children: option.icon }), option.title] }, index));
27818
+ })] }), props.csv_upload?.enable && (jsx(CSVUpload, { open: csv.open, drawerToggle: handleToggleClose, data: csv.data })), props.renderFunction({ dataGridProps: createGridProps })] }));
27641
27819
  };
27642
27820
 
27643
27821
  const Base = (props) => {
@@ -28089,12 +28267,11 @@ const EditToolbar = (props) => {
28089
28267
  const FieldArrayField = (props) => {
28090
28268
  const detail = useMemo(() => props.pageType === "detail", [props.pageType]);
28091
28269
  const { fields, append, remove, update } = useFieldArray({
28092
- control: props.form.control,
28270
+ control: props.form?.control,
28093
28271
  name: props.name,
28094
28272
  keyName: "_id",
28095
28273
  });
28096
- // console.log(props.form?.watch(props.name));
28097
- // console.log(fields);
28274
+ const errors = props.form.formState.errors;
28098
28275
  const getIndex = useCallback((id) => findIndex(fields, function (field) {
28099
28276
  return field._id == id;
28100
28277
  }), [fields]);
@@ -28150,9 +28327,18 @@ const FieldArrayField = (props) => {
28150
28327
  },
28151
28328
  },
28152
28329
  getRowId: (row) => row._id,
28153
- getRowClassName: (params) => params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd",
28330
+ getRowClassName: (params) => {
28331
+ const hasError = !!(errors &&
28332
+ props.name in errors &&
28333
+ errors[props.name][getIndex(params.row._id)]);
28334
+ return hasError
28335
+ ? "row-error"
28336
+ : params.indexRelativeToCurrentPage % 2 === 0
28337
+ ? "even"
28338
+ : "odd";
28339
+ },
28154
28340
  density: "compact",
28155
- onRowClick: props.pageType == "edit" ? handleRowClick : undefined,
28341
+ onRowClick: props.pageType != "detail" ? handleRowClick : undefined,
28156
28342
  }, props.dataGridProps);
28157
28343
  return (jsxs(Fragment, { children: [jsx(MainDrawer, { open: drawer.open, drawerToggle: handleCancel, title: "Trailer", slots: {
28158
28344
  button: (jsx(SaveCancelButton, { slotProps: {
@@ -28710,67 +28896,70 @@ function themeTypography() {
28710
28896
  // ==============================|| PERSONALIZADO DE COMPONENTES DE MUI ||============================== //
28711
28897
  /**
28712
28898
  * Cambia el diseño default de ciertos componentes de Material UI
28713
- **/
28899
+ **/
28714
28900
  function componentStyleOverrides(theme) {
28715
28901
  return {
28716
28902
  MuiAlert: {
28717
28903
  defaultProps: {
28718
- variant: 'filled'
28904
+ variant: "filled",
28719
28905
  },
28720
28906
  },
28721
28907
  MuiListItemButton: {
28722
28908
  styleOverrides: {
28723
28909
  root: {
28724
- '&:hover': {
28910
+ "&:hover": {
28725
28911
  backgroundColor: `${theme.palette.primary.main} !important`,
28726
- '& .MuiTypography-root': {
28727
- color: 'white !important',
28912
+ "& .MuiTypography-root": {
28913
+ color: "white !important",
28728
28914
  },
28729
- '& .MuiSvgIcon-root': {
28730
- color: 'white !important'
28731
- }
28732
- }
28733
- }
28734
- }
28915
+ "& .MuiSvgIcon-root": {
28916
+ color: "white !important",
28917
+ },
28918
+ },
28919
+ },
28920
+ },
28735
28921
  },
28736
28922
  MuiDataGrid: {
28737
28923
  styleOverrides: {
28738
28924
  columnHeader: {
28739
- '& .MuiDataGrid-columnHeaderTitle': {
28740
- fontWeight: 'bold'
28925
+ "& .MuiDataGrid-columnHeaderTitle": {
28926
+ fontWeight: "bold",
28741
28927
  },
28742
- '&:focus': {
28743
- outline: 'none',
28928
+ "&:focus": {
28929
+ outline: "none",
28744
28930
  },
28745
28931
  },
28746
28932
  row: {
28933
+ [`&.row-error`]: {
28934
+ backgroundColor: red[100],
28935
+ },
28747
28936
  [`&.even`]: {
28748
28937
  backgroundColor: grey[50],
28749
28938
  },
28750
- '&:hover': {
28939
+ "&:hover": {
28751
28940
  backgroundColor: alpha$1(theme.palette.primary.main, 0.2),
28752
- '@media (hover: none)': {
28753
- backgroundColor: 'transparent',
28941
+ "@media (hover: none)": {
28942
+ backgroundColor: "transparent",
28754
28943
  },
28755
- }
28944
+ },
28756
28945
  },
28757
28946
  cell: {
28758
- '& .MuiOutlinedInput-notchedOutline': {
28759
- border: 'none',
28947
+ "& .MuiOutlinedInput-notchedOutline": {
28948
+ border: "none",
28760
28949
  },
28761
- '&.MuiDataGrid-cell--editing': {
28762
- backgroundColor: 'rgb(217 243 190)',
28763
- '& .MuiInputBase-root': {
28764
- height: '100%',
28950
+ "&.MuiDataGrid-cell--editing": {
28951
+ backgroundColor: "rgb(217 243 190)",
28952
+ "& .MuiInputBase-root": {
28953
+ height: "100%",
28765
28954
  },
28766
28955
  },
28767
- '& .Mui-error': {
28768
- backgroundColor: 'rgba(234,27,43,0.2)',
28769
- color: '#ef1a2b',
28770
- fontWeight: 'bold',
28956
+ "& .Mui-error": {
28957
+ backgroundColor: "rgba(234,27,43,0.2)",
28958
+ color: "#ef1a2b",
28959
+ fontWeight: "bold",
28771
28960
  },
28772
28961
  },
28773
- }
28962
+ },
28774
28963
  },
28775
28964
  };
28776
28965
  }
@@ -28812,5 +29001,5 @@ const theme = () => {
28812
29001
  return themes;
28813
29002
  };
28814
29003
 
28815
- export { APIContext, APIProvider, ActiveCell, Base, ButtonWithDrawer, CSVUpload, ContentLayout, ControlledDate, ControlledDropdown, ControlledFileField, FileUploadBox as ControlledFileUploadBox, ControlledNumber, ControlledPhoneNumber, ControlledSelect, ControlledSlider as ControlledSimpleSlider, ControlledSlider$1 as ControlledSlider, ControlledSwitch, ControlledText, ControlledTimePicker, ControlledToggleButtons, CoverPage, CreateButtonBase, CreateButtonWithMenuOptions, DeleteButton, DeleteConfirmationDialog, DetailPage, EditButton, ExportCSV, HistorialDrawer, ListPage, Loadable, LoadingComponent, Logo, MainDrawer, MenuItemWithLoading, ModuleCard, MoreOptions, MyGridEditSingleSelect, NavigationContext, NavigationProvider, NormalOrIcon, NotAllowed, NotFound, ObjectProgressStack, SaveCancelButton, StatusBadge, StyledMenu, Tabs, Transitions, UncontrolledText, changeTitle, closeProgressSnack, dayjs, deleteColumn, editColumn, filterQuery, formParser, header as headerReducer, manualCacheRefresh, mergeSettings, openProgressSnack, query, renderEditCellWithErrorTooltip, setErrors, snackProgress_default as snackProgressReducer, tags, theme, updateProgressSnackData, useAPI, useHasPermission, useNavigation, valueLabel };
29004
+ export { APIContext, APIProvider, ActiveCell, Base, ButtonWithDrawer, CSVUpload, ContentLayout, ControlledDate, ControlledDropdown, ControlledFileField, FileUploadBox as ControlledFileUploadBox, ControlledNumber, ControlledPhoneNumber, ControlledSelect, ControlledSlider as ControlledSimpleSlider, ControlledSlider$1 as ControlledSlider, ControlledSwitch, ControlledText, ControlledTimePicker, ControlledToggleButtons, CoverPage, CreateButtonBase, CreateButtonWithMenuOptions, CrudDropdown, DeleteButton, DeleteConfirmationDialog, DetailPage, EditButton, ExportCSV, HistorialDrawer, ListPage, Loadable, LoadingComponent, Logo, MainDrawer, MenuItemWithLoading, ModuleCard, MoreOptions, MyGridEditSingleSelect, NavigationContext, NavigationProvider, NormalOrIcon, NotAllowed, NotFound, ObjectProgressStack, SaveCancelButton, StatusBadge, StyledMenu, Tabs, Transitions, UncontrolledText, changeTitle, closeProgressSnack, dayjs, deleteColumn, editColumn, filterQuery, formParser, header as headerReducer, manualCacheRefresh, mergeSettings, openProgressSnack, query, renderEditCellWithErrorTooltip, setErrors, snackProgress_default as snackProgressReducer, tags, theme, updateProgressSnackData, useAPI, useHasPermission, useNavigation, valueLabel };
28816
29005
  //# sourceMappingURL=index.js.map