frontend-plus-react 0.2.0 → 0.4.0
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/CLAUDE.md +153 -0
- package/README.md +24 -0
- package/dist/index.cjs +2353 -1619
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +63 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +107 -24
- package/dist/index.d.ts +107 -24
- package/dist/index.js +2043 -1280
- package/dist/index.js.map +1 -1
- package/package.json +13 -5
package/dist/index.css
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
+
/* src/components/grid/GenericDataGrid.css */
|
|
2
|
+
.fpr-celda {
|
|
3
|
+
position: absolute;
|
|
4
|
+
inset: 0;
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: flex-start;
|
|
8
|
+
padding: 0 12px 0 8px;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
font-size: 0.875rem;
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
transition: background-color 0.3s ease-in-out;
|
|
15
|
+
}
|
|
16
|
+
.fpr-celda-numerica {
|
|
17
|
+
justify-content: flex-end;
|
|
18
|
+
}
|
|
19
|
+
.fpr-fila-saliendo {
|
|
20
|
+
opacity: 0;
|
|
21
|
+
transition: opacity 0.4s ease-in-out;
|
|
22
|
+
}
|
|
23
|
+
.fpr-fila-detalle > .rdg-cell {
|
|
24
|
+
padding: 0;
|
|
25
|
+
background-color: #f3f6fa;
|
|
26
|
+
white-space: normal;
|
|
27
|
+
overflow: visible;
|
|
28
|
+
}
|
|
29
|
+
.fpr-detalle {
|
|
30
|
+
position: sticky;
|
|
31
|
+
left: 0;
|
|
32
|
+
height: 100%;
|
|
33
|
+
width: max-content;
|
|
34
|
+
box-sizing: border-box;
|
|
35
|
+
padding: 4px 8px 4px 28px;
|
|
36
|
+
border-left: 3px solid #90caf9;
|
|
37
|
+
background-color: #f3f6fa;
|
|
38
|
+
}
|
|
39
|
+
.fpr-detalle-wscreen {
|
|
40
|
+
height: 100%;
|
|
41
|
+
overflow: auto;
|
|
42
|
+
}
|
|
43
|
+
.fpr-detalle-wscreen-contenido {
|
|
44
|
+
width: max-content;
|
|
45
|
+
max-width: 100%;
|
|
46
|
+
}
|
|
47
|
+
.fpr-boton-detalle {
|
|
48
|
+
display: flex;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
align-items: center;
|
|
51
|
+
height: 100%;
|
|
52
|
+
}
|
|
53
|
+
.typed-controls-signal-no-data {
|
|
54
|
+
background-color: #fff9c4 !important;
|
|
55
|
+
color: #fbc02d;
|
|
56
|
+
font-weight: bold;
|
|
57
|
+
}
|
|
58
|
+
.typed-controls-signal-unknown-data {
|
|
59
|
+
background-color: #ffe0b2 !important;
|
|
60
|
+
color: #fb8c00;
|
|
61
|
+
font-weight: bold;
|
|
62
|
+
}
|
|
63
|
+
|
|
1
64
|
/* src/App.css */
|
|
2
65
|
html,
|
|
3
66
|
body,
|
package/dist/index.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/App.css"],"sourcesContent":["/* src/app.css */\n\n/* Estilos globales para asegurar que la aplicación ocupe el 100% del viewport\n y que el scroll sea gestionado por componentes específicos, no por la página. */\n html, body, #root {\n height: 100%; /* Ocupa el 100% del alto del viewport */\n margin: 0; /* Elimina márgenes por defecto del navegador */\n padding: 0; /* Elimina rellenos por defecto del navegador */\n overflow: hidden; /* ¡CLAVE! Previene scrolls a nivel de la página (horizontal y vertical) */\n box-sizing: border-box; /* Asegura que padding y border se incluyan en el width/height */\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* El contenedor principal de tu aplicación (si es <App />) */\n.App {\n height: 100%; /* Asegura que la App ocupe el 100% del alto de #root */\n display: flex; /* Utiliza flexbox para su contenido (MainLayout) */\n flex-direction: column; /* Los hijos se apilan verticalmente */\n}\n\n/* Otros estilos que tenías en tu archivo */\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh; /* Revisa si esto es necesario o si causa desbordamiento */\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n\n/* Estilos base para las filas de react-data-grid */\n.rdg-row {\n /* La transición debe ser lo suficientemente larga para ser visible */\n transition: opacity 0.5s ease-out, transform 0.5s ease-out;\n}\n\n/* Esta clase se aplica a la fila cuando se va a borrar */\n.deleting-row {\n opacity: 0; /* Hace que la fila se desvanezca */\n transform: translateX(-100%); /* Mueve la fila hacia la izquierda */\n pointer-events: none; /* Evita interacciones mientras se desvanece */\n}"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/components/grid/GenericDataGrid.css","../src/App.css"],"sourcesContent":["/* src/components/grid/GenericDataGrid.css */\n\n/* Celda de datos (reemplaza al Box + Typography de MUI que se armaba en cada celda) */\n.fpr-celda {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n padding: 0 12px 0 8px;\n box-sizing: border-box;\n font-size: 0.875rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background-color 0.3s ease-in-out;\n}\n\n.fpr-celda-numerica {\n justify-content: flex-end;\n}\n\n/* Fila que se está borrando (antes era un style copiado en cada fila) */\n.fpr-fila-saliendo {\n opacity: 0;\n transition: opacity 0.4s ease-in-out;\n}\n\n/* Fila de detalle desplegada: una sola celda (colSpan) con la grilla anidada adentro */\n.fpr-fila-detalle > .rdg-cell {\n padding: 0;\n background-color: #f3f6fa;\n white-space: normal;\n /* react-data-grid recorta las celdas (overflow: clip, en un @layer): la grilla anidada\n puede ser más ancha que las columnas del padre, como el td de detalle de backend-plus */\n overflow: visible;\n}\n\n.fpr-detalle {\n position: sticky; /* queda a la vista aunque la grilla de arriba esté scrolleada a la derecha */\n left: 0;\n height: 100%;\n /* el ancho lo da el contenido (las columnas de la grilla anidada), hasta lo visible */\n width: max-content;\n box-sizing: border-box;\n padding: 4px 8px 4px 28px; /* sangría: se ve de qué fila es el detalle */\n border-left: 3px solid #90caf9;\n background-color: #f3f6fa;\n}\n\n/* Detalle que es una pantalla propia (wScreen): el contenido se mide y la fila toma su alto */\n.fpr-detalle-wscreen {\n height: 100%;\n overflow: auto;\n}\n\n.fpr-detalle-wscreen-contenido {\n width: max-content;\n max-width: 100%;\n}\n\n.fpr-boton-detalle {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n}\n\n/* Estas clases estaban solo en index.css, que la librería no importa */\n.typed-controls-signal-no-data {\n background-color: #fff9c4 !important;\n color: #fbc02d;\n font-weight: bold;\n}\n\n.typed-controls-signal-unknown-data {\n background-color: #ffe0b2 !important;\n color: #fb8c00;\n font-weight: bold;\n}\n","/* src/app.css */\n\n/* Estilos globales para asegurar que la aplicación ocupe el 100% del viewport\n y que el scroll sea gestionado por componentes específicos, no por la página. */\n html, body, #root {\n height: 100%; /* Ocupa el 100% del alto del viewport */\n margin: 0; /* Elimina márgenes por defecto del navegador */\n padding: 0; /* Elimina rellenos por defecto del navegador */\n overflow: hidden; /* ¡CLAVE! Previene scrolls a nivel de la página (horizontal y vertical) */\n box-sizing: border-box; /* Asegura que padding y border se incluyan en el width/height */\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* El contenedor principal de tu aplicación (si es <App />) */\n.App {\n height: 100%; /* Asegura que la App ocupe el 100% del alto de #root */\n display: flex; /* Utiliza flexbox para su contenido (MainLayout) */\n flex-direction: column; /* Los hijos se apilan verticalmente */\n}\n\n/* Otros estilos que tenías en tu archivo */\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh; /* Revisa si esto es necesario o si causa desbordamiento */\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n\n/* Estilos base para las filas de react-data-grid */\n.rdg-row {\n /* La transición debe ser lo suficientemente larga para ser visible */\n transition: opacity 0.5s ease-out, transform 0.5s ease-out;\n}\n\n/* Esta clase se aplica a la fila cuando se va a borrar */\n.deleting-row {\n opacity: 0; /* Hace que la fila se desvanezca */\n transform: translateX(-100%); /* Mueve la fila hacia la izquierda */\n pointer-events: none; /* Evita interacciones mientras se desvanece */\n}"],"mappings":";AAGA,CAAC;AACC,YAAU;AACV,SAAO;AACP,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS,EAAE,KAAK,EAAE;AAClB,cAAY;AACZ,aAAW;AACX,eAAa;AACb,YAAU;AACV,iBAAe;AACf,cAAY,iBAAiB,KAAK;AACpC;AAEA,CAAC;AACC,mBAAiB;AACnB;AAGA,CAAC;AACC,WAAS;AACT,cAAY,QAAQ,KAAK;AAC3B;AAGA,CAAC,iBAAiB,EAAE,CAAC;AACnB,WAAS;AACT,oBAAkB;AAClB,eAAa;AAGb,YAAU;AACZ;AAEA,CAAC;AACC,YAAU;AACV,QAAM;AACN,UAAQ;AAER,SAAO;AACP,cAAY;AACZ,WAAS,IAAI,IAAI,IAAI;AACrB,eAAa,IAAI,MAAM;AACvB,oBAAkB;AACpB;AAGA,CAAC;AACC,UAAQ;AACR,YAAU;AACZ;AAEA,CAAC;AACC,SAAO;AACP,aAAW;AACb;AAEA,CAAC;AACC,WAAS;AACT,mBAAiB;AACjB,eAAa;AACb,UAAQ;AACV;AAGA,CAAC;AACC,oBAAkB;AAClB,SAAO;AACP,eAAa;AACf;AAEA,CAAC;AACC,oBAAkB;AAClB,SAAO;AACP,eAAa;AACf;;;AC3EE;AAAM;AAAM,CAAC;AACb,UAAQ;AACR,UAAQ;AACR,WAAS;AACT,YAAU;AACV,cAAY;AACd;AAEA;AACE;AAAA,IAAa,aAAa;AAAA,IAAE,kBAAkB;AAAA,IAAE,UAAU;AAAA,IAAE,QAAQ;AAAA,IAAE,QAAQ;AAAA,IAC5E,QAAQ;AAAA,IAAE,WAAW;AAAA,IAAE,WAAW;AAAA,IAAE,YAAY;AAAA,IAAE,gBAAgB;AAAA,IAClE;AACF,0BAAwB;AACxB,2BAAyB;AAC3B;AAGA,CAAC;AACC,UAAQ;AACR,WAAS;AACT,kBAAgB;AAClB;AAGA,CAAC;AACC,UAAQ;AACR,kBAAgB;AAClB;AAEA,OAAO,CAAC,sBAAsB,EAAE;AAC9B,GAND;AAOG,eAAW,cAAc,SAAS,IAAI;AACxC;AACF;AAEA,CAAC;AACC,oBAAkB;AAClB,cAAY;AACZ,WAAS;AACT,kBAAgB;AAChB,eAAa;AACb,mBAAiB;AACjB,aAAW,KAAK,KAAK,EAAE;AACvB,SAAO;AACT;AAEA,CAAC;AACC,SAAO;AACT;AAEA,WAnBe;AAoBb;AACE,eAAW,OAAO;AACpB;AACA;AACE,eAAW,OAAO;AACpB;AACF;AAEA;AACE;AAAA,IAAa,eAAe;AAAA,IAAE,KAAK;AAAA,IAAE,MAAM;AAAA,IAAE,QAAQ;AAAA,IAAE,aAAa;AAAA,IAClE;AACJ;AAGA,CAAC;AAEC,cAAY,QAAQ,KAAK,QAAQ,EAAE,UAAU,KAAK;AACpD;AAGA,CAAC;AACC,WAAS;AACT,aAAW,WAAW;AACtB,kBAAgB;AAClB;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -11,16 +11,34 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
11
11
|
*/
|
|
12
12
|
declare const extractPathsFromRoutes: (node: ReactNode) => string[];
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Marca con la que una fila nueva conserva su identidad en la grilla mientras se edita (antes de tener su clave primaria).
|
|
16
|
+
* Es un Symbol: no aparece en Object.keys ni en JSON.stringify, pero el spread de la fila (...fila) la conserva.
|
|
17
|
+
*/
|
|
18
|
+
declare const DOM_TEMP_ID: unique symbol;
|
|
19
|
+
/** Una fila de datos de una tabla: los valores salen del servidor ya decodificados (JSON4all) */
|
|
20
|
+
type FilaDeDatos = Record<string, unknown> & {
|
|
21
|
+
[DOM_TEMP_ID]?: string;
|
|
22
|
+
};
|
|
14
23
|
interface WScreenProps {
|
|
15
24
|
screenName: string;
|
|
25
|
+
/**
|
|
26
|
+
* Parámetros de la pantalla como objeto plano (en backend-plus, el primer argumento de `mainAction`).
|
|
27
|
+
* Como detalle de una grilla son los fixedFields del detalle; en una ruta, la query string.
|
|
28
|
+
*/
|
|
29
|
+
params?: Record<string, unknown>;
|
|
16
30
|
}
|
|
17
|
-
|
|
31
|
+
/** Decide, para una fila, si se muestra el botón de un detalle (`condition` del DetailTable) */
|
|
32
|
+
type CondicionDeDetalle = (fila: FilaDeDatos) => boolean;
|
|
33
|
+
type CondicionesMap = Record<string, CondicionDeDetalle>;
|
|
34
|
+
interface ClientSideProps extends RenderCellProps<FilaDeDatos, FilaDeResumen> {
|
|
18
35
|
fieldDefinition: FieldDefinition;
|
|
19
36
|
tableDefinition: TableDefinition;
|
|
20
37
|
primaryKey: string[];
|
|
21
38
|
}
|
|
22
39
|
interface ResultOkProps {
|
|
23
|
-
|
|
40
|
+
/** Lo que devolvió el procedimiento (la forma depende de cada procedimiento) */
|
|
41
|
+
data: unknown;
|
|
24
42
|
}
|
|
25
43
|
type WScreenMap = Record<string, FC<WScreenProps>>;
|
|
26
44
|
type ClientSidesMap = Record<string, FC<ClientSideProps>>;
|
|
@@ -32,6 +50,8 @@ interface AppProps {
|
|
|
32
50
|
myWScreens?: WScreenMap;
|
|
33
51
|
myClientSides?: ClientSidesMap;
|
|
34
52
|
myResultsOk?: ResultsOksMap;
|
|
53
|
+
/** Condiciones de los detalles, por nombre (la `condition` de un DetailTable) */
|
|
54
|
+
myConditions?: CondicionesMap;
|
|
35
55
|
}
|
|
36
56
|
|
|
37
57
|
interface CellFeedback {
|
|
@@ -41,24 +61,24 @@ interface CellFeedback {
|
|
|
41
61
|
message?: string;
|
|
42
62
|
}
|
|
43
63
|
type CellFeedbackMap = Map<string, CellFeedback>;
|
|
44
|
-
|
|
64
|
+
/** Lo que el manejo de teclas del editor necesita saber de la tecla (sirve para un evento real o uno encolado) */
|
|
65
|
+
type TeclaDeEditor = Pick<React.KeyboardEvent, 'key' | 'target'>;
|
|
66
|
+
interface InputRendererProps<R extends FilaDeDatos, S> {
|
|
45
67
|
column: Column<R, S>;
|
|
46
68
|
row: R;
|
|
47
69
|
rowIdx: number;
|
|
48
70
|
onRowChange: (row: R, commitChanges?: boolean) => void;
|
|
49
71
|
onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;
|
|
50
72
|
tableDefinition: TableDefinition;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
setTableData: React.Dispatch<React.SetStateAction<
|
|
55
|
-
setLocalCellChanges: React.Dispatch<React.SetStateAction<Map<string, Set<string>>>>;
|
|
56
|
-
localCellChanges: Map<string, Set<string>>;
|
|
73
|
+
onKeyPress?: (rowIndex: number, columnKey: string, event: TeclaDeEditor, handleCommit: (currentValue: unknown, closeEditor: boolean, focusNextCell: boolean) => Promise<void>) => void;
|
|
74
|
+
/** El editor se registra para recibir las teclas (F4) que caen en la celda antes de que él tenga el foco; devuelve la baja */
|
|
75
|
+
registrarEditor?: (procesar: (key: string) => void) => () => void;
|
|
76
|
+
setTableData: React.Dispatch<React.SetStateAction<FilaDeDatos[]>>;
|
|
57
77
|
primaryKey: string[];
|
|
58
78
|
}
|
|
59
79
|
interface Ancestor {
|
|
60
80
|
tableName: string;
|
|
61
|
-
row:
|
|
81
|
+
row: FilaDeDatos;
|
|
62
82
|
tableDefinition: TableDefinition;
|
|
63
83
|
fixedFields?: FixedField[];
|
|
64
84
|
}
|
|
@@ -71,8 +91,8 @@ interface GenericDataGridProps$1 {
|
|
|
71
91
|
}
|
|
72
92
|
interface FixedField {
|
|
73
93
|
fieldName: string;
|
|
74
|
-
value:
|
|
75
|
-
until?:
|
|
94
|
+
value: unknown;
|
|
95
|
+
until?: unknown;
|
|
76
96
|
}
|
|
77
97
|
interface ConfirmDialogProps {
|
|
78
98
|
open: boolean;
|
|
@@ -80,13 +100,37 @@ interface ConfirmDialogProps {
|
|
|
80
100
|
title: string;
|
|
81
101
|
message: string;
|
|
82
102
|
}
|
|
83
|
-
|
|
103
|
+
/** El filtro de una columna: un texto (busca que contenga) o un operador con su valor */
|
|
104
|
+
type FiltroDeColumna = string | {
|
|
105
|
+
operator?: string;
|
|
106
|
+
value?: string;
|
|
107
|
+
};
|
|
108
|
+
type FiltrosDeGrilla = Record<string, FiltroDeColumna>;
|
|
109
|
+
/** Una entrada de la fila de totales: qué se calculó (suma, promedio...) y su valor */
|
|
110
|
+
type EntradaDeTotal = {
|
|
111
|
+
type: string;
|
|
112
|
+
value: number;
|
|
113
|
+
};
|
|
114
|
+
/** Fila de resumen con los filtros de cada columna (arriba de la grilla, cuando se muestran los filtros) */
|
|
115
|
+
type FilaDeFiltros = {
|
|
116
|
+
id: 'filterRow';
|
|
117
|
+
filters: FiltrosDeGrilla;
|
|
118
|
+
setFilters: React.Dispatch<React.SetStateAction<FiltrosDeGrilla>>;
|
|
119
|
+
};
|
|
120
|
+
/** Fila de resumen con los totales de las columnas que los tienen (pie de la grilla) */
|
|
121
|
+
type FilaDeTotales = {
|
|
122
|
+
id: 'bottomSummaryRow';
|
|
123
|
+
totales: Record<string, EntradaDeTotal>;
|
|
124
|
+
};
|
|
125
|
+
/** Las filas de resumen de react-data-grid: filtros o totales */
|
|
126
|
+
type FilaDeResumen = FilaDeFiltros | FilaDeTotales;
|
|
127
|
+
interface FilterRendererProps<R extends FilaDeDatos, S> {
|
|
84
128
|
column: Column<R, S>;
|
|
85
|
-
filters:
|
|
86
|
-
setFilters: React.Dispatch<React.SetStateAction<
|
|
129
|
+
filters: FiltrosDeGrilla;
|
|
130
|
+
setFilters: React.Dispatch<React.SetStateAction<FiltrosDeGrilla>>;
|
|
87
131
|
}
|
|
88
132
|
interface GenericDataGridForDetailProps {
|
|
89
|
-
parentRow:
|
|
133
|
+
parentRow: FilaDeDatos;
|
|
90
134
|
detailTableDefinition: DetailTable;
|
|
91
135
|
parentTableName: string;
|
|
92
136
|
}
|
|
@@ -98,7 +142,7 @@ interface MenuListItemProps {
|
|
|
98
142
|
level: number;
|
|
99
143
|
onMenuItemClick?: () => void;
|
|
100
144
|
}
|
|
101
|
-
interface CustomCellProps<R extends
|
|
145
|
+
interface CustomCellProps<R extends FilaDeDatos, SR> extends RenderCellProps<R, SR> {
|
|
102
146
|
column: RenderCellProps<R, SR>['column'] & {
|
|
103
147
|
isPK?: boolean;
|
|
104
148
|
};
|
|
@@ -142,9 +186,12 @@ interface SnackbarProviderProps {
|
|
|
142
186
|
interface CallApiOptions {
|
|
143
187
|
isCritical?: boolean;
|
|
144
188
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
189
|
+
/** Los parámetros de un procedimiento por nombre; se codifican según la definición que manda el servidor */
|
|
190
|
+
type ParametrosDeProcedimiento = Record<string, unknown>;
|
|
191
|
+
interface UseApiCallResult {
|
|
192
|
+
/** R es la forma del resultado de ese procedimiento (el servidor puede no devolver nada: undefined) */
|
|
193
|
+
callApi: <R = unknown>(procedureName: string, params: ParametrosDeProcedimiento, opts?: CallApiOptions) => Promise<R | undefined>;
|
|
194
|
+
callApiUpload: <R = unknown>(procedureName: string, file: File, params: ParametrosDeProcedimiento, opts?: CallApiOptions) => Promise<R | undefined>;
|
|
148
195
|
loading: boolean;
|
|
149
196
|
error: Error | null;
|
|
150
197
|
}
|
|
@@ -172,6 +219,8 @@ interface RouterState {
|
|
|
172
219
|
redirectPath: string | null;
|
|
173
220
|
}
|
|
174
221
|
interface FetchApiOptions extends RequestInit {
|
|
222
|
+
/** No poner Content-Type: lo arma el navegador (por ejemplo con un FormData, que lleva su boundary) */
|
|
223
|
+
sinContentType?: boolean;
|
|
175
224
|
}
|
|
176
225
|
interface DataGridOption {
|
|
177
226
|
id: string;
|
|
@@ -184,15 +233,37 @@ interface DataGridOption {
|
|
|
184
233
|
interface GenericDataGridProps {
|
|
185
234
|
tableName: string;
|
|
186
235
|
fixedFields?: FixedField[];
|
|
236
|
+
/** Abre un detalle en otra pestaña (Ctrl+click o botón del medio en el botón del detalle) */
|
|
187
237
|
onOpenDetail?: (tableName: string, fixedFields: FixedField[], label: string, ancestors: Ancestor[]) => void;
|
|
188
238
|
gridStyles?: React$1.CSSProperties;
|
|
189
239
|
ancestors?: Ancestor[];
|
|
240
|
+
/** Es una grilla de detalle desplegada dentro de otra grilla */
|
|
241
|
+
anidada?: boolean;
|
|
242
|
+
/** Título a mostrar en lugar del de la tabla (por omisión, el título o nombre de la tabla, igual que la grilla principal) */
|
|
243
|
+
titulo?: string;
|
|
244
|
+
/** Clave en el CacheGrillasContext para volver a mostrarse sin recargar */
|
|
245
|
+
claveCache?: string;
|
|
246
|
+
/** La grilla anidada informa el alto que necesita para mostrarse completa */
|
|
247
|
+
onAltoDeseado?: (alto: number) => void;
|
|
248
|
+
/** La grilla anidada informa el ancho que necesita (sus columnas y los detalles que tenga abiertos) */
|
|
249
|
+
onAnchoDeseado?: (ancho: number) => void;
|
|
250
|
+
/** Alto máximo que puede tener esta grilla anidada (lo calcula la de arriba a partir de la ventana) */
|
|
251
|
+
altoDisponible?: number;
|
|
252
|
+
/**
|
|
253
|
+
* Tope opcional para el alto de las filas de detalle (en px). Sin tope (lo normal) cada detalle
|
|
254
|
+
* se muestra completo, como en backend-plus; con tope, el detalle más alto scrollea por dentro
|
|
255
|
+
* y virtualiza sus propias filas (útil si hay detalles de miles de filas).
|
|
256
|
+
*/
|
|
257
|
+
altoMaximoDetalle?: number;
|
|
190
258
|
}
|
|
259
|
+
|
|
191
260
|
declare const GenericDataGrid: React$1.FC<GenericDataGridProps>;
|
|
192
261
|
|
|
193
262
|
declare let clientSides: Record<string, React$1.FC<ClientSideProps>>;
|
|
194
263
|
declare const extendClientSides: (newRenderers: Record<string, React$1.FC<ClientSideProps>>) => void;
|
|
195
264
|
|
|
265
|
+
declare const extendConditions: (nuevas: CondicionesMap) => void;
|
|
266
|
+
|
|
196
267
|
declare const ConfirmDialog: React.FC<ConfirmDialogProps>;
|
|
197
268
|
|
|
198
269
|
interface RoutesProps {
|
|
@@ -206,7 +277,10 @@ declare const FrontendPlusProviders: React$1.FC<{
|
|
|
206
277
|
children: React$1.ReactNode;
|
|
207
278
|
publicPaths: string[];
|
|
208
279
|
}>;
|
|
209
|
-
declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk }: AppProps
|
|
280
|
+
declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions, puenteBP }: AppProps & {
|
|
281
|
+
/** Las wScreens que la aplicación no registró se piden al cliente de backend-plus (mismo origen que el backend) */
|
|
282
|
+
puenteBP?: boolean;
|
|
283
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
210
284
|
|
|
211
285
|
declare const MainLayout: React$1.FC;
|
|
212
286
|
|
|
@@ -224,8 +298,8 @@ declare const useApp: () => {
|
|
|
224
298
|
};
|
|
225
299
|
declare const AppProvider: React$1.FC<AppProviderProps>;
|
|
226
300
|
|
|
227
|
-
declare const useApiCall:
|
|
228
|
-
declare const useApiCallWithoutSnackbar:
|
|
301
|
+
declare const useApiCall: () => UseApiCallResult;
|
|
302
|
+
declare const useApiCallWithoutSnackbar: () => UseApiCallResult;
|
|
229
303
|
|
|
230
304
|
/**
|
|
231
305
|
* Hook personalizado para manejar la lógica de cierre de sesión.
|
|
@@ -245,4 +319,13 @@ type ResultComponentMap = {
|
|
|
245
319
|
declare let resultsOk: ResultComponentMap;
|
|
246
320
|
declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
|
|
247
321
|
|
|
248
|
-
|
|
322
|
+
interface GrillaBPProps {
|
|
323
|
+
tabla: string;
|
|
324
|
+
fixedFields?: FixedField[];
|
|
325
|
+
}
|
|
326
|
+
/** La grilla de backend-plus (`myOwn.tableGrid`) dentro de una página React: conserva todo lo que ya hace esa grilla */
|
|
327
|
+
declare const GrillaBP: React$1.FC<GrillaBPProps>;
|
|
328
|
+
|
|
329
|
+
declare const habilitarPuenteBP: () => void;
|
|
330
|
+
|
|
331
|
+
export { type Ancestor, App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CallApiOptions, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, type CondicionDeDetalle, type CondicionesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, DOM_TEMP_ID, type DataGridOption, type EntradaDeTotal, type FetchApiOptions, type FilaDeDatos, type FilaDeFiltros, type FilaDeResumen, type FilaDeTotales, type FilterRendererProps, type FiltroDeColumna, type FiltrosDeGrilla, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, GrillaBP, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type ParametrosDeProcedimiento, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type TeclaDeEditor, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendConditions, extendResultsOk, extendWScreens, extractPathsFromRoutes, habilitarPuenteBP, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,16 +11,34 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
11
11
|
*/
|
|
12
12
|
declare const extractPathsFromRoutes: (node: ReactNode) => string[];
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Marca con la que una fila nueva conserva su identidad en la grilla mientras se edita (antes de tener su clave primaria).
|
|
16
|
+
* Es un Symbol: no aparece en Object.keys ni en JSON.stringify, pero el spread de la fila (...fila) la conserva.
|
|
17
|
+
*/
|
|
18
|
+
declare const DOM_TEMP_ID: unique symbol;
|
|
19
|
+
/** Una fila de datos de una tabla: los valores salen del servidor ya decodificados (JSON4all) */
|
|
20
|
+
type FilaDeDatos = Record<string, unknown> & {
|
|
21
|
+
[DOM_TEMP_ID]?: string;
|
|
22
|
+
};
|
|
14
23
|
interface WScreenProps {
|
|
15
24
|
screenName: string;
|
|
25
|
+
/**
|
|
26
|
+
* Parámetros de la pantalla como objeto plano (en backend-plus, el primer argumento de `mainAction`).
|
|
27
|
+
* Como detalle de una grilla son los fixedFields del detalle; en una ruta, la query string.
|
|
28
|
+
*/
|
|
29
|
+
params?: Record<string, unknown>;
|
|
16
30
|
}
|
|
17
|
-
|
|
31
|
+
/** Decide, para una fila, si se muestra el botón de un detalle (`condition` del DetailTable) */
|
|
32
|
+
type CondicionDeDetalle = (fila: FilaDeDatos) => boolean;
|
|
33
|
+
type CondicionesMap = Record<string, CondicionDeDetalle>;
|
|
34
|
+
interface ClientSideProps extends RenderCellProps<FilaDeDatos, FilaDeResumen> {
|
|
18
35
|
fieldDefinition: FieldDefinition;
|
|
19
36
|
tableDefinition: TableDefinition;
|
|
20
37
|
primaryKey: string[];
|
|
21
38
|
}
|
|
22
39
|
interface ResultOkProps {
|
|
23
|
-
|
|
40
|
+
/** Lo que devolvió el procedimiento (la forma depende de cada procedimiento) */
|
|
41
|
+
data: unknown;
|
|
24
42
|
}
|
|
25
43
|
type WScreenMap = Record<string, FC<WScreenProps>>;
|
|
26
44
|
type ClientSidesMap = Record<string, FC<ClientSideProps>>;
|
|
@@ -32,6 +50,8 @@ interface AppProps {
|
|
|
32
50
|
myWScreens?: WScreenMap;
|
|
33
51
|
myClientSides?: ClientSidesMap;
|
|
34
52
|
myResultsOk?: ResultsOksMap;
|
|
53
|
+
/** Condiciones de los detalles, por nombre (la `condition` de un DetailTable) */
|
|
54
|
+
myConditions?: CondicionesMap;
|
|
35
55
|
}
|
|
36
56
|
|
|
37
57
|
interface CellFeedback {
|
|
@@ -41,24 +61,24 @@ interface CellFeedback {
|
|
|
41
61
|
message?: string;
|
|
42
62
|
}
|
|
43
63
|
type CellFeedbackMap = Map<string, CellFeedback>;
|
|
44
|
-
|
|
64
|
+
/** Lo que el manejo de teclas del editor necesita saber de la tecla (sirve para un evento real o uno encolado) */
|
|
65
|
+
type TeclaDeEditor = Pick<React.KeyboardEvent, 'key' | 'target'>;
|
|
66
|
+
interface InputRendererProps<R extends FilaDeDatos, S> {
|
|
45
67
|
column: Column<R, S>;
|
|
46
68
|
row: R;
|
|
47
69
|
rowIdx: number;
|
|
48
70
|
onRowChange: (row: R, commitChanges?: boolean) => void;
|
|
49
71
|
onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;
|
|
50
72
|
tableDefinition: TableDefinition;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
setTableData: React.Dispatch<React.SetStateAction<
|
|
55
|
-
setLocalCellChanges: React.Dispatch<React.SetStateAction<Map<string, Set<string>>>>;
|
|
56
|
-
localCellChanges: Map<string, Set<string>>;
|
|
73
|
+
onKeyPress?: (rowIndex: number, columnKey: string, event: TeclaDeEditor, handleCommit: (currentValue: unknown, closeEditor: boolean, focusNextCell: boolean) => Promise<void>) => void;
|
|
74
|
+
/** El editor se registra para recibir las teclas (F4) que caen en la celda antes de que él tenga el foco; devuelve la baja */
|
|
75
|
+
registrarEditor?: (procesar: (key: string) => void) => () => void;
|
|
76
|
+
setTableData: React.Dispatch<React.SetStateAction<FilaDeDatos[]>>;
|
|
57
77
|
primaryKey: string[];
|
|
58
78
|
}
|
|
59
79
|
interface Ancestor {
|
|
60
80
|
tableName: string;
|
|
61
|
-
row:
|
|
81
|
+
row: FilaDeDatos;
|
|
62
82
|
tableDefinition: TableDefinition;
|
|
63
83
|
fixedFields?: FixedField[];
|
|
64
84
|
}
|
|
@@ -71,8 +91,8 @@ interface GenericDataGridProps$1 {
|
|
|
71
91
|
}
|
|
72
92
|
interface FixedField {
|
|
73
93
|
fieldName: string;
|
|
74
|
-
value:
|
|
75
|
-
until?:
|
|
94
|
+
value: unknown;
|
|
95
|
+
until?: unknown;
|
|
76
96
|
}
|
|
77
97
|
interface ConfirmDialogProps {
|
|
78
98
|
open: boolean;
|
|
@@ -80,13 +100,37 @@ interface ConfirmDialogProps {
|
|
|
80
100
|
title: string;
|
|
81
101
|
message: string;
|
|
82
102
|
}
|
|
83
|
-
|
|
103
|
+
/** El filtro de una columna: un texto (busca que contenga) o un operador con su valor */
|
|
104
|
+
type FiltroDeColumna = string | {
|
|
105
|
+
operator?: string;
|
|
106
|
+
value?: string;
|
|
107
|
+
};
|
|
108
|
+
type FiltrosDeGrilla = Record<string, FiltroDeColumna>;
|
|
109
|
+
/** Una entrada de la fila de totales: qué se calculó (suma, promedio...) y su valor */
|
|
110
|
+
type EntradaDeTotal = {
|
|
111
|
+
type: string;
|
|
112
|
+
value: number;
|
|
113
|
+
};
|
|
114
|
+
/** Fila de resumen con los filtros de cada columna (arriba de la grilla, cuando se muestran los filtros) */
|
|
115
|
+
type FilaDeFiltros = {
|
|
116
|
+
id: 'filterRow';
|
|
117
|
+
filters: FiltrosDeGrilla;
|
|
118
|
+
setFilters: React.Dispatch<React.SetStateAction<FiltrosDeGrilla>>;
|
|
119
|
+
};
|
|
120
|
+
/** Fila de resumen con los totales de las columnas que los tienen (pie de la grilla) */
|
|
121
|
+
type FilaDeTotales = {
|
|
122
|
+
id: 'bottomSummaryRow';
|
|
123
|
+
totales: Record<string, EntradaDeTotal>;
|
|
124
|
+
};
|
|
125
|
+
/** Las filas de resumen de react-data-grid: filtros o totales */
|
|
126
|
+
type FilaDeResumen = FilaDeFiltros | FilaDeTotales;
|
|
127
|
+
interface FilterRendererProps<R extends FilaDeDatos, S> {
|
|
84
128
|
column: Column<R, S>;
|
|
85
|
-
filters:
|
|
86
|
-
setFilters: React.Dispatch<React.SetStateAction<
|
|
129
|
+
filters: FiltrosDeGrilla;
|
|
130
|
+
setFilters: React.Dispatch<React.SetStateAction<FiltrosDeGrilla>>;
|
|
87
131
|
}
|
|
88
132
|
interface GenericDataGridForDetailProps {
|
|
89
|
-
parentRow:
|
|
133
|
+
parentRow: FilaDeDatos;
|
|
90
134
|
detailTableDefinition: DetailTable;
|
|
91
135
|
parentTableName: string;
|
|
92
136
|
}
|
|
@@ -98,7 +142,7 @@ interface MenuListItemProps {
|
|
|
98
142
|
level: number;
|
|
99
143
|
onMenuItemClick?: () => void;
|
|
100
144
|
}
|
|
101
|
-
interface CustomCellProps<R extends
|
|
145
|
+
interface CustomCellProps<R extends FilaDeDatos, SR> extends RenderCellProps<R, SR> {
|
|
102
146
|
column: RenderCellProps<R, SR>['column'] & {
|
|
103
147
|
isPK?: boolean;
|
|
104
148
|
};
|
|
@@ -142,9 +186,12 @@ interface SnackbarProviderProps {
|
|
|
142
186
|
interface CallApiOptions {
|
|
143
187
|
isCritical?: boolean;
|
|
144
188
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
189
|
+
/** Los parámetros de un procedimiento por nombre; se codifican según la definición que manda el servidor */
|
|
190
|
+
type ParametrosDeProcedimiento = Record<string, unknown>;
|
|
191
|
+
interface UseApiCallResult {
|
|
192
|
+
/** R es la forma del resultado de ese procedimiento (el servidor puede no devolver nada: undefined) */
|
|
193
|
+
callApi: <R = unknown>(procedureName: string, params: ParametrosDeProcedimiento, opts?: CallApiOptions) => Promise<R | undefined>;
|
|
194
|
+
callApiUpload: <R = unknown>(procedureName: string, file: File, params: ParametrosDeProcedimiento, opts?: CallApiOptions) => Promise<R | undefined>;
|
|
148
195
|
loading: boolean;
|
|
149
196
|
error: Error | null;
|
|
150
197
|
}
|
|
@@ -172,6 +219,8 @@ interface RouterState {
|
|
|
172
219
|
redirectPath: string | null;
|
|
173
220
|
}
|
|
174
221
|
interface FetchApiOptions extends RequestInit {
|
|
222
|
+
/** No poner Content-Type: lo arma el navegador (por ejemplo con un FormData, que lleva su boundary) */
|
|
223
|
+
sinContentType?: boolean;
|
|
175
224
|
}
|
|
176
225
|
interface DataGridOption {
|
|
177
226
|
id: string;
|
|
@@ -184,15 +233,37 @@ interface DataGridOption {
|
|
|
184
233
|
interface GenericDataGridProps {
|
|
185
234
|
tableName: string;
|
|
186
235
|
fixedFields?: FixedField[];
|
|
236
|
+
/** Abre un detalle en otra pestaña (Ctrl+click o botón del medio en el botón del detalle) */
|
|
187
237
|
onOpenDetail?: (tableName: string, fixedFields: FixedField[], label: string, ancestors: Ancestor[]) => void;
|
|
188
238
|
gridStyles?: React$1.CSSProperties;
|
|
189
239
|
ancestors?: Ancestor[];
|
|
240
|
+
/** Es una grilla de detalle desplegada dentro de otra grilla */
|
|
241
|
+
anidada?: boolean;
|
|
242
|
+
/** Título a mostrar en lugar del de la tabla (por omisión, el título o nombre de la tabla, igual que la grilla principal) */
|
|
243
|
+
titulo?: string;
|
|
244
|
+
/** Clave en el CacheGrillasContext para volver a mostrarse sin recargar */
|
|
245
|
+
claveCache?: string;
|
|
246
|
+
/** La grilla anidada informa el alto que necesita para mostrarse completa */
|
|
247
|
+
onAltoDeseado?: (alto: number) => void;
|
|
248
|
+
/** La grilla anidada informa el ancho que necesita (sus columnas y los detalles que tenga abiertos) */
|
|
249
|
+
onAnchoDeseado?: (ancho: number) => void;
|
|
250
|
+
/** Alto máximo que puede tener esta grilla anidada (lo calcula la de arriba a partir de la ventana) */
|
|
251
|
+
altoDisponible?: number;
|
|
252
|
+
/**
|
|
253
|
+
* Tope opcional para el alto de las filas de detalle (en px). Sin tope (lo normal) cada detalle
|
|
254
|
+
* se muestra completo, como en backend-plus; con tope, el detalle más alto scrollea por dentro
|
|
255
|
+
* y virtualiza sus propias filas (útil si hay detalles de miles de filas).
|
|
256
|
+
*/
|
|
257
|
+
altoMaximoDetalle?: number;
|
|
190
258
|
}
|
|
259
|
+
|
|
191
260
|
declare const GenericDataGrid: React$1.FC<GenericDataGridProps>;
|
|
192
261
|
|
|
193
262
|
declare let clientSides: Record<string, React$1.FC<ClientSideProps>>;
|
|
194
263
|
declare const extendClientSides: (newRenderers: Record<string, React$1.FC<ClientSideProps>>) => void;
|
|
195
264
|
|
|
265
|
+
declare const extendConditions: (nuevas: CondicionesMap) => void;
|
|
266
|
+
|
|
196
267
|
declare const ConfirmDialog: React.FC<ConfirmDialogProps>;
|
|
197
268
|
|
|
198
269
|
interface RoutesProps {
|
|
@@ -206,7 +277,10 @@ declare const FrontendPlusProviders: React$1.FC<{
|
|
|
206
277
|
children: React$1.ReactNode;
|
|
207
278
|
publicPaths: string[];
|
|
208
279
|
}>;
|
|
209
|
-
declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk }: AppProps
|
|
280
|
+
declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions, puenteBP }: AppProps & {
|
|
281
|
+
/** Las wScreens que la aplicación no registró se piden al cliente de backend-plus (mismo origen que el backend) */
|
|
282
|
+
puenteBP?: boolean;
|
|
283
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
210
284
|
|
|
211
285
|
declare const MainLayout: React$1.FC;
|
|
212
286
|
|
|
@@ -224,8 +298,8 @@ declare const useApp: () => {
|
|
|
224
298
|
};
|
|
225
299
|
declare const AppProvider: React$1.FC<AppProviderProps>;
|
|
226
300
|
|
|
227
|
-
declare const useApiCall:
|
|
228
|
-
declare const useApiCallWithoutSnackbar:
|
|
301
|
+
declare const useApiCall: () => UseApiCallResult;
|
|
302
|
+
declare const useApiCallWithoutSnackbar: () => UseApiCallResult;
|
|
229
303
|
|
|
230
304
|
/**
|
|
231
305
|
* Hook personalizado para manejar la lógica de cierre de sesión.
|
|
@@ -245,4 +319,13 @@ type ResultComponentMap = {
|
|
|
245
319
|
declare let resultsOk: ResultComponentMap;
|
|
246
320
|
declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
|
|
247
321
|
|
|
248
|
-
|
|
322
|
+
interface GrillaBPProps {
|
|
323
|
+
tabla: string;
|
|
324
|
+
fixedFields?: FixedField[];
|
|
325
|
+
}
|
|
326
|
+
/** La grilla de backend-plus (`myOwn.tableGrid`) dentro de una página React: conserva todo lo que ya hace esa grilla */
|
|
327
|
+
declare const GrillaBP: React$1.FC<GrillaBPProps>;
|
|
328
|
+
|
|
329
|
+
declare const habilitarPuenteBP: () => void;
|
|
330
|
+
|
|
331
|
+
export { type Ancestor, App, type AppContextType, type AppProps, AppProvider, type AppProviderProps, type CallApiOptions, type CellFeedback, type CellFeedbackMap, type ClientContextState, type ClientSideProps, type ClientSidesMap, type CondicionDeDetalle, type CondicionesMap, ConfirmDialog, type ConfirmDialogProps, type CustomCellProps, type CustomHeaderCellProps, DOM_TEMP_ID, type DataGridOption, type EntradaDeTotal, type FetchApiOptions, type FilaDeDatos, type FilaDeFiltros, type FilaDeResumen, type FilaDeTotales, type FilterRendererProps, type FiltroDeColumna, type FiltrosDeGrilla, type FixedField, FrontendPlusProviders, FrontendPlusReactRoutes, GenericDataGrid, type GenericDataGridForDetailProps, type GenericDataGridProps$1 as GenericDataGridProps, GrillaBP, type InputRendererProps, MainLayout, type MenuListItemProps, type MenuUiState, type ParametrosDeProcedimiento, type PrivateRouteProps, type ResultOkProps, type ResultsOksMap, type RouterState, type SideMenuProps, type SnackbarContextType, SnackbarProvider, type SnackbarProviderProps, type SnackbarState, type TeclaDeEditor, type UseApiCallResult, type WScreenMap, type WScreenProps, cambiarGuionesBajosPorEspacios, clientSides, extendClientSides, extendConditions, extendResultsOk, extendWScreens, extractPathsFromRoutes, habilitarPuenteBP, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
|