@acvl/frontend-components 0.0.85 → 0.0.87
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/cjs/index.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/index.d.ts +1400 -1129
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as _mui_material from '@mui/material';
|
|
2
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$1 from 'react';
|
|
4
|
-
import React__default, { ReactNode, Dispatch, SetStateAction, JSX, RefObject, ReactElement, ComponentType,
|
|
4
|
+
import React__default, { ReactNode, Dispatch, SetStateAction, JSX, RefObject, FC, ReactElement, ComponentType, BaseSyntheticEvent, JSXElementConstructor, ElementType } from 'react';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
6
|
import { GridRowId, GridRowSelectionModel, GridSortModel, GridFilterModel, GridRowModesModel, GridRenderEditCellParams, GridToolbarProps, DataGridProps as DataGridProps$1, GridApi, GridPaginationModel, GridColumnVisibilityModel, useGridApiRef, GridColDef } from '@mui/x-data-grid';
|
|
7
7
|
import { DataGridProps, GridBaseColDef } from '@mui/x-data-grid/internals';
|
|
8
8
|
import { NavigateOptions } from 'react-router-dom';
|
|
9
9
|
import * as zod_v4_core from 'zod/v4/core';
|
|
10
10
|
import * as zod from 'zod';
|
|
11
|
-
import { coerce, z } from 'zod';
|
|
11
|
+
import { coerce, ZodType, z } from 'zod';
|
|
12
12
|
import { NumericFormatProps } from 'react-number-format';
|
|
13
13
|
import { TextFieldProps } from '@mui/material/TextField';
|
|
14
14
|
import dayjs from 'dayjs';
|
|
@@ -18,8 +18,10 @@ import * as _reduxjs_toolkit from '@reduxjs/toolkit';
|
|
|
18
18
|
import * as _emotion_styled from '@emotion/styled';
|
|
19
19
|
import * as _mui_system from '@mui/system';
|
|
20
20
|
import { Theme as Theme$1, CssVarsTheme, CSSObject } from '@mui/material/styles';
|
|
21
|
-
import {
|
|
21
|
+
import { BaseQueryFn, FetchArgs, EndpointDefinitions, Api, CoreModule } from '@reduxjs/toolkit/query';
|
|
22
|
+
import { reactHooksModuleName } from '@reduxjs/toolkit/query/react';
|
|
22
23
|
import { UseFormReturn } from 'react-hook-form';
|
|
24
|
+
import { DebouncedFunc } from 'lodash';
|
|
23
25
|
import { Breadcrumb, PageHeaderProps, Navigation, Branding, Session, Authentication, DashboardHeaderProps } from '@toolpad/core';
|
|
24
26
|
import { SidebarFooterProps } from '@toolpad/core/DashboardLayout';
|
|
25
27
|
|
|
@@ -1887,115 +1889,532 @@ declare const COLOR_SCHEME_SELECTOR = "data-color-scheme";
|
|
|
1887
1889
|
type AppTheme = Theme$1 & CssVarsTheme;
|
|
1888
1890
|
declare const theme: () => AppTheme;
|
|
1889
1891
|
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1892
|
+
/**
|
|
1893
|
+
* Datos que recibe el renderizado de detalle de un input. Es un subconjunto de
|
|
1894
|
+
* `FieldProps` (los campos que necesita la vista de solo lectura), más un
|
|
1895
|
+
* `content` opcional con el valor ya formateado y envuelto con pre/post por el
|
|
1896
|
+
* contenedor `DetailField` (útil para renderizadores completos como archivos).
|
|
1897
|
+
*/
|
|
1898
|
+
interface DetailRenderProps {
|
|
1899
|
+
fieldData?: any;
|
|
1900
|
+
/** Registro completo de la página; permite leer valores hermanos. */
|
|
1901
|
+
data?: any;
|
|
1902
|
+
name?: string;
|
|
1903
|
+
detail_name?: string;
|
|
1904
|
+
extraProps?: any;
|
|
1905
|
+
/** Valor formateado + pre/post, disponible para `Detail`. */
|
|
1906
|
+
content?: string;
|
|
1900
1907
|
}
|
|
1901
|
-
/**
|
|
1902
|
-
*
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
/** Muestra un divisor bajo el encabezado/tabs. Por defecto `true`. */
|
|
1915
|
-
divider?: boolean;
|
|
1916
|
-
/** Altura del contenedor. Con un número (px) el contenido ocupa el espacio
|
|
1917
|
-
* restante y hace scroll; con `"100%"` solo iguala la altura de la columna. */
|
|
1918
|
-
height?: number | string;
|
|
1919
|
-
/** Estilos adicionales para el `Paper`. */
|
|
1920
|
-
sx?: SxProps<Theme>;
|
|
1921
|
-
children?: ReactNode;
|
|
1908
|
+
/**
|
|
1909
|
+
* Contrato de un input controlado de v2. Además de renderizar su modo de
|
|
1910
|
+
* edición (el propio componente), puede aportar su propia lógica de detalle:
|
|
1911
|
+
*
|
|
1912
|
+
* - `formatDetail`: convierte el valor en contenido mostrable (string o nodo).
|
|
1913
|
+
* Cubre la mayoría de los casos; el contenedor se encarga de envolverlo con
|
|
1914
|
+
* enlaces de navegación y pre/post.
|
|
1915
|
+
* - `Detail`: renderizado de detalle completo (badges, popovers…). Poco común;
|
|
1916
|
+
* solo para inputs que necesitan controlar toda su UI de solo lectura.
|
|
1917
|
+
*/
|
|
1918
|
+
interface ControlledInput<P = any> extends FC<P> {
|
|
1919
|
+
formatDetail?: (props: DetailRenderProps) => ReactNode;
|
|
1920
|
+
Detail?: (props: DetailRenderProps) => ReactNode;
|
|
1922
1921
|
}
|
|
1923
|
-
/** Contenedor estándar de panel: `Paper` con encabezado (ícono + título + acción),
|
|
1924
|
-
* divisor opcional y contenido. Unifica el aspecto de los paneles del dashboard. */
|
|
1925
|
-
declare function Panel({ icon, title, action, tabs, divider, height, sx, children }: PanelProps): react_jsx_runtime.JSX.Element;
|
|
1926
1922
|
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1923
|
+
/**
|
|
1924
|
+
* Forma JSON que se guarda en el formulario / se envía al backend.
|
|
1925
|
+
* Para direcciones escritas a mano solo viene `formatted_address`.
|
|
1926
|
+
*/
|
|
1927
|
+
interface AddressValue {
|
|
1928
|
+
formatted_address: string;
|
|
1929
|
+
place_id?: string | null;
|
|
1930
|
+
lat?: number | null;
|
|
1931
|
+
lng?: number | null;
|
|
1932
|
+
street_number?: string;
|
|
1933
|
+
route?: string | null;
|
|
1934
|
+
neighborhood?: string | null;
|
|
1935
|
+
locality?: string | null;
|
|
1936
|
+
administrative_area_level_1?: string | null;
|
|
1937
|
+
postal_code?: string | null;
|
|
1938
|
+
country?: string | null;
|
|
1939
|
+
country_code?: string | null;
|
|
1931
1940
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1941
|
+
interface ControlledAddressAutocompleteProps {
|
|
1942
|
+
name: string;
|
|
1943
|
+
label?: string;
|
|
1944
|
+
control: any;
|
|
1945
|
+
fieldProps?: TextFieldProps$1;
|
|
1946
|
+
extraProps?: {
|
|
1947
|
+
/**
|
|
1948
|
+
* API key de Google Maps. Si no se pasa, se intenta leer
|
|
1949
|
+
* `VITE_GOOGLE_MAPS_API_KEY` de `import.meta.env`.
|
|
1950
|
+
*/
|
|
1951
|
+
apiKey?: string;
|
|
1952
|
+
/** Restringe los resultados a estos países, p.ej. ["mx", "us"]. */
|
|
1953
|
+
countries?: string[];
|
|
1954
|
+
/** Idioma de los resultados, p.ej. "es". */
|
|
1955
|
+
language?: string;
|
|
1956
|
+
/**
|
|
1957
|
+
* Callback opcional con el `Place` resuelto (con addressComponents,
|
|
1958
|
+
* location, etc.) por si la pantalla necesita autollenar otros campos.
|
|
1959
|
+
*/
|
|
1960
|
+
onResolved?: (place: any) => void;
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
declare const ControlledAddressAutocomplete: {
|
|
1964
|
+
({ name, label, control, fieldProps, extraProps, }: ControlledAddressAutocompleteProps): react_jsx_runtime.JSX.Element;
|
|
1965
|
+
displayName: string;
|
|
1966
|
+
formatDetail({ fieldData }: DetailRenderProps): string;
|
|
1967
|
+
};
|
|
1935
1968
|
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
/**
|
|
1940
|
-
* The query keys this input writes. Usually one, but a range input owns two
|
|
1941
|
-
* (`_min`/`_max`, `_after`/`_before`), which is why this isn't just `field`.
|
|
1942
|
-
*/
|
|
1943
|
-
keys: string[];
|
|
1969
|
+
/** Opción de un desplegable: `{ value, label }`. */
|
|
1970
|
+
interface Opciones {
|
|
1971
|
+
value: string;
|
|
1944
1972
|
label: string;
|
|
1945
|
-
|
|
1946
|
-
|
|
1973
|
+
}
|
|
1974
|
+
interface ControlledAmountWithCurrencyProps {
|
|
1975
|
+
/** Ruta del monto en el formulario, p.ej. "valores_de_factura.subtotal". */
|
|
1976
|
+
name: string;
|
|
1977
|
+
/** Control de react-hook-form (lo inyecta el `EditField` de la página). */
|
|
1978
|
+
control?: any;
|
|
1979
|
+
fieldProps?: Partial<NumericFormatProps<InputBaseProps>>;
|
|
1980
|
+
extraProps?: {
|
|
1981
|
+
/**
|
|
1982
|
+
* Ruta de la moneda en el formulario. Por defecto `${name}_moneda`,
|
|
1983
|
+
* de modo que "valores_de_factura.subtotal" usa
|
|
1984
|
+
* "valores_de_factura.subtotal_moneda".
|
|
1985
|
+
*/
|
|
1986
|
+
currencyName?: string;
|
|
1987
|
+
/** Origen de las opciones de moneda (endpoint `como_opciones`). */
|
|
1988
|
+
queryArgs?: ComoOpcionesProps;
|
|
1989
|
+
/** Opciones estáticas de moneda (alternativa a `queryArgs`). */
|
|
1990
|
+
options?: Opciones[];
|
|
1991
|
+
};
|
|
1947
1992
|
}
|
|
1948
1993
|
/**
|
|
1949
|
-
*
|
|
1950
|
-
*
|
|
1994
|
+
* Campo compuesto de monto + moneda que se muestra como una sola fila con
|
|
1995
|
+
* borde: importe alineado a la derecha y un selector de moneda compacto al
|
|
1996
|
+
* final.
|
|
1951
1997
|
*
|
|
1952
|
-
*
|
|
1953
|
-
*
|
|
1998
|
+
* Está pensado para usarse como `type` de un campo de una página de detalle.
|
|
1999
|
+
* La etiqueta la aporta el `Field` contenedor (no el propio campo):
|
|
2000
|
+
*
|
|
2001
|
+
* ```ts
|
|
2002
|
+
* {
|
|
2003
|
+
* name: "valores_de_factura.subtotal",
|
|
2004
|
+
* label: "Subtotal",
|
|
2005
|
+
* type: ControlledAmountWithCurrency,
|
|
2006
|
+
* gridProps: { size: 12 },
|
|
2007
|
+
* }
|
|
2008
|
+
* ```
|
|
1954
2009
|
*/
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
* the panel, so one key never gets two inputs writing to it.
|
|
1961
|
-
*/
|
|
1962
|
-
field: string;
|
|
1963
|
-
label: string;
|
|
1964
|
-
/** Any controlled input. The panel clones `control` in, exactly as it does for columns. */
|
|
1965
|
-
element: ReactElement;
|
|
1966
|
-
/** Defaults to `z.any().optional()` — enough for a value the backend validates anyway. */
|
|
1967
|
-
schema?: z.ZodType<any, any>;
|
|
1968
|
-
/** What the panel resets to, and what "Limpiar" restores. Defaults to `""`. */
|
|
1969
|
-
defaultValue?: any;
|
|
1970
|
-
}
|
|
2010
|
+
declare const ControlledAmountWithCurrency: {
|
|
2011
|
+
({ name, control, fieldProps, extraProps, }: ControlledAmountWithCurrencyProps): react_jsx_runtime.JSX.Element;
|
|
2012
|
+
displayName: string;
|
|
2013
|
+
formatDetail({ fieldData, extraProps, data, name, }: DetailRenderProps): string;
|
|
2014
|
+
};
|
|
1971
2015
|
|
|
1972
2016
|
/**
|
|
1973
|
-
*
|
|
1974
|
-
*
|
|
2017
|
+
* Helpers puros del `ControlledAutocomplete`: los argumentos de la consulta, la
|
|
2018
|
+
* lista que se muestra y las cuentas del "seleccionar todo". Viven fuera del
|
|
2019
|
+
* componente para poder probarlos sin montar MUI ni RTK Query.
|
|
1975
2020
|
*/
|
|
1976
|
-
|
|
2021
|
+
|
|
2022
|
+
/** Una opción del desplegable, tal como la devuelve `como_opciones`. */
|
|
2023
|
+
interface AutocompleteOption {
|
|
2024
|
+
value: any;
|
|
2025
|
+
label: string;
|
|
2026
|
+
}
|
|
1977
2027
|
|
|
1978
2028
|
/**
|
|
1979
|
-
*
|
|
2029
|
+
* Props que el consumidor escribe en `fieldProps` pensando en "el campo" pero que
|
|
2030
|
+
* son del `TextField` que dibuja `renderInput`, no del `Autocomplete`.
|
|
1980
2031
|
*
|
|
1981
|
-
*
|
|
1982
|
-
*
|
|
1983
|
-
*
|
|
1984
|
-
*
|
|
1985
|
-
* endpoints read an `endpoint` or `tipo` off it).
|
|
2032
|
+
* MUI sólo reenvía a `renderInput` `id`, `disabled`, `size`, `fullWidth` e
|
|
2033
|
+
* `InputProps`; lo demás se quedaba en el nodo raíz del `Autocomplete` —sin
|
|
2034
|
+
* efecto y sin aviso—, así que un `fieldProps: { helperText: "…" }` no se veía
|
|
2035
|
+
* por ningún lado. Se reparten antes del spread para que lleguen a su sitio.
|
|
1986
2036
|
*/
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2037
|
+
declare const TEXT_FIELD_KEYS: readonly ["helperText", "placeholder", "required", "margin"];
|
|
2038
|
+
type TextFieldOnlyProps = Pick<TextFieldProps$1, (typeof TEXT_FIELD_KEYS)[number]>;
|
|
2039
|
+
type AutocompleteFieldProps = Partial<AutocompleteProps<any, any, any, any>> & TextFieldOnlyProps;
|
|
2040
|
+
interface ControlledAutocompleteProps {
|
|
2041
|
+
name: string;
|
|
2042
|
+
label?: string;
|
|
2043
|
+
/** Control de react-hook-form; lo inyecta el `EditField` o el panel de filtros. */
|
|
2044
|
+
control?: any;
|
|
2045
|
+
/**
|
|
2046
|
+
* Props del campo (ganan sobre las de aquí). Las del `Autocomplete` van tal
|
|
2047
|
+
* cual; las que son del `TextField` (`helperText`, `placeholder`, `required`,
|
|
2048
|
+
* `margin`) se enrutan solas al input, que es donde se ven.
|
|
2049
|
+
*/
|
|
2050
|
+
fieldProps?: AutocompleteFieldProps;
|
|
2051
|
+
extraProps?: {
|
|
2052
|
+
/** Selección múltiple con casillas y chips. Por defecto, simple. */
|
|
2053
|
+
multiple?: boolean;
|
|
2054
|
+
/** Opciones fijas. Con ellas no se consulta nada y filtra el navegador. */
|
|
2055
|
+
options?: AutocompleteOption[];
|
|
2056
|
+
/** Origen remoto de las opciones (endpoint `como_opciones`). */
|
|
2057
|
+
queryArgs?: ComoOpcionesProps;
|
|
2058
|
+
/** Filtro contra el que se busca el texto. Por defecto `nombre__icontains`. */
|
|
2059
|
+
searchField?: string;
|
|
2060
|
+
/** Retardo del tecleo antes de consultar. Por defecto 400 ms. */
|
|
2061
|
+
debounceMs?: number;
|
|
2062
|
+
/** Caracteres mínimos para consultar. Por defecto 0 (lista completa al abrir). */
|
|
2063
|
+
minChars?: number;
|
|
2064
|
+
/** Fila de "seleccionar todo" en el modo múltiple. Por defecto, sí. */
|
|
2065
|
+
selectAll?: boolean;
|
|
2066
|
+
/**
|
|
2067
|
+
* Quita el hueco reservado para el mensaje de error debajo del campo. No
|
|
2068
|
+
* afecta al `helperText` de `fieldProps`: si hay texto de ayuda, se ve.
|
|
2069
|
+
*/
|
|
2070
|
+
disableHT?: boolean;
|
|
2071
|
+
};
|
|
1994
2072
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2073
|
+
/**
|
|
2074
|
+
* Desplegable de opciones para react-hook-form: simple o múltiple, con opciones
|
|
2075
|
+
* fijas o consultadas a `como_opciones` según lo que se escribe. Unifica los
|
|
2076
|
+
* `ControlledDropdown` (simple) y `ControlledSelect` (múltiple) de v1, que eran
|
|
2077
|
+
* el mismo componente duplicado.
|
|
2078
|
+
*
|
|
2079
|
+
* ```ts
|
|
2080
|
+
* {
|
|
2081
|
+
* name: "cliente",
|
|
2082
|
+
* label: "Cliente",
|
|
2083
|
+
* type: ControlledAutocomplete,
|
|
2084
|
+
* extraProps: { queryArgs: { endpoint: "clientes" } },
|
|
2085
|
+
* }
|
|
2086
|
+
* ```
|
|
2087
|
+
*
|
|
2088
|
+
* Sobre las peticiones, que era el punto flojo de v1:
|
|
2089
|
+
*
|
|
2090
|
+
* - **Una por apertura.** v1 pedía dos veces al abrir (el `onOpen` disparaba la
|
|
2091
|
+
* consulta y el efecto la repetía con retardo) y otra vez en cada render del
|
|
2092
|
+
* padre, porque `queryArgs` llega como objeto literal y su identidad cambiaba.
|
|
2093
|
+
* - **Elegir una opción no consulta.** Al elegir, MUI reescribe el texto del
|
|
2094
|
+
* campo con la etiqueta; v1 lo trataba como búsqueda nueva y volvía a pedir.
|
|
2095
|
+
* - **Sin parpadeo ni respuestas cruzadas.** La lista es la del hook de RTK
|
|
2096
|
+
* Query, que siempre corresponde a los últimos argumentos disparados; v1
|
|
2097
|
+
* guardaba las opciones en estado propio, las vaciaba en cada tecla y una
|
|
2098
|
+
* respuesta lenta podía pisar a una más nueva.
|
|
2099
|
+
* - **Repetir una búsqueda sale de la caché**, incluido borrar el texto para
|
|
2100
|
+
* volver al listado completo.
|
|
2101
|
+
*/
|
|
2102
|
+
declare const ControlledAutocomplete: ControlledInput<ControlledAutocompleteProps>;
|
|
2103
|
+
|
|
2104
|
+
interface ControlledColorProps {
|
|
2105
|
+
/** Ruta del color en el formulario. */
|
|
2106
|
+
name: string;
|
|
2107
|
+
/** Control de react-hook-form (lo inyecta el `EditField` de la página). */
|
|
2108
|
+
control?: any;
|
|
2109
|
+
/** `readOnly` no es prop de `TextField`, pero el `EditField` lo inyecta ahí. */
|
|
2110
|
+
fieldProps?: TextFieldProps$1 & {
|
|
2111
|
+
readOnly?: boolean;
|
|
2112
|
+
};
|
|
2113
|
+
extraProps?: {
|
|
2114
|
+
/** Colores de acceso rápido. Por defecto, la paleta de la librería. */
|
|
2115
|
+
presets?: string[];
|
|
2116
|
+
/** Muestra el botón de "Sin color". Por defecto `true`. */
|
|
2117
|
+
clearable?: boolean;
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2120
|
+
/**
|
|
2121
|
+
* Campo de color en hexadecimal. Se puede escribir el hex a mano o abrirlo
|
|
2122
|
+
* desde la muestra de la izquierda, que despliega la paleta de accesos rápidos
|
|
2123
|
+
* y el selector del sistema para cualquier otro color.
|
|
2124
|
+
*
|
|
2125
|
+
* El valor que guarda en el formulario es siempre una cadena `#RRGGBB` (o `""`
|
|
2126
|
+
* si se quita el color), que es lo que espera el backend.
|
|
2127
|
+
*
|
|
2128
|
+
* ```ts
|
|
2129
|
+
* {
|
|
2130
|
+
* name: "color_en_calendario",
|
|
2131
|
+
* label: "Color en calendario",
|
|
2132
|
+
* type: ControlledColor,
|
|
2133
|
+
* gridProps: { size: { xs: 12, md: 4 } },
|
|
2134
|
+
* }
|
|
2135
|
+
* ```
|
|
2136
|
+
*/
|
|
2137
|
+
declare const ControlledColor: ControlledInput<ControlledColorProps>;
|
|
2138
|
+
|
|
2139
|
+
/**
|
|
2140
|
+
* `ControlledDate` de v2. Reutiliza el renderizado de edición de v1 (no se
|
|
2141
|
+
* duplica su lógica) y añade el renderizado de detalle mediante `formatDetail`,
|
|
2142
|
+
* de modo que la página de detalle no necesita conocer este tipo de campo.
|
|
2143
|
+
*
|
|
2144
|
+
* Migrar un input a v2 consiste en esto: envolver el componente de v1 y
|
|
2145
|
+
* adjuntarle `formatDetail` (y opcionalmente `Detail`). Sirve de plantilla para
|
|
2146
|
+
* el resto de inputs.
|
|
2147
|
+
*/
|
|
2148
|
+
declare const ControlledDate: ControlledInput;
|
|
2149
|
+
|
|
2150
|
+
/**
|
|
2151
|
+
* `ControlledSelect` de v2: hoy es un `ControlledAutocomplete` en modo múltiple.
|
|
2152
|
+
*
|
|
2153
|
+
* Se conserva el nombre porque ya lo usan varias pantallas de los dos
|
|
2154
|
+
* proyectos; lo que cambia por dentro es cuándo y cuántas veces se piden las
|
|
2155
|
+
* opciones (ver `ControlledAutocomplete`). `disableHT` viene en `true` para no
|
|
2156
|
+
* mover el alto de esas pantallas: el select de v1 no reservaba el renglón del
|
|
2157
|
+
* mensaje de error. Quien lo necesite puede pasarlo en `false`.
|
|
2158
|
+
*
|
|
2159
|
+
* Para código nuevo conviene usar `ControlledAutocomplete` directamente, que
|
|
2160
|
+
* además cubre el modo simple.
|
|
2161
|
+
*/
|
|
2162
|
+
declare const ControlledSelect: ControlledInput;
|
|
2163
|
+
|
|
2164
|
+
/**
|
|
2165
|
+
* `ControlledFileField` de v2. Reutiliza el renderizado de edición de v1 y
|
|
2166
|
+
* aporta su renderizado de detalle completo mediante `Detail` (badge + popover),
|
|
2167
|
+
* además del texto formateado mediante `formatDetail`.
|
|
2168
|
+
*/
|
|
2169
|
+
declare const ControlledFileField: ControlledInput;
|
|
2170
|
+
|
|
2171
|
+
interface FieldProps {
|
|
2172
|
+
pageType?: PageType;
|
|
2173
|
+
fieldData?: any;
|
|
2174
|
+
/** Registro completo de la página; permite a los campos leer valores hermanos. */
|
|
2175
|
+
data?: any;
|
|
2176
|
+
name: string;
|
|
2177
|
+
detail_name?: string;
|
|
2178
|
+
label: string;
|
|
2179
|
+
/** Ubicación de la etiqueta respecto al campo. Por defecto `"top"`. */
|
|
2180
|
+
labelPosition?: "top" | "left";
|
|
2181
|
+
/** Input controlado a renderizar (edición) y, opcionalmente, su detalle. */
|
|
2182
|
+
type: ControlledInput;
|
|
2183
|
+
gridProps?: GridProps;
|
|
2184
|
+
fieldProps?: object;
|
|
2185
|
+
extraProps?: any;
|
|
2186
|
+
detailFieldProps?: {
|
|
2187
|
+
preValue?: string;
|
|
2188
|
+
postValue?: string;
|
|
2189
|
+
};
|
|
2190
|
+
navigation?: {
|
|
2191
|
+
url: string;
|
|
2192
|
+
permission: string;
|
|
2193
|
+
};
|
|
2194
|
+
permission?: string;
|
|
2195
|
+
display?: boolean;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
/**
|
|
2199
|
+
* Un catálogo administrable por el negocio: código, nombre, descripción y activo.
|
|
2200
|
+
*
|
|
2201
|
+
* Muchos modelos de un sistema son idénticos salvo por su nombre, su endpoint y —a lo mucho— un
|
|
2202
|
+
* par de campos extra, así que se declaran en vez de escribirse: los endpoints los arma
|
|
2203
|
+
* `crearFabricaDeCatalogos` y la pantalla `CatalogoList` y `CatalogoItem`, a partir de esto.
|
|
2204
|
+
*
|
|
2205
|
+
* Lo que NO cabe aquí se escribe a mano. La fábrica existe para lo repetitivo; en cuanto un
|
|
2206
|
+
* catálogo necesita lógica propia deja de ser uno de estos y pasa a ser una pantalla normal.
|
|
2207
|
+
* Estirar la fábrica para acomodarlo es cómo se convierte en el lugar donde se esconden los
|
|
2208
|
+
* casos especiales — el mismo criterio con el que en el backend los modelos comparten base pero
|
|
2209
|
+
* los filtros, serializadores y vistas no.
|
|
2210
|
+
*
|
|
2211
|
+
* ## Lo que el backend tiene que cumplir
|
|
2212
|
+
*
|
|
2213
|
+
* Los campos base **no son configurables**: son el contrato. El recurso en `endpoint` sirve, en
|
|
2214
|
+
* el listado y en el detalle:
|
|
2215
|
+
*
|
|
2216
|
+
* - `id`.
|
|
2217
|
+
* - `codigo` — cadena, obligatoria y **única**. Es la llave con la que se identifica el registro
|
|
2218
|
+
* fuera de la base (la del CSV, la que alguien dicta por teléfono). La ficha avisa que "se
|
|
2219
|
+
* guarda en mayúsculas y sin espacios", así que el backend lo normaliza así al guardar, y
|
|
2220
|
+
* busca con la misma normalización al importar: si no, una actualización por código no
|
|
2221
|
+
* encuentra la fila y choca contra el `unique`.
|
|
2222
|
+
* - `nombre` — cadena, obligatoria. Es el orden inicial del listado.
|
|
2223
|
+
* - `descripcion` — texto libre, puede ser nulo.
|
|
2224
|
+
* - `activo` — booleano. Es la baja lógica: un registro referenciado no se borra, se desactiva.
|
|
2225
|
+
*
|
|
2226
|
+
* **La unicidad de `codigo` la garantiza el backend, no la grilla.** Un choque vuelve como un
|
|
2227
|
+
* 400 con el error en `codigo`, y la edición en línea lo pinta sobre la celda
|
|
2228
|
+
* (`renderEditCellWithErrorTooltip` con `mutationErrors`); la ficha, sobre el campo. El
|
|
2229
|
+
* `extra.queryArgs.endpoint` que lleva la columna `codigo` no valida nada: es lo que hace que el
|
|
2230
|
+
* panel de filtros la ofrezca como selector múltiple, con las opciones que sirve el
|
|
2231
|
+
* `como_opciones` de ese mismo endpoint, y filtre por `codigo__in`. Por eso el recurso también
|
|
2232
|
+
* tiene que servir `como_opciones`.
|
|
2233
|
+
*
|
|
2234
|
+
* Y lo que ya pide cualquier pantalla de la librería:
|
|
2235
|
+
*
|
|
2236
|
+
* - El listado, paginado con `results` y `count`.
|
|
2237
|
+
* - `obj_permissions` en cada registro (`edit`, `delete`). Es lo único que la ficha consulta para
|
|
2238
|
+
* ofrecer editar y borrar, y la grilla para dejar editar un renglón. Como la baja es lógica,
|
|
2239
|
+
* el backend tiene que calcular `obj_permissions.delete` con el `deletable` del registro —falso
|
|
2240
|
+
* mientras algo lo referencie—, no sólo con el permiso del modelo: si no, la ficha ofrece un
|
|
2241
|
+
* borrado que el servidor va a rechazar.
|
|
2242
|
+
* - Guardar (POST o PATCH) contesta `{ detail, list }`: `manualCacheRefresh` copia `detail` en la
|
|
2243
|
+
* caché del detalle y `list` en el renglón del listado, sin volver a pedirlos.
|
|
2244
|
+
*/
|
|
2245
|
+
interface DefinicionDeCatalogo {
|
|
2246
|
+
/**
|
|
2247
|
+
* Identificador único dentro del store. Nombra los endpoints de RTK Query y el tag de caché,
|
|
2248
|
+
* así que **no puede repetirse entre catálogos**: todos inyectan sobre el mismo `createApi`.
|
|
2249
|
+
*/
|
|
2250
|
+
clave: string;
|
|
2251
|
+
/** Ruta del recurso en el backend, sin diagonal final: `/<app>/<recurso>`. */
|
|
2252
|
+
endpoint: string;
|
|
2253
|
+
/** Permiso del modelo como lo resuelve `has_perm`, sin la acción: `<app>.<modelo>`. */
|
|
2254
|
+
permiso: string;
|
|
2255
|
+
/** Singular, para los mensajes y el título del detalle. */
|
|
2256
|
+
singular: string;
|
|
2257
|
+
/** Plural, para el título del listado. */
|
|
2258
|
+
plural: string;
|
|
2259
|
+
/** Campos propios, encima de código / nombre / descripción / activo. */
|
|
2260
|
+
camposExtra?: FieldProps[];
|
|
2261
|
+
/**
|
|
2262
|
+
* Columnas propias del listado, insertadas antes de `Descripción`.
|
|
2263
|
+
*
|
|
2264
|
+
* Es una función y no un arreglo para que reciba `mutationErrors`, que es lo que pinta
|
|
2265
|
+
* el tooltip de error sobre la celda que el servidor rechazó. Sin eso, las columnas
|
|
2266
|
+
* declaradas aquí fallarían en silencio mientras las de la base sí avisan.
|
|
2267
|
+
*/
|
|
2268
|
+
columnasExtra?: (props?: EditGridColumnsProps) => GridColDefPropsOverrides[];
|
|
2269
|
+
/**
|
|
2270
|
+
* Columnas de la base que este catálogo **no** enseña.
|
|
2271
|
+
*
|
|
2272
|
+
* Quita, no agrega: es lo único que la deja ser una opción sin volverse el lugar donde se
|
|
2273
|
+
* esconden los casos especiales. Existe porque un catálogo puede tener algo más informativo
|
|
2274
|
+
* que decir en el mismo espacio —a quién le aplica cada registro, antes que su
|
|
2275
|
+
* descripción— y el ancho de una grilla no es infinito.
|
|
2276
|
+
*
|
|
2277
|
+
* El campo sigue estando en la ficha y en el CSV; lo único que cambia es qué se ve de un
|
|
2278
|
+
* vistazo en el listado.
|
|
2279
|
+
*/
|
|
2280
|
+
ocultarColumnas?: string[];
|
|
2281
|
+
/** Se suma al esquema base de zod. */
|
|
2282
|
+
esquemaExtra?: Record<string, ZodType>;
|
|
2283
|
+
/** Valores iniciales de los campos extra en el alta. */
|
|
2284
|
+
valoresExtra?: Record<string, unknown>;
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
/** Los módulos de un `createApi` de `@reduxjs/toolkit/query/react`: el núcleo y los hooks. */
|
|
2288
|
+
type ConHooks = CoreModule | typeof reactHooksModuleName;
|
|
2289
|
+
/**
|
|
2290
|
+
* Los cuatro hooks de un catálogo simple.
|
|
2291
|
+
*
|
|
2292
|
+
* Van como `any` porque los nombres de los endpoints se arman en tiempo de ejecución a partir de
|
|
2293
|
+
* `clave`, así que TypeScript no puede derivar los hooks `useXQuery` que RTK genera.
|
|
2294
|
+
*/
|
|
2295
|
+
interface CatalogoAPI {
|
|
2296
|
+
/** `useQuery` del detalle: `useObtener({ id })`. */
|
|
2297
|
+
useObtener: any;
|
|
2298
|
+
/** `useLazyQuery` del listado: lo que `ServerGrid_v2` pide en `api.data.query`. */
|
|
2299
|
+
useListarLazy: any;
|
|
2300
|
+
/** `useMutation` de guardar: POST sin id, PATCH con id. */
|
|
2301
|
+
useGuardar: any;
|
|
2302
|
+
/** `useMutation` de borrar. */
|
|
2303
|
+
useEliminar: any;
|
|
2304
|
+
}
|
|
2305
|
+
/** Lo que devuelve `crearFabricaDeCatalogos`: la fábrica ya atada al `createApi` de una app. */
|
|
2306
|
+
type CrearCatalogoAPI = (definicion: DefinicionDeCatalogo) => CatalogoAPI;
|
|
2307
|
+
/**
|
|
2308
|
+
* Ata la fábrica de catálogos al `createApi` de una app.
|
|
2309
|
+
*
|
|
2310
|
+
* El `createApi` es de cada app —su `baseQuery`, su refresh del token, sus tags— y tiene que ser
|
|
2311
|
+
* uno solo, así que se inyecta en vez de crearse aquí. Cada app lo hace una vez:
|
|
2312
|
+
*
|
|
2313
|
+
* export const crearCatalogoAPI = crearFabricaDeCatalogos(mainAPI);
|
|
2314
|
+
*
|
|
2315
|
+
* y de ahí en adelante declara catálogos sin volver a nombrar su store.
|
|
2316
|
+
*
|
|
2317
|
+
* Acepta el `createApi` tal como sale de `@reduxjs/toolkit/query/react`, con dos condiciones que
|
|
2318
|
+
* el tipo comprueba: que traiga los hooks de React —son lo que la fábrica devuelve— y que su
|
|
2319
|
+
* `baseQuery` acepte `string | FetchArgs`, que es lo que arman los endpoints (una URL para leer;
|
|
2320
|
+
* `{ url, method, body }` para escribir). El parámetro es genérico a propósito: `Api` es
|
|
2321
|
+
* invariante en sus definiciones, así que ningún `Api<any, …>` fijo acepta el `mainAPI` concreto
|
|
2322
|
+
* de una app, y así entra tal cual.
|
|
2323
|
+
*
|
|
2324
|
+
* Lo que devuelve arma los cuatro endpoints de RTK Query que necesita un catálogo simple. Es
|
|
2325
|
+
* exactamente el `<modelo>API.ts` de un CRUD escrito a mano, parametrizado: obtener uno, listar
|
|
2326
|
+
* con los argumentos del grid, guardar (POST o PATCH según traiga id) y borrar. Los nombres se
|
|
2327
|
+
* derivan de `definicion.clave` porque **todos los catálogos inyectan sobre el mismo `createApi`**
|
|
2328
|
+
* y dos endpoints con el mismo nombre se pisan en silencio: con `overrideExisting: false`, el
|
|
2329
|
+
* segundo catálogo con una clave repetida se queda con los endpoints —y el `endpoint`— del
|
|
2330
|
+
* primero.
|
|
2331
|
+
*
|
|
2332
|
+
* `serializeQueryArgs` replica el del molde: el listado guarda una sola entrada de caché por
|
|
2333
|
+
* recurso —los filtros y el orden viajan en los args y no deben multiplicarla— y el detalle una
|
|
2334
|
+
* por id. `forceRefetch` con `isEqual` es lo que hace que un cambio de filtro sí vuelva a pedir.
|
|
2335
|
+
*
|
|
2336
|
+
* Se llama al cargar el módulo, una vez por catálogo, y no dentro de un componente: cada llamada
|
|
2337
|
+
* inyecta endpoints en el store.
|
|
2338
|
+
*/
|
|
2339
|
+
declare const crearFabricaDeCatalogos: <BaseQuery extends BaseQueryFn<string | FetchArgs, any, any, any, any>, Definiciones extends EndpointDefinitions, ReducerPath extends string, Tags extends string>(mainAPI: Api<BaseQuery, Definiciones, ReducerPath, Tags, ConHooks>) => CrearCatalogoAPI;
|
|
2340
|
+
|
|
2341
|
+
/**
|
|
2342
|
+
* Las columnas de un catálogo simple: código, nombre, las propias que declare, descripción y
|
|
2343
|
+
* activo.
|
|
2344
|
+
*
|
|
2345
|
+
* Un catálogo puede omitir alguna de las de la base con `ocultarColumnas` — quitar, nunca cambiar
|
|
2346
|
+
* lo que hacen; ver `DefinicionDeCatalogo`.
|
|
2347
|
+
*
|
|
2348
|
+
* `codigo` lleva `extra.queryArgs.endpoint`, que es lo que hace que el panel de filtros la
|
|
2349
|
+
* ofrezca como selector múltiple con las opciones del propio recurso (`como_opciones`). **No
|
|
2350
|
+
* valida la unicidad**: eso lo hace el backend al guardar, y el choque vuelve como el error que
|
|
2351
|
+
* `renderEditCellWithErrorTooltip` pinta sobre la celda.
|
|
2352
|
+
*/
|
|
2353
|
+
declare const columnasDeCatalogo: (definicion: DefinicionDeCatalogo) => (props?: EditGridColumnsProps) => GridColDefPropsOverrides[];
|
|
2354
|
+
|
|
2355
|
+
interface FilterInput {
|
|
2356
|
+
/** The column this input filters on — used only as a React key. */
|
|
2357
|
+
field: string;
|
|
2358
|
+
/**
|
|
2359
|
+
* The query keys this input writes. Usually one, but a range input owns two
|
|
2360
|
+
* (`_min`/`_max`, `_after`/`_before`), which is why this isn't just `field`.
|
|
2361
|
+
*/
|
|
2362
|
+
keys: string[];
|
|
2363
|
+
label: string;
|
|
2364
|
+
type: string;
|
|
2365
|
+
element: ReactElement;
|
|
2366
|
+
}
|
|
2367
|
+
/**
|
|
2368
|
+
* A filter the page adds itself, for something no column represents — a scope toggle, a flag
|
|
2369
|
+
* the backend computes, anything whose value isn't a column's value.
|
|
2370
|
+
*
|
|
2371
|
+
* The element is read fresh on every render rather than captured with the schema, so an input
|
|
2372
|
+
* that closes over page state stays current.
|
|
2373
|
+
*/
|
|
2374
|
+
interface CustomFilterDef {
|
|
2375
|
+
/**
|
|
2376
|
+
* The query key sent to the backend, and the form field name the element must bind to.
|
|
2377
|
+
*
|
|
2378
|
+
* Wins over a column that would generate the same key: the column's input is dropped from
|
|
2379
|
+
* the panel, so one key never gets two inputs writing to it.
|
|
2380
|
+
*/
|
|
2381
|
+
field: string;
|
|
2382
|
+
label: string;
|
|
2383
|
+
/** Any controlled input. The panel clones `control` in, exactly as it does for columns. */
|
|
2384
|
+
element: ReactElement;
|
|
2385
|
+
/** Defaults to `z.any().optional()` — enough for a value the backend validates anyway. */
|
|
2386
|
+
schema?: z.ZodType<any, any>;
|
|
2387
|
+
/** What the panel resets to, and what "Limpiar" restores. Defaults to `""`. */
|
|
2388
|
+
defaultValue?: any;
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
/**
|
|
2392
|
+
* Where the filter panel renders. `"drawer"` (the default) docks it to the right of the rows;
|
|
2393
|
+
* `"popper"` floats it off the toolbar button, the way it used to.
|
|
2394
|
+
*/
|
|
2395
|
+
type FiltersVariant = "drawer" | "popper";
|
|
2396
|
+
|
|
2397
|
+
/**
|
|
2398
|
+
* What the grid hands its RTK lazy query — the corrected `GridArgs`.
|
|
2399
|
+
*
|
|
2400
|
+
* v1 typed `filterModel` as MUI's `GridFilterModel` (`items: GridFilterItem[]`), a shape the
|
|
2401
|
+
* grid has never sent; it actually sends `MyGridFilterModel`, whose `items` is a plain
|
|
2402
|
+
* key/value bag. Endpoints typed against the v1 type were describing something that never
|
|
2403
|
+
* arrived. The index signature is real too: `api.data.args` may add arbitrary keys (several
|
|
2404
|
+
* endpoints read an `endpoint` or `tipo` off it).
|
|
2405
|
+
*/
|
|
2406
|
+
interface ServerGridArgs {
|
|
2407
|
+
page?: number;
|
|
2408
|
+
pageSize?: number;
|
|
2409
|
+
sortModel: GridSortModel;
|
|
2410
|
+
filterModel: MyGridFilterModel;
|
|
2411
|
+
ignoreSort?: boolean;
|
|
2412
|
+
[key: string]: any;
|
|
2413
|
+
}
|
|
2414
|
+
interface ServerGridDataApi {
|
|
2415
|
+
/** RTK Query lazy hook, e.g. `useLazyGetConceptosQuery`. */
|
|
2416
|
+
query: any;
|
|
2417
|
+
/** Extra query args, deep-merged over the grid's own. Deep-compared, so literals are safe. */
|
|
1999
2418
|
args?: any;
|
|
2000
2419
|
/** Filter keys the user may not clear from the filters panel. */
|
|
2001
2420
|
protectFilters?: string[];
|
|
@@ -2225,209 +2644,46 @@ interface GridLayerContribution {
|
|
|
2225
2644
|
}
|
|
2226
2645
|
type GridLayerMap = Partial<Record<GridLayerId, GridLayerContribution>>;
|
|
2227
2646
|
|
|
2647
|
+
interface CatalogoListProps {
|
|
2648
|
+
definicion: DefinicionDeCatalogo;
|
|
2649
|
+
api: CatalogoAPI;
|
|
2650
|
+
/**
|
|
2651
|
+
* Ruta a la que navega un renglón, y llave con la que el grid guarda filtros y columnas.
|
|
2652
|
+
*
|
|
2653
|
+
* Por defecto es la ruta actual, que es lo correcto cuando el listado ES la página. Dentro de
|
|
2654
|
+
* una pestaña hay que pasarla explícitamente: ahí `useLocation()` devuelve la ruta de la
|
|
2655
|
+
* página contenedora, así que sin esto los renglones navegarían al detalle de la página que
|
|
2656
|
+
* contiene las pestañas y todas ellas compartirían una sola llave de persistencia.
|
|
2657
|
+
*/
|
|
2658
|
+
pathname?: string;
|
|
2659
|
+
/**
|
|
2660
|
+
* La importación del listado: lo que va tal cual en `create.csv_upload` de `ServerGrid_v2`.
|
|
2661
|
+
*
|
|
2662
|
+
* - **Sin esto no hay importación.** La grilla no pinta la opción de CSV, y el menú de Crear
|
|
2663
|
+
* se queda sólo con "Manual".
|
|
2664
|
+
* - `{ enable: true }` abre el cajón de CSV de la librería (`CSVUpload`): sube el archivo con
|
|
2665
|
+
* el `useSubirCSVMutation` que la app registra en su `APIProvider`, contra el `pathname` de
|
|
2666
|
+
* la grilla, y ofrece la plantilla estática `/plantillas/plantilla_<último segmento>.xlsx`.
|
|
2667
|
+
* - `{ enable: true, component }` cambia ese cajón por el de la app, que recibe las mismas
|
|
2668
|
+
* props (`CSVUploadSlotProps`). Es por donde entra un importador propio, con lo que su
|
|
2669
|
+
* backend acepte junto al archivo. El componente tiene que ser **estable** —memoizado, o
|
|
2670
|
+
* declarado fuera del render—: uno nuevo en cada render desmonta el cajón y se pierde el
|
|
2671
|
+
* archivo que el usuario ya había elegido.
|
|
2672
|
+
*
|
|
2673
|
+
* Se recibe hecho y no se arma aquí porque la política de importación es de cada app, y
|
|
2674
|
+
* crecerle opciones a la librería para cubrirlas a todas es cómo un componente compartido se
|
|
2675
|
+
* vuelve la unión de tres aplicaciones. Si la política depende del permiso del catálogo, ése
|
|
2676
|
+
* ya viaja en `definicion.permiso`.
|
|
2677
|
+
*/
|
|
2678
|
+
csvUpload?: ServerGridCreateApi["csv_upload"];
|
|
2679
|
+
}
|
|
2228
2680
|
/**
|
|
2229
|
-
*
|
|
2230
|
-
* optional create / edit / delete modes layered on top.
|
|
2681
|
+
* El listado de un catálogo simple: grid del servidor, edición en línea, borrado y alta.
|
|
2231
2682
|
*
|
|
2232
|
-
*
|
|
2233
|
-
*
|
|
2234
|
-
* called as plain functions and their hooks landed in the grid's own hook list — a page that
|
|
2235
|
-
* built `api.edit` conditionally would then change React's hook order and crash.
|
|
2683
|
+
* El alta siempre está —sujeta al permiso de agregar—; la importación CSV sólo si se pasa
|
|
2684
|
+
* `csvUpload`.
|
|
2236
2685
|
*/
|
|
2237
|
-
declare
|
|
2238
|
-
|
|
2239
|
-
interface ExportCSVProps {
|
|
2240
|
-
handleClick: () => void;
|
|
2241
|
-
filterModel: MyGridFilterModel;
|
|
2242
|
-
sortModel: GridSortModel;
|
|
2243
|
-
rowSelectionModel: GridRowSelectionModel;
|
|
2244
|
-
/** The scoping the grid queries with. Without it an export exceeds what the grid shows. */
|
|
2245
|
-
queryArgs?: ServerGridArgs;
|
|
2246
|
-
disabledWithoutSelection?: boolean;
|
|
2247
|
-
/** Rows the current filters match, for the count shown in the picker. */
|
|
2248
|
-
rowCount?: number;
|
|
2249
|
-
ignore?: {
|
|
2250
|
-
filters?: string[];
|
|
2251
|
-
sort?: boolean;
|
|
2252
|
-
};
|
|
2253
|
-
slots?: {
|
|
2254
|
-
endpoint?: string;
|
|
2255
|
-
title?: string;
|
|
2256
|
-
variant?: string;
|
|
2257
|
-
column_key?: string;
|
|
2258
|
-
/** Opens the column picker instead of downloading straight away. Defaults to on. */
|
|
2259
|
-
columnPicker?: boolean;
|
|
2260
|
-
};
|
|
2261
|
-
}
|
|
2262
|
-
/**
|
|
2263
|
-
* Downloads the whole filtered result set as CSV — the server rebuilds it from the filters,
|
|
2264
|
-
* so this is never limited to the rows currently on screen.
|
|
2265
|
-
*/
|
|
2266
|
-
declare function ExportCSV(props: ExportCSVProps): react_jsx_runtime.JSX.Element;
|
|
2267
|
-
|
|
2268
|
-
interface UseServerGridOptions {
|
|
2269
|
-
/** Where this grid's state is remembered. Fixed for the lifetime of the mount. */
|
|
2270
|
-
storageKey: string;
|
|
2271
|
-
dontSaveState?: boolean;
|
|
2272
|
-
/** RTK Query lazy hook, e.g. `useLazyGetConceptosQuery`. */
|
|
2273
|
-
query: any;
|
|
2274
|
-
/** Extra query args, deep-compared — object literals are safe. */
|
|
2275
|
-
args?: any;
|
|
2276
|
-
/** Passed to the lazy hook (`{ pollingInterval }`, …). Also deep-compared. */
|
|
2277
|
-
queryOptions?: {
|
|
2278
|
-
[key: string]: any;
|
|
2279
|
-
};
|
|
2280
|
-
initialState?: MyDataGridProps["initialState"];
|
|
2281
|
-
columns?: readonly GridColDef[];
|
|
2282
|
-
}
|
|
2283
|
-
interface ServerGridPermissions {
|
|
2284
|
-
create?: boolean;
|
|
2285
|
-
edit?: boolean;
|
|
2286
|
-
delete?: boolean;
|
|
2287
|
-
}
|
|
2288
|
-
interface ServerGridState {
|
|
2289
|
-
apiRef: ReturnType<typeof useGridApiRef>;
|
|
2290
|
-
rows: readonly any[];
|
|
2291
|
-
rowCount: number;
|
|
2292
|
-
permissions: ServerGridPermissions;
|
|
2293
|
-
isLoading: boolean;
|
|
2294
|
-
isFetching: boolean;
|
|
2295
|
-
isError: boolean;
|
|
2296
|
-
paginationModel: GridPaginationModel;
|
|
2297
|
-
setPaginationModel: Dispatch<SetStateAction<GridPaginationModel>>;
|
|
2298
|
-
sortModel: GridSortModel;
|
|
2299
|
-
setSortModel: Dispatch<SetStateAction<GridSortModel>>;
|
|
2300
|
-
filterModel: MyGridFilterModel;
|
|
2301
|
-
setFilterModel: Dispatch<SetStateAction<MyGridFilterModel>>;
|
|
2302
|
-
columnVisibilityModel: GridColumnVisibilityModel;
|
|
2303
|
-
setColumnVisibilityModel: Dispatch<SetStateAction<GridColumnVisibilityModel>>;
|
|
2304
|
-
rowSelectionModel: GridRowSelectionModel;
|
|
2305
|
-
setRowSelectionModel: Dispatch<SetStateAction<GridRowSelectionModel>>;
|
|
2306
|
-
/** Debounced quick-search setter. Cancelled on unmount. */
|
|
2307
|
-
setQuickSearchValue: DebouncedFunc<(value: string) => void>;
|
|
2308
|
-
/** Toolbar collapse, hoisted here so shortcuts can reopen a collapsed toolbar. */
|
|
2309
|
-
toolbarExpanded: boolean;
|
|
2310
|
-
setToolbarExpanded: Dispatch<SetStateAction<boolean>>;
|
|
2311
|
-
/**
|
|
2312
|
-
* Whether the filter panel is showing. Up here rather than in the toolbar because the
|
|
2313
|
-
* docked panel is a sibling of the grid, not a child of the button that opens it — and
|
|
2314
|
-
* because Ctrl+Shift+F has to reach it from a collapsed toolbar either way.
|
|
2315
|
-
*/
|
|
2316
|
-
filtersOpen: boolean;
|
|
2317
|
-
setFiltersOpen: Dispatch<SetStateAction<boolean>>;
|
|
2318
|
-
/** Exactly what was last sent to the server. Also feeds the CSV export. */
|
|
2319
|
-
args: ServerGridArgs;
|
|
2320
|
-
refetch: () => void;
|
|
2321
|
-
subscribeRows: (callback: (snapshot: RowsSnapshot) => void) => () => void;
|
|
2322
|
-
}
|
|
2323
|
-
/**
|
|
2324
|
-
* Everything a server-mode grid needs to hold: the models the user drives, the persisted
|
|
2325
|
-
* state they start from, and the lazy query that keeps rows in step with them. Renders
|
|
2326
|
-
* nothing — `ServerGrid` supplies it through context, and pages that need a shape the grid
|
|
2327
|
-
* doesn't offer can drive their own `DataGrid` from it.
|
|
2328
|
-
*/
|
|
2329
|
-
declare function useServerGrid(options: UseServerGridOptions): ServerGridState;
|
|
2330
|
-
|
|
2331
|
-
interface ComposeGridPropsInput {
|
|
2332
|
-
/** The grid's own baseline — slots, locale, density. */
|
|
2333
|
-
defaults: Partial<MyDataGridProps>;
|
|
2334
|
-
layers: GridLayerMap;
|
|
2335
|
-
/** `props.dataGridProps`, straight from the page. */
|
|
2336
|
-
consumer?: Partial<MyDataGridProps>;
|
|
2337
|
-
}
|
|
2338
|
-
/**
|
|
2339
|
-
* Flattens the grid defaults, every mounted layer and the consumer's own props into one
|
|
2340
|
-
* `DataGrid` prop object.
|
|
2341
|
-
*
|
|
2342
|
-
* Precedence, low to high:
|
|
2343
|
-
* 1. grid defaults
|
|
2344
|
-
* 2. layer `defaults`, in `LAYER_ORDER`
|
|
2345
|
-
* 3. the consumer's `dataGridProps`
|
|
2346
|
-
* 4. layer `overrides`, in `LAYER_ORDER`
|
|
2347
|
-
*
|
|
2348
|
-
* Tier 4 sits above the consumer on purpose — a layer must be able to force the grid into a
|
|
2349
|
-
* coherent state while its mode is on (no checkboxes and no row navigation while rows are
|
|
2350
|
-
* being deleted). It is only ever allowed to publish mode-*on* values there; see
|
|
2351
|
-
* `GridLayerContribution.overrides`.
|
|
2352
|
-
*/
|
|
2353
|
-
declare function composeGridProps({ defaults, layers, consumer, }: ComposeGridPropsInput): Partial<MyDataGridProps>;
|
|
2354
|
-
|
|
2355
|
-
/**
|
|
2356
|
-
* Columns the user is allowed to hide.
|
|
2357
|
-
*
|
|
2358
|
-
* v1 excluded `"actions"` by *field*, but that is a column **type** — the real action columns
|
|
2359
|
-
* are `edit` and `delete`, so both showed up in the columns panel and could be hidden (and
|
|
2360
|
-
* persisted hidden) out from under the layer that owns them. Matched on both here.
|
|
2361
|
-
*/
|
|
2362
|
-
declare const togglableFields: (columns?: readonly GridColDef[]) => string[];
|
|
2363
|
-
interface ResolvedGridState {
|
|
2364
|
-
paginationModel: GridPaginationModel;
|
|
2365
|
-
sortModel: GridSortModel;
|
|
2366
|
-
filterModel: MyGridFilterModel;
|
|
2367
|
-
columnVisibilityModel: GridColumnVisibilityModel;
|
|
2368
|
-
}
|
|
2369
|
-
interface ResolveInitialStateInput {
|
|
2370
|
-
storageKey: string;
|
|
2371
|
-
/** `slotProps.dontSaveState` — skip the session store entirely. */
|
|
2372
|
-
disabled?: boolean;
|
|
2373
|
-
initialState?: MyDataGridProps["initialState"];
|
|
2374
|
-
columns?: readonly GridColDef[];
|
|
2375
|
-
}
|
|
2376
|
-
/**
|
|
2377
|
-
* Works out the state a grid starts in, from what the session remembers and what the page
|
|
2378
|
-
* declared. The only place that precedence lives.
|
|
2379
|
-
*
|
|
2380
|
-
* Pagination, sorting and column visibility prefer the **session**: those are the user's own
|
|
2381
|
-
* choices and should survive navigating away and back.
|
|
2382
|
-
*
|
|
2383
|
-
* Filters are the exception — the page's `initialState.filters` wins, key by key. Those
|
|
2384
|
-
* express scoping ("this embarque's recibos"), not preference, and in v1 the session beat
|
|
2385
|
-
* them outright, so a grid opened on record B kept showing record A's rows for the rest of
|
|
2386
|
-
* the session. Pages worked around it by repeating the same filter in `api.data.args`; they
|
|
2387
|
-
* no longer have to. A user-set filter on any *other* key still survives.
|
|
2388
|
-
*/
|
|
2389
|
-
declare function resolveInitialState({ storageKey, disabled, initialState, columns, }: ResolveInitialStateInput): ResolvedGridState;
|
|
2390
|
-
|
|
2391
|
-
/**
|
|
2392
|
-
* Page sizes offered by the grid and by the pagination slot. One list: in v1 the grid and
|
|
2393
|
-
* `CustomPagination` each declared their own copy and had to be kept in sync by hand.
|
|
2394
|
-
*
|
|
2395
|
-
* `-1` is "all" — the backends read that literal and return the whole result set with
|
|
2396
|
-
* `next`/`previous` null but a correct `count`. Only its label is translated; the value is wire
|
|
2397
|
-
* protocol and never changes.
|
|
2398
|
-
*/
|
|
2399
|
-
declare const pageSizeOptions: (etiquetaTodos: string) => (number | {
|
|
2400
|
-
value: number;
|
|
2401
|
-
label: string;
|
|
2402
|
-
})[];
|
|
2403
|
-
declare const DEFAULT_PAGINATION: GridPaginationModel;
|
|
2404
|
-
/**
|
|
2405
|
-
* The order layer contributions are applied in — columns, toolbar buttons and prop overrides
|
|
2406
|
-
* alike. Declared here so it never depends on how the layers happen to nest, which is what
|
|
2407
|
-
* made the delete column's position accidental in v1.
|
|
2408
|
-
*/
|
|
2409
|
-
declare const LAYER_ORDER: readonly GridLayerId[];
|
|
2410
|
-
|
|
2411
|
-
interface DeleteGridColumnsProps {
|
|
2412
|
-
displayDelete?: boolean;
|
|
2413
|
-
handleOpen: (id: GridRowId) => () => void;
|
|
2414
|
-
/**
|
|
2415
|
-
* Rótulo de la columna y de la acción. Es un parámetro y no un `useTextos()` porque esto no
|
|
2416
|
-
* es un componente: lo llama la capa de borrado, que sí es la que tiene el idioma a mano.
|
|
2417
|
-
* El default en español mantiene andando a quien la llame sin pasarlo.
|
|
2418
|
-
*/
|
|
2419
|
-
etiqueta?: string;
|
|
2420
|
-
}
|
|
2421
|
-
/**
|
|
2422
|
-
* The per-row delete action, shown only while delete mode is on.
|
|
2423
|
-
*
|
|
2424
|
-
* v1 left `type` off, so the column defaulted to `string`: sortable by a user, and offered in
|
|
2425
|
-
* the filters panel as an "Eliminar" text filter that meant nothing. Declaring `type: "actions"`
|
|
2426
|
-
* fixes both — but it has to come with `getActions` rather than `renderCell`, because an
|
|
2427
|
-
* explicit `renderCell` beats the actions type's own cell and takes its keyboard handling and
|
|
2428
|
-
* overflow menu with it.
|
|
2429
|
-
*/
|
|
2430
|
-
declare const deleteColumn: (props: DeleteGridColumnsProps) => GridColDefPropsOverrides[];
|
|
2686
|
+
declare const CatalogoList: ({ definicion, api, pathname, csvUpload }: CatalogoListProps) => react_jsx_runtime.JSX.Element;
|
|
2431
2687
|
|
|
2432
2688
|
type ChipColor = StatusColor;
|
|
2433
2689
|
type ChipOption = {
|
|
@@ -2456,310 +2712,156 @@ declare const renderChipCell: (options: ChipOption[], colors?: Record<string, Ch
|
|
|
2456
2712
|
value?: unknown;
|
|
2457
2713
|
}) => react_jsx_runtime.JSX.Element;
|
|
2458
2714
|
|
|
2715
|
+
interface PulseDotProps {
|
|
2716
|
+
/** Cuando es `true`, el punto es verde y parpadea; si no, usa `inactiveColor`. */
|
|
2717
|
+
active: boolean;
|
|
2718
|
+
/** Color cuando no está activo. Por defecto `error.main`. */
|
|
2719
|
+
inactiveColor?: string;
|
|
2720
|
+
/** Tamaño del punto en px. Por defecto 10. */
|
|
2721
|
+
size?: number;
|
|
2722
|
+
/** Título opcional; si se pasa, envuelve el punto en un Tooltip. */
|
|
2723
|
+
title?: ReactNode;
|
|
2724
|
+
}
|
|
2725
|
+
/** Punto de estado: verde con animación de parpadeo cuando está activo, de lo
|
|
2726
|
+
* contrario un color fijo. Se usa para indicar conexión/actividad en vivo. */
|
|
2727
|
+
declare function PulseDot({ active, inactiveColor, size, title }: PulseDotProps): react_jsx_runtime.JSX.Element;
|
|
2728
|
+
|
|
2459
2729
|
/**
|
|
2460
|
-
*
|
|
2461
|
-
*
|
|
2462
|
-
*
|
|
2463
|
-
*
|
|
2730
|
+
* El contenedor que declara todo renglón que lleve un título y sus adornos: el encabezado de
|
|
2731
|
+
* una página, el de un cajón y el de un diálogo.
|
|
2732
|
+
*
|
|
2733
|
+
* Se llama igual en los tres a propósito. Lo que aterriza en ese renglón —el estado de un
|
|
2734
|
+
* registro, una barra de acciones— tiene que encogerse cuando el renglón se queda corto, y con
|
|
2735
|
+
* un solo nombre esa regla se escribe una vez y sirve en los tres sitios: cada cosa mide contra
|
|
2736
|
+
* 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
|
|
2737
|
+
* es el del cajón. Los breakpoints del viewport no sabrían distinguirlos —la pantalla es la
|
|
2738
|
+
* misma— y `@container` sí.
|
|
2739
|
+
*
|
|
2740
|
+
* No se pisan entre ellos aunque compartan nombre: un cajón y un diálogo se pintan por portal,
|
|
2741
|
+
* fuera del árbol de la página, así que nunca hay uno dentro de otro. Y si lo hubiera, una
|
|
2742
|
+
* `@container` resuelve contra el contenedor ancestro más cercano, que es justo el que manda.
|
|
2464
2743
|
*/
|
|
2465
|
-
|
|
2466
|
-
fieldData?: any;
|
|
2467
|
-
/** Registro completo de la página; permite leer valores hermanos. */
|
|
2468
|
-
data?: any;
|
|
2469
|
-
name?: string;
|
|
2470
|
-
detail_name?: string;
|
|
2471
|
-
extraProps?: any;
|
|
2472
|
-
/** Valor formateado + pre/post, disponible para `Detail`. */
|
|
2473
|
-
content?: string;
|
|
2474
|
-
}
|
|
2744
|
+
declare const HEADER_CONTAINER = "acv-header";
|
|
2475
2745
|
/**
|
|
2476
|
-
*
|
|
2477
|
-
*
|
|
2746
|
+
* Debajo de este ancho el renglón se considera angosto y lo que viva en él debería encogerse:
|
|
2747
|
+
* la insignia de estado, por ejemplo, se queda en un punto de color con el rótulo en el globo.
|
|
2478
2748
|
*
|
|
2479
|
-
*
|
|
2480
|
-
*
|
|
2481
|
-
*
|
|
2482
|
-
*
|
|
2483
|
-
* solo para inputs que necesitan controlar toda su UI de solo lectura.
|
|
2749
|
+
* Se escribe como regla y no como número suelto para que quien la use no tenga que rearmar la
|
|
2750
|
+
* consulta —ni equivocarse al hacerlo—:
|
|
2751
|
+
*
|
|
2752
|
+
* sx={{ [HEADER_NARROW]: { display: "none" } }}
|
|
2484
2753
|
*/
|
|
2485
|
-
|
|
2486
|
-
formatDetail?: (props: DetailRenderProps) => ReactNode;
|
|
2487
|
-
Detail?: (props: DetailRenderProps) => ReactNode;
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2754
|
+
declare const HEADER_NARROW = "@container acv-header (max-width: 600px)";
|
|
2490
2755
|
/**
|
|
2491
|
-
*
|
|
2492
|
-
*
|
|
2756
|
+
* Convierte un renglón en el contenedor contra el que se miden sus adornos.
|
|
2757
|
+
*
|
|
2758
|
+
* `inline-size`, nunca `size`: contener también el eje de bloque le fijaría la altura al
|
|
2759
|
+
* encabezado, que crece con lo que lleva dentro —un subtítulo, un título en dos renglones—.
|
|
2493
2760
|
*/
|
|
2494
|
-
|
|
2495
|
-
formatted_address: string;
|
|
2496
|
-
place_id?: string | null;
|
|
2497
|
-
lat?: number | null;
|
|
2498
|
-
lng?: number | null;
|
|
2499
|
-
street_number?: string;
|
|
2500
|
-
route?: string | null;
|
|
2501
|
-
neighborhood?: string | null;
|
|
2502
|
-
locality?: string | null;
|
|
2503
|
-
administrative_area_level_1?: string | null;
|
|
2504
|
-
postal_code?: string | null;
|
|
2505
|
-
country?: string | null;
|
|
2506
|
-
country_code?: string | null;
|
|
2507
|
-
}
|
|
2508
|
-
interface ControlledAddressAutocompleteProps {
|
|
2509
|
-
name: string;
|
|
2510
|
-
label?: string;
|
|
2511
|
-
control: any;
|
|
2512
|
-
fieldProps?: TextFieldProps$1;
|
|
2513
|
-
extraProps?: {
|
|
2514
|
-
/**
|
|
2515
|
-
* API key de Google Maps. Si no se pasa, se intenta leer
|
|
2516
|
-
* `VITE_GOOGLE_MAPS_API_KEY` de `import.meta.env`.
|
|
2517
|
-
*/
|
|
2518
|
-
apiKey?: string;
|
|
2519
|
-
/** Restringe los resultados a estos países, p.ej. ["mx", "us"]. */
|
|
2520
|
-
countries?: string[];
|
|
2521
|
-
/** Idioma de los resultados, p.ej. "es". */
|
|
2522
|
-
language?: string;
|
|
2523
|
-
/**
|
|
2524
|
-
* Callback opcional con el `Place` resuelto (con addressComponents,
|
|
2525
|
-
* location, etc.) por si la pantalla necesita autollenar otros campos.
|
|
2526
|
-
*/
|
|
2527
|
-
onResolved?: (place: any) => void;
|
|
2528
|
-
};
|
|
2529
|
-
}
|
|
2530
|
-
declare const ControlledAddressAutocomplete: {
|
|
2531
|
-
({ name, label, control, fieldProps, extraProps, }: ControlledAddressAutocompleteProps): react_jsx_runtime.JSX.Element;
|
|
2532
|
-
displayName: string;
|
|
2533
|
-
formatDetail({ fieldData }: DetailRenderProps): string;
|
|
2534
|
-
};
|
|
2761
|
+
declare const headerContainerSx: CSSObject;
|
|
2535
2762
|
|
|
2536
|
-
/** Opción de un desplegable: `{ value, label }`. */
|
|
2537
|
-
interface Opciones {
|
|
2538
|
-
value: string;
|
|
2539
|
-
label: string;
|
|
2540
|
-
}
|
|
2541
|
-
interface ControlledAmountWithCurrencyProps {
|
|
2542
|
-
/** Ruta del monto en el formulario, p.ej. "valores_de_factura.subtotal". */
|
|
2543
|
-
name: string;
|
|
2544
|
-
/** Control de react-hook-form (lo inyecta el `EditField` de la página). */
|
|
2545
|
-
control?: any;
|
|
2546
|
-
fieldProps?: Partial<NumericFormatProps<InputBaseProps>>;
|
|
2547
|
-
extraProps?: {
|
|
2548
|
-
/**
|
|
2549
|
-
* Ruta de la moneda en el formulario. Por defecto `${name}_moneda`,
|
|
2550
|
-
* de modo que "valores_de_factura.subtotal" usa
|
|
2551
|
-
* "valores_de_factura.subtotal_moneda".
|
|
2552
|
-
*/
|
|
2553
|
-
currencyName?: string;
|
|
2554
|
-
/** Origen de las opciones de moneda (endpoint `como_opciones`). */
|
|
2555
|
-
queryArgs?: ComoOpcionesProps;
|
|
2556
|
-
/** Opciones estáticas de moneda (alternativa a `queryArgs`). */
|
|
2557
|
-
options?: Opciones[];
|
|
2558
|
-
};
|
|
2559
|
-
}
|
|
2560
2763
|
/**
|
|
2561
|
-
*
|
|
2562
|
-
*
|
|
2563
|
-
* final.
|
|
2764
|
+
* Cómo se está dibujando la barra. En orden de lo que ocupa: las acciones a la vista con su
|
|
2765
|
+
* etiqueta, las mismas sólo con el icono, sólo las fijadas, o ninguna.
|
|
2564
2766
|
*
|
|
2565
|
-
*
|
|
2566
|
-
*
|
|
2767
|
+
* El modo dice qué se dibuja *fuera* del menú; lo que quede fuera de eso —y lo que sobre del
|
|
2768
|
+
* tope de `maxVisible`— está siempre dentro de él, así que hasta en `"full"` puede haber menú.
|
|
2567
2769
|
*
|
|
2568
|
-
*
|
|
2569
|
-
*
|
|
2570
|
-
* name: "valores_de_factura.subtotal",
|
|
2571
|
-
* label: "Subtotal",
|
|
2572
|
-
* type: ControlledAmountWithCurrency,
|
|
2573
|
-
* gridProps: { size: 12 },
|
|
2574
|
-
* }
|
|
2575
|
-
* ```
|
|
2576
|
-
*/
|
|
2577
|
-
declare const ControlledAmountWithCurrency: {
|
|
2578
|
-
({ name, control, fieldProps, extraProps, }: ControlledAmountWithCurrencyProps): react_jsx_runtime.JSX.Element;
|
|
2579
|
-
displayName: string;
|
|
2580
|
-
formatDetail({ fieldData, extraProps, data, name, }: DetailRenderProps): string;
|
|
2581
|
-
};
|
|
2582
|
-
|
|
2583
|
-
/**
|
|
2584
|
-
* Helpers puros del `ControlledAutocomplete`: los argumentos de la consulta, la
|
|
2585
|
-
* lista que se muestra y las cuentas del "seleccionar todo". Viven fuera del
|
|
2586
|
-
* componente para poder probarlos sin montar MUI ni RTK Query.
|
|
2770
|
+
* `"pinned"` sólo es un escalón cuando hay alguna acción fijada; sin ellas la barra pasa de
|
|
2771
|
+
* `"icons"` derecho a `"menu"`.
|
|
2587
2772
|
*/
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
interface
|
|
2591
|
-
|
|
2773
|
+
declare const RESPONSIVE_ACTION_MODES: readonly ["full", "icons", "pinned", "menu"];
|
|
2774
|
+
type ResponsiveActionsMode = (typeof RESPONSIVE_ACTION_MODES)[number];
|
|
2775
|
+
interface ResponsiveAction {
|
|
2776
|
+
/** Texto del botón; también lo que se lee en el menú y en el tooltip del modo icono. */
|
|
2592
2777
|
label: string;
|
|
2778
|
+
/** Se dibuja como `startIcon`, como el botón entero, o a la izquierda del renglón del menú. */
|
|
2779
|
+
icon: ReactNode;
|
|
2780
|
+
onClick: () => void;
|
|
2781
|
+
/** Ayuda larga. Sustituye a `label` como tooltip —el modo icono siempre lleva uno. */
|
|
2782
|
+
tooltip?: string;
|
|
2783
|
+
disabled?: boolean;
|
|
2784
|
+
/** Spinner en lugar del icono, y la acción bloqueada mientras tanto. */
|
|
2785
|
+
loading?: boolean;
|
|
2786
|
+
/** También tiñe el renglón del menú, para que la acción se vea igual se dibuje como se dibuje. */
|
|
2787
|
+
color?: ButtonProps["color"];
|
|
2788
|
+
/**
|
|
2789
|
+
* La última en esconderse: cuando el renglón deja de dar para todas, esta se queda a la vista
|
|
2790
|
+
* —como icono— y las demás se van al menú. Es para la que se usa siempre (editar, en una
|
|
2791
|
+
* ficha); fijar media barra no sirve de mucho, porque entonces ese escalón acaba pesando casi
|
|
2792
|
+
* lo mismo que el anterior y se salta solo.
|
|
2793
|
+
*/
|
|
2794
|
+
pinned?: boolean;
|
|
2593
2795
|
}
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
* Props que el consumidor escribe en `fieldProps` pensando en "el campo" pero que
|
|
2597
|
-
* son del `TextField` que dibuja `renderInput`, no del `Autocomplete`.
|
|
2598
|
-
*
|
|
2599
|
-
* MUI sólo reenvía a `renderInput` `id`, `disabled`, `size`, `fullWidth` e
|
|
2600
|
-
* `InputProps`; lo demás se quedaba en el nodo raíz del `Autocomplete` —sin
|
|
2601
|
-
* efecto y sin aviso—, así que un `fieldProps: { helperText: "…" }` no se veía
|
|
2602
|
-
* por ningún lado. Se reparten antes del spread para que lleguen a su sitio.
|
|
2603
|
-
*/
|
|
2604
|
-
declare const TEXT_FIELD_KEYS: readonly ["helperText", "placeholder", "required", "margin"];
|
|
2605
|
-
type TextFieldOnlyProps = Pick<TextFieldProps$1, (typeof TEXT_FIELD_KEYS)[number]>;
|
|
2606
|
-
type AutocompleteFieldProps = Partial<AutocompleteProps<any, any, any, any>> & TextFieldOnlyProps;
|
|
2607
|
-
interface ControlledAutocompleteProps {
|
|
2608
|
-
name: string;
|
|
2609
|
-
label?: string;
|
|
2610
|
-
/** Control de react-hook-form; lo inyecta el `EditField` o el panel de filtros. */
|
|
2611
|
-
control?: any;
|
|
2796
|
+
interface ResponsiveActionsProps {
|
|
2797
|
+
actions: ResponsiveAction[];
|
|
2612
2798
|
/**
|
|
2613
|
-
*
|
|
2614
|
-
*
|
|
2615
|
-
*
|
|
2799
|
+
* Cuántas acciones se dibujan como botón, como mucho. Las demás se van al menú desde el
|
|
2800
|
+
* primer modo, quepan o no: es un tope de cuántas *merecen* estar a la vista, no de cuántas
|
|
2801
|
+
* caben —de eso ya se encarga la medición—. Sin él salen todas.
|
|
2802
|
+
*
|
|
2803
|
+
* Se queda con las primeras, así que el orden manda: lo importante va delante. Fijar una
|
|
2804
|
+
* acción (`pinned`) no la adelanta, sólo la hace la última en esconderse.
|
|
2616
2805
|
*/
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
options?: AutocompleteOption[];
|
|
2623
|
-
/** Origen remoto de las opciones (endpoint `como_opciones`). */
|
|
2624
|
-
queryArgs?: ComoOpcionesProps;
|
|
2625
|
-
/** Filtro contra el que se busca el texto. Por defecto `nombre__icontains`. */
|
|
2626
|
-
searchField?: string;
|
|
2627
|
-
/** Retardo del tecleo antes de consultar. Por defecto 400 ms. */
|
|
2628
|
-
debounceMs?: number;
|
|
2629
|
-
/** Caracteres mínimos para consultar. Por defecto 0 (lista completa al abrir). */
|
|
2630
|
-
minChars?: number;
|
|
2631
|
-
/** Fila de "seleccionar todo" en el modo múltiple. Por defecto, sí. */
|
|
2632
|
-
selectAll?: boolean;
|
|
2633
|
-
/**
|
|
2634
|
-
* Quita el hueco reservado para el mensaje de error debajo del campo. No
|
|
2635
|
-
* afecta al `helperText` de `fieldProps`: si hay texto de ayuda, se ve.
|
|
2636
|
-
*/
|
|
2637
|
-
disableHT?: boolean;
|
|
2638
|
-
};
|
|
2806
|
+
maxVisible?: number;
|
|
2807
|
+
/** @default "small" */
|
|
2808
|
+
size?: "small" | "medium";
|
|
2809
|
+
/** Fija el modo y apaga la medición. Para cuando el ancho no es quien debe decidir. */
|
|
2810
|
+
mode?: ResponsiveActionsMode;
|
|
2639
2811
|
}
|
|
2640
2812
|
/**
|
|
2641
|
-
*
|
|
2642
|
-
*
|
|
2643
|
-
*
|
|
2644
|
-
* el mismo componente duplicado.
|
|
2813
|
+
* Una barra de acciones que se encoge sola cuando deja de caber: primero pierde las etiquetas y
|
|
2814
|
+
* se queda en iconos, después esconde en un menú de tres puntos todo menos lo fijado, y al final
|
|
2815
|
+
* se mete ahí entera.
|
|
2645
2816
|
*
|
|
2646
|
-
*
|
|
2647
|
-
*
|
|
2648
|
-
*
|
|
2649
|
-
* label: "Cliente",
|
|
2650
|
-
* type: ControlledAutocomplete,
|
|
2651
|
-
* extraProps: { queryArgs: { endpoint: "clientes" } },
|
|
2652
|
-
* }
|
|
2653
|
-
* ```
|
|
2817
|
+
* Encogerse es cosa del ancho; cuántas acciones merecen un botón, no. Para eso está `maxVisible`,
|
|
2818
|
+
* que manda al menú lo que pase de la cuenta aunque sobre sitio —una barra de ocho botones cabe
|
|
2819
|
+
* en una pantalla ancha y aun así no hay quien la lea—.
|
|
2654
2820
|
*
|
|
2655
|
-
*
|
|
2821
|
+
* Mide, no adivina. Los breakpoints del viewport no sirven aquí —la misma barra vive en una
|
|
2822
|
+
* página ancha y en un cajón de 460px, donde la pantalla es grande y el hueco no—, así que
|
|
2823
|
+
* compara el ancho que le dejaron con el que sus botones piden y baja un escalón cuando no
|
|
2824
|
+
* alcanza. Es el mismo motivo por el que el layout de los campos resuelve por `@container`.
|
|
2656
2825
|
*
|
|
2657
|
-
*
|
|
2658
|
-
*
|
|
2659
|
-
*
|
|
2660
|
-
* - **Elegir una opción no consulta.** Al elegir, MUI reescribe el texto del
|
|
2661
|
-
* campo con la etiqueta; v1 lo trataba como búsqueda nueva y volvía a pedir.
|
|
2662
|
-
* - **Sin parpadeo ni respuestas cruzadas.** La lista es la del hook de RTK
|
|
2663
|
-
* Query, que siempre corresponde a los últimos argumentos disparados; v1
|
|
2664
|
-
* guardaba las opciones en estado propio, las vaciaba en cada tecla y una
|
|
2665
|
-
* respuesta lenta podía pisar a una más nueva.
|
|
2666
|
-
* - **Repetir una búsqueda sale de la caché**, incluido borrar el texto para
|
|
2667
|
-
* volver al listado completo.
|
|
2826
|
+
* Para que la medición signifique algo, el padre tiene que ser un renglón flex que le deje
|
|
2827
|
+
* crecer al sobrante: la raíz se estira (`flexGrow`) para que su ancho *sea* el hueco, y los
|
|
2828
|
+
* botones van dentro sin encogerse, así que su ancho es lo que piden de verdad.
|
|
2668
2829
|
*/
|
|
2669
|
-
declare const
|
|
2830
|
+
declare const ResponsiveActions: ({ actions, maxVisible, size, mode: forcedMode, }: ResponsiveActionsProps) => react_jsx_runtime.JSX.Element | null;
|
|
2670
2831
|
|
|
2671
|
-
interface
|
|
2672
|
-
/**
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2832
|
+
interface DetailActionsProps {
|
|
2833
|
+
/**
|
|
2834
|
+
* Editar. Va fijada, así que es la última en irse al menú cuando el renglón se estrecha: es
|
|
2835
|
+
* la acción de siempre en una ficha, y la que se busca sin leer. Se lleva consigo el Ctrl+E
|
|
2836
|
+
* que vivía en `EditButton`, el botón suelto que esta barra vino a sustituir.
|
|
2837
|
+
*/
|
|
2838
|
+
edit?: {
|
|
2839
|
+
onClick: () => void;
|
|
2679
2840
|
};
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2841
|
+
delete?: {
|
|
2842
|
+
mutation: any;
|
|
2843
|
+
disableNavBack?: boolean;
|
|
2844
|
+
};
|
|
2845
|
+
historial?: {
|
|
2846
|
+
endpoint?: string;
|
|
2847
|
+
/** Defaults to `"docked"` — the panel takes its own space beside the page. */
|
|
2848
|
+
variant?: _HistorialDrawerProps["variant"];
|
|
2849
|
+
/** Panel width in px. Defaults to 600. */
|
|
2850
|
+
width?: number | string;
|
|
2685
2851
|
};
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
* type: ControlledColor,
|
|
2700
|
-
* gridProps: { size: { xs: 12, md: 4 } },
|
|
2701
|
-
* }
|
|
2702
|
-
* ```
|
|
2703
|
-
*/
|
|
2704
|
-
declare const ControlledColor: ControlledInput<ControlledColorProps>;
|
|
2705
|
-
|
|
2706
|
-
/**
|
|
2707
|
-
* `ControlledDate` de v2. Reutiliza el renderizado de edición de v1 (no se
|
|
2708
|
-
* duplica su lógica) y añade el renderizado de detalle mediante `formatDetail`,
|
|
2709
|
-
* de modo que la página de detalle no necesita conocer este tipo de campo.
|
|
2710
|
-
*
|
|
2711
|
-
* Migrar un input a v2 consiste en esto: envolver el componente de v1 y
|
|
2712
|
-
* adjuntarle `formatDetail` (y opcionalmente `Detail`). Sirve de plantilla para
|
|
2713
|
-
* el resto de inputs.
|
|
2714
|
-
*/
|
|
2715
|
-
declare const ControlledDate: ControlledInput;
|
|
2716
|
-
|
|
2717
|
-
/**
|
|
2718
|
-
* `ControlledSelect` de v2: hoy es un `ControlledAutocomplete` en modo múltiple.
|
|
2719
|
-
*
|
|
2720
|
-
* Se conserva el nombre porque ya lo usan varias pantallas de los dos
|
|
2721
|
-
* proyectos; lo que cambia por dentro es cuándo y cuántas veces se piden las
|
|
2722
|
-
* opciones (ver `ControlledAutocomplete`). `disableHT` viene en `true` para no
|
|
2723
|
-
* mover el alto de esas pantallas: el select de v1 no reservaba el renglón del
|
|
2724
|
-
* mensaje de error. Quien lo necesite puede pasarlo en `false`.
|
|
2725
|
-
*
|
|
2726
|
-
* Para código nuevo conviene usar `ControlledAutocomplete` directamente, que
|
|
2727
|
-
* además cubre el modo simple.
|
|
2728
|
-
*/
|
|
2729
|
-
declare const ControlledSelect: ControlledInput;
|
|
2730
|
-
|
|
2731
|
-
/**
|
|
2732
|
-
* `ControlledFileField` de v2. Reutiliza el renderizado de edición de v1 y
|
|
2733
|
-
* aporta su renderizado de detalle completo mediante `Detail` (badge + popover),
|
|
2734
|
-
* además del texto formateado mediante `formatDetail`.
|
|
2735
|
-
*/
|
|
2736
|
-
declare const ControlledFileField: ControlledInput;
|
|
2737
|
-
|
|
2738
|
-
interface FieldProps {
|
|
2739
|
-
pageType?: PageType;
|
|
2740
|
-
fieldData?: any;
|
|
2741
|
-
/** Registro completo de la página; permite a los campos leer valores hermanos. */
|
|
2742
|
-
data?: any;
|
|
2743
|
-
name: string;
|
|
2744
|
-
detail_name?: string;
|
|
2745
|
-
label: string;
|
|
2746
|
-
/** Ubicación de la etiqueta respecto al campo. Por defecto `"top"`. */
|
|
2747
|
-
labelPosition?: "top" | "left";
|
|
2748
|
-
/** Input controlado a renderizar (edición) y, opcionalmente, su detalle. */
|
|
2749
|
-
type: ControlledInput;
|
|
2750
|
-
gridProps?: GridProps;
|
|
2751
|
-
fieldProps?: object;
|
|
2752
|
-
extraProps?: any;
|
|
2753
|
-
detailFieldProps?: {
|
|
2754
|
-
preValue?: string;
|
|
2755
|
-
postValue?: string;
|
|
2756
|
-
};
|
|
2757
|
-
navigation?: {
|
|
2758
|
-
url: string;
|
|
2759
|
-
permission: string;
|
|
2760
|
-
};
|
|
2761
|
-
permission?: string;
|
|
2762
|
-
display?: boolean;
|
|
2852
|
+
extraButtons?: {
|
|
2853
|
+
title: string;
|
|
2854
|
+
icon: ReactNode;
|
|
2855
|
+
onClick: () => void;
|
|
2856
|
+
}[];
|
|
2857
|
+
/** Tamaño de los botones. `"small"` para las cabeceras del cajón. */
|
|
2858
|
+
size?: "small" | "medium";
|
|
2859
|
+
/**
|
|
2860
|
+
* Fija cómo se dibuja la barra en vez de dejar que se mida. El cajón lo usa para quedarse
|
|
2861
|
+
* siempre en el menú de tres puntos: su cabecera ya lleva sus propios botones al lado.
|
|
2862
|
+
* @see ResponsiveActionsProps.mode
|
|
2863
|
+
*/
|
|
2864
|
+
mode?: ResponsiveActionsMode;
|
|
2763
2865
|
}
|
|
2764
2866
|
|
|
2765
2867
|
interface SubsectionProps {
|
|
@@ -3009,648 +3111,792 @@ interface DetailExtraButton {
|
|
|
3009
3111
|
display?: (data: any) => boolean;
|
|
3010
3112
|
}
|
|
3011
3113
|
|
|
3012
|
-
interface
|
|
3013
|
-
/** Open the previous record of the list the drawer is walking. */
|
|
3014
|
-
onPrev: () => void;
|
|
3015
|
-
onNext: () => void;
|
|
3016
|
-
/** Whether a previous/next record exists. The arrows are disabled when it doesn't. */
|
|
3017
|
-
hasPrev: boolean;
|
|
3018
|
-
hasNext: boolean;
|
|
3019
|
-
/** 1-based position of the current record, shown between the arrows. */
|
|
3020
|
-
position?: number;
|
|
3021
|
-
/** Size of the list; shown as `position / count`. */
|
|
3022
|
-
count?: number;
|
|
3023
|
-
/** Blocks both arrows for a caller-side reason (e.g. while the next batch loads). */
|
|
3024
|
-
disabled?: boolean;
|
|
3025
|
-
}
|
|
3026
|
-
interface DetailFormDrawerProps {
|
|
3027
|
-
open: boolean;
|
|
3028
|
-
/** Close the drawer. Also invoked after a successful save and on cancel. */
|
|
3029
|
-
onClose: () => void;
|
|
3030
|
-
title?: ReactNode;
|
|
3114
|
+
interface DetailPageV2Props {
|
|
3031
3115
|
api: DetailFormApi;
|
|
3032
3116
|
form: DetailFormConfig["form"];
|
|
3033
3117
|
sections: DetailFormConfig["sections"];
|
|
3034
|
-
|
|
3035
|
-
pageType?: PageType;
|
|
3036
|
-
/**
|
|
3037
|
-
* Open a `"detail"` drawer straight in edit mode, as if the user had hit the Editar
|
|
3038
|
-
* button. Ignored for the other page types, and for records the user may not edit.
|
|
3039
|
-
*/
|
|
3040
|
-
startInEdit?: boolean;
|
|
3041
|
-
/**
|
|
3042
|
-
* Identity of the record on show. Swapping it (as the navigator does, without remounting
|
|
3043
|
-
* the drawer) re-derives the per-record chrome — the in-place edit toggle drops back to
|
|
3044
|
-
* read-only and `startInEdit` is re-applied against the new record's own permissions.
|
|
3045
|
-
*/
|
|
3046
|
-
recordKey?: string | number;
|
|
3047
|
-
permissionsPath?: string;
|
|
3048
|
-
/** Runs after a successful mutation, before the drawer closes. Receives the response. */
|
|
3049
|
-
onSuccess?: (response: any) => void;
|
|
3050
|
-
/**
|
|
3051
|
-
* Guardar deja el cajón abierto —y editando— en vez de cerrarlo. El usuario lo cierra
|
|
3052
|
-
* cuando termina, con la X o con Cancelar.
|
|
3053
|
-
*
|
|
3054
|
-
* Para registros que se capturan de a poco, o que llevan dentro su propia grilla editable:
|
|
3055
|
-
* ahí cerrar al guardar cuesta reabrir el registro, volver a entrar a editar y volver a
|
|
3056
|
-
* bajar hasta donde se iba. El caso que lo pide es un cajón anidado —una orden de envío
|
|
3057
|
-
* abierta desde la pestaña de su embarque, con la grilla de sus recibos adentro—, donde el
|
|
3058
|
-
* cierre además se lleva la grilla de en medio.
|
|
3059
|
-
*
|
|
3060
|
-
* Un guardado que **no** guardó igual cierra: `useMutationHandler` corre su `onSuccess` sin
|
|
3061
|
-
* respuesta ante un 403 para quitar la pantalla de en medio, y eso no es algo en lo que
|
|
3062
|
-
* quedarse. Tampoco compite con "Guardar ↓" — ése ya se queda abierto por su cuenta, y
|
|
3063
|
-
* cuando los dos aplican gana el paso al siguiente registro, que es lo que se pidió.
|
|
3064
|
-
*/
|
|
3065
|
-
keepOpenOnSave?: boolean;
|
|
3118
|
+
pageType: PageType;
|
|
3066
3119
|
/**
|
|
3067
|
-
*
|
|
3068
|
-
*
|
|
3069
|
-
* traiga sus acciones se abra en su página o en el cajón.
|
|
3120
|
+
* What the `size` breakpoints of the fields — and of the subsections themselves — resolve
|
|
3121
|
+
* against. Defaults to `"container"`: the width of the form, not of the screen.
|
|
3070
3122
|
*
|
|
3071
|
-
*
|
|
3072
|
-
*
|
|
3073
|
-
*
|
|
3074
|
-
*
|
|
3075
|
-
* página. `display` y `onClick` reciben el registro cargado.
|
|
3076
|
-
*/
|
|
3077
|
-
extraButtons?: DetailExtraButton[];
|
|
3078
|
-
/**
|
|
3079
|
-
* Footer record navigator: prev/next arrows (Alt+↑ / Alt+↓) that step through a list of
|
|
3080
|
-
* sibling records — e.g. the rows of the grid the drawer was opened from — without
|
|
3081
|
-
* closing the drawer. Omit it and no navigator renders.
|
|
3082
|
-
*/
|
|
3083
|
-
navigation?: DetailFormDrawerNavigation;
|
|
3084
|
-
/** Panel width. Defaults to `600`. */
|
|
3085
|
-
width?: number | string;
|
|
3086
|
-
/** Side the drawer slides in from. Defaults to `"right"`. */
|
|
3087
|
-
anchor?: DrawerProps["anchor"];
|
|
3088
|
-
/**
|
|
3089
|
-
* `"temporary"` (the default) floats over the page. `"docked"` takes its own space at
|
|
3090
|
-
* the side of the screen and shrinks the app instead of covering it, so the page behind
|
|
3091
|
-
* stays usable — see `MainDrawer_v2`.
|
|
3123
|
+
* A full page is no longer the whole viewport minus the sidebar — a docked side panel
|
|
3124
|
+
* takes its share of it — so the screen stopped being a good proxy for how much room
|
|
3125
|
+
* the fields actually have. Against the form they re-flow as that room changes, with
|
|
3126
|
+
* no re-render: the breakpoint ladder is CSS.
|
|
3092
3127
|
*
|
|
3093
|
-
*
|
|
3094
|
-
* is open, so a drawer that guards unsaved edits behind the backdrop no longer does.
|
|
3095
|
-
*/
|
|
3096
|
-
variant?: MainDrawerV2Props["variant"];
|
|
3097
|
-
/**
|
|
3098
|
-
* Let the user drag the drawer's inner edge to resize it. Forwarded to `MainDrawer_v2`
|
|
3099
|
-
* along with the four props below — see it for the full behaviour.
|
|
3100
|
-
*/
|
|
3101
|
-
resizable?: boolean;
|
|
3102
|
-
/** Smallest width the drag allows, in px. Defaults to `320`. */
|
|
3103
|
-
minWidth?: number;
|
|
3104
|
-
/** Largest width the drag allows, in px. Defaults to the viewport minus a margin. */
|
|
3105
|
-
maxWidth?: number;
|
|
3106
|
-
/**
|
|
3107
|
-
* Remember the dragged width under this `localStorage` key. Worth setting whenever the
|
|
3108
|
-
* drawer is remounted per record — a fresh mount otherwise forgets the drag.
|
|
3109
|
-
*/
|
|
3110
|
-
widthStorageKey?: string;
|
|
3111
|
-
/** Fires with the final dragged width in px, or `null` when a double click resets it. */
|
|
3112
|
-
onWidthChange?: (width: number | null) => void;
|
|
3113
|
-
/**
|
|
3114
|
-
* What the `size` breakpoints of the fields — and of the subsections themselves — resolve
|
|
3115
|
-
* against. Defaults to `"container"`: a drawer is narrow by construction, so viewport
|
|
3116
|
-
* breakpoints would pick the wide-screen value and cram the fields — and they would not
|
|
3117
|
-
* react to a drag either.
|
|
3128
|
+
* `"viewport"` restores MUI's own behaviour for a page that needs it.
|
|
3118
3129
|
* @see DetailFormProps.responsiveTo
|
|
3119
3130
|
*/
|
|
3120
3131
|
responsiveTo?: DetailFormProps["responsiveTo"];
|
|
3121
3132
|
/** @see DetailFormProps.containerBreakpoints */
|
|
3122
3133
|
containerBreakpoints?: DetailFormProps["containerBreakpoints"];
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3134
|
+
/**
|
|
3135
|
+
* Deja el renglón del título —con el estado y la barra de acciones— pegado al tope mientras
|
|
3136
|
+
* se scrollea la ficha. Las migas se recogen al llegar arriba, así que lo que se queda es
|
|
3137
|
+
* sólo lo que hace falta tener a la mano.
|
|
3138
|
+
*
|
|
3139
|
+
* Encendido por defecto: una ficha es larga y sus acciones viven arriba, así que sin esto
|
|
3140
|
+
* editar o abrir el historial obliga a volver al principio. Vale igual capturando —ahí lo
|
|
3141
|
+
* que queda a la mano es Guardar y Cancelar—, que es la otra mitad del mismo problema.
|
|
3142
|
+
*
|
|
3143
|
+
* Apagarlo tiene sentido en una ficha corta, donde el encabezado nunca se va. Se ignora
|
|
3144
|
+
* cuando no hay renglón de título donde poner las acciones (pantalla completa, o un
|
|
3145
|
+
* `pageHeader` propio que no lo reserve): ahí vuelven a la esquina flotante de siempre.
|
|
3146
|
+
* @default true
|
|
3147
|
+
*/
|
|
3148
|
+
stickyHeader?: boolean;
|
|
3149
|
+
slots?: {
|
|
3150
|
+
button?: ReactNode;
|
|
3126
3151
|
/**
|
|
3127
|
-
*
|
|
3128
|
-
*
|
|
3129
|
-
*
|
|
3152
|
+
* Acciones propias del registro, junto a las del armazón. En `"detail"` entran en la
|
|
3153
|
+
* barra de acciones; en alta y edición, como iconos al lado de Guardar.
|
|
3154
|
+
*
|
|
3155
|
+
* Las mismas se le pueden pasar al cajón de `DrawerGrid_v2` (`drawer.extraButtons`),
|
|
3156
|
+
* para que el registro traiga sus acciones se abra donde se abra.
|
|
3130
3157
|
*/
|
|
3131
|
-
|
|
3132
|
-
};
|
|
3133
|
-
slots?: {
|
|
3158
|
+
extraButtons?: DetailExtraButton[];
|
|
3134
3159
|
/**
|
|
3135
|
-
* Ruta al estado del registro —`"estado"`—,
|
|
3136
|
-
*
|
|
3160
|
+
* Ruta al estado del registro dentro del dato —`"estado"`—, que el backend manda como
|
|
3161
|
+
* `{ value, label }`: se lee la etiqueta y el código decide el color.
|
|
3137
3162
|
*
|
|
3138
|
-
* @see DetailPageV2Props.
|
|
3163
|
+
* @see DetailPageV2Props.slotProps.badge
|
|
3139
3164
|
*/
|
|
3140
3165
|
badge?: string;
|
|
3141
|
-
/** Extra actions rendered in the header, left of the close button (e.g. "open full page"). */
|
|
3142
|
-
headerActions?: ReactNode;
|
|
3143
3166
|
};
|
|
3144
3167
|
slotProps?: {
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3168
|
+
button?: {
|
|
3169
|
+
save?: {
|
|
3170
|
+
type: "onClick";
|
|
3171
|
+
disableNavBack?: boolean;
|
|
3172
|
+
onClick?: () => void;
|
|
3173
|
+
};
|
|
3174
|
+
cancel?: Partial<ButtonProps>;
|
|
3175
|
+
};
|
|
3176
|
+
/**
|
|
3177
|
+
* The history panel opened from the actions bar. It docks beside the page rather
|
|
3178
|
+
* than floating over it, so the record stays readable next to what the history says
|
|
3179
|
+
* about it — see `DetailActionsProps.historial` for how to change that.
|
|
3180
|
+
*/
|
|
3181
|
+
historial?: DetailActionsProps["historial"];
|
|
3182
|
+
permissionsPath?: string;
|
|
3183
|
+
deleteButton?: {
|
|
3184
|
+
disableNavBack?: boolean;
|
|
3185
|
+
};
|
|
3150
3186
|
badge?: {
|
|
3187
|
+
/**
|
|
3188
|
+
* De qué color se pinta cada estado, por código:
|
|
3189
|
+
*
|
|
3190
|
+
* colors: { "1": "warning", "2": "info", "3": "success" }
|
|
3191
|
+
*
|
|
3192
|
+
* Es el mismo mapa que recibe `renderChipCell` en las columnas de una tabla, así que
|
|
3193
|
+
* lo natural es declararlo junto al catálogo y pasarlo a los dos: el estado "2" se ve
|
|
3194
|
+
* igual en la lista que en la ficha.
|
|
3195
|
+
*
|
|
3196
|
+
* Sin mapa la insignia queda neutra —gris—, que es como se veían todos antes de que
|
|
3197
|
+
* hubiera con qué distinguirlos.
|
|
3198
|
+
*/
|
|
3151
3199
|
colors?: Record<string, StatusColor>;
|
|
3152
|
-
/**
|
|
3200
|
+
/**
|
|
3201
|
+
* Los estados con su rótulo, para poder mostrarlo en otro idioma.
|
|
3202
|
+
*
|
|
3203
|
+
* Es el mismo `ChipOption[]` que reciben las columnas de la tabla, y se resuelve
|
|
3204
|
+
* igual (`resolveChipOption`), así que la ficha y la lista nombran el estado con la
|
|
3205
|
+
* misma palabra. Sin esto, la insignia sólo puede repetir lo que mandó el backend,
|
|
3206
|
+
* que viene en español (`get_estado_display`).
|
|
3207
|
+
*
|
|
3208
|
+
* Ojo con traducir el `label` de una opción: casi todos estos endpoints mandan la
|
|
3209
|
+
* etiqueta y no el código, así que el emparejado real es contra el texto en español
|
|
3210
|
+
* — para eso está `ChipOption.match`.
|
|
3211
|
+
*/
|
|
3153
3212
|
options?: ChipOption[];
|
|
3154
3213
|
};
|
|
3155
3214
|
};
|
|
3156
3215
|
}
|
|
3216
|
+
declare function DetailPage(props: DetailPageV2Props): react_jsx_runtime.JSX.Element;
|
|
3217
|
+
|
|
3218
|
+
type ConfiguracionDeInsignia = NonNullable<NonNullable<DetailPageV2Props["slotProps"]>["badge"]>;
|
|
3157
3219
|
/**
|
|
3158
|
-
*
|
|
3159
|
-
* `
|
|
3160
|
-
* the form exactly like every other v2 drawer. What it adds on top is the per-record
|
|
3161
|
-
* furniture: edit/delete in the header — plus the record's own actions, when the consumer
|
|
3162
|
-
* hands them over in `extraButtons`, in a "⋮" menu beside them — and a footer holding the
|
|
3163
|
-
* form actions and, when
|
|
3164
|
-
* `navigation` is given, a prev/next record navigator (Alt+↑ / Alt+↓) plus "Guardar ↓"
|
|
3165
|
-
* (Alt+Shift+↓) — a save that steps to the next record instead of closing, so a column can be
|
|
3166
|
-
* captured down a list in one pass without the hands leaving the keyboard. Rename it with
|
|
3167
|
-
* `labels.saveAndNext`. Guardar sits outside the `<form>` and submits via the native
|
|
3168
|
-
* `form={formId}` attribute; Guardar ↓ submits by hand, so the implicit Enter stays Guardar.
|
|
3220
|
+
* La insignia de estado junto al título de la ficha: exactamente `slots.badge` y
|
|
3221
|
+
* `slotProps.badge` de `DetailPage_v2`, y nada más.
|
|
3169
3222
|
*
|
|
3170
|
-
*
|
|
3171
|
-
*
|
|
3172
|
-
*
|
|
3223
|
+
* Es un hueco y no algo fijo porque qué estado enseñar —y con qué colores— depende de lo que
|
|
3224
|
+
* mande el backend de cada app. Vale la pena cuando lo manda: si la baja es lógica, "está dado de
|
|
3225
|
+
* baja" es un estado del registro y no su ausencia, y un catálogo desactivado se ve igual que uno
|
|
3226
|
+
* vivo hasta que alguien nota que dejó de aparecer en los selectores.
|
|
3227
|
+
*
|
|
3228
|
+
* **No apuntes `slots.badge` a `activo`.** La insignia no se dibuja cuando lo que encuentra es
|
|
3229
|
+
* falso, así que apuntarla al booleano la haría salir sólo en los registros vivos y desaparecer
|
|
3230
|
+
* en los dados de baja — al revés de para lo que sirve. Apúntala a un campo que el backend mande
|
|
3231
|
+
* en los dos casos, como `{ value, label }` o como cadena.
|
|
3232
|
+
*
|
|
3233
|
+
* Sólo se pinta en modo detalle. Son estas dos props y no las de `DetailPage_v2` en general
|
|
3234
|
+
* porque un comodín sería justo el lugar donde se esconden los casos especiales (ver
|
|
3235
|
+
* `DefinicionDeCatalogo`).
|
|
3173
3236
|
*/
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
form: DetailFormConfig["form"];
|
|
3179
|
-
sections: DetailFormConfig["sections"];
|
|
3180
|
-
permissionsPath?: string;
|
|
3181
|
-
/** Panel width. Defaults to the drawer's own default (600). */
|
|
3182
|
-
width?: number | string;
|
|
3183
|
-
/**
|
|
3184
|
-
* How the panel sits on the screen. Defaults to `"temporary"`: it floats over the page,
|
|
3185
|
-
* modal, the way it always has.
|
|
3186
|
-
*
|
|
3187
|
-
* `"docked"` gives it its own space at the side and shrinks the app instead of covering
|
|
3188
|
-
* it, so the grid stays visible next to the record. Worth it where the row and the list
|
|
3189
|
-
* are read together; it costs two things, both from dropping the modal:
|
|
3190
|
-
*
|
|
3191
|
-
* - Nothing stops the user from re-sorting, filtering or paging the grid while the
|
|
3192
|
-
* drawer is open, and the footer navigator walks the rows it sampled when the record
|
|
3193
|
-
* opened. It stays on the list the user was reading, which is usually what's wanted,
|
|
3194
|
-
* but it can no longer claim to match what's on screen.
|
|
3195
|
-
* - Unsaved edits are no longer fenced off by the backdrop.
|
|
3196
|
-
*/
|
|
3197
|
-
variant?: DetailFormDrawerProps["variant"];
|
|
3198
|
-
/**
|
|
3199
|
-
* Let the user drag the drawer's inner edge to resize it. The dragged width is remembered
|
|
3200
|
-
* across openings under a key derived from the grid's own storage key — override it with
|
|
3201
|
-
* `widthStorageKey`, or turn the memory off by passing an empty string.
|
|
3202
|
-
*/
|
|
3203
|
-
resizable?: boolean;
|
|
3204
|
-
/** Smallest width the drag allows, in px. Defaults to `320`. */
|
|
3205
|
-
minWidth?: number;
|
|
3206
|
-
/** Largest width the drag allows, in px. Defaults to the viewport minus a margin. */
|
|
3207
|
-
maxWidth?: number;
|
|
3208
|
-
/** Where the dragged width is remembered. Defaults to the grid's storage key + `_DW`. */
|
|
3209
|
-
widthStorageKey?: string;
|
|
3210
|
-
/**
|
|
3211
|
-
* What the fields' `size` breakpoints resolve against. Defaults to `"container"` — the
|
|
3212
|
-
* width of the panel, not of the screen.
|
|
3213
|
-
* @see DetailFormDrawerProps.responsiveTo
|
|
3214
|
-
*/
|
|
3215
|
-
responsiveTo?: DetailFormDrawerProps["responsiveTo"];
|
|
3216
|
-
/** @see DetailFormDrawerProps.containerBreakpoints */
|
|
3217
|
-
containerBreakpoints?: DetailFormDrawerProps["containerBreakpoints"];
|
|
3218
|
-
title?: {
|
|
3219
|
-
create?: ReactNode;
|
|
3220
|
-
record?: ReactNode | ((id: GridRowId) => ReactNode);
|
|
3221
|
-
};
|
|
3222
|
-
/** Create-mode API (opened by the "Quick create" menu option). */
|
|
3223
|
-
create: {
|
|
3224
|
-
mutation: any;
|
|
3225
|
-
/** Defaults to `"create"`. */
|
|
3226
|
-
pageType?: PageType;
|
|
3227
|
-
successMessage?: string | ((response: any) => string);
|
|
3237
|
+
interface InsigniaDeCatalogo {
|
|
3238
|
+
slots: {
|
|
3239
|
+
/** Ruta al estado dentro del detalle: `slots.badge` de `DetailPage_v2`. */
|
|
3240
|
+
badge: string;
|
|
3228
3241
|
};
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
query: any;
|
|
3233
|
-
mutation: any;
|
|
3234
|
-
/**
|
|
3235
|
-
* Defaults to `"detail"` (read-only), matching a row-click. Use `"edit"` for an always
|
|
3236
|
-
* editable drawer — a `"detail"` drawer already opens editing while the grid itself is
|
|
3237
|
-
* in edit mode.
|
|
3238
|
-
*/
|
|
3239
|
-
pageType?: PageType;
|
|
3240
|
-
successMessage?: string | ((response: any) => string);
|
|
3241
|
-
/** Extra query args merged with `{ id }`. */
|
|
3242
|
-
args?: (id: GridRowId) => Record<string, any>;
|
|
3243
|
-
/** Optional delete mutation. When set and the user has delete permission, a delete button appears in the drawer header. */
|
|
3244
|
-
delete?: {
|
|
3245
|
-
mutation: any;
|
|
3246
|
-
};
|
|
3242
|
+
slotProps?: {
|
|
3243
|
+
/** Colores y rótulos por código: `slotProps.badge` de `DetailPage_v2`. */
|
|
3244
|
+
badge?: ConfiguracionDeInsignia;
|
|
3247
3245
|
};
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3246
|
+
}
|
|
3247
|
+
interface CatalogoItemProps {
|
|
3248
|
+
definicion: DefinicionDeCatalogo;
|
|
3249
|
+
api: CatalogoAPI;
|
|
3250
|
+
type: PageType;
|
|
3251
|
+
/** La insignia de estado junto al título. Sin ella, la ficha no lleva ninguna. */
|
|
3252
|
+
insignia?: InsigniaDeCatalogo;
|
|
3253
|
+
}
|
|
3254
|
+
/**
|
|
3255
|
+
* El alta, detalle y edición de un catálogo simple.
|
|
3256
|
+
*
|
|
3257
|
+
* `codigo` y `nombre` son obligatorios; `descripcion` es libre y `activo` es la baja lógica —un
|
|
3258
|
+
* catálogo referenciado no se borra, se desactiva, y el backend lo refleja en el
|
|
3259
|
+
* `obj_permissions.delete` del detalle a partir de `deletable`—. El botón de borrar lo pinta o no
|
|
3260
|
+
* `DetailPage_v2` con ese `obj_permissions`, así que aquí no hay nada que decidir.
|
|
3261
|
+
*/
|
|
3262
|
+
declare const CatalogoItem: ({ definicion, api, type, insignia }: CatalogoItemProps) => react_jsx_runtime.JSX.Element;
|
|
3263
|
+
|
|
3264
|
+
interface KpiCardProps {
|
|
3265
|
+
icon: ReactNode;
|
|
3266
|
+
label: string;
|
|
3267
|
+
value: ReactNode;
|
|
3268
|
+
caption?: string;
|
|
3269
|
+
color?: string;
|
|
3270
|
+
/** Variante tipográfica del valor. Por defecto `h4`; usa `h5` cuando el valor es
|
|
3271
|
+
* largo o hay muchas tarjetas por fila. */
|
|
3272
|
+
valueVariant?: TypographyProps["variant"];
|
|
3273
|
+
isLoading: boolean;
|
|
3274
|
+
}
|
|
3275
|
+
/** Tarjeta de KPI: ícono + etiqueta, un valor destacado y una leyenda opcional.
|
|
3276
|
+
* Muestra un esqueleto mientras se cargan los datos. */
|
|
3277
|
+
declare function KpiCard({ icon, label, value, caption, color, valueVariant, isLoading, }: KpiCardProps): react_jsx_runtime.JSX.Element;
|
|
3278
|
+
|
|
3279
|
+
interface PanelProps {
|
|
3280
|
+
/** Ícono a la izquierda del título (típicamente `color="action" fontSize="small"`). */
|
|
3281
|
+
icon?: ReactNode;
|
|
3282
|
+
/** Título del encabezado. Si se omite (y no hay ícono ni acción), no se renderiza encabezado. */
|
|
3283
|
+
title?: ReactNode;
|
|
3284
|
+
/** Contenido alineado a la derecha del encabezado (chips, botones, etc.). */
|
|
3285
|
+
action?: ReactNode;
|
|
3286
|
+
/** Región entre el encabezado y el divisor, p. ej. un `<Tabs>`. */
|
|
3287
|
+
tabs?: ReactNode;
|
|
3288
|
+
/** Muestra un divisor bajo el encabezado/tabs. Por defecto `true`. */
|
|
3289
|
+
divider?: boolean;
|
|
3290
|
+
/** Altura del contenedor. Con un número (px) el contenido ocupa el espacio
|
|
3291
|
+
* restante y hace scroll; con `"100%"` solo iguala la altura de la columna. */
|
|
3292
|
+
height?: number | string;
|
|
3293
|
+
/** Estilos adicionales para el `Paper`. */
|
|
3294
|
+
sx?: SxProps<Theme>;
|
|
3295
|
+
children?: ReactNode;
|
|
3296
|
+
}
|
|
3297
|
+
/** Contenedor estándar de panel: `Paper` con encabezado (ícono + título + acción),
|
|
3298
|
+
* divisor opcional y contenido. Unifica el aspecto de los paneles del dashboard. */
|
|
3299
|
+
declare function Panel({ icon, title, action, tabs, divider, height, sx, children }: PanelProps): react_jsx_runtime.JSX.Element;
|
|
3300
|
+
|
|
3301
|
+
interface PollingCountdownChipProps {
|
|
3302
|
+
pollingInterval: number;
|
|
3303
|
+
isFetching: boolean;
|
|
3304
|
+
onRefresh?: () => void;
|
|
3305
|
+
}
|
|
3306
|
+
/** Chip con cuenta regresiva hasta el próximo refresco de un polling. Al terminar cada
|
|
3307
|
+
* fetch reinicia el conteo; opcionalmente refresca al hacer clic. */
|
|
3308
|
+
declare function PollingCountdownChip({ pollingInterval, isFetching, onRefresh, }: PollingCountdownChipProps): react_jsx_runtime.JSX.Element;
|
|
3309
|
+
|
|
3310
|
+
/**
|
|
3311
|
+
* Server-mode DataGrid: pagination, sorting and filtering all resolved by the backend, with
|
|
3312
|
+
* optional create / edit / delete modes layered on top.
|
|
3313
|
+
*
|
|
3314
|
+
* The optional modes are real components wrapping the grid, so each one's hooks belong to it
|
|
3315
|
+
* rather than to this component. That is the difference from v1, where the wrappers were
|
|
3316
|
+
* called as plain functions and their hooks landed in the grid's own hook list — a page that
|
|
3317
|
+
* built `api.edit` conditionally would then change React's hook order and crash.
|
|
3318
|
+
*/
|
|
3319
|
+
declare function ServerGrid(props: ServerGridProps): react_jsx_runtime.JSX.Element;
|
|
3320
|
+
|
|
3321
|
+
interface ExportCSVProps {
|
|
3322
|
+
handleClick: () => void;
|
|
3323
|
+
filterModel: MyGridFilterModel;
|
|
3324
|
+
sortModel: GridSortModel;
|
|
3325
|
+
rowSelectionModel: GridRowSelectionModel;
|
|
3326
|
+
/** The scoping the grid queries with. Without it an export exceeds what the grid shows. */
|
|
3327
|
+
queryArgs?: ServerGridArgs;
|
|
3328
|
+
disabledWithoutSelection?: boolean;
|
|
3329
|
+
/** Rows the current filters match, for the count shown in the picker. */
|
|
3330
|
+
rowCount?: number;
|
|
3331
|
+
ignore?: {
|
|
3332
|
+
filters?: string[];
|
|
3333
|
+
sort?: boolean;
|
|
3277
3334
|
};
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
* shortcuts, which would otherwise navigate to a route that isn't registered.
|
|
3286
|
-
*/
|
|
3287
|
-
showOpenFullPage?: boolean;
|
|
3288
|
-
/**
|
|
3289
|
-
* Show the footer navigator that walks the grid's rows — prev/next arrows plus the
|
|
3290
|
-
* record's position — in the record drawer. Defaults to `true`.
|
|
3291
|
-
*
|
|
3292
|
-
* It also gates "Guardar ↓", the save that steps to the next row instead of closing:
|
|
3293
|
-
* without a list to walk there is nothing to continue to.
|
|
3294
|
-
*/
|
|
3295
|
-
showNavigator?: boolean;
|
|
3296
|
-
/**
|
|
3297
|
-
* Guardar deja el cajón abierto y editando en vez de cerrarlo; se cierra con la X o con
|
|
3298
|
-
* Cancelar. Para registros que se capturan de a poco, o que llevan su propia grilla
|
|
3299
|
-
* editable adentro y perderían el lugar al cerrarse.
|
|
3300
|
-
*
|
|
3301
|
-
* @see DetailFormDrawerProps.keepOpenOnSave
|
|
3302
|
-
*/
|
|
3303
|
-
keepOpenOnSave?: boolean;
|
|
3304
|
-
/** Rótulos del pie del cajón. `saveAndNext` por defecto es `"Guardar ↓"`. */
|
|
3305
|
-
labels?: {
|
|
3306
|
-
save?: string;
|
|
3307
|
-
cancel?: string;
|
|
3308
|
-
saveAndNext?: string;
|
|
3335
|
+
slots?: {
|
|
3336
|
+
endpoint?: string;
|
|
3337
|
+
title?: string;
|
|
3338
|
+
variant?: string;
|
|
3339
|
+
column_key?: string;
|
|
3340
|
+
/** Opens the column picker instead of downloading straight away. Defaults to on. */
|
|
3341
|
+
columnPicker?: boolean;
|
|
3309
3342
|
};
|
|
3310
3343
|
}
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3344
|
+
/**
|
|
3345
|
+
* Downloads the whole filtered result set as CSV — the server rebuilds it from the filters,
|
|
3346
|
+
* so this is never limited to the rows currently on screen.
|
|
3347
|
+
*/
|
|
3348
|
+
declare function ExportCSV(props: ExportCSVProps): react_jsx_runtime.JSX.Element;
|
|
3349
|
+
|
|
3350
|
+
interface UseServerGridOptions {
|
|
3351
|
+
/** Where this grid's state is remembered. Fixed for the lifetime of the mount. */
|
|
3352
|
+
storageKey: string;
|
|
3353
|
+
dontSaveState?: boolean;
|
|
3354
|
+
/** RTK Query lazy hook, e.g. `useLazyGetConceptosQuery`. */
|
|
3355
|
+
query: any;
|
|
3356
|
+
/** Extra query args, deep-compared — object literals are safe. */
|
|
3357
|
+
args?: any;
|
|
3358
|
+
/** Passed to the lazy hook (`{ pollingInterval }`, …). Also deep-compared. */
|
|
3359
|
+
queryOptions?: {
|
|
3360
|
+
[key: string]: any;
|
|
3361
|
+
};
|
|
3362
|
+
initialState?: MyDataGridProps["initialState"];
|
|
3363
|
+
columns?: readonly GridColDef[];
|
|
3321
3364
|
}
|
|
3322
|
-
interface
|
|
3365
|
+
interface ServerGridPermissions {
|
|
3366
|
+
create?: boolean;
|
|
3367
|
+
edit?: boolean;
|
|
3368
|
+
delete?: boolean;
|
|
3369
|
+
}
|
|
3370
|
+
interface ServerGridState {
|
|
3371
|
+
apiRef: ReturnType<typeof useGridApiRef>;
|
|
3372
|
+
rows: readonly any[];
|
|
3373
|
+
rowCount: number;
|
|
3374
|
+
permissions: ServerGridPermissions;
|
|
3375
|
+
isLoading: boolean;
|
|
3376
|
+
isFetching: boolean;
|
|
3377
|
+
isError: boolean;
|
|
3378
|
+
paginationModel: GridPaginationModel;
|
|
3379
|
+
setPaginationModel: Dispatch<SetStateAction<GridPaginationModel>>;
|
|
3380
|
+
sortModel: GridSortModel;
|
|
3381
|
+
setSortModel: Dispatch<SetStateAction<GridSortModel>>;
|
|
3382
|
+
filterModel: MyGridFilterModel;
|
|
3383
|
+
setFilterModel: Dispatch<SetStateAction<MyGridFilterModel>>;
|
|
3384
|
+
columnVisibilityModel: GridColumnVisibilityModel;
|
|
3385
|
+
setColumnVisibilityModel: Dispatch<SetStateAction<GridColumnVisibilityModel>>;
|
|
3386
|
+
rowSelectionModel: GridRowSelectionModel;
|
|
3387
|
+
setRowSelectionModel: Dispatch<SetStateAction<GridRowSelectionModel>>;
|
|
3388
|
+
/** Debounced quick-search setter. Cancelled on unmount. */
|
|
3389
|
+
setQuickSearchValue: DebouncedFunc<(value: string) => void>;
|
|
3390
|
+
/** Toolbar collapse, hoisted here so shortcuts can reopen a collapsed toolbar. */
|
|
3391
|
+
toolbarExpanded: boolean;
|
|
3392
|
+
setToolbarExpanded: Dispatch<SetStateAction<boolean>>;
|
|
3323
3393
|
/**
|
|
3324
|
-
*
|
|
3325
|
-
*
|
|
3326
|
-
*
|
|
3327
|
-
* mutation and no columns, because everything that writes goes through the drawer form.
|
|
3394
|
+
* Whether the filter panel is showing. Up here rather than in the toolbar because the
|
|
3395
|
+
* docked panel is a sibling of the grid, not a child of the button that opens it — and
|
|
3396
|
+
* because Ctrl+Shift+F has to reach it from a collapsed toolbar either way.
|
|
3328
3397
|
*/
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
drawer: DrawerGridDrawerConfig;
|
|
3398
|
+
filtersOpen: boolean;
|
|
3399
|
+
setFiltersOpen: Dispatch<SetStateAction<boolean>>;
|
|
3400
|
+
/** Exactly what was last sent to the server. Also feeds the CSV export. */
|
|
3401
|
+
args: ServerGridArgs;
|
|
3402
|
+
refetch: () => void;
|
|
3403
|
+
subscribeRows: (callback: (snapshot: RowsSnapshot) => void) => () => void;
|
|
3336
3404
|
}
|
|
3337
3405
|
/**
|
|
3338
|
-
*
|
|
3339
|
-
*
|
|
3340
|
-
*
|
|
3341
|
-
*
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
*
|
|
3354
|
-
*
|
|
3355
|
-
* `drawer.showNavigator: false`.
|
|
3356
|
-
*
|
|
3357
|
-
* Editing a list that way gets a third footer button, "Guardar ↓" / Alt+Shift+↓ (rename it
|
|
3358
|
-
* with `drawer.labels.saveAndNext`): it saves and steps to the next row instead of closing,
|
|
3359
|
-
* carrying the edit mode over, so capturing a column across many rows is one pass rather than
|
|
3360
|
-
* open-edit-save-reopen per row — and with the shortcut, without leaving the keyboard. It
|
|
3361
|
-
* rides on the navigator — no navigator, or last row, and there is just Guardar.
|
|
3362
|
-
*
|
|
3363
|
-
* `drawer.keepOpenOnSave` hace que Guardar no cierre: el registro se queda en pantalla y
|
|
3364
|
-
* editando. Vale la pena donde el cajón lleva su propia grilla adentro —cerrarlo se lleva
|
|
3365
|
-
* también lo que se estaba capturando ahí— o donde el registro se llena en varias pasadas.
|
|
3366
|
-
*
|
|
3367
|
-
* Edit mode is opt-in with `api.edit: {}` and adds nothing to the grid but a toolbar toggle —
|
|
3368
|
-
* no mutation, no actions column, no in-grid editing. While it's on, a row click opens the
|
|
3369
|
-
* record drawer already editing, provided the record allows it; the drawer form is the only
|
|
3370
|
-
* thing that writes. A grid embedded in a detail form can hand the mode over instead, with
|
|
3371
|
-
* `api.edit: { active: pageType === "edit" }`, so it follows the form rather than asking for
|
|
3372
|
-
* a second switch.
|
|
3406
|
+
* Everything a server-mode grid needs to hold: the models the user drives, the persisted
|
|
3407
|
+
* state they start from, and the lazy query that keeps rows in step with them. Renders
|
|
3408
|
+
* nothing — `ServerGrid` supplies it through context, and pages that need a shape the grid
|
|
3409
|
+
* doesn't offer can drive their own `DataGrid` from it.
|
|
3410
|
+
*/
|
|
3411
|
+
declare function useServerGrid(options: UseServerGridOptions): ServerGridState;
|
|
3412
|
+
|
|
3413
|
+
interface ComposeGridPropsInput {
|
|
3414
|
+
/** The grid's own baseline — slots, locale, density. */
|
|
3415
|
+
defaults: Partial<MyDataGridProps>;
|
|
3416
|
+
layers: GridLayerMap;
|
|
3417
|
+
/** `props.dataGridProps`, straight from the page. */
|
|
3418
|
+
consumer?: Partial<MyDataGridProps>;
|
|
3419
|
+
}
|
|
3420
|
+
/**
|
|
3421
|
+
* Flattens the grid defaults, every mounted layer and the consumer's own props into one
|
|
3422
|
+
* `DataGrid` prop object.
|
|
3373
3423
|
*
|
|
3374
|
-
*
|
|
3375
|
-
*
|
|
3424
|
+
* Precedence, low to high:
|
|
3425
|
+
* 1. grid defaults
|
|
3426
|
+
* 2. layer `defaults`, in `LAYER_ORDER`
|
|
3427
|
+
* 3. the consumer's `dataGridProps`
|
|
3428
|
+
* 4. layer `overrides`, in `LAYER_ORDER`
|
|
3376
3429
|
*
|
|
3377
|
-
*
|
|
3378
|
-
*
|
|
3379
|
-
*
|
|
3430
|
+
* Tier 4 sits above the consumer on purpose — a layer must be able to force the grid into a
|
|
3431
|
+
* coherent state while its mode is on (no checkboxes and no row navigation while rows are
|
|
3432
|
+
* being deleted). It is only ever allowed to publish mode-*on* values there; see
|
|
3433
|
+
* `GridLayerContribution.overrides`.
|
|
3380
3434
|
*/
|
|
3381
|
-
declare function
|
|
3435
|
+
declare function composeGridProps({ defaults, layers, consumer, }: ComposeGridPropsInput): Partial<MyDataGridProps>;
|
|
3382
3436
|
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3437
|
+
/**
|
|
3438
|
+
* Columns the user is allowed to hide.
|
|
3439
|
+
*
|
|
3440
|
+
* v1 excluded `"actions"` by *field*, but that is a column **type** — the real action columns
|
|
3441
|
+
* are `edit` and `delete`, so both showed up in the columns panel and could be hidden (and
|
|
3442
|
+
* persisted hidden) out from under the layer that owns them. Matched on both here.
|
|
3443
|
+
*/
|
|
3444
|
+
declare const togglableFields: (columns?: readonly GridColDef[]) => string[];
|
|
3445
|
+
interface ResolvedGridState {
|
|
3446
|
+
paginationModel: GridPaginationModel;
|
|
3447
|
+
sortModel: GridSortModel;
|
|
3448
|
+
filterModel: MyGridFilterModel;
|
|
3449
|
+
columnVisibilityModel: GridColumnVisibilityModel;
|
|
3394
3450
|
}
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
active: boolean;
|
|
3402
|
-
/** Color cuando no está activo. Por defecto `error.main`. */
|
|
3403
|
-
inactiveColor?: string;
|
|
3404
|
-
/** Tamaño del punto en px. Por defecto 10. */
|
|
3405
|
-
size?: number;
|
|
3406
|
-
/** Título opcional; si se pasa, envuelve el punto en un Tooltip. */
|
|
3407
|
-
title?: ReactNode;
|
|
3451
|
+
interface ResolveInitialStateInput {
|
|
3452
|
+
storageKey: string;
|
|
3453
|
+
/** `slotProps.dontSaveState` — skip the session store entirely. */
|
|
3454
|
+
disabled?: boolean;
|
|
3455
|
+
initialState?: MyDataGridProps["initialState"];
|
|
3456
|
+
columns?: readonly GridColDef[];
|
|
3408
3457
|
}
|
|
3409
|
-
/** Punto de estado: verde con animación de parpadeo cuando está activo, de lo
|
|
3410
|
-
* contrario un color fijo. Se usa para indicar conexión/actividad en vivo. */
|
|
3411
|
-
declare function PulseDot({ active, inactiveColor, size, title }: PulseDotProps): react_jsx_runtime.JSX.Element;
|
|
3412
|
-
|
|
3413
3458
|
/**
|
|
3414
|
-
*
|
|
3415
|
-
*
|
|
3459
|
+
* Works out the state a grid starts in, from what the session remembers and what the page
|
|
3460
|
+
* declared. The only place that precedence lives.
|
|
3416
3461
|
*
|
|
3417
|
-
*
|
|
3418
|
-
*
|
|
3419
|
-
* un solo nombre esa regla se escribe una vez y sirve en los tres sitios: cada cosa mide contra
|
|
3420
|
-
* 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
|
|
3421
|
-
* es el del cajón. Los breakpoints del viewport no sabrían distinguirlos —la pantalla es la
|
|
3422
|
-
* misma— y `@container` sí.
|
|
3462
|
+
* Pagination, sorting and column visibility prefer the **session**: those are the user's own
|
|
3463
|
+
* choices and should survive navigating away and back.
|
|
3423
3464
|
*
|
|
3424
|
-
*
|
|
3425
|
-
*
|
|
3426
|
-
*
|
|
3465
|
+
* Filters are the exception — the page's `initialState.filters` wins, key by key. Those
|
|
3466
|
+
* express scoping ("this embarque's recibos"), not preference, and in v1 the session beat
|
|
3467
|
+
* them outright, so a grid opened on record B kept showing record A's rows for the rest of
|
|
3468
|
+
* the session. Pages worked around it by repeating the same filter in `api.data.args`; they
|
|
3469
|
+
* no longer have to. A user-set filter on any *other* key still survives.
|
|
3427
3470
|
*/
|
|
3428
|
-
declare
|
|
3471
|
+
declare function resolveInitialState({ storageKey, disabled, initialState, columns, }: ResolveInitialStateInput): ResolvedGridState;
|
|
3472
|
+
|
|
3429
3473
|
/**
|
|
3430
|
-
*
|
|
3431
|
-
*
|
|
3432
|
-
*
|
|
3433
|
-
* Se escribe como regla y no como número suelto para que quien la use no tenga que rearmar la
|
|
3434
|
-
* consulta —ni equivocarse al hacerlo—:
|
|
3474
|
+
* Page sizes offered by the grid and by the pagination slot. One list: in v1 the grid and
|
|
3475
|
+
* `CustomPagination` each declared their own copy and had to be kept in sync by hand.
|
|
3435
3476
|
*
|
|
3436
|
-
*
|
|
3477
|
+
* `-1` is "all" — the backends read that literal and return the whole result set with
|
|
3478
|
+
* `next`/`previous` null but a correct `count`. Only its label is translated; the value is wire
|
|
3479
|
+
* protocol and never changes.
|
|
3437
3480
|
*/
|
|
3438
|
-
declare const
|
|
3481
|
+
declare const pageSizeOptions: (etiquetaTodos: string) => (number | {
|
|
3482
|
+
value: number;
|
|
3483
|
+
label: string;
|
|
3484
|
+
})[];
|
|
3485
|
+
declare const DEFAULT_PAGINATION: GridPaginationModel;
|
|
3439
3486
|
/**
|
|
3440
|
-
*
|
|
3441
|
-
*
|
|
3442
|
-
*
|
|
3443
|
-
* encabezado, que crece con lo que lleva dentro —un subtítulo, un título en dos renglones—.
|
|
3487
|
+
* The order layer contributions are applied in — columns, toolbar buttons and prop overrides
|
|
3488
|
+
* alike. Declared here so it never depends on how the layers happen to nest, which is what
|
|
3489
|
+
* made the delete column's position accidental in v1.
|
|
3444
3490
|
*/
|
|
3445
|
-
declare const
|
|
3491
|
+
declare const LAYER_ORDER: readonly GridLayerId[];
|
|
3446
3492
|
|
|
3493
|
+
interface DeleteGridColumnsProps {
|
|
3494
|
+
displayDelete?: boolean;
|
|
3495
|
+
handleOpen: (id: GridRowId) => () => void;
|
|
3496
|
+
/**
|
|
3497
|
+
* Rótulo de la columna y de la acción. Es un parámetro y no un `useTextos()` porque esto no
|
|
3498
|
+
* es un componente: lo llama la capa de borrado, que sí es la que tiene el idioma a mano.
|
|
3499
|
+
* El default en español mantiene andando a quien la llame sin pasarlo.
|
|
3500
|
+
*/
|
|
3501
|
+
etiqueta?: string;
|
|
3502
|
+
}
|
|
3447
3503
|
/**
|
|
3448
|
-
*
|
|
3449
|
-
* etiqueta, las mismas sólo con el icono, sólo las fijadas, o ninguna.
|
|
3450
|
-
*
|
|
3451
|
-
* El modo dice qué se dibuja *fuera* del menú; lo que quede fuera de eso —y lo que sobre del
|
|
3452
|
-
* tope de `maxVisible`— está siempre dentro de él, así que hasta en `"full"` puede haber menú.
|
|
3504
|
+
* The per-row delete action, shown only while delete mode is on.
|
|
3453
3505
|
*
|
|
3454
|
-
* `
|
|
3455
|
-
*
|
|
3506
|
+
* v1 left `type` off, so the column defaulted to `string`: sortable by a user, and offered in
|
|
3507
|
+
* the filters panel as an "Eliminar" text filter that meant nothing. Declaring `type: "actions"`
|
|
3508
|
+
* fixes both — but it has to come with `getActions` rather than `renderCell`, because an
|
|
3509
|
+
* explicit `renderCell` beats the actions type's own cell and takes its keyboard handling and
|
|
3510
|
+
* overflow menu with it.
|
|
3456
3511
|
*/
|
|
3457
|
-
declare const
|
|
3458
|
-
|
|
3459
|
-
interface
|
|
3460
|
-
/**
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3512
|
+
declare const deleteColumn: (props: DeleteGridColumnsProps) => GridColDefPropsOverrides[];
|
|
3513
|
+
|
|
3514
|
+
interface DetailFormDrawerNavigation {
|
|
3515
|
+
/** Open the previous record of the list the drawer is walking. */
|
|
3516
|
+
onPrev: () => void;
|
|
3517
|
+
onNext: () => void;
|
|
3518
|
+
/** Whether a previous/next record exists. The arrows are disabled when it doesn't. */
|
|
3519
|
+
hasPrev: boolean;
|
|
3520
|
+
hasNext: boolean;
|
|
3521
|
+
/** 1-based position of the current record, shown between the arrows. */
|
|
3522
|
+
position?: number;
|
|
3523
|
+
/** Size of the list; shown as `position / count`. */
|
|
3524
|
+
count?: number;
|
|
3525
|
+
/** Blocks both arrows for a caller-side reason (e.g. while the next batch loads). */
|
|
3467
3526
|
disabled?: boolean;
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3527
|
+
}
|
|
3528
|
+
interface DetailFormDrawerProps {
|
|
3529
|
+
open: boolean;
|
|
3530
|
+
/** Close the drawer. Also invoked after a successful save and on cancel. */
|
|
3531
|
+
onClose: () => void;
|
|
3532
|
+
title?: ReactNode;
|
|
3533
|
+
api: DetailFormApi;
|
|
3534
|
+
form: DetailFormConfig["form"];
|
|
3535
|
+
sections: DetailFormConfig["sections"];
|
|
3536
|
+
/** Defaults to `"create"`. */
|
|
3537
|
+
pageType?: PageType;
|
|
3472
3538
|
/**
|
|
3473
|
-
*
|
|
3474
|
-
*
|
|
3475
|
-
* ficha); fijar media barra no sirve de mucho, porque entonces ese escalón acaba pesando casi
|
|
3476
|
-
* lo mismo que el anterior y se salta solo.
|
|
3539
|
+
* Open a `"detail"` drawer straight in edit mode, as if the user had hit the Editar
|
|
3540
|
+
* button. Ignored for the other page types, and for records the user may not edit.
|
|
3477
3541
|
*/
|
|
3478
|
-
|
|
3479
|
-
}
|
|
3480
|
-
interface ResponsiveActionsProps {
|
|
3481
|
-
actions: ResponsiveAction[];
|
|
3542
|
+
startInEdit?: boolean;
|
|
3482
3543
|
/**
|
|
3483
|
-
*
|
|
3484
|
-
*
|
|
3485
|
-
*
|
|
3544
|
+
* Identity of the record on show. Swapping it (as the navigator does, without remounting
|
|
3545
|
+
* the drawer) re-derives the per-record chrome — the in-place edit toggle drops back to
|
|
3546
|
+
* read-only and `startInEdit` is re-applied against the new record's own permissions.
|
|
3547
|
+
*/
|
|
3548
|
+
recordKey?: string | number;
|
|
3549
|
+
permissionsPath?: string;
|
|
3550
|
+
/** Runs after a successful mutation, before the drawer closes. Receives the response. */
|
|
3551
|
+
onSuccess?: (response: any) => void;
|
|
3552
|
+
/**
|
|
3553
|
+
* Guardar deja el cajón abierto —y editando— en vez de cerrarlo. El usuario lo cierra
|
|
3554
|
+
* cuando termina, con la X o con Cancelar.
|
|
3486
3555
|
*
|
|
3487
|
-
*
|
|
3488
|
-
*
|
|
3556
|
+
* Para registros que se capturan de a poco, o que llevan dentro su propia grilla editable:
|
|
3557
|
+
* ahí cerrar al guardar cuesta reabrir el registro, volver a entrar a editar y volver a
|
|
3558
|
+
* bajar hasta donde se iba. El caso que lo pide es un cajón anidado —una orden de envío
|
|
3559
|
+
* abierta desde la pestaña de su embarque, con la grilla de sus recibos adentro—, donde el
|
|
3560
|
+
* cierre además se lleva la grilla de en medio.
|
|
3561
|
+
*
|
|
3562
|
+
* Un guardado que **no** guardó igual cierra: `useMutationHandler` corre su `onSuccess` sin
|
|
3563
|
+
* respuesta ante un 403 para quitar la pantalla de en medio, y eso no es algo en lo que
|
|
3564
|
+
* quedarse. Tampoco compite con "Guardar ↓" — ése ya se queda abierto por su cuenta, y
|
|
3565
|
+
* cuando los dos aplican gana el paso al siguiente registro, que es lo que se pidió.
|
|
3489
3566
|
*/
|
|
3490
|
-
|
|
3491
|
-
/**
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3567
|
+
keepOpenOnSave?: boolean;
|
|
3568
|
+
/**
|
|
3569
|
+
* Acciones propias del registro —cerrar, revertir, descargar su PDF—, las mismas que
|
|
3570
|
+
* `DetailPage_v2` recibe en `slots.extraButtons` y con la misma forma, para que un registro
|
|
3571
|
+
* traiga sus acciones se abra en su página o en el cajón.
|
|
3572
|
+
*
|
|
3573
|
+
* Van en un menú "⋮" de la cabecera —no como iconos sueltos— porque la cabecera del cajón
|
|
3574
|
+
* es angosta y ya carga Editar, Eliminar y lo que venga en `slots.headerActions`; el menú
|
|
3575
|
+
* además las nombra, igual que el de la página completa. Se filtran contra el modo que el
|
|
3576
|
+
* cajón muestra *en ese momento*: entrar a editar esconde las de `"detail"`, como en la
|
|
3577
|
+
* página. `display` y `onClick` reciben el registro cargado.
|
|
3578
|
+
*/
|
|
3579
|
+
extraButtons?: DetailExtraButton[];
|
|
3580
|
+
/**
|
|
3581
|
+
* Footer record navigator: prev/next arrows (Alt+↑ / Alt+↓) that step through a list of
|
|
3582
|
+
* sibling records — e.g. the rows of the grid the drawer was opened from — without
|
|
3583
|
+
* closing the drawer. Omit it and no navigator renders.
|
|
3584
|
+
*/
|
|
3585
|
+
navigation?: DetailFormDrawerNavigation;
|
|
3586
|
+
/** Panel width. Defaults to `600`. */
|
|
3587
|
+
width?: number | string;
|
|
3588
|
+
/** Side the drawer slides in from. Defaults to `"right"`. */
|
|
3589
|
+
anchor?: DrawerProps["anchor"];
|
|
3590
|
+
/**
|
|
3591
|
+
* `"temporary"` (the default) floats over the page. `"docked"` takes its own space at
|
|
3592
|
+
* the side of the screen and shrinks the app instead of covering it, so the page behind
|
|
3593
|
+
* stays usable — see `MainDrawer_v2`.
|
|
3594
|
+
*
|
|
3595
|
+
* Docked drops the modal: nothing stops the user from touching the page while the form
|
|
3596
|
+
* is open, so a drawer that guards unsaved edits behind the backdrop no longer does.
|
|
3597
|
+
*/
|
|
3598
|
+
variant?: MainDrawerV2Props["variant"];
|
|
3599
|
+
/**
|
|
3600
|
+
* Let the user drag the drawer's inner edge to resize it. Forwarded to `MainDrawer_v2`
|
|
3601
|
+
* along with the four props below — see it for the full behaviour.
|
|
3602
|
+
*/
|
|
3603
|
+
resizable?: boolean;
|
|
3604
|
+
/** Smallest width the drag allows, in px. Defaults to `320`. */
|
|
3605
|
+
minWidth?: number;
|
|
3606
|
+
/** Largest width the drag allows, in px. Defaults to the viewport minus a margin. */
|
|
3607
|
+
maxWidth?: number;
|
|
3608
|
+
/**
|
|
3609
|
+
* Remember the dragged width under this `localStorage` key. Worth setting whenever the
|
|
3610
|
+
* drawer is remounted per record — a fresh mount otherwise forgets the drag.
|
|
3611
|
+
*/
|
|
3612
|
+
widthStorageKey?: string;
|
|
3613
|
+
/** Fires with the final dragged width in px, or `null` when a double click resets it. */
|
|
3614
|
+
onWidthChange?: (width: number | null) => void;
|
|
3615
|
+
/**
|
|
3616
|
+
* What the `size` breakpoints of the fields — and of the subsections themselves — resolve
|
|
3617
|
+
* against. Defaults to `"container"`: a drawer is narrow by construction, so viewport
|
|
3618
|
+
* breakpoints would pick the wide-screen value and cram the fields — and they would not
|
|
3619
|
+
* react to a drag either.
|
|
3620
|
+
* @see DetailFormProps.responsiveTo
|
|
3621
|
+
*/
|
|
3622
|
+
responsiveTo?: DetailFormProps["responsiveTo"];
|
|
3623
|
+
/** @see DetailFormProps.containerBreakpoints */
|
|
3624
|
+
containerBreakpoints?: DetailFormProps["containerBreakpoints"];
|
|
3625
|
+
labels?: {
|
|
3626
|
+
save?: string;
|
|
3627
|
+
cancel?: string;
|
|
3628
|
+
/**
|
|
3629
|
+
* Rótulo del guardar-y-seguir. Por defecto `"Guardar ↓"`, corto porque va junto al
|
|
3630
|
+
* Guardar de siempre y el tooltip ya dice qué hace; pásale un texto propio donde el
|
|
3631
|
+
* paso al siguiente registro merezca nombrarse ("Guardar y siguiente bulto").
|
|
3632
|
+
*/
|
|
3633
|
+
saveAndNext?: string;
|
|
3634
|
+
};
|
|
3635
|
+
slots?: {
|
|
3636
|
+
/**
|
|
3637
|
+
* Ruta al estado del registro —`"estado"`—, la misma que recibe `DetailPage_v2`: se
|
|
3638
|
+
* pinta junto al título, como en la página, y con el mismo mapa de colores.
|
|
3639
|
+
*
|
|
3640
|
+
* @see DetailPageV2Props.slots.badge
|
|
3641
|
+
*/
|
|
3642
|
+
badge?: string;
|
|
3643
|
+
/** Extra actions rendered in the header, left of the close button (e.g. "open full page"). */
|
|
3644
|
+
headerActions?: ReactNode;
|
|
3645
|
+
};
|
|
3646
|
+
slotProps?: {
|
|
3647
|
+
drawer?: Partial<DrawerProps>;
|
|
3648
|
+
saveButton?: Partial<ButtonProps>;
|
|
3649
|
+
cancelButton?: Partial<ButtonProps>;
|
|
3650
|
+
saveAndNextButton?: Partial<ButtonProps>;
|
|
3651
|
+
/** @see DetailPageV2Props.slotProps.badge */
|
|
3652
|
+
badge?: {
|
|
3653
|
+
colors?: Record<string, StatusColor>;
|
|
3654
|
+
/** @see DetailPageV2Props.slotProps.badge.options */
|
|
3655
|
+
options?: ChipOption[];
|
|
3656
|
+
};
|
|
3657
|
+
};
|
|
3495
3658
|
}
|
|
3496
3659
|
/**
|
|
3497
|
-
*
|
|
3498
|
-
*
|
|
3499
|
-
*
|
|
3500
|
-
*
|
|
3501
|
-
*
|
|
3502
|
-
*
|
|
3503
|
-
*
|
|
3504
|
-
*
|
|
3505
|
-
*
|
|
3506
|
-
*
|
|
3507
|
-
*
|
|
3508
|
-
* alcanza. Es el mismo motivo por el que el layout de los campos resuelve por `@container`.
|
|
3660
|
+
* A record form inside a side drawer. Reuses the same `useDetailForm` engine and
|
|
3661
|
+
* `DetailForm` body as `DetailPage_v2`, and `MainDrawer_v2` for the chrome — so it frames
|
|
3662
|
+
* the form exactly like every other v2 drawer. What it adds on top is the per-record
|
|
3663
|
+
* furniture: edit/delete in the header — plus the record's own actions, when the consumer
|
|
3664
|
+
* hands them over in `extraButtons`, in a "⋮" menu beside them — and a footer holding the
|
|
3665
|
+
* form actions and, when
|
|
3666
|
+
* `navigation` is given, a prev/next record navigator (Alt+↑ / Alt+↓) plus "Guardar ↓"
|
|
3667
|
+
* (Alt+Shift+↓) — a save that steps to the next record instead of closing, so a column can be
|
|
3668
|
+
* captured down a list in one pass without the hands leaving the keyboard. Rename it with
|
|
3669
|
+
* `labels.saveAndNext`. Guardar sits outside the `<form>` and submits via the native
|
|
3670
|
+
* `form={formId}` attribute; Guardar ↓ submits by hand, so the implicit Enter stays Guardar.
|
|
3509
3671
|
*
|
|
3510
|
-
*
|
|
3511
|
-
*
|
|
3512
|
-
*
|
|
3672
|
+
* `keepOpenOnSave` cambia lo que hace Guardar cuando no hay a dónde avanzar: en vez de cerrar,
|
|
3673
|
+
* deja el registro en pantalla y editando — para formularios que se capturan de a poco o que
|
|
3674
|
+
* llevan una grilla adentro.
|
|
3513
3675
|
*/
|
|
3514
|
-
declare
|
|
3676
|
+
declare function DetailFormDrawer({ open, onClose, title, api, form, sections, pageType, startInEdit, recordKey, permissionsPath, onSuccess, keepOpenOnSave, extraButtons, navigation, width, anchor, variant, resizable, minWidth, maxWidth, widthStorageKey, onWidthChange, responsiveTo, containerBreakpoints, labels, slots, slotProps, }: DetailFormDrawerProps): react_jsx_runtime.JSX.Element;
|
|
3515
3677
|
|
|
3516
|
-
interface
|
|
3678
|
+
interface DrawerGridDrawerConfig {
|
|
3679
|
+
/** Shared field layout, used by every mode. Same shape as `DetailPage_v2`'s `form`/`sections`. */
|
|
3680
|
+
form: DetailFormConfig["form"];
|
|
3681
|
+
sections: DetailFormConfig["sections"];
|
|
3682
|
+
permissionsPath?: string;
|
|
3683
|
+
/** Panel width. Defaults to the drawer's own default (600). */
|
|
3684
|
+
width?: number | string;
|
|
3517
3685
|
/**
|
|
3518
|
-
*
|
|
3519
|
-
*
|
|
3520
|
-
*
|
|
3686
|
+
* How the panel sits on the screen. Defaults to `"temporary"`: it floats over the page,
|
|
3687
|
+
* modal, the way it always has.
|
|
3688
|
+
*
|
|
3689
|
+
* `"docked"` gives it its own space at the side and shrinks the app instead of covering
|
|
3690
|
+
* it, so the grid stays visible next to the record. Worth it where the row and the list
|
|
3691
|
+
* are read together; it costs two things, both from dropping the modal:
|
|
3692
|
+
*
|
|
3693
|
+
* - Nothing stops the user from re-sorting, filtering or paging the grid while the
|
|
3694
|
+
* drawer is open, and the footer navigator walks the rows it sampled when the record
|
|
3695
|
+
* opened. It stays on the list the user was reading, which is usually what's wanted,
|
|
3696
|
+
* but it can no longer claim to match what's on screen.
|
|
3697
|
+
* - Unsaved edits are no longer fenced off by the backdrop.
|
|
3521
3698
|
*/
|
|
3522
|
-
|
|
3523
|
-
|
|
3699
|
+
variant?: DetailFormDrawerProps["variant"];
|
|
3700
|
+
/**
|
|
3701
|
+
* Let the user drag the drawer's inner edge to resize it. The dragged width is remembered
|
|
3702
|
+
* across openings under a key derived from the grid's own storage key — override it with
|
|
3703
|
+
* `widthStorageKey`, or turn the memory off by passing an empty string.
|
|
3704
|
+
*/
|
|
3705
|
+
resizable?: boolean;
|
|
3706
|
+
/** Smallest width the drag allows, in px. Defaults to `320`. */
|
|
3707
|
+
minWidth?: number;
|
|
3708
|
+
/** Largest width the drag allows, in px. Defaults to the viewport minus a margin. */
|
|
3709
|
+
maxWidth?: number;
|
|
3710
|
+
/** Where the dragged width is remembered. Defaults to the grid's storage key + `_DW`. */
|
|
3711
|
+
widthStorageKey?: string;
|
|
3712
|
+
/**
|
|
3713
|
+
* What the fields' `size` breakpoints resolve against. Defaults to `"container"` — the
|
|
3714
|
+
* width of the panel, not of the screen.
|
|
3715
|
+
* @see DetailFormDrawerProps.responsiveTo
|
|
3716
|
+
*/
|
|
3717
|
+
responsiveTo?: DetailFormDrawerProps["responsiveTo"];
|
|
3718
|
+
/** @see DetailFormDrawerProps.containerBreakpoints */
|
|
3719
|
+
containerBreakpoints?: DetailFormDrawerProps["containerBreakpoints"];
|
|
3720
|
+
title?: {
|
|
3721
|
+
create?: ReactNode;
|
|
3722
|
+
record?: ReactNode | ((id: GridRowId) => ReactNode);
|
|
3524
3723
|
};
|
|
3525
|
-
|
|
3724
|
+
/** Create-mode API (opened by the "Quick create" menu option). */
|
|
3725
|
+
create: {
|
|
3526
3726
|
mutation: any;
|
|
3527
|
-
|
|
3727
|
+
/** Defaults to `"create"`. */
|
|
3728
|
+
pageType?: PageType;
|
|
3729
|
+
successMessage?: string | ((response: any) => string);
|
|
3528
3730
|
};
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
/**
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3731
|
+
/** Record-mode API (opened by a row click). */
|
|
3732
|
+
record: {
|
|
3733
|
+
/** Single-record query hook, called with `{ id, ...args(id) }`. */
|
|
3734
|
+
query: any;
|
|
3735
|
+
mutation: any;
|
|
3736
|
+
/**
|
|
3737
|
+
* Defaults to `"detail"` (read-only), matching a row-click. Use `"edit"` for an always
|
|
3738
|
+
* editable drawer — a `"detail"` drawer already opens editing while the grid itself is
|
|
3739
|
+
* in edit mode.
|
|
3740
|
+
*/
|
|
3741
|
+
pageType?: PageType;
|
|
3742
|
+
successMessage?: string | ((response: any) => string);
|
|
3743
|
+
/** Extra query args merged with `{ id }`. */
|
|
3744
|
+
args?: (id: GridRowId) => Record<string, any>;
|
|
3745
|
+
/** Optional delete mutation. When set and the user has delete permission, a delete button appears in the drawer header. */
|
|
3746
|
+
delete?: {
|
|
3747
|
+
mutation: any;
|
|
3748
|
+
};
|
|
3535
3749
|
};
|
|
3536
|
-
extraButtons?: {
|
|
3537
|
-
title: string;
|
|
3538
|
-
icon: ReactNode;
|
|
3539
|
-
onClick: () => void;
|
|
3540
|
-
}[];
|
|
3541
|
-
/** Tamaño de los botones. `"small"` para las cabeceras del cajón. */
|
|
3542
|
-
size?: "small" | "medium";
|
|
3543
3750
|
/**
|
|
3544
|
-
*
|
|
3545
|
-
*
|
|
3546
|
-
*
|
|
3751
|
+
* Acciones propias del registro —las mismas que su página completa recibe en
|
|
3752
|
+
* `DetailPage_v2`'s `slots.extraButtons`, y con la misma forma—, en un menú "⋮" de la
|
|
3753
|
+
* cabecera del cajón. Se filtran por modo y por `display(registro)`, así que las de la
|
|
3754
|
+
* página se pasan tal cual: abrir el renglón en el cajón deja de ser una versión recortada
|
|
3755
|
+
* de abrirlo en su página.
|
|
3547
3756
|
*/
|
|
3548
|
-
|
|
3549
|
-
}
|
|
3550
|
-
|
|
3551
|
-
interface DetailPageV2Props {
|
|
3552
|
-
api: DetailFormApi;
|
|
3553
|
-
form: DetailFormConfig["form"];
|
|
3554
|
-
sections: DetailFormConfig["sections"];
|
|
3555
|
-
pageType: PageType;
|
|
3757
|
+
extraButtons?: DetailExtraButton[];
|
|
3556
3758
|
/**
|
|
3557
|
-
*
|
|
3558
|
-
*
|
|
3759
|
+
* El estado del registro, junto al título de la cabecera del cajón —igual que en su página
|
|
3760
|
+
* completa—. `path` es la ruta al campo dentro del dato, que el backend manda como
|
|
3761
|
+
* `{ value, label }`, y `colors` dice de qué color va cada código:
|
|
3559
3762
|
*
|
|
3560
|
-
*
|
|
3561
|
-
* takes its share of it — so the screen stopped being a good proxy for how much room
|
|
3562
|
-
* the fields actually have. Against the form they re-flow as that room changes, with
|
|
3563
|
-
* no re-render: the breakpoint ladder is CSS.
|
|
3763
|
+
* badge: { path: "estado", colors: { "1": "warning", "2": "info" } }
|
|
3564
3764
|
*
|
|
3565
|
-
* `
|
|
3566
|
-
*
|
|
3765
|
+
* `colors` es el mismo mapa que recibe `renderChipCell`, así que lo natural es declararlo
|
|
3766
|
+
* junto al catálogo y pasárselo a los dos: el estado se ve igual en la columna de la tabla
|
|
3767
|
+
* que en el cajón que abre esa misma fila.
|
|
3768
|
+
*
|
|
3769
|
+
* @see DetailPageV2Props.slots.badge
|
|
3567
3770
|
*/
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3771
|
+
badge?: {
|
|
3772
|
+
path: string;
|
|
3773
|
+
colors?: Record<string, StatusColor>;
|
|
3774
|
+
/**
|
|
3775
|
+
* Los estados con su rótulo, para poder mostrarlo en otro idioma.
|
|
3776
|
+
* @see DetailPageV2Props.slotProps.badge.options
|
|
3777
|
+
*/
|
|
3778
|
+
options?: ChipOption[];
|
|
3779
|
+
};
|
|
3780
|
+
/** Runs after any successful create/edit (e.g. side effects; the grid refetches via RTK tag invalidation). */
|
|
3781
|
+
onSaved?: (response: any) => void;
|
|
3571
3782
|
/**
|
|
3572
|
-
*
|
|
3573
|
-
* se scrollea la ficha. Las migas se recogen al llegar arriba, así que lo que se queda es
|
|
3574
|
-
* sólo lo que hace falta tener a la mano.
|
|
3783
|
+
* Whether these records have a full page of their own. Defaults to `true`.
|
|
3575
3784
|
*
|
|
3576
|
-
*
|
|
3577
|
-
*
|
|
3578
|
-
*
|
|
3785
|
+
* Set it to `false` for rows that exist only inside their parent and have no route —
|
|
3786
|
+
* it drops the drawer header's "open full page" button *and* the Ctrl/Alt+click
|
|
3787
|
+
* shortcuts, which would otherwise navigate to a route that isn't registered.
|
|
3788
|
+
*/
|
|
3789
|
+
showOpenFullPage?: boolean;
|
|
3790
|
+
/**
|
|
3791
|
+
* Show the footer navigator that walks the grid's rows — prev/next arrows plus the
|
|
3792
|
+
* record's position — in the record drawer. Defaults to `true`.
|
|
3579
3793
|
*
|
|
3580
|
-
*
|
|
3581
|
-
*
|
|
3582
|
-
* `pageHeader` propio que no lo reserve): ahí vuelven a la esquina flotante de siempre.
|
|
3583
|
-
* @default true
|
|
3794
|
+
* It also gates "Guardar ↓", the save that steps to the next row instead of closing:
|
|
3795
|
+
* without a list to walk there is nothing to continue to.
|
|
3584
3796
|
*/
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
*
|
|
3600
|
-
* @see DetailPageV2Props.slotProps.badge
|
|
3601
|
-
*/
|
|
3602
|
-
badge?: string;
|
|
3797
|
+
showNavigator?: boolean;
|
|
3798
|
+
/**
|
|
3799
|
+
* Guardar deja el cajón abierto y editando en vez de cerrarlo; se cierra con la X o con
|
|
3800
|
+
* Cancelar. Para registros que se capturan de a poco, o que llevan su propia grilla
|
|
3801
|
+
* editable adentro y perderían el lugar al cerrarse.
|
|
3802
|
+
*
|
|
3803
|
+
* @see DetailFormDrawerProps.keepOpenOnSave
|
|
3804
|
+
*/
|
|
3805
|
+
keepOpenOnSave?: boolean;
|
|
3806
|
+
/** Rótulos del pie del cajón. `saveAndNext` por defecto es `"Guardar ↓"`. */
|
|
3807
|
+
labels?: {
|
|
3808
|
+
save?: string;
|
|
3809
|
+
cancel?: string;
|
|
3810
|
+
saveAndNext?: string;
|
|
3603
3811
|
};
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
*
|
|
3627
|
-
* colors: { "1": "warning", "2": "info", "3": "success" }
|
|
3628
|
-
*
|
|
3629
|
-
* Es el mismo mapa que recibe `renderChipCell` en las columnas de una tabla, así que
|
|
3630
|
-
* lo natural es declararlo junto al catálogo y pasarlo a los dos: el estado "2" se ve
|
|
3631
|
-
* igual en la lista que en la ficha.
|
|
3632
|
-
*
|
|
3633
|
-
* Sin mapa la insignia queda neutra —gris—, que es como se veían todos antes de que
|
|
3634
|
-
* hubiera con qué distinguirlos.
|
|
3635
|
-
*/
|
|
3636
|
-
colors?: Record<string, StatusColor>;
|
|
3637
|
-
/**
|
|
3638
|
-
* Los estados con su rótulo, para poder mostrarlo en otro idioma.
|
|
3639
|
-
*
|
|
3640
|
-
* Es el mismo `ChipOption[]` que reciben las columnas de la tabla, y se resuelve
|
|
3641
|
-
* igual (`resolveChipOption`), así que la ficha y la lista nombran el estado con la
|
|
3642
|
-
* misma palabra. Sin esto, la insignia sólo puede repetir lo que mandó el backend,
|
|
3643
|
-
* que viene en español (`get_estado_display`).
|
|
3644
|
-
*
|
|
3645
|
-
* Ojo con traducir el `label` de una opción: casi todos estos endpoints mandan la
|
|
3646
|
-
* etiqueta y no el código, así que el emparejado real es contra el texto en español
|
|
3647
|
-
* — para eso está `ChipOption.match`.
|
|
3648
|
-
*/
|
|
3649
|
-
options?: ChipOption[];
|
|
3812
|
+
}
|
|
3813
|
+
interface DrawerGridEditConfig {
|
|
3814
|
+
/** Hides the toggle (and its shortcuts) without touching permissions. */
|
|
3815
|
+
disabled?: boolean;
|
|
3816
|
+
/**
|
|
3817
|
+
* Drives edit mode from outside instead of leaving it to the toolbar toggle — pass the
|
|
3818
|
+
* edit state of the form this grid is embedded in and a row click follows it, opening the
|
|
3819
|
+
* drawer already editing without the user flipping a second switch. The toolbar button
|
|
3820
|
+
* disappears while it's set, and it stays fail-closed against the model's permission.
|
|
3821
|
+
*/
|
|
3822
|
+
active?: boolean;
|
|
3823
|
+
}
|
|
3824
|
+
interface DrawerGridProps {
|
|
3825
|
+
/**
|
|
3826
|
+
* Full `ServerGrid_v2` configuration (pathname, api, dataGridProps, slotProps, ref), with
|
|
3827
|
+
* one twist: `api.edit` here is the drawer's edit *mode* — a toolbar toggle that makes a
|
|
3828
|
+
* row click open the drawer already editing — not in-grid row editing. It takes no
|
|
3829
|
+
* mutation and no columns, because everything that writes goes through the drawer form.
|
|
3830
|
+
*/
|
|
3831
|
+
grid: Omit<ServerGridProps, "api" | "ref"> & {
|
|
3832
|
+
api: Omit<ServerGridProps["api"], "edit" | "editToggle"> & {
|
|
3833
|
+
edit?: DrawerGridEditConfig;
|
|
3650
3834
|
};
|
|
3835
|
+
ref?: RefObject<any>;
|
|
3651
3836
|
};
|
|
3837
|
+
drawer: DrawerGridDrawerConfig;
|
|
3652
3838
|
}
|
|
3653
|
-
|
|
3839
|
+
/**
|
|
3840
|
+
* A `ServerGrid_v2` whose rows and create button open a `DetailFormDrawer_v2` instead of
|
|
3841
|
+
* navigating to a full page — without giving up the full-page routes.
|
|
3842
|
+
*
|
|
3843
|
+
* The panel floats over the page by default. `drawer.variant: "docked"` gives it its own
|
|
3844
|
+
* space at the side instead, shrinking the app so the grid stays visible next to the
|
|
3845
|
+
* record; read that prop before switching, the two differ in more than looks.
|
|
3846
|
+
*
|
|
3847
|
+
* A row click and the create menu's "Manual" option both open the drawer; Ctrl/Cmd+click still opens the full
|
|
3848
|
+
* page in a new tab, Alt+click opens it in the same tab, and the record drawer carries an
|
|
3849
|
+
* "open full page" button — so the routes stay reachable either way. Grids whose rows have
|
|
3850
|
+
* no route of their own turn all three off with `drawer.showOpenFullPage: false`.
|
|
3851
|
+
*
|
|
3852
|
+
* A record drawer also carries a footer navigator: arrows (and Alt+↑ / Alt+↓) that walk the
|
|
3853
|
+
* grid's rows in their displayed order, position counter included, so reviewing a list no
|
|
3854
|
+
* longer means closing the drawer and clicking the next row. Stepping off either end of the
|
|
3855
|
+
* page turns the grid's own page instead of stopping, so the walk covers every row behind
|
|
3856
|
+
* the current filters — not just the ones on screen. Turn it off with
|
|
3857
|
+
* `drawer.showNavigator: false`.
|
|
3858
|
+
*
|
|
3859
|
+
* Editing a list that way gets a third footer button, "Guardar ↓" / Alt+Shift+↓ (rename it
|
|
3860
|
+
* with `drawer.labels.saveAndNext`): it saves and steps to the next row instead of closing,
|
|
3861
|
+
* carrying the edit mode over, so capturing a column across many rows is one pass rather than
|
|
3862
|
+
* open-edit-save-reopen per row — and with the shortcut, without leaving the keyboard. It
|
|
3863
|
+
* rides on the navigator — no navigator, or last row, and there is just Guardar.
|
|
3864
|
+
*
|
|
3865
|
+
* `drawer.keepOpenOnSave` hace que Guardar no cierre: el registro se queda en pantalla y
|
|
3866
|
+
* editando. Vale la pena donde el cajón lleva su propia grilla adentro —cerrarlo se lleva
|
|
3867
|
+
* también lo que se estaba capturando ahí— o donde el registro se llena en varias pasadas.
|
|
3868
|
+
*
|
|
3869
|
+
* Edit mode is opt-in with `api.edit: {}` and adds nothing to the grid but a toolbar toggle —
|
|
3870
|
+
* no mutation, no actions column, no in-grid editing. While it's on, a row click opens the
|
|
3871
|
+
* record drawer already editing, provided the record allows it; the drawer form is the only
|
|
3872
|
+
* thing that writes. A grid embedded in a detail form can hand the mode over instead, with
|
|
3873
|
+
* `api.edit: { active: pageType === "edit" }`, so it follows the form rather than asking for
|
|
3874
|
+
* a second switch.
|
|
3875
|
+
*
|
|
3876
|
+
* The full grid config goes under `grid` (`{ pathname, api, dataGridProps, slotProps }`),
|
|
3877
|
+
* alongside `drawer`.
|
|
3878
|
+
*
|
|
3879
|
+
* Composition only: the grid stays drawer-agnostic (its `onRowClick`, `onManualCreate` and
|
|
3880
|
+
* `onEditModeChange` are generic passthroughs), and the navigator reaches it through the
|
|
3881
|
+
* public `ServerGridHandle` rather than MUI's internal state.
|
|
3882
|
+
*/
|
|
3883
|
+
declare function DrawerGrid({ grid, drawer }: DrawerGridProps): react_jsx_runtime.JSX.Element;
|
|
3884
|
+
|
|
3885
|
+
interface ConfirmDialogProps {
|
|
3886
|
+
open: boolean;
|
|
3887
|
+
titulo: string;
|
|
3888
|
+
mensaje: ReactNode;
|
|
3889
|
+
confirmLabel?: string;
|
|
3890
|
+
cancelLabel?: string;
|
|
3891
|
+
confirmColor?: "primary" | "secondary" | "error" | "warning" | "info" | "success";
|
|
3892
|
+
confirmIcon?: ReactNode;
|
|
3893
|
+
isLoading?: boolean;
|
|
3894
|
+
onConfirm: () => void;
|
|
3895
|
+
onClose: () => void;
|
|
3896
|
+
}
|
|
3897
|
+
/** Diálogo de confirmación genérico: título, mensaje y un par de acciones. El botón de
|
|
3898
|
+
* confirmar puede mostrar estado de carga mientras se resuelve la acción. */
|
|
3899
|
+
declare function ConfirmDialog({ open, titulo, mensaje, confirmLabel, cancelLabel, confirmColor, confirmIcon, isLoading, onConfirm, onClose, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
|
|
3654
3900
|
|
|
3655
3901
|
interface DetailFormDialogProps {
|
|
3656
3902
|
open: boolean;
|
|
@@ -4398,5 +4644,30 @@ interface UseColorModeResult {
|
|
|
4398
4644
|
}
|
|
4399
4645
|
declare function useColorMode(): UseColorModeResult;
|
|
4400
4646
|
|
|
4401
|
-
|
|
4402
|
-
|
|
4647
|
+
/**
|
|
4648
|
+
* El argumento de una mutación que llega envuelto: lo que manda `DetailPage_v2` (y cualquier
|
|
4649
|
+
* formulario que pase por `useMutationHandler`), con el cuerpo en `data` y los argumentos de la
|
|
4650
|
+
* página en `params`.
|
|
4651
|
+
*/
|
|
4652
|
+
interface MutationArgs<T = any> {
|
|
4653
|
+
data: T;
|
|
4654
|
+
params?: {
|
|
4655
|
+
[k: string]: any;
|
|
4656
|
+
};
|
|
4657
|
+
}
|
|
4658
|
+
/** El cuerpo de la mutación, venga envuelto o suelto. */
|
|
4659
|
+
declare const mutationData: (arg: any) => any;
|
|
4660
|
+
/** Los argumentos de la página, si llegaron envueltos. Un renglón suelto no trae. */
|
|
4661
|
+
declare const mutationParams: (arg: any) => {
|
|
4662
|
+
[k: string]: any;
|
|
4663
|
+
} | undefined;
|
|
4664
|
+
/**
|
|
4665
|
+
* El id del registro, que decide entre alta y edición (POST o PATCH).
|
|
4666
|
+
*
|
|
4667
|
+
* De un `FormData` sale con `get("id")`, así que llega como cadena —o `null` si no lo trae—, no
|
|
4668
|
+
* como número.
|
|
4669
|
+
*/
|
|
4670
|
+
declare const mutationId: (arg: any) => any;
|
|
4671
|
+
|
|
4672
|
+
export { APIContext, APIProvider, AccountMenuContent, ActiveCell, ActiveIcon, Base, ButtonWithDrawer, COLOR_SCHEME_SELECTOR, CSVUpload, CatalogoItem, CatalogoList, 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, LocaleContext, LocaleProvider, Logo, MainDrawer, MainDrawer$1 as MainDrawer_v2, MainLayout, MenuItemWithLoading, ModuleCard, MoreOptions, MyGridEditSingleSelect, NavigationContext, NavigationProvider, NormalOrIcon, NotAllowed, NotFound, NotificationItem, NotificationsBell, ObjectProgressStack, PageActionsHostContext, PageBadgeHostContext, PageInfo, PageInfoHostContext, Panel, PollingCountdownChip, PulseDot, RESPONSIVE_ACTION_MODES, ResponsiveActions, SIDE_PANEL_WIDTH_VAR, SaveCancelButton, ServerGrid as ServerGrid_v2, SidePanelHostContext, StatusBadge, StickyPageHeaderContext, StyledMenu, TEXTOS, Tabs, Transitions, TrueFalse, UncontrolledText, aplicarLocaleDeDayjs, changeTitle, closeProgressSnack, columnasDeCatalogo, composeGridProps, crearFabricaDeCatalogos, deleteColumn$1 as deleteColumn, deleteColumn as deleteColumn_v2, editColumn, filterQuery, formContainerSx, formGridSx, formParser, headerContainerSx, _default as headerReducer, localeDeNumeros, localeTextDeMUI, localeTextDeToolpad, manualCacheRefresh, mergeSettings, mutationData, mutationId, mutationParams, openProgressSnack, pageSizeOptions, query, renderChipCell, renderEditCellWithErrorTooltip, resolveChipOption, resolveInitialState, resolveStatusColor, setErrors, singularizarPalabra, singularizarTitulo, _default$1 as snackProgressReducer, statusColors, tags, theme, togglableFields, updateProgressSnackData, useAPI, useColorMode, useDetailForm, useHasPermission, useHasPermission_v2, useKeyboardShortcut, useLocale, useMutationHandler, useNavigation, usePageActionsHost, usePageBadgeHost, usePageInfoHost, useServerGrid, useSidePanelHost, useStickyPageHeader, useStickyPageHeaderHost, useTextos, valueLabel };
|
|
4673
|
+
export type { APIcontextProps, AccountMenuContentProps, AccountMenuItem, AddressValue, AppTheme, AutocompleteOption, CatalogoAPI, CatalogoItemProps, CatalogoListProps, ChipCellProps, ChipColor, ChipOption, ColorMode, ComoOpcionesProps, ConfirmDialogProps, ControlledAutocompleteProps, ControlledInput, CrearCatalogoAPI, CustomFilterDef, CustomToolbarProps, DefinicionDeCatalogo, 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, InsigniaDeCatalogo, JSONFormProps, JSONParserProps, KeyboardShortcut, KpiCardProps, Locale, LocaleContextProps, LocaleProviderProps, MainDrawerV2Props, MainLayoutFooterConfig, MainLayoutPageHeaderProps, MainLayoutProps, MainLayoutSidebarFooterProps, MutationArgs, 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, StickyPageHeaderHost, Textos, UseColorModeResult, UseServerGridOptions };
|