@acvl/frontend-components 0.0.71 → 0.0.73

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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _mui_material from '@mui/material';
2
- import { ButtonProps, ButtonGroupProps, IconButtonProps, MenuItemProps, AlertProps, BoxProps, AutocompleteProps, SliderProps, SwitchProps, GridProps, DrawerProps, SxProps, Theme, StackProps, TypographyProps, MenuProps, PaletteColorOptions, TextFieldProps as TextFieldProps$1, InputBaseProps, DialogProps, DialogContentProps } from '@mui/material';
2
+ import { ButtonProps, ButtonGroupProps, IconButtonProps, MenuItemProps, BoxProps, AutocompleteProps, SliderProps, SwitchProps, GridProps, DrawerProps, SxProps, Theme, StackProps, TypographyProps, MenuProps, PaletteColorOptions, TextFieldProps as TextFieldProps$1, InputBaseProps, DialogProps, DialogContentProps } from '@mui/material';
3
3
  import * as React from 'react';
4
4
  import React__default, { ReactNode, Dispatch, SetStateAction, JSX, RefObject, ReactElement, FC, BaseSyntheticEvent, JSXElementConstructor, ElementType } from 'react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -127,13 +127,68 @@ interface ExtraButtonsProps {
127
127
  }
128
128
  declare const ExtraButtons: (props: ExtraButtonsProps) => react_jsx_runtime.JSX.Element;
129
129
 
130
+ /**
131
+ * Los colores de la paleta con los que se puede pintar un estado. Son los mismos que admite el
132
+ * chip de una tabla (`ChipCell`), y a propósito: así el mapa de colores de un catálogo —el que
133
+ * dice que el estado "2" es `info`— se declara una vez y sirve en la tabla y en la ficha.
134
+ */
135
+ type StatusColor = "primary" | "secondary" | "error" | "warning" | "info" | "success";
130
136
  interface StatusBadgeProps {
131
- severity?: AlertProps['severity'];
137
+ /**
138
+ * El color, no la gravedad, aunque se siga llamando así: las cuatro severidades de un
139
+ * `Alert` son también nombres de la paleta, y esto admite además `primary` y `secondary`.
140
+ *
141
+ * Rara vez se escribe a mano —lo normal es sacarlo de {@link resolveStatusColor}, que es
142
+ * quien sabe qué color le toca a cada estado del catálogo—.
143
+ */
144
+ severity?: StatusColor;
132
145
  title: string;
133
146
  slotProps?: {
134
147
  box?: Partial<BoxProps>;
135
148
  };
136
149
  }
150
+ /**
151
+ * Los dos colores de un estado: la tinta —texto y contorno— y el relleno.
152
+ *
153
+ * Salen del tema y no de una gama fija (`green[800]`, `yellow[100]`…), que es lo que hace que
154
+ * un mismo estado se vea igual en la pastilla de una ficha que en el chip de una tabla
155
+ * (`ChipCell`), y que los dos sigan al esquema de color activo en vez de quedarse en los tonos
156
+ * del claro. `severity` es además el nombre del color en la paleta —`success`, `warning`…—, así
157
+ * que no hay tabla de equivalencias que mantener: sin severidad se pinta neutro.
158
+ *
159
+ * El relleno es el mismo tono al 20%. Va escrito contra el canal (`mainChannel`) porque es la
160
+ * forma de que una transparencia siga a las variables CSS; `ChipCell` calcula ese mismo 20% con
161
+ * `alpha()`, que lo resuelve una sola vez y contra el esquema claro. Un tema sin variables se
162
+ * queda sin relleno —el contorno y el texto siguen en pie—.
163
+ *
164
+ * Se exporta porque el rótulo no siempre cabe: donde hay que reducirlo a un punto de color
165
+ * —un encabezado angosto— ese punto tiene que decir lo mismo, y la única forma de que no se
166
+ * separen con el tiempo es que el color salga de aquí.
167
+ */
168
+ declare const statusColors: (severity?: StatusColor) => {
169
+ /** Texto y contorno. */
170
+ ink: string;
171
+ /** Fondo. */
172
+ fill: string;
173
+ };
174
+ /**
175
+ * El color que le toca a un estado, según el mapa que declara el proyecto:
176
+ *
177
+ * const coloresDeEstado: Record<string, StatusColor> = { "1": "warning", "2": "info" };
178
+ *
179
+ * Es el mismo mapa que recibe `renderChipCell`, y esa es la idea: el estado "2" se ve igual en
180
+ * la columna de una tabla que en la cabecera de su ficha, sin declararlo dos veces.
181
+ *
182
+ * El estado llega como lo manda el backend —`{ value: "2", label: "Nueva" }`—, así que busca
183
+ * primero por código, que es lo estable, y después por etiqueta sin distinguir mayúsculas, para
184
+ * los endpoints que sólo mandan el texto. Sin mapa —o sin coincidencia— queda un último intento:
185
+ * que el propio valor sea ya un nombre de la paleta, que es como se pintaban los estados cuando
186
+ * el backend mandaba la severidad en vez del código.
187
+ *
188
+ * Devuelve `undefined` cuando no encuentra ninguno, y eso es una respuesta: la insignia se pinta
189
+ * neutra en vez de inventarle un color a un estado que nadie clasificó.
190
+ */
191
+ declare const resolveStatusColor: (estado: unknown, colors?: Record<string, StatusColor>) => StatusColor | undefined;
137
192
  declare const StatusBadge: React__default.FC<StatusBadgeProps>;
138
193
 
139
194
  interface CoverPageCardProps$1 {
@@ -392,7 +447,7 @@ interface ExportCSVButtonProps extends Pick<ExportButtonProps, "filterModel" | "
392
447
  column_key?: string;
393
448
  };
394
449
  }
395
- declare const ExportCSV: React__default.FC<ExportCSVButtonProps>;
450
+ declare const ExportCSV$1: React__default.FC<ExportCSVButtonProps>;
396
451
 
397
452
  declare const CustomNoRows: () => react_jsx_runtime.JSX.Element;
398
453
 
