frontend-plus-react 0.1.19 → 0.3.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/README.md +24 -0
- package/dist/index.cjs +4160 -2423
- 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 +155 -61
- package/dist/index.d.ts +155 -61
- package/dist/index.js +3996 -2227
- package/dist/index.js.map +1 -1
- package/package.json +19 -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
|
@@ -1,62 +1,58 @@
|
|
|
1
|
-
import React$1, { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import React$1, { ReactNode, FC } from 'react';
|
|
2
|
+
import { TableDefinition, FieldDefinition, MenuInfoBase, ProcedureDef, AppConfigClientSetup, DetailTable } from 'backend-plus';
|
|
3
3
|
export { FieldDefinition, TableDefinition } from 'backend-plus';
|
|
4
4
|
import { Details } from 'express-useragent';
|
|
5
5
|
import { RenderCellProps, Column, RenderHeaderCellProps } from 'react-data-grid';
|
|
6
6
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Recorre recursivamente los hijos de React buscando componentes que tengan una prop 'path'.
|
|
10
|
+
* Esto permite pasar <Route path="..."> o Fragmentos <><Route.../></> y extraer los strings.
|
|
11
|
+
*/
|
|
12
|
+
declare const extractPathsFromRoutes: (node: ReactNode) => string[];
|
|
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
|
+
};
|
|
8
23
|
interface WScreenProps {
|
|
9
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>;
|
|
10
30
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
interface ClientSideProps extends RenderCellProps<
|
|
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> {
|
|
15
35
|
fieldDefinition: FieldDefinition;
|
|
16
36
|
tableDefinition: TableDefinition;
|
|
17
37
|
primaryKey: string[];
|
|
18
38
|
}
|
|
19
|
-
declare let clientSides: Record<string, React$1.FC<ClientSideProps>>;
|
|
20
|
-
declare const extendClientSides: (newRenderers: Record<string, React$1.FC<ClientSideProps>>) => void;
|
|
21
|
-
|
|
22
39
|
interface ResultOkProps {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
type ResultComponentMap = {
|
|
26
|
-
[key: string]: React$1.FC<ResultOkProps>;
|
|
27
|
-
};
|
|
28
|
-
declare let resultsOk: ResultComponentMap;
|
|
29
|
-
declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
|
|
30
|
-
|
|
31
|
-
interface RoutesProps {
|
|
32
|
-
myRoutes?: React$1.ReactNode;
|
|
33
|
-
myUnloggedRoutes?: React$1.ReactNode;
|
|
34
|
-
layout?: React$1.ComponentType;
|
|
35
|
-
unloggedLayout?: React$1.ComponentType;
|
|
40
|
+
/** Lo que devolvió el procedimiento (la forma depende de cada procedimiento) */
|
|
41
|
+
data: unknown;
|
|
36
42
|
}
|
|
37
|
-
|
|
38
|
-
type
|
|
39
|
-
type
|
|
40
|
-
type ResultsOksMap = Record<string, React$1.FC<ResultOkProps>>;
|
|
43
|
+
type WScreenMap = Record<string, FC<WScreenProps>>;
|
|
44
|
+
type ClientSidesMap = Record<string, FC<ClientSideProps>>;
|
|
45
|
+
type ResultsOksMap = Record<string, FC<ResultOkProps>>;
|
|
41
46
|
interface AppProps {
|
|
42
|
-
myRoutes?:
|
|
43
|
-
myUnloggedRoutes?:
|
|
44
|
-
unloggedLayout?: React
|
|
47
|
+
myRoutes?: ReactNode;
|
|
48
|
+
myUnloggedRoutes?: ReactNode;
|
|
49
|
+
unloggedLayout?: React.ComponentType;
|
|
45
50
|
myWScreens?: WScreenMap;
|
|
46
51
|
myClientSides?: ClientSidesMap;
|
|
47
52
|
myResultsOk?: ResultsOksMap;
|
|
53
|
+
/** Condiciones de los detalles, por nombre (la `condition` de un DetailTable) */
|
|
54
|
+
myConditions?: CondicionesMap;
|
|
48
55
|
}
|
|
49
|
-
declare const FrontendPlusProviders: React$1.FC<{
|
|
50
|
-
children: React$1.ReactNode;
|
|
51
|
-
publicPaths: string[];
|
|
52
|
-
}>;
|
|
53
|
-
declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk }: AppProps) => react_jsx_runtime.JSX.Element;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Recorre recursivamente los hijos de React buscando componentes que tengan una prop 'path'.
|
|
57
|
-
* Esto permite pasar <Route path="..."> o Fragmentos <><Route.../></> y extraer los strings.
|
|
58
|
-
*/
|
|
59
|
-
declare const extractPathsFromRoutes: (node: ReactNode) => string[];
|
|
60
56
|
|
|
61
57
|
interface CellFeedback {
|
|
62
58
|
rowId: string;
|
|
@@ -65,27 +61,38 @@ interface CellFeedback {
|
|
|
65
61
|
message?: string;
|
|
66
62
|
}
|
|
67
63
|
type CellFeedbackMap = Map<string, CellFeedback>;
|
|
68
|
-
|
|
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> {
|
|
69
67
|
column: Column<R, S>;
|
|
70
68
|
row: R;
|
|
71
69
|
rowIdx: number;
|
|
72
70
|
onRowChange: (row: R, commitChanges?: boolean) => void;
|
|
73
71
|
onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;
|
|
74
72
|
tableDefinition: TableDefinition;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
setTableData: React.Dispatch<React.SetStateAction<
|
|
79
|
-
setLocalCellChanges: React.Dispatch<React.SetStateAction<Map<string, Set<string>>>>;
|
|
80
|
-
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[]>>;
|
|
81
77
|
primaryKey: string[];
|
|
82
78
|
}
|
|
79
|
+
interface Ancestor {
|
|
80
|
+
tableName: string;
|
|
81
|
+
row: FilaDeDatos;
|
|
82
|
+
tableDefinition: TableDefinition;
|
|
83
|
+
fixedFields?: FixedField[];
|
|
84
|
+
}
|
|
83
85
|
interface GenericDataGridProps$1 {
|
|
86
|
+
tableName: string;
|
|
87
|
+
fixedFields?: FixedField[];
|
|
88
|
+
onOpenDetail?: (tableName: string, fixedFields: FixedField[], label: string, ancestors: Ancestor[]) => void;
|
|
89
|
+
gridStyles?: React.CSSProperties;
|
|
90
|
+
ancestors?: Ancestor[];
|
|
84
91
|
}
|
|
85
92
|
interface FixedField {
|
|
86
93
|
fieldName: string;
|
|
87
|
-
value:
|
|
88
|
-
until?:
|
|
94
|
+
value: unknown;
|
|
95
|
+
until?: unknown;
|
|
89
96
|
}
|
|
90
97
|
interface ConfirmDialogProps {
|
|
91
98
|
open: boolean;
|
|
@@ -93,13 +100,37 @@ interface ConfirmDialogProps {
|
|
|
93
100
|
title: string;
|
|
94
101
|
message: string;
|
|
95
102
|
}
|
|
96
|
-
|
|
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> {
|
|
97
128
|
column: Column<R, S>;
|
|
98
|
-
filters:
|
|
99
|
-
setFilters: React.Dispatch<React.SetStateAction<
|
|
129
|
+
filters: FiltrosDeGrilla;
|
|
130
|
+
setFilters: React.Dispatch<React.SetStateAction<FiltrosDeGrilla>>;
|
|
100
131
|
}
|
|
101
132
|
interface GenericDataGridForDetailProps {
|
|
102
|
-
parentRow:
|
|
133
|
+
parentRow: FilaDeDatos;
|
|
103
134
|
detailTableDefinition: DetailTable;
|
|
104
135
|
parentTableName: string;
|
|
105
136
|
}
|
|
@@ -111,7 +142,7 @@ interface MenuListItemProps {
|
|
|
111
142
|
level: number;
|
|
112
143
|
onMenuItemClick?: () => void;
|
|
113
144
|
}
|
|
114
|
-
interface CustomCellProps<R extends
|
|
145
|
+
interface CustomCellProps<R extends FilaDeDatos, SR> extends RenderCellProps<R, SR> {
|
|
115
146
|
column: RenderCellProps<R, SR>['column'] & {
|
|
116
147
|
isPK?: boolean;
|
|
117
148
|
};
|
|
@@ -152,10 +183,15 @@ interface SnackbarContextType {
|
|
|
152
183
|
interface SnackbarProviderProps {
|
|
153
184
|
children: ReactNode;
|
|
154
185
|
}
|
|
155
|
-
interface
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
186
|
+
interface CallApiOptions {
|
|
187
|
+
isCritical?: boolean;
|
|
188
|
+
}
|
|
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>;
|
|
159
195
|
loading: boolean;
|
|
160
196
|
error: Error | null;
|
|
161
197
|
}
|
|
@@ -183,17 +219,66 @@ interface RouterState {
|
|
|
183
219
|
redirectPath: string | null;
|
|
184
220
|
}
|
|
185
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;
|
|
224
|
+
}
|
|
225
|
+
interface DataGridOption {
|
|
226
|
+
id: string;
|
|
227
|
+
label: string;
|
|
228
|
+
icon: React.ReactNode;
|
|
229
|
+
handler: () => Promise<void>;
|
|
230
|
+
visible?: boolean;
|
|
186
231
|
}
|
|
187
232
|
|
|
188
233
|
interface GenericDataGridProps {
|
|
189
234
|
tableName: string;
|
|
190
235
|
fixedFields?: FixedField[];
|
|
236
|
+
/** Abre un detalle en otra pestaña (Ctrl+click o botón del medio en el botón del detalle) */
|
|
237
|
+
onOpenDetail?: (tableName: string, fixedFields: FixedField[], label: string, ancestors: Ancestor[]) => void;
|
|
191
238
|
gridStyles?: React$1.CSSProperties;
|
|
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;
|
|
192
258
|
}
|
|
259
|
+
|
|
193
260
|
declare const GenericDataGrid: React$1.FC<GenericDataGridProps>;
|
|
194
261
|
|
|
262
|
+
declare let clientSides: Record<string, React$1.FC<ClientSideProps>>;
|
|
263
|
+
declare const extendClientSides: (newRenderers: Record<string, React$1.FC<ClientSideProps>>) => void;
|
|
264
|
+
|
|
265
|
+
declare const extendConditions: (nuevas: CondicionesMap) => void;
|
|
266
|
+
|
|
195
267
|
declare const ConfirmDialog: React.FC<ConfirmDialogProps>;
|
|
196
268
|
|
|
269
|
+
interface RoutesProps {
|
|
270
|
+
myRoutes?: React$1.ReactNode;
|
|
271
|
+
myUnloggedRoutes?: React$1.ReactNode;
|
|
272
|
+
layout?: React$1.ComponentType;
|
|
273
|
+
unloggedLayout?: React$1.ComponentType;
|
|
274
|
+
}
|
|
275
|
+
declare function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout, unloggedLayout: UnloggedLayout }: RoutesProps): react_jsx_runtime.JSX.Element;
|
|
276
|
+
declare const FrontendPlusProviders: React$1.FC<{
|
|
277
|
+
children: React$1.ReactNode;
|
|
278
|
+
publicPaths: string[];
|
|
279
|
+
}>;
|
|
280
|
+
declare const App: ({ myRoutes, myUnloggedRoutes, unloggedLayout, myWScreens, myClientSides, myResultsOk, myConditions }: AppProps) => react_jsx_runtime.JSX.Element;
|
|
281
|
+
|
|
197
282
|
declare const MainLayout: React$1.FC;
|
|
198
283
|
|
|
199
284
|
declare const SnackbarProvider: React$1.FC<SnackbarProviderProps>;
|
|
@@ -210,8 +295,8 @@ declare const useApp: () => {
|
|
|
210
295
|
};
|
|
211
296
|
declare const AppProvider: React$1.FC<AppProviderProps>;
|
|
212
297
|
|
|
213
|
-
declare const useApiCall:
|
|
214
|
-
declare const useApiCallWithoutSnackbar:
|
|
298
|
+
declare const useApiCall: () => UseApiCallResult;
|
|
299
|
+
declare const useApiCallWithoutSnackbar: () => UseApiCallResult;
|
|
215
300
|
|
|
216
301
|
/**
|
|
217
302
|
* Hook personalizado para manejar la lógica de cierre de sesión.
|
|
@@ -222,4 +307,13 @@ declare const useLogout: () => () => Promise<void>;
|
|
|
222
307
|
|
|
223
308
|
declare const cambiarGuionesBajosPorEspacios: (texto: string) => string;
|
|
224
309
|
|
|
225
|
-
|
|
310
|
+
declare let wScreens: Record<string, React$1.FC<WScreenProps>>;
|
|
311
|
+
declare const extendWScreens: (newWScreens: Record<string, React$1.FC<WScreenProps>>) => void;
|
|
312
|
+
|
|
313
|
+
type ResultComponentMap = {
|
|
314
|
+
[key: string]: React$1.FC<ResultOkProps>;
|
|
315
|
+
};
|
|
316
|
+
declare let resultsOk: ResultComponentMap;
|
|
317
|
+
declare const extendResultsOk: (newComponents: ResultComponentMap) => void;
|
|
318
|
+
|
|
319
|
+
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, 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, resultsOk as resultComponents, useApiCall, useApiCallWithoutSnackbar, useApp, useLogout, useSnackbar, wScreens };
|