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.d.ts
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 };
|