@@ -737,6 +792,12 @@ interface MainDrawerV2Props {
737
792
  /** Radio de las esquinas del panel de contenido. Por defecto `theme.shape.borderRadius`. */
738
793
  contentBorderRadius?: number;
739
794
  slots?: {
795
+ /**
796
+ * Lo que califica al título y va pegado a él —el estado de un registro—. No se encoge:
797
+ * lo que cede ancho cuando el encabezado se queda corto es el título, que ya corta con
798
+ * elipsis.
799
+ */
800
+ badge?: ReactNode;
740
801
  /** Acciones del encabezado, a la izquierda del botón de cerrar. */
741
802
  headerActions?: ReactNode;
742
803
  /** Pie fijo — no scrollea con el cuerpo. Pensado para guardar/cancelar. */
@@ -828,6 +889,16 @@ declare module "@mui/x-data-grid" {
828
889
  pageType: PageType;
829
890
  }
830
891
  }
892
+ /**
893
+ * Campo del panel de edición. Es el mismo campo de un formulario, salvo que su `display` puede
894
+ * ser una función: la evalúa contra la fila que se está editando, así una fila pinta sólo los
895
+ * campos que le tocan según lo que ya tiene capturado —una condición de "primer envío" no lleva
896
+ * cantidad, y pedirla nada más para ignorarla al guardar confunde a quien la captura.
897
+ */
898
+ interface ArrayFieldItemProps extends Omit<FieldProps$1, "display"> {
899
+ /** Por defecto `true`. Como función, recibe la fila en edición y su índice. */
900
+ display?: boolean | ((row: any, index: number) => boolean);
901
+ }
831
902
  interface ArrayFieldProps {
832
903
  name: string;
833
904
  label: string;
@@ -838,7 +909,7 @@ interface ArrayFieldProps {
838
909
  gridProps?: GridProps;
839
910
  pageType?: PageType;
840
911
  parser?: JSONParserProps;
841
- fields: FieldProps$1[];
912
+ fields: ArrayFieldItemProps[];
842
913
  /**
843
914
  * What the edit panel's fields resolve their `size` breakpoints against. Defaults to
844
915
  * `"container"`: that panel is a drawer, narrow by construction. It needs its own setting
@@ -1056,6 +1127,12 @@ interface APIcontextProps {
1056
1127
  useSubirCSVMutation: any;
1057
1128
  useRemoverCSVMutation: any;
1058
1129
  useGenericCrudMutation: any;
1130
+ /** Columnas exportables de un listado, para el selector del CSV. */
1131
+ useGetColumnasDeExportacionQuery: any;
1132
+ /** Presets de columnas guardados por el usuario, por recurso y variante. */
1133
+ useGetPreferenciasDeExportacionQuery: any;
1134
+ useGuardarPreferenciaDeExportacionMutation: any;
1135
+ useBorrarPreferenciaDeExportacionMutation: any;
1059
1136
  }
1060
1137
  declare const APIContext: React.Context<APIcontextProps | null>;
1061
1138
  declare const APIProvider: ({ children, hooks, }: {
@@ -1611,6 +1688,35 @@ type GridLayerMap = Partial<Record<GridLayerId, GridLayerContribution>>;
1611
1688
  */
1612
1689
  declare function ServerGrid(props: ServerGridProps): react_jsx_runtime.JSX.Element;
1613
1690
 
1691
+ interface ExportCSVProps {
1692
+ handleClick: () => void;
1693
+ filterModel: MyGridFilterModel;
1694
+ sortModel: GridSortModel;
1695
+ rowSelectionModel: GridRowSelectionModel;
1696
+ /** The scoping the grid queries with. Without it an export exceeds what the grid shows. */
1697
+ queryArgs?: ServerGridArgs;
1698
+ disabledWithoutSelection?: boolean;
1699
+ /** Rows the current filters match, for the count shown in the picker. */
1700
+ rowCount?: number;
1701
+ ignore?: {
1702
+ filters?: string[];
1703
+ sort?: boolean;
1704
+ };
1705
+ slots?: {
1706
+ endpoint?: string;
1707
+ title?: string;
1708
+ variant?: string;
1709
+ column_key?: string;
1710
+ /** Opens the column picker instead of downloading straight away. Defaults to on. */
1711
+ columnPicker?: boolean;
1712
+ };
1713
+ }
1714
+ /**
1715
+ * Downloads the whole filtered result set as CSV — the server rebuilds it from the filters,
1716
+ * so this is never limited to the rows currently on screen.
1717
+ */
1718
+ declare function ExportCSV(props: ExportCSVProps): react_jsx_runtime.JSX.Element;
1719
+
1614
1720
  interface UseServerGridOptions {
1615
1721
  /** Where this grid's state is remembered. Fixed for the lifetime of the mount. */
1616
1722
  storageKey: string;
@@ -1768,7 +1874,7 @@ interface DeleteGridColumnsProps {
1768
1874
  */
1769
1875
  declare const deleteColumn: (props: DeleteGridColumnsProps) => GridColDefPropsOverrides[];
1770
1876
 
1771
- type ChipColor = "primary" | "secondary" | "error" | "warning" | "info" | "success";
1877
+ type ChipColor = StatusColor;
1772
1878
  type ChipOption = {
1773
1879
  value: string;
1774
1880
  label: string;
@@ -1908,6 +2014,75 @@ declare const ControlledAmountWithCurrency: {
1908
2014
  formatDetail({ fieldData, extraProps, data, name, }: DetailRenderProps): string;
1909
2015
  };
1910
2016
 
2017
+ /**
2018
+ * Helpers puros del `ControlledAutocomplete`: los argumentos de la consulta, la
2019
+ * lista que se muestra y las cuentas del "seleccionar todo". Viven fuera del
2020
+ * componente para poder probarlos sin montar MUI ni RTK Query.
2021
+ */
2022
+
2023
+ /** Una opción del desplegable, tal como la devuelve `como_opciones`. */
2024
+ interface AutocompleteOption {
2025
+ value: any;
2026
+ label: string;
2027
+ }
2028
+
2029
+ interface ControlledAutocompleteProps {
2030
+ name: string;
2031
+ label?: string;
2032
+ /** Control de react-hook-form; lo inyecta el `EditField` o el panel de filtros. */
2033
+ control?: any;
2034
+ /** Props que se pasan tal cual al `Autocomplete` (ganan sobre las de aquí). */
2035
+ fieldProps?: Partial<AutocompleteProps<any, any, any, any>>;
2036
+ extraProps?: {
2037
+ /** Selección múltiple con casillas y chips. Por defecto, simple. */
2038
+ multiple?: boolean;
2039
+ /** Opciones fijas. Con ellas no se consulta nada y filtra el navegador. */
2040
+ options?: AutocompleteOption[];
2041
+ /** Origen remoto de las opciones (endpoint `como_opciones`). */
2042
+ queryArgs?: ComoOpcionesProps;
2043
+ /** Filtro contra el que se busca el texto. Por defecto `nombre__icontains`. */
2044
+ searchField?: string;
2045
+ /** Retardo del tecleo antes de consultar. Por defecto 400 ms. */
2046
+ debounceMs?: number;
2047
+ /** Caracteres mínimos para consultar. Por defecto 0 (lista completa al abrir). */
2048
+ minChars?: number;
2049
+ /** Fila de "seleccionar todo" en el modo múltiple. Por defecto, sí. */
2050
+ selectAll?: boolean;
2051
+ /** Quita el hueco reservado para el mensaje de error debajo del campo. */
2052
+ disableHT?: boolean;
2053
+ };
2054
+ }
2055
+ /**
2056
+ * Desplegable de opciones para react-hook-form: simple o múltiple, con opciones
2057
+ * fijas o consultadas a `como_opciones` según lo que se escribe. Unifica los
2058
+ * `ControlledDropdown` (simple) y `ControlledSelect` (múltiple) de v1, que eran
2059
+ * el mismo componente duplicado.
2060
+ *
2061
+ * ```ts
2062
+ * {
2063
+ * name: "cliente",
2064
+ * label: "Cliente",
2065
+ * type: ControlledAutocomplete,
2066
+ * extraProps: { queryArgs: { endpoint: "clientes" } },
2067
+ * }
2068
+ * ```
2069
+ *
2070
+ * Sobre las peticiones, que era el punto flojo de v1:
2071
+ *
2072
+ * - **Una por apertura.** v1 pedía dos veces al abrir (el `onOpen` disparaba la
2073
+ * consulta y el efecto la repetía con retardo) y otra vez en cada render del
2074
+ * padre, porque `queryArgs` llega como objeto literal y su identidad cambiaba.
2075
+ * - **Elegir una opción no consulta.** Al elegir, MUI reescribe el texto del
2076
+ * campo con la etiqueta; v1 lo trataba como búsqueda nueva y volvía a pedir.
2077
+ * - **Sin parpadeo ni respuestas cruzadas.** La lista es la del hook de RTK
2078
+ * Query, que siempre corresponde a los últimos argumentos disparados; v1
2079
+ * guardaba las opciones en estado propio, las vaciaba en cada tecla y una
2080
+ * respuesta lenta podía pisar a una más nueva.
2081
+ * - **Repetir una búsqueda sale de la caché**, incluido borrar el texto para
2082
+ * volver al listado completo.
2083
+ */
2084
+ declare const ControlledAutocomplete: ControlledInput<ControlledAutocompleteProps>;
2085
+
1911
2086
  interface ControlledColorProps {
1912
2087
  /** Ruta del color en el formulario. */
1913
2088
  name: string;
@@ -1955,8 +2130,16 @@ declare const ControlledColor: ControlledInput<ControlledColorProps>;
1955
2130
  declare const ControlledDate: ControlledInput;
1956
2131
 
1957
2132
  /**
1958
- * `ControlledSelect` de v2. Reutiliza el renderizado de edición de v1 y añade el
1959
- * renderizado de detalle (une las etiquetas de las opciones seleccionadas).
2133
+ * `ControlledSelect` de v2: hoy es un `ControlledAutocomplete` en modo múltiple.
2134
+ *
2135
+ * Se conserva el nombre porque ya lo usan varias pantallas de los dos
2136
+ * proyectos; lo que cambia por dentro es cuándo y cuántas veces se piden las
2137
+ * opciones (ver `ControlledAutocomplete`). `disableHT` viene en `true` para no
2138
+ * mover el alto de esas pantallas: el select de v1 no reservaba el renglón del
2139
+ * mensaje de error. Quien lo necesite puede pasarlo en `false`.
2140
+ *
2141
+ * Para código nuevo conviene usar `ControlledAutocomplete` directamente, que
2142
+ * además cubre el modo simple.
1960
2143
  */
1961
2144
  declare const ControlledSelect: ControlledInput;
1962
2145
 
@@ -2014,6 +2197,17 @@ interface SubsectionProps {
2014
2197
  fields?: FieldProps[];
2015
2198
  arrayFields?: ArrayFieldProps[];
2016
2199
  content?: (data: any) => ReactNode;
2200
+ /**
2201
+ * Acciones de la subsección, alineadas a la derecha en el renglón del título.
2202
+ *
2203
+ * Son de la subsección, no de su contenido: viven fuera del `Collapse`, así que siguen a la
2204
+ * mano con la subsección plegada. Y son hermanas del título, no sus hijas: usarlas no la
2205
+ * pliega —plegar es del título y su flecha, que es donde se declara con el cursor.
2206
+ *
2207
+ * El hueco que les queda a la derecha del título es suyo, así que una barra que sepa medirse
2208
+ * —`ResponsiveActions`— puede encogerse ahí dentro en lugar de desbordar el renglón.
2209
+ */
2210
+ actions?: ReactNode | ((data: any) => ReactNode);
2017
2211
  }
2018
2212
 
2019
2213
  interface SectionProps extends Partial<Omit<MyTab, "children">> {
@@ -2333,6 +2527,13 @@ interface DetailFormDrawerProps {
2333
2527
  saveAndNext?: string;
2334
2528
  };
2335
2529
  slots?: {
2530
+ /**
2531
+ * Ruta al estado del registro —`"estado"`—, la misma que recibe `DetailPage_v2`: se
2532
+ * pinta junto al título, como en la página, y con el mismo mapa de colores.
2533
+ *
2534
+ * @see DetailPageV2Props.slots.badge
2535
+ */
2536
+ badge?: string;
2336
2537
  /** Extra actions rendered in the header, left of the close button (e.g. "open full page"). */
2337
2538
  headerActions?: ReactNode;
2338
2539
  };
@@ -2341,6 +2542,10 @@ interface DetailFormDrawerProps {
2341
2542
  saveButton?: Partial<ButtonProps>;
2342
2543
  cancelButton?: Partial<ButtonProps>;
2343
2544
  saveAndNextButton?: Partial<ButtonProps>;
2545
+ /** @see DetailPageV2Props.slotProps.badge */
2546
+ badge?: {
2547
+ colors?: Record<string, StatusColor>;
2548
+ };
2344
2549
  };
2345
2550
  }
2346
2551
  /**
@@ -2438,6 +2643,23 @@ interface DrawerGridDrawerConfig {
2438
2643
  * de abrirlo en su página.
2439
2644
  */
2440
2645
  extraButtons?: DetailExtraButton[];
2646
+ /**
2647
+ * El estado del registro, junto al título de la cabecera del cajón —igual que en su página
2648
+ * completa—. `path` es la ruta al campo dentro del dato, que el backend manda como
2649
+ * `{ value, label }`, y `colors` dice de qué color va cada código:
2650
+ *
2651
+ * badge: { path: "estado", colors: { "1": "warning", "2": "info" } }
2652
+ *
2653
+ * `colors` es el mismo mapa que recibe `renderChipCell`, así que lo natural es declararlo
2654
+ * junto al catálogo y pasárselo a los dos: el estado se ve igual en la columna de la tabla
2655
+ * que en el cajón que abre esa misma fila.
2656
+ *
2657
+ * @see DetailPageV2Props.slots.badge
2658
+ */
2659
+ badge?: {
2660
+ path: string;
2661
+ colors?: Record<string, StatusColor>;
2662
+ };
2441
2663
  /** Runs after any successful create/edit (e.g. side effects; the grid refetches via RTK tag invalidation). */
2442
2664
  onSaved?: (response: any) => void;
2443
2665
  /**
@@ -2547,7 +2769,132 @@ interface ConfirmDialogProps {
2547
2769
  * confirmar puede mostrar estado de carga mientras se resuelve la acción. */
2548
2770
  declare function ConfirmDialog({ open, titulo, mensaje, confirmLabel, cancelLabel, confirmColor, confirmIcon, isLoading, onConfirm, onClose, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
2549
2771
 
2550
- interface ActionsMenuProps {
2772
+ interface PulseDotProps {
2773
+ /** Cuando es `true`, el punto es verde y parpadea; si no, usa `inactiveColor`. */
2774
+ active: boolean;
2775
+ /** Color cuando no está activo. Por defecto `error.main`. */
2776
+ inactiveColor?: string;
2777
+ /** Tamaño del punto en px. Por defecto 10. */
2778
+ size?: number;
2779
+ /** Título opcional; si se pasa, envuelve el punto en un Tooltip. */
2780
+ title?: ReactNode;
2781
+ }
2782
+ /** Punto de estado: verde con animación de parpadeo cuando está activo, de lo
2783
+ * contrario un color fijo. Se usa para indicar conexión/actividad en vivo. */
2784
+ declare function PulseDot({ active, inactiveColor, size, title }: PulseDotProps): react_jsx_runtime.JSX.Element;
2785
+
2786
+ /**
2787
+ * El contenedor que declara todo renglón que lleve un título y sus adornos: el encabezado de
2788
+ * una página, el de un cajón y el de un diálogo.
2789
+ *
2790
+ * Se llama igual en los tres a propósito. Lo que aterriza en ese renglón —el estado de un
2791
+ * registro, una barra de acciones— tiene que encogerse cuando el renglón se queda corto, y con
2792
+ * un solo nombre esa regla se escribe una vez y sirve en los tres sitios: cada cosa mide contra
2793
+ * el renglón que la contiene, que en una página es el ancho de la página y en un cajón de 460px
2794
+ * es el del cajón. Los breakpoints del viewport no sabrían distinguirlos —la pantalla es la
2795
+ * misma— y `@container` sí.
2796
+ *
2797
+ * No se pisan entre ellos aunque compartan nombre: un cajón y un diálogo se pintan por portal,
2798
+ * fuera del árbol de la página, así que nunca hay uno dentro de otro. Y si lo hubiera, una
2799
+ * `@container` resuelve contra el contenedor ancestro más cercano, que es justo el que manda.
2800
+ */
2801
+ declare const HEADER_CONTAINER = "acv-header";
2802
+ /**
2803
+ * Debajo de este ancho el renglón se considera angosto y lo que viva en él debería encogerse:
2804
+ * la insignia de estado, por ejemplo, se queda en un punto de color con el rótulo en el globo.
2805
+ *
2806
+ * Se escribe como regla y no como número suelto para que quien la use no tenga que rearmar la
2807
+ * consulta —ni equivocarse al hacerlo—:
2808
+ *
2809
+ * sx={{ [HEADER_NARROW]: { display: "none" } }}
2810
+ */
2811
+ declare const HEADER_NARROW = "@container acv-header (max-width: 600px)";
2812
+ /**
2813
+ * Convierte un renglón en el contenedor contra el que se miden sus adornos.
2814
+ *
2815
+ * `inline-size`, nunca `size`: contener también el eje de bloque le fijaría la altura al
2816
+ * encabezado, que crece con lo que lleva dentro —un subtítulo, un título en dos renglones—.
2817
+ */
2818
+ declare const headerContainerSx: CSSObject;
2819
+
2820
+ /**
2821
+ * Cómo se está dibujando la barra. En orden de lo que ocupa: las acciones a la vista con su
2822
+ * etiqueta, las mismas sólo con el icono, sólo las fijadas, o ninguna.
2823
+ *
2824
+ * El modo dice qué se dibuja *fuera* del menú; lo que quede fuera de eso —y lo que sobre del
2825
+ * tope de `maxVisible`— está siempre dentro de él, así que hasta en `"full"` puede haber menú.
2826
+ *
2827
+ * `"pinned"` sólo es un escalón cuando hay alguna acción fijada; sin ellas la barra pasa de
2828
+ * `"icons"` derecho a `"menu"`.
2829
+ */
2830
+ declare const RESPONSIVE_ACTION_MODES: readonly ["full", "icons", "pinned", "menu"];
2831
+ type ResponsiveActionsMode = (typeof RESPONSIVE_ACTION_MODES)[number];
2832
+ interface ResponsiveAction {
2833
+ /** Texto del botón; también lo que se lee en el menú y en el tooltip del modo icono. */
2834
+ label: string;
2835
+ /** Se dibuja como `startIcon`, como el botón entero, o a la izquierda del renglón del menú. */
2836
+ icon: ReactNode;
2837
+ onClick: () => void;
2838
+ /** Ayuda larga. Sustituye a `label` como tooltip —el modo icono siempre lleva uno. */
2839
+ tooltip?: string;
2840
+ disabled?: boolean;
2841
+ /** Spinner en lugar del icono, y la acción bloqueada mientras tanto. */
2842
+ loading?: boolean;
2843
+ /** También tiñe el renglón del menú, para que la acción se vea igual se dibuje como se dibuje. */
2844
+ color?: ButtonProps["color"];
2845
+ /**
2846
+ * La última en esconderse: cuando el renglón deja de dar para todas, esta se queda a la vista
2847
+ * —como icono— y las demás se van al menú. Es para la que se usa siempre (editar, en una
2848
+ * ficha); fijar media barra no sirve de mucho, porque entonces ese escalón acaba pesando casi
2849
+ * lo mismo que el anterior y se salta solo.
2850
+ */
2851
+ pinned?: boolean;
2852
+ }
2853
+ interface ResponsiveActionsProps {
2854
+ actions: ResponsiveAction[];
2855
+ /**
2856
+ * Cuántas acciones se dibujan como botón, como mucho. Las demás se van al menú desde el
2857
+ * primer modo, quepan o no: es un tope de cuántas *merecen* estar a la vista, no de cuántas
2858
+ * caben —de eso ya se encarga la medición—. Sin él salen todas.
2859
+ *
2860
+ * Se queda con las primeras, así que el orden manda: lo importante va delante. Fijar una
2861
+ * acción (`pinned`) no la adelanta, sólo la hace la última en esconderse.
2862
+ */
2863
+ maxVisible?: number;
2864
+ /** @default "small" */
2865
+ size?: "small" | "medium";
2866
+ /** Fija el modo y apaga la medición. Para cuando el ancho no es quien debe decidir. */
2867
+ mode?: ResponsiveActionsMode;
2868
+ }
2869
+ /**
2870
+ * Una barra de acciones que se encoge sola cuando deja de caber: primero pierde las etiquetas y
2871
+ * se queda en iconos, después esconde en un menú de tres puntos todo menos lo fijado, y al final
2872
+ * se mete ahí entera.
2873
+ *
2874
+ * Encogerse es cosa del ancho; cuántas acciones merecen un botón, no. Para eso está `maxVisible`,
2875
+ * que manda al menú lo que pase de la cuenta aunque sobre sitio —una barra de ocho botones cabe
2876
+ * en una pantalla ancha y aun así no hay quien la lea—.
2877
+ *
2878
+ * Mide, no adivina. Los breakpoints del viewport no sirven aquí —la misma barra vive en una
2879
+ * página ancha y en un cajón de 460px, donde la pantalla es grande y el hueco no—, así que
2880
+ * compara el ancho que le dejaron con el que sus botones piden y baja un escalón cuando no
2881
+ * alcanza. Es el mismo motivo por el que el layout de los campos resuelve por `@container`.
2882
+ *
2883
+ * Para que la medición signifique algo, el padre tiene que ser un renglón flex que le deje
2884
+ * crecer al sobrante: la raíz se estira (`flexGrow`) para que su ancho *sea* el hueco, y los
2885
+ * botones van dentro sin encogerse, así que su ancho es lo que piden de verdad.
2886
+ */
2887
+ declare const ResponsiveActions: ({ actions, maxVisible, size, mode: forcedMode, }: ResponsiveActionsProps) => react_jsx_runtime.JSX.Element | null;
2888
+
2889
+ interface DetailActionsProps {
2890
+ /**
2891
+ * Editar. Va fijada, así que es la última en irse al menú cuando el renglón se estrecha: es
2892
+ * la acción de siempre en una ficha, y la que se busca sin leer. Se lleva consigo el Ctrl+E
2893
+ * que vivía en `EditButton`, el botón suelto que esta barra vino a sustituir.
2894
+ */
2895
+ edit?: {
2896
+ onClick: () => void;
2897
+ };
2551
2898
  delete?: {
2552
2899
  mutation: any;
2553
2900
  disableNavBack?: boolean;
@@ -2564,8 +2911,14 @@ interface ActionsMenuProps {
2564
2911
  icon: ReactNode;
2565
2912
  onClick: () => void;
2566
2913
  }[];
2567
- /** Tamaño del botón que abre el menú. `"small"` para las cabeceras del cajón. */
2914
+ /** Tamaño de los botones. `"small"` para las cabeceras del cajón. */
2568
2915
  size?: "small" | "medium";
2916
+ /**
2917
+ * Fija cómo se dibuja la barra en vez de dejar que se mida. El cajón lo usa para quedarse
2918
+ * siempre en el menú de tres puntos: su cabecera ya lleva sus propios botones al lado.
2919
+ * @see ResponsiveActionsProps.mode
2920
+ */
2921
+ mode?: ResponsiveActionsMode;
2569
2922
  }
2570
2923
 
2571
2924
  interface DetailPageV2Props {
@@ -2591,13 +2944,19 @@ interface DetailPageV2Props {
2591
2944
  slots?: {
2592
2945
  button?: ReactNode;
2593
2946
  /**
2594
- * Acciones propias del registro, junto a las del armazón. En `"detail"` viven dentro
2595
- * del menú de acciones; en alta y edición, como iconos al lado de Guardar.
2947
+ * Acciones propias del registro, junto a las del armazón. En `"detail"` entran en la
2948
+ * barra de acciones; en alta y edición, como iconos al lado de Guardar.
2596
2949
  *
2597
2950
  * Las mismas se le pueden pasar al cajón de `DrawerGrid_v2` (`drawer.extraButtons`),
2598
2951
  * para que el registro traiga sus acciones se abra donde se abra.
2599
2952
  */
2600
2953
  extraButtons?: DetailExtraButton[];
2954
+ /**
2955
+ * Ruta al estado del registro dentro del dato —`"estado"`—, que el backend manda como
2956
+ * `{ value, label }`: se lee la etiqueta y el código decide el color.
2957
+ *
2958
+ * @see DetailPageV2Props.slotProps.badge
2959
+ */
2601
2960
  badge?: string;
2602
2961
  };
2603
2962
  slotProps?: {
@@ -2610,15 +2969,30 @@ interface DetailPageV2Props {
2610
2969
  cancel?: Partial<ButtonProps>;
2611
2970
  };
2612
2971
  /**
2613
- * The history panel opened from the actions menu. It docks beside the page rather
2972
+ * The history panel opened from the actions bar. It docks beside the page rather
2614
2973
  * than floating over it, so the record stays readable next to what the history says
2615
- * about it — see `ActionsMenuProps.historial` for how to change that.
2974
+ * about it — see `DetailActionsProps.historial` for how to change that.
2616
2975
  */
2617
- historial?: ActionsMenuProps["historial"];
2976
+ historial?: DetailActionsProps["historial"];
2618
2977
  permissionsPath?: string;
2619
2978
  deleteButton?: {
2620
2979
  disableNavBack?: boolean;
2621
2980
  };
2981
+ badge?: {
2982
+ /**
2983
+ * De qué color se pinta cada estado, por código:
2984
+ *
2985
+ * colors: { "1": "warning", "2": "info", "3": "success" }
2986
+ *
2987
+ * Es el mismo mapa que recibe `renderChipCell` en las columnas de una tabla, así que
2988
+ * lo natural es declararlo junto al catálogo y pasarlo a los dos: el estado "2" se ve
2989
+ * igual en la lista que en la ficha.
2990
+ *
2991
+ * Sin mapa la insignia queda neutra —gris—, que es como se veían todos antes de que
2992
+ * hubiera con qué distinguirlos.
2993
+ */
2994
+ colors?: Record<string, StatusColor>;
2995
+ };
2622
2996
  };
2623
2997
  }
2624
2998
  declare function DetailPage(props: DetailPageV2Props): react_jsx_runtime.JSX.Element;
@@ -2649,11 +3023,27 @@ interface DetailFormDialogProps {
2649
3023
  save?: string;
2650
3024
  cancel?: string;
2651
3025
  };
3026
+ slots?: {
3027
+ /**
3028
+ * Ruta al estado del registro —`"estado"`—, la misma que recibe `DetailPage_v2`: se
3029
+ * pinta junto al título, con el mismo mapa de colores.
3030
+ *
3031
+ * Un diálogo es angosto por construcción, así que casi siempre se verá como el punto de
3032
+ * color con el rótulo en el globo.
3033
+ *
3034
+ * @see DetailPageV2Props.slots.badge
3035
+ */
3036
+ badge?: string;
3037
+ };
2652
3038
  slotProps?: {
2653
3039
  dialog?: Partial<DialogProps>;
2654
3040
  content?: Partial<DialogContentProps>;
2655
3041
  saveButton?: Partial<ButtonProps>;
2656
3042
  cancelButton?: Partial<ButtonProps>;
3043
+ /** @see DetailPageV2Props.slotProps.badge */
3044
+ badge?: {
3045
+ colors?: Record<string, StatusColor>;
3046
+ };
2657
3047
  };
2658
3048
  }
2659
3049
  /**
@@ -2662,7 +3052,7 @@ interface DetailFormDialogProps {
2662
3052
  * becomes a `DialogTitle` and the buttons move into `DialogActions`. The save button lives
2663
3053
  * outside the `<form>` tree, so it submits via the native `form={formId}` attribute.
2664
3054
  */
2665
- declare function DetailFormDialog({ open, onClose, title, api, form, sections, pageType, permissionsPath, onSuccess, responsiveTo, containerBreakpoints, labels, slotProps, }: DetailFormDialogProps): react_jsx_runtime.JSX.Element;
3055
+ declare function DetailFormDialog({ open, onClose, title, api, form, sections, pageType, permissionsPath, onSuccess, responsiveTo, containerBreakpoints, labels, slots, slotProps, }: DetailFormDialogProps): react_jsx_runtime.JSX.Element;
2666
3056
 
2667
3057
  /**
2668
3058
  * Encabezado por defecto del `PageContainer`: resuelve título y breadcrumbs a
@@ -2671,6 +3061,11 @@ declare function DetailFormDialog({ open, onClose, title, api, form, sections, p
2671
3061
  *
2672
3062
  * El título se lee de `state.header.title` (slice `headerReducer` de la librería)
2673
3063
  * cuando hay un id en la ruta; de lo contrario se deriva del título de la página.
3064
+ *
3065
+ * Pinta la misma estructura que el `PageHeader` de Toolpad —breadcrumbs arriba, título
3066
+ * y barra de acciones abajo— y no aquel componente, porque su título es un `string` y
3067
+ * aquí hace falta poder poner algo a su lado: el hueco donde aterriza la nota de la
3068
+ * página (ver `PageInfo`).
2674
3069
  **/
2675
3070
  /**
2676
3071
  * Página sin entrada en la navegación de Toolpad. Como `useActivePage` no la
@@ -2687,6 +3082,45 @@ interface MainLayoutPageHeaderProps extends PageHeaderProps {
2687
3082
  documentTitleSuffix?: string;
2688
3083
  }
2689
3084
 
3085
+ /**
3086
+ * Pie por defecto del sidebar: aviso de privacidad, versión del sistema y aviso
3087
+ * de copyright.
3088
+ *
3089
+ * Todo lo que se pinta depende del proyecto que consume el layout, así que llega
3090
+ * por props (la versión no se lee de `import.meta.env` aquí). Cada pieza aparece
3091
+ * sólo si le pasaron lo suyo: sin `privacyUrl` no hay enlace y sin `version` no
3092
+ * hay versión, que es como se comportaba este pie antes de crecer.
3093
+ *
3094
+ * Con `releaseNotesUrl` la versión deja de ser texto muerto y pasa a ser un
3095
+ * enlace a las novedades, con un punto encendido mientras el proyecto reporte
3096
+ * que hay algo sin leer.
3097
+ **/
3098
+ /**
3099
+ * Lo que el proyecto configura del pie por defecto. Va aparte de las props del
3100
+ * componente porque `MainLayout` lo recibe entero en su prop `footer` y se lo
3101
+ * inyecta al slot, que de Toolpad sólo recibe `mini`.
3102
+ */
3103
+ interface MainLayoutFooterConfig {
3104
+ /** Versión del sistema; sin ella no se pinta la línea. */
3105
+ version?: string;
3106
+ /** Texto de copyright. Por defecto el de ACV con el año en curso. */
3107
+ copyright?: string;
3108
+ /** Ruta del aviso de privacidad; sin ella no se pinta el enlace. */
3109
+ privacyUrl?: string;
3110
+ /** Texto del enlace de privacidad con el sidebar expandido. */
3111
+ privacyLabel?: string;
3112
+ /** Texto del enlace de privacidad con el sidebar plegado. */
3113
+ privacyLabelMini?: string;
3114
+ /** Ruta de las novedades; con ella la versión se vuelve un enlace. */
3115
+ releaseNotesUrl?: string;
3116
+ /** Tooltip del enlace de la versión. */
3117
+ releaseNotesTooltip?: string;
3118
+ /** Enciende el punto sobre la versión mientras haya novedades sin abrir. */
3119
+ hasUnreadReleaseNotes?: boolean;
3120
+ }
3121
+ interface MainLayoutSidebarFooterProps extends SidebarFooterProps, MainLayoutFooterConfig {
3122
+ }
3123
+
2690
3124
  /**
2691
3125
  * Cascarón de la aplicación construido sobre Toolpad: barra superior, menú de
2692
3126
  * navegación, alertas, tema y el `PageContainer` que renderiza el `Outlet`.
@@ -2719,11 +3153,11 @@ interface MainLayoutProps {
2719
3153
  detachedPages?: DetachedPage[];
2720
3154
  /** Sufijo del `document.title` (ej. "Embarques" => "Título | Embarques"). */
2721
3155
  documentTitleSuffix?: string;
2722
- /** Configuración del pie del sidebar por defecto. */
2723
- footer?: {
2724
- version?: string;
2725
- copyright?: string;
2726
- };
3156
+ /**
3157
+ * Configuración del pie del sidebar por defecto: versión, copyright, aviso de
3158
+ * privacidad y enlace a las novedades. Cada pieza se pinta sólo si se pasa.
3159
+ */
3160
+ footer?: MainLayoutFooterConfig;
2727
3161
  /** Ancho del sidebar expandido. */
2728
3162
  sidebarExpandedWidth?: number;
2729
3163
  /**
@@ -2842,15 +3276,111 @@ interface MainLayoutProps {
2842
3276
  declare const SIDE_PANEL_WIDTH_VAR = "--acv-side-panel-width";
2843
3277
  declare const MainLayout: (props: MainLayoutProps) => react_jsx_runtime.JSX.Element;
2844
3278
 
3279
+ interface PageInfoProps {
3280
+ /**
3281
+ * La nota. Admite marcado —negritas, listas, enlaces—, así que puede ser lo mismo
3282
+ * que antes se pintaba en un `Alert` al principio del contenido.
3283
+ */
3284
+ children: ReactNode;
3285
+ /** Nombre accesible del botón. */
3286
+ label?: string;
3287
+ /** Ancho máximo del globo, en px. */
3288
+ maxWidth?: number;
3289
+ }
2845
3290
  /**
2846
- * Pie por defecto del sidebar: versión del sistema y aviso de copyright.
2847
- * La versión y el texto de copyright se reciben por props porque dependen
2848
- * del proyecto que consume el layout (no se leen de `import.meta.env` aquí).
3291
+ * Explica la página desde un botón junto a su título, en vez de gastar un `Alert` en la
3292
+ * primera pantalla: el que ya sabe cómo funciona no vuelve a leerlo, pero sigue a mano
3293
+ * para el que llega nuevo.
3294
+ *
3295
+ * Se declara dentro de la página —no pinta nada donde se pone— y viaja por portal hasta
3296
+ * el hueco del encabezado (ver `PageInfoHostContext`). Sólo puede haber una nota por
3297
+ * página: dos `<PageInfo>` a la vez dejan los dos botones uno junto al otro.
3298
+ *
3299
+ * <PageInfo>
3300
+ * El tope limita la <strong>suma de los porcentajes</strong> del mes.
3301
+ * </PageInfo>
3302
+ *
3303
+ * El globo se abre al pasar el cursor y también al llegar al botón con el tabulador, y
3304
+ * es interactivo: se puede entrar en él a copiar el texto o a seguir un enlace.
2849
3305
  **/
2850
- interface MainLayoutSidebarFooterProps extends SidebarFooterProps {
2851
- version?: string;
2852
- copyright?: string;
3306
+ declare const PageInfo: ({ children, label, maxWidth }: PageInfoProps) => react_jsx_runtime.JSX.Element | null;
3307
+
3308
+ interface PageInfoHost {
3309
+ /**
3310
+ * El nodo que el encabezado reserva junto al título, o `null` mientras no haya uno
3311
+ * —pantalla completa, o un `pageHeader` propio que no lo reserve—.
3312
+ */
3313
+ element: HTMLElement | null;
3314
+ /** Lo publica el encabezado al montarse, y lo retira (`null`) al desmontarse. */
3315
+ publicar: (element: HTMLElement | null) => void;
3316
+ }
3317
+ /**
3318
+ * Cómo llega la nota de una página hasta el costado de su título.
3319
+ *
3320
+ * La nota la escribe la página —es texto suyo, no del cascarón— pero se pinta en el
3321
+ * encabezado, que ni siquiera es hijo suyo: `PageContainer` lo dibuja aparte del
3322
+ * `Outlet`. Así que `<PageInfo>` se declara donde se quiera dentro de la página y se
3323
+ * teletransporta (portal) hasta `element`.
3324
+ *
3325
+ * Fuera de un `MainLayout` el contexto es `null` y `<PageInfo>` no pinta nada, en vez de
3326
+ * soltar el botón en medio del contenido.
3327
+ */
3328
+ declare const PageInfoHostContext: React.Context<PageInfoHost | null>;
3329
+ /** El hueco de la nota del encabezado, o `null` si no hay ninguno arriba. */
3330
+ declare const usePageInfoHost: () => PageInfoHost | null;
3331
+
3332
+ interface PageActionsHost {
3333
+ /**
3334
+ * El nodo que el encabezado deja libre a la derecha del título, o `null` mientras no haya
3335
+ * uno —pantalla completa, o un `pageHeader` propio que no lo reserve—.
3336
+ */
3337
+ element: HTMLElement | null;
3338
+ /** Lo publica el encabezado al montarse, y lo retira (`null`) al desmontarse. */
3339
+ publicar: (element: HTMLElement | null) => void;
2853
3340
  }
3341
+ /**
3342
+ * Cómo llegan las acciones de una página hasta el renglón de su título.
3343
+ *
3344
+ * Mismo viaje que la nota de la página (ver `PageInfoHostContext`) y por la misma razón: las
3345
+ * acciones son de la página, pero se pintan en el encabezado, que ni siquiera es hijo suyo.
3346
+ * La diferencia está en para qué sirve el hueco. La nota sólo necesitaba dónde aterrizar; estas
3347
+ * necesitan además *cuánto espacio hay*, y por eso el hueco se queda con el sobrante del renglón
3348
+ * en vez de ceñirse a su contenido: así una barra que se mide sola (`ResponsiveActions`) puede
3349
+ * comparar lo que piden sus botones contra lo que el título le dejó, y encogerse cuando ya no
3350
+ * alcanza. Es la respuesta que la esquina flotante del `ContentLayout` no sabe dar: al estar
3351
+ * posicionada y ajustarse a su contenido, ahí el hueco y los botones miden siempre lo mismo.
3352
+ *
3353
+ * Fuera de un `MainLayout` el contexto es `null`, y quien lo use se las arregla por su cuenta
3354
+ * —la página de detalle vuelve a la esquina flotante de siempre—.
3355
+ */
3356
+ declare const PageActionsHostContext: React.Context<PageActionsHost | null>;
3357
+ /** El hueco de las acciones del encabezado, o `null` si no hay ninguno arriba. */
3358
+ declare const usePageActionsHost: () => PageActionsHost | null;
3359
+
3360
+ interface PageBadgeHost {
3361
+ /**
3362
+ * El nodo que el encabezado reserva al lado del título, o `null` mientras no haya uno
3363
+ * —pantalla completa, o un `pageHeader` propio que no lo reserve—.
3364
+ */
3365
+ element: HTMLElement | null;
3366
+ /** Lo publica el encabezado al montarse, y lo retira (`null`) al desmontarse. */
3367
+ publicar: (element: HTMLElement | null) => void;
3368
+ }
3369
+ /**
3370
+ * Cómo llega el estado de un registro hasta el lado de su título.
3371
+ *
3372
+ * Mismo viaje que la nota (ver `PageInfoHostContext`) y que las acciones
3373
+ * (`PageActionsHostContext`); lo que cambia es dónde aterriza y por qué. El estado califica al
3374
+ * registro igual que su nombre —"embarque 12345, cerrado"—, así que se lee junto a él y no en
3375
+ * la otra punta del renglón: allí quedaba pegado a los botones, como si fuera uno más, y encima
3376
+ * gastaba el ancho que las acciones necesitan para no encogerse.
3377
+ *
3378
+ * Fuera de un `MainLayout` el contexto es `null` y la página de detalle vuelve a colgar la
3379
+ * insignia de la esquina flotante del `ContentLayout`, que es donde vivía.
3380
+ */
3381
+ declare const PageBadgeHostContext: React.Context<PageBadgeHost | null>;
3382
+ /** El hueco de la insignia del encabezado, o `null` si no hay ninguno arriba. */
3383
+ declare const usePageBadgeHost: () => PageBadgeHost | null;
2854
3384
 
2855
3385
  /**
2856
3386
  * Contenido por defecto de cada snack dentro de `ObjectProgressStack`.
@@ -2861,6 +3391,180 @@ interface ProgressStatusProps {
2861
3391
  progress?: number;
2862
3392
  }
2863
3393
 
3394
+ /**
3395
+ * La lupa de la barra superior: se despliega en un campo que consulta el
3396
+ * buscador global del backend y agrupa los resultados por modelo. Elegir uno
3397
+ * navega a su ficha.
3398
+ *
3399
+ * La consulta no la hace la librería: el proyecto pasa su hook lazy de RTK Query
3400
+ * en `useSearch`, que se dispara con retardo (`debounceMs`) mientras se escribe.
3401
+ *
3402
+ * Ctrl+F abre el campo y Escape lo cierra; en pantallas chicas se despliega
3403
+ * sobre la barra en vez de empujarla.
3404
+ **/
3405
+ /** Forma de cada resultado tal como lo devuelve el buscador del backend. */
3406
+ interface GlobalSearchOption {
3407
+ /** Id del registro. */
3408
+ value: string | number;
3409
+ /** Texto que se muestra. */
3410
+ label: string;
3411
+ /** Modelo al que pertenece; es también el criterio de agrupación. */
3412
+ modelo: string;
3413
+ /** Ruta del portal a la que lleva el resultado. */
3414
+ frontend_url: string;
3415
+ /** Nombre de una paleta de `@mui/material/colors` para la pastilla del modelo. */
3416
+ color?: string;
3417
+ }
3418
+ interface GlobalSearchProps {
3419
+ /**
3420
+ * Hook lazy de RTK Query que resuelve la búsqueda, tal cual lo exporta el
3421
+ * proyecto (`useLazyGetBusquedaQuery`). Se le pasa el texto escrito y debe
3422
+ * devolver la lista de resultados.
3423
+ */
3424
+ useSearch: any;
3425
+ /** Espera antes de disparar la consulta, en ms. */
3426
+ debounceMs?: number;
3427
+ /** Ancho del campo abierto en escritorio, en px. */
3428
+ width?: number;
3429
+ placeholder?: string;
3430
+ /**
3431
+ * Renombra el modelo antes de pintarlo en la pastilla, para los casos en que
3432
+ * el nombre del backend no es el que ve el usuario.
3433
+ */
3434
+ modelLabels?: Record<string, string>;
3435
+ }
3436
+ declare const GlobalSearch: ({ useSearch, debounceMs, width, placeholder, modelLabels, }: GlobalSearchProps) => react_jsx_runtime.JSX.Element;
3437
+
3438
+ /**
3439
+ * Una notificación del panel: icono, mensaje y hace cuánto llegó. Abrirla la
3440
+ * marca como leída y navega a su registro.
3441
+ *
3442
+ * El icono depende del modelo de cada proyecto, así que se recibe por
3443
+ * `renderIcon`. Con `onOpen` un proyecto puede hacerse cargo de la apertura
3444
+ * —descargar un archivo en vez de navegar, por ejemplo— devolviendo `true`.
3445
+ *
3446
+ * Para notificaciones que necesiten estado propio (un spinner mientras se
3447
+ * descarga algo) el panel admite reemplazar la fila entera por `slots.item`;
3448
+ * lo natural entonces es envolver esta misma fila.
3449
+ **/
3450
+ interface NotificationItemProps {
3451
+ notification: any;
3452
+ /** Marca la notificación como leída. Lo enlaza el panel con la mutación del proyecto. */
3453
+ onRead: (notification: any) => void;
3454
+ /** Aviso al panel de que se abrió una notificación (en móvil lo cierra). */
3455
+ onClose: () => void;
3456
+ /** Primera de la lista: hereda el redondeo de la esquina superior. */
3457
+ first?: boolean;
3458
+ /** Última de la lista: hereda el redondeo de la esquina inferior. */
3459
+ last?: boolean;
3460
+ /** Icono de la fila. Por defecto un interrogante. */
3461
+ renderIcon?: (notification: any, iconProps: any) => ReactNode;
3462
+ /**
3463
+ * Se ejecuta al abrir, antes de navegar. Devolver `true` significa "ya me
3464
+ * encargué": la fila no navega a `notification.url`.
3465
+ */
3466
+ onOpen?: (notification: any) => boolean | void;
3467
+ }
3468
+ declare const NotificationItem: (props: NotificationItemProps) => react_jsx_runtime.JSX.Element;
3469
+
3470
+ /**
3471
+ * La campana de la barra superior y su panel de notificaciones, con las pestañas
3472
+ * de todas / no leídas, su paginación y los botones de leer y borrar todas.
3473
+ *
3474
+ * El panel va acoplado al costado (`variant="docked"`) y no flotando sobre la
3475
+ * página: encoge el contenido en vez de taparlo, así que se puede ir abriendo
3476
+ * notificaciones y seguir viendo la pantalla en la que se estaba.
3477
+ *
3478
+ * No se coloca a mano en el layout: `MainDrawer_v2` acoplado viaja por portal
3479
+ * hasta el hueco que `MainLayout` reserva al costado (ver `SidePanelHostContext`).
3480
+ * Ese hueco es uno solo y los paneles se turnan, de modo que abrir esto encoge
3481
+ * al que estuviera abierto y cerrarlo se lo devuelve.
3482
+ *
3483
+ * En pantallas chicas no cabe nada al lado, así que ahí vuelve a ser un drawer
3484
+ * flotante que se cierra al abrir una notificación.
3485
+ *
3486
+ * Los datos no los pide la librería: el proyecto pasa sus hooks de RTK Query en
3487
+ * `api` y arma los argumentos de la consulta en `buildQueryArgs`, porque el
3488
+ * endpoint de notificaciones no tiene la misma firma en todos los portales.
3489
+ **/
3490
+ interface NotificationsApi {
3491
+ /** `useGetNotificacionesQuery` — recibe lo que devuelva `buildQueryArgs`. */
3492
+ useGetNotificaciones: any;
3493
+ /** `useLeerNotificacionMutation` — marca una como leída al abrirla. */
3494
+ useLeerNotificacion: any;
3495
+ /** `useLeerTodasNotificacionesMutation`. */
3496
+ useLeerTodas: any;
3497
+ /** `useBorrarTodasNotificacionesMutation`. */
3498
+ useBorrarTodas: any;
3499
+ }
3500
+ interface NotificationsBellProps {
3501
+ /** Hooks de RTK Query del proyecto. */
3502
+ api: NotificationsApi;
3503
+ /**
3504
+ * Argumentos de `useGetNotificaciones` para cada pestaña. Devolver `skipToken`
3505
+ * mientras no haya usuario en sesión: el panel llama al hook igual, y así no
3506
+ * se pide nada hasta que hay a quién pedírselo.
3507
+ */
3508
+ buildQueryArgs: (opts: {
3509
+ page: number;
3510
+ soloNoLeidas: boolean;
3511
+ }) => unknown;
3512
+ /** Icono de cada fila, según el modelo de la notificación. */
3513
+ renderIcon?: (notification: any, iconProps: any) => ReactNode;
3514
+ /**
3515
+ * Se ejecuta al abrir una notificación, antes de navegar. Devolver `true`
3516
+ * significa "ya me encargué" y la fila no navega a `notification.url`.
3517
+ */
3518
+ onOpenNotification?: (notification: any) => boolean | void;
3519
+ /** Título del panel. */
3520
+ title?: string;
3521
+ /** Ancho del panel abierto, mientras el usuario no lo arrastre a otra cosa. */
3522
+ width?: number;
3523
+ /**
3524
+ * Clave donde se recuerda el ancho arrastrado. Conviene que sea propia de
3525
+ * este panel: compartirla con otro los deja pisándose el ancho entre sí.
3526
+ */
3527
+ widthStorageKey?: string;
3528
+ slots?: {
3529
+ /**
3530
+ * Reemplaza la fila entera. Para notificaciones que necesiten estado
3531
+ * propio —un spinner mientras se descarga un archivo—, ya que un
3532
+ * `renderIcon` no puede usar hooks. Lo natural es envolver el
3533
+ * `NotificationItem` de la librería.
3534
+ */
3535
+ item?: ElementType<NotificationItemProps>;
3536
+ };
3537
+ }
3538
+ declare const NotificationsBell: ({ api, buildQueryArgs, renderIcon, onOpenNotification, title, width, widthStorageKey, slots, }: NotificationsBellProps) => react_jsx_runtime.JSX.Element;
3539
+
3540
+ /**
3541
+ * Contenido del popover de la cuenta (slot `popoverContent` del `Account` de
3542
+ * Toolpad): la ficha del usuario, el interruptor de claro/oscuro, las filas que
3543
+ * añada el proyecto y el botón de salir.
3544
+ *
3545
+ * Con `onProfileClick` la ficha entera se vuelve clicable —se toca donde uno se
3546
+ * ve— y ahí es donde cuelga el perfil. Ojo: este menú se cierra con el mismo
3547
+ * clic (el `Popover` de Toolpad lleva su propio `onClick` que lo cierra), así
3548
+ * que lo que se abra desde aquí no puede vivir dentro del menú.
3549
+ **/
3550
+ interface AccountMenuItem {
3551
+ /** Icono a la izquierda de la fila. */
3552
+ icon?: ReactNode;
3553
+ label: string;
3554
+ onClick: () => void;
3555
+ }
3556
+ interface AccountMenuContentProps {
3557
+ /** Contenido del avatar; normalmente la inicial del usuario. */
3558
+ avatarLabel?: ReactNode;
3559
+ /** Si se pasa, la ficha del usuario es clicable (típicamente abre el perfil). */
3560
+ onProfileClick?: () => void;
3561
+ /** Filas extra entre la ficha y el interruptor de tema. */
3562
+ items?: AccountMenuItem[];
3563
+ /** Ancho mínimo del popover. */
3564
+ minWidth?: number;
3565
+ }
3566
+ declare const AccountMenuContent: ({ avatarLabel, onProfileClick, items, minWidth, }: AccountMenuContentProps) => react_jsx_runtime.JSX.Element;
3567
+
2864
3568
  interface MutationHandlerOptions {
2865
3569
  mutationFn: (data: any) => {
2866
3570
  unwrap: () => Promise<any>;
@@ -2934,19 +3638,5 @@ interface UseColorModeResult {
2934
3638
  }
2935
3639
  declare function useColorMode(): UseColorModeResult;
2936
3640
 
2937
- interface PulseDotProps {
2938
- /** Cuando es `true`, el punto es verde y parpadea; si no, usa `inactiveColor`. */
2939
- active: boolean;
2940
- /** Color cuando no está activo. Por defecto `error.main`. */
2941
- inactiveColor?: string;
2942
- /** Tamaño del punto en px. Por defecto 10. */
2943
- size?: number;
2944
- /** Título opcional; si se pasa, envuelve el punto en un Tooltip. */
2945
- title?: ReactNode;
2946
- }
2947
- /** Punto de estado: verde con animación de parpadeo cuando está activo, de lo
2948
- * contrario un color fijo. Se usa para indicar conexión/actividad en vivo. */
2949
- declare function PulseDot({ active, inactiveColor, size, title }: PulseDotProps): react_jsx_runtime.JSX.Element;
2950
-
2951
- export { APIContext, APIProvider, ActiveCell, ActiveIcon, Base, ButtonWithDrawer, COLOR_SCHEME_SELECTOR, CSVUpload, ChipCell, ConfirmDialog, ContentLayout, ControlledAddressAutocomplete, ControlledAmountWithCurrency, ControlledColor, ControlledDate$1 as ControlledDate, ControlledDate as ControlledDate_v2, ControlledDropdown, ControlledFileField$1 as ControlledFileField, ControlledFileField as ControlledFileField_v2, FileUploadBox as ControlledFileUploadBox, ControlledNumber, ControlledPhoneNumber, ControlledSelect$1 as ControlledSelect, ControlledSelect as ControlledSelect_v2, ControlledSlider as ControlledSimpleSlider, ControlledSlider$1 as ControlledSlider, ControlledSwitch, ControlledText, ControlledTimePicker, ControlledToggleButtons, CoverPage, CreateButtonBase, CreateButtonWithMenuOptions, CrudDropdown, CustomNoRows, DEFAULT_FORM_BREAKPOINTS, DEFAULT_PAGINATION, DeleteButton, DeleteConfirmationDialog, DetailFormDialog as DetailFormDialog_v2, DetailFormDrawer as DetailFormDrawer_v2, DetailForm as DetailForm_v2, DetailPage$1 as DetailPage, DetailPage as DetailPage_v2, DrawerGrid as DrawerGrid_v2, EditButton, ExportCSV, ExtraButtons, FORM_CONTAINER_NAME, HistorialDrawer, KpiCard, LAYER_ORDER, ListPage, Loadable, LoadingComponent, Logo, MainDrawer, MainDrawer$1 as MainDrawer_v2, MainLayout, MenuItemWithLoading, ModuleCard, MoreOptions, MyGridEditSingleSelect, NavigationContext, NavigationProvider, NormalOrIcon, NotAllowed, NotFound, ObjectProgressStack, PAGE_SIZE_OPTIONS, Panel, PollingCountdownChip, PulseDot, SIDE_PANEL_WIDTH_VAR, SaveCancelButton, ServerGrid as ServerGrid_v2, SidePanelHostContext, StatusBadge, StyledMenu, Tabs, Transitions, TrueFalse, UncontrolledText, changeTitle, closeProgressSnack, composeGridProps, deleteColumn$1 as deleteColumn, deleteColumn as deleteColumn_v2, editColumn, filterQuery, formContainerSx, formGridSx, formParser, _default as headerReducer, manualCacheRefresh, mergeSettings, openProgressSnack, query, renderChipCell, renderEditCellWithErrorTooltip, resolveChipOption, resolveInitialState, setErrors, _default$1 as snackProgressReducer, tags, theme, togglableFields, updateProgressSnackData, useAPI, useColorMode, useDetailForm, useHasPermission, useHasPermission_v2, useKeyboardShortcut, useMutationHandler, useNavigation, useServerGrid, useSidePanelHost, valueLabel };
2952
- export type { APIcontextProps, AddressValue, AppTheme, ChipCellProps, ChipColor, ChipOption, ColorMode, ComoOpcionesProps, ConfirmDialogProps, ControlledInput, CustomFilterDef, CustomToolbarProps, DeleteGridColumnsProps$1 as DeleteGridColumnsProps, DetachedPage, DetailExtraButton, DetailFormApi, DetailFormConfig, DetailFormController, DetailFormDialogProps, DetailFormDrawerNavigation, DetailFormDrawerProps, DetailFormProps, DetailFormStatus, DetailPageV2Props, DetailRenderProps, DrawerGridDrawerConfig, DrawerGridEditConfig, DrawerGridProps, EditGridColumnsProps, EditReadOnlyFields, FieldFilter, FieldProps$1 as FieldProps, FieldValidationProps, FilterInput, FormBreakpoint, FormGridSxOptions, GridArgs, GridColDefPropsOverrides, GridLayerContribution, GridLayerId, GridLayerMap, JSONFormProps, JSONParserProps, KeyboardShortcut, KpiCardProps, MainDrawerV2Props, MainLayoutPageHeaderProps, MainLayoutProps, MainLayoutSidebarFooterProps, MyDataGridProps, MyGridFilterModel, MyTab, MyTabProps, PageType, PanelProps, PollingCountdownChipProps, ProgressStatusProps, PulseDotProps, RowsSnapshot, ServerGridArgs, ServerGridCreateApi, ServerGridDataApi, ServerGridDeleteApi, ServerGridEditApi, ServerGridEditToggleApi, ServerGridHandle, ServerGridProps, ServerGridSnapshot, ServerGridState, SidePanelHost, UseColorModeResult, UseServerGridOptions };
3641
+ export { APIContext, APIProvider, AccountMenuContent, ActiveCell, ActiveIcon, Base, ButtonWithDrawer, COLOR_SCHEME_SELECTOR, CSVUpload, ChipCell, ConfirmDialog, ContentLayout, ControlledAddressAutocomplete, ControlledAmountWithCurrency, ControlledAutocomplete, ControlledColor, ControlledDate$1 as ControlledDate, ControlledDate as ControlledDate_v2, ControlledDropdown, ControlledFileField$1 as ControlledFileField, ControlledFileField as ControlledFileField_v2, FileUploadBox as ControlledFileUploadBox, ControlledNumber, ControlledPhoneNumber, ControlledSelect$1 as ControlledSelect, ControlledSelect as ControlledSelect_v2, ControlledSlider as ControlledSimpleSlider, ControlledSlider$1 as ControlledSlider, ControlledSwitch, ControlledText, ControlledTimePicker, ControlledToggleButtons, CoverPage, CreateButtonBase, CreateButtonWithMenuOptions, CrudDropdown, CustomNoRows, DEFAULT_FORM_BREAKPOINTS, DEFAULT_PAGINATION, DeleteButton, DeleteConfirmationDialog, DetailFormDialog as DetailFormDialog_v2, DetailFormDrawer as DetailFormDrawer_v2, DetailForm as DetailForm_v2, DetailPage$1 as DetailPage, DetailPage as DetailPage_v2, DrawerGrid as DrawerGrid_v2, EditButton, ExportCSV$1 as ExportCSV, ExportCSV as ExportCSV_v2, ExtraButtons, FORM_CONTAINER_NAME, GlobalSearch, HEADER_CONTAINER, HEADER_NARROW, HistorialDrawer, KpiCard, LAYER_ORDER, ListPage, Loadable, LoadingComponent, Logo, MainDrawer, MainDrawer$1 as MainDrawer_v2, MainLayout, MenuItemWithLoading, ModuleCard, MoreOptions, MyGridEditSingleSelect, NavigationContext, NavigationProvider, NormalOrIcon, NotAllowed, NotFound, NotificationItem, NotificationsBell, ObjectProgressStack, PAGE_SIZE_OPTIONS, PageActionsHostContext, PageBadgeHostContext, PageInfo, PageInfoHostContext, Panel, PollingCountdownChip, PulseDot, RESPONSIVE_ACTION_MODES, ResponsiveActions, SIDE_PANEL_WIDTH_VAR, SaveCancelButton, ServerGrid as ServerGrid_v2, SidePanelHostContext, StatusBadge, StyledMenu, Tabs, Transitions, TrueFalse, UncontrolledText, changeTitle, closeProgressSnack, composeGridProps, deleteColumn$1 as deleteColumn, deleteColumn as deleteColumn_v2, editColumn, filterQuery, formContainerSx, formGridSx, formParser, headerContainerSx, _default as headerReducer, manualCacheRefresh, mergeSettings, openProgressSnack, query, renderChipCell, renderEditCellWithErrorTooltip, resolveChipOption, resolveInitialState, resolveStatusColor, setErrors, _default$1 as snackProgressReducer, statusColors, tags, theme, togglableFields, updateProgressSnackData, useAPI, useColorMode, useDetailForm, useHasPermission, useHasPermission_v2, useKeyboardShortcut, useMutationHandler, useNavigation, usePageActionsHost, usePageBadgeHost, usePageInfoHost, useServerGrid, useSidePanelHost, valueLabel };
3642
+ export type { APIcontextProps, AccountMenuContentProps, AccountMenuItem, AddressValue, AppTheme, AutocompleteOption, ChipCellProps, ChipColor, ChipOption, ColorMode, ComoOpcionesProps, ConfirmDialogProps, ControlledAutocompleteProps, ControlledInput, CustomFilterDef, CustomToolbarProps, DeleteGridColumnsProps$1 as DeleteGridColumnsProps, DetachedPage, DetailExtraButton, DetailFormApi, DetailFormConfig, DetailFormController, DetailFormDialogProps, DetailFormDrawerNavigation, DetailFormDrawerProps, DetailFormProps, DetailFormStatus, DetailPageV2Props, DetailRenderProps, DrawerGridDrawerConfig, DrawerGridEditConfig, DrawerGridProps, EditGridColumnsProps, EditReadOnlyFields, ExportCSVProps as ExportCSVProps_v2, FieldFilter, FieldProps$1 as FieldProps, FieldValidationProps, FilterInput, FormBreakpoint, FormGridSxOptions, GlobalSearchOption, GlobalSearchProps, GridArgs, GridColDefPropsOverrides, GridLayerContribution, GridLayerId, GridLayerMap, JSONFormProps, JSONParserProps, KeyboardShortcut, KpiCardProps, MainDrawerV2Props, MainLayoutFooterConfig, MainLayoutPageHeaderProps, MainLayoutProps, MainLayoutSidebarFooterProps, MyDataGridProps, MyGridFilterModel, MyTab, MyTabProps, NotificationItemProps, NotificationsApi, NotificationsBellProps, PageActionsHost, PageBadgeHost, PageInfoHost, PageInfoProps, PageType, PanelProps, PollingCountdownChipProps, ProgressStatusProps, PulseDotProps, ResponsiveAction, ResponsiveActionsMode, ResponsiveActionsProps, RowsSnapshot, ServerGridArgs, ServerGridCreateApi, ServerGridDataApi, ServerGridDeleteApi, ServerGridEditApi, ServerGridEditToggleApi, ServerGridHandle, ServerGridProps, ServerGridSnapshot, ServerGridState, SidePanelHost, StatusColor, UseColorModeResult, UseServerGridOptions };