frontend-plus-react 0.2.0 → 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 +2061 -1608
- 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 +95 -24
- package/dist/index.d.ts +95 -24
- package/dist/index.js +1662 -1177
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/grid/GenericDataGrid.tsx
|
|
2
|
-
import { useState as useState12, useEffect as
|
|
2
|
+
import { useState as useState12, useEffect as useEffect5, useCallback as useCallback11, useContext as useContext4, useMemo as useMemo9, useRef as useRef6 } from "react";
|
|
3
3
|
import { DataGrid } from "react-data-grid";
|
|
4
4
|
import "react-data-grid/lib/styles.css";
|
|
5
5
|
|
|
@@ -66,12 +66,27 @@ var useSnackbar = () => {
|
|
|
66
66
|
return context;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
// src/utils/errores.ts
|
|
70
|
+
function mensajeDeError(error, porDefecto = "Error desconocido") {
|
|
71
|
+
if (error instanceof Error) return error.message || porDefecto;
|
|
72
|
+
if (typeof error === "string" && error !== "") return error;
|
|
73
|
+
return porDefecto;
|
|
74
|
+
}
|
|
75
|
+
function requerido(valor, descripcion) {
|
|
76
|
+
if (valor === null || valor === void 0) {
|
|
77
|
+
throw new Error(`El servidor no devolvi\xF3 ${descripcion}`);
|
|
78
|
+
}
|
|
79
|
+
return valor;
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
// src/env.ts
|
|
70
83
|
var getEnvVar = (key) => {
|
|
71
|
-
|
|
84
|
+
const viteEnv = import.meta.env;
|
|
85
|
+
if (viteEnv) {
|
|
72
86
|
const viteKey = `VITE_${key}`;
|
|
73
|
-
|
|
74
|
-
|
|
87
|
+
const valor = viteEnv[viteKey];
|
|
88
|
+
if (valor) {
|
|
89
|
+
return valor;
|
|
75
90
|
}
|
|
76
91
|
}
|
|
77
92
|
if (typeof process !== "undefined" && process.env) {
|
|
@@ -93,61 +108,89 @@ var envConfig = {
|
|
|
93
108
|
|
|
94
109
|
// src/utils/fetchApi.ts
|
|
95
110
|
import JSON4all from "json4all";
|
|
111
|
+
var obtenerDefinicionesDeProcedimientos = () => void 0;
|
|
112
|
+
function registrarFuenteDeProcedimientos(fuente) {
|
|
113
|
+
obtenerDefinicionesDeProcedimientos = fuente;
|
|
114
|
+
}
|
|
115
|
+
function codificarParametro(valor, encoding, procedureName, paramName) {
|
|
116
|
+
switch (encoding ?? "JSON4all") {
|
|
117
|
+
case "plain":
|
|
118
|
+
if (typeof valor === "object" && valor !== null) {
|
|
119
|
+
throw new Error(`El par\xE1metro '${paramName}' de '${procedureName}' es plain y no admite objetos`);
|
|
120
|
+
}
|
|
121
|
+
return String(valor);
|
|
122
|
+
case "JSON":
|
|
123
|
+
return JSON.stringify(valor);
|
|
124
|
+
case "JSON4all":
|
|
125
|
+
return JSON4all.stringify(valor);
|
|
126
|
+
default:
|
|
127
|
+
throw new Error(`Encoding '${encoding}' no soportado para el par\xE1metro '${paramName}' de '${procedureName}'`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function codificarParametros(procedureName, params) {
|
|
131
|
+
const definicion = obtenerDefinicionesDeProcedimientos()?.[procedureName];
|
|
132
|
+
const codificados = {};
|
|
133
|
+
if (!definicion) {
|
|
134
|
+
for (const [nombre, valor] of Object.entries(params)) {
|
|
135
|
+
if (valor === void 0) continue;
|
|
136
|
+
codificados[nombre] = typeof valor === "object" && valor !== null ? JSON4all.stringify(valor) : String(valor);
|
|
137
|
+
}
|
|
138
|
+
return { codificados, method: "post" };
|
|
139
|
+
}
|
|
140
|
+
const declarados = new Set(definicion.parameters.map((p) => p.name));
|
|
141
|
+
for (const nombre of Object.keys(params)) {
|
|
142
|
+
if (!declarados.has(nombre)) {
|
|
143
|
+
console.warn(`El par\xE1metro '${nombre}' no est\xE1 declarado en el procedimiento '${procedureName}' y no se env\xEDa`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (const paramDef of definicion.parameters) {
|
|
147
|
+
const valor = params[paramDef.name];
|
|
148
|
+
if (valor === void 0) continue;
|
|
149
|
+
codificados[paramDef.name] = codificarParametro(valor, paramDef.encoding, procedureName, paramDef.name);
|
|
150
|
+
}
|
|
151
|
+
return { codificados, method: definicion.method ?? "post" };
|
|
152
|
+
}
|
|
96
153
|
async function fetchApi(endPoint, options) {
|
|
97
154
|
const BACKEND_URL = envConfig.backendUrl;
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
155
|
+
const { sinContentType, ...opcionesDeFetch } = options;
|
|
156
|
+
const headers = new Headers(opcionesDeFetch.headers);
|
|
157
|
+
if (!sinContentType && !headers.has("Content-Type")) {
|
|
158
|
+
headers.set("Content-Type", "application/x-www-form-urlencoded");
|
|
159
|
+
}
|
|
101
160
|
const config = {
|
|
102
|
-
...
|
|
103
|
-
headers
|
|
104
|
-
...options?.headers && "Content-Type" in options.headers && options.headers["Content-Type"] === void 0 ? {} : { "Content-Type": "application/x-www-form-urlencoded" },
|
|
105
|
-
...options?.headers
|
|
106
|
-
},
|
|
161
|
+
...opcionesDeFetch,
|
|
162
|
+
headers,
|
|
107
163
|
credentials: "include"
|
|
108
164
|
};
|
|
109
|
-
if (config.headers && config.headers["Content-Type"] === void 0) {
|
|
110
|
-
delete config.headers["Content-Type"];
|
|
111
|
-
}
|
|
112
165
|
if (config.method === "GET" || config.method === "HEAD") {
|
|
113
166
|
delete config.body;
|
|
114
167
|
}
|
|
115
168
|
return await fetch(BACKEND_URL + endPoint, config);
|
|
116
169
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
} catch (e) {
|
|
127
|
-
console.warn(`Warning: Could not stringify value for key '${key}'. Keeping original value. Error:`, e);
|
|
128
|
-
newParams[key] = value;
|
|
129
|
-
}
|
|
130
|
-
} else {
|
|
131
|
-
newParams[key] = value;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return newParams;
|
|
170
|
+
function esRespuestaConError(resultado) {
|
|
171
|
+
if (typeof resultado !== "object" || resultado === null || !("error" in resultado)) return false;
|
|
172
|
+
const { error } = resultado;
|
|
173
|
+
return typeof error === "object" && error !== null && "message" in error;
|
|
174
|
+
}
|
|
175
|
+
function resultadoDeProcedimiento(texto) {
|
|
176
|
+
const resultado = parseBackendResponse(texto);
|
|
177
|
+
if (esRespuestaConError(resultado)) {
|
|
178
|
+
throw new Error(resultado.error.message);
|
|
136
179
|
}
|
|
137
|
-
|
|
138
|
-
|
|
180
|
+
return resultado;
|
|
181
|
+
}
|
|
182
|
+
async function ejecutar(descripcion, procedureName, pedido) {
|
|
183
|
+
const response = await pedido;
|
|
139
184
|
if (response.ok) {
|
|
140
|
-
|
|
141
|
-
const result = parseBackendResponse(rawResponseText);
|
|
142
|
-
if (result.error) {
|
|
143
|
-
throw new Error(result.error.message);
|
|
144
|
-
} else {
|
|
145
|
-
return result;
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
const errorTextDefinition = await response.text();
|
|
149
|
-
throw new Error(`Error al ejecutar procedure '${procedureName}': ${response.status} - ${errorTextDefinition}`);
|
|
185
|
+
return resultadoDeProcedimiento(await response.text());
|
|
150
186
|
}
|
|
187
|
+
const errorTextDefinition = await response.text();
|
|
188
|
+
throw new Error(`Error al ejecutar ${descripcion} '${procedureName}': ${response.status} - ${errorTextDefinition}`);
|
|
189
|
+
}
|
|
190
|
+
var executeBackendProcedure = async (procedureName, params) => {
|
|
191
|
+
const { codificados, method } = codificarParametros(procedureName, params);
|
|
192
|
+
const query = new URLSearchParams(codificados);
|
|
193
|
+
return ejecutar("procedure", procedureName, method === "get" ? fetchApi(`/${procedureName}?${query}`, { method: "GET" }) : fetchApi(`/${procedureName}`, { body: query, method: "POST" }));
|
|
151
194
|
};
|
|
152
195
|
function parseBackendResponse(text) {
|
|
153
196
|
const trimmedText = text.trim();
|
|
@@ -178,45 +221,21 @@ function parseBackendResponse(text) {
|
|
|
178
221
|
}
|
|
179
222
|
}
|
|
180
223
|
}
|
|
181
|
-
throw new Error(`No se pudo parsear la respuesta del servidor: ${e
|
|
224
|
+
throw new Error(`No se pudo parsear la respuesta del servidor: ${mensajeDeError(e)}`);
|
|
182
225
|
}
|
|
183
226
|
}
|
|
184
227
|
var executeBackendUpload = async (procedureName, file, params) => {
|
|
185
228
|
const formData = new FormData();
|
|
186
229
|
formData.append("file", file);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (typeof value === "object" && value !== null) {
|
|
191
|
-
formData.append(key, JSON.stringify(value));
|
|
192
|
-
} else {
|
|
193
|
-
formData.append(key, value);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const response = await fetchApi(`/${procedureName}`, {
|
|
198
|
-
body: formData,
|
|
199
|
-
method: "POST",
|
|
200
|
-
headers: {
|
|
201
|
-
"Content-Type": void 0
|
|
202
|
-
// Dejamos que el navegador establezca el boundary
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
if (response.ok) {
|
|
206
|
-
const rawResponseText = await response.text();
|
|
207
|
-
const result = parseBackendResponse(rawResponseText);
|
|
208
|
-
if (result.error) {
|
|
209
|
-
throw new Error(result.error.message);
|
|
210
|
-
} else {
|
|
211
|
-
return result;
|
|
212
|
-
}
|
|
213
|
-
} else {
|
|
214
|
-
const errorTextDefinition = await response.text();
|
|
215
|
-
throw new Error(`Error al ejecutar upload '${procedureName}': ${response.status} - ${errorTextDefinition}`);
|
|
230
|
+
const { codificados } = codificarParametros(procedureName, params);
|
|
231
|
+
for (const [key, value] of Object.entries(codificados)) {
|
|
232
|
+
formData.append(key, value);
|
|
216
233
|
}
|
|
234
|
+
return ejecutar("upload", procedureName, fetchApi(`/${procedureName}`, { body: formData, method: "POST", sinContentType: true }));
|
|
217
235
|
};
|
|
218
236
|
|
|
219
237
|
// src/hooks/useApiCall.ts
|
|
238
|
+
var comoError = (err) => err instanceof Error ? err : new Error(mensajeDeError(err));
|
|
220
239
|
var useApiCall = () => {
|
|
221
240
|
const { showSnackbar } = useSnackbar();
|
|
222
241
|
const [loading, setLoading] = useState2(false);
|
|
@@ -228,7 +247,7 @@ var useApiCall = () => {
|
|
|
228
247
|
const result = await executeBackendProcedure(procedureName, params);
|
|
229
248
|
return result === null ? void 0 : result;
|
|
230
249
|
} catch (err) {
|
|
231
|
-
if (opts.isCritical) setError(err);
|
|
250
|
+
if (opts.isCritical) setError(comoError(err));
|
|
232
251
|
let snackbarMessage = `Error inesperado al ejecutar '${procedureName}'.`;
|
|
233
252
|
if (err instanceof TypeError) {
|
|
234
253
|
snackbarMessage = `Problema de conexi\xF3n: ${err.message}. Por favor, revisa tu internet o intenta de nuevo.`;
|
|
@@ -248,7 +267,7 @@ var useApiCall = () => {
|
|
|
248
267
|
const result = await executeBackendUpload(procedureName, file, params);
|
|
249
268
|
return result === null ? void 0 : result;
|
|
250
269
|
} catch (err) {
|
|
251
|
-
if (opts.isCritical) setError(err);
|
|
270
|
+
if (opts.isCritical) setError(comoError(err));
|
|
252
271
|
let snackbarMessage = `Error inesperado al subir archivo en '${procedureName}'.`;
|
|
253
272
|
if (err instanceof TypeError) {
|
|
254
273
|
snackbarMessage = `Problema de conexi\xF3n: ${err.message}. Por favor, revisa tu internet o intenta de nuevo.`;
|
|
@@ -266,28 +285,28 @@ var useApiCall = () => {
|
|
|
266
285
|
var useApiCallWithoutSnackbar = () => {
|
|
267
286
|
const [loading, setLoading] = useState2(false);
|
|
268
287
|
const [error, setError] = useState2(null);
|
|
269
|
-
const callApi = useCallback2(async (procedureName, params,
|
|
288
|
+
const callApi = useCallback2(async (procedureName, params, _opts = { isCritical: true }) => {
|
|
270
289
|
setLoading(true);
|
|
271
290
|
setError(null);
|
|
272
291
|
try {
|
|
273
292
|
const result = await executeBackendProcedure(procedureName, params);
|
|
274
293
|
return result === null ? void 0 : result;
|
|
275
294
|
} catch (err) {
|
|
276
|
-
setError(err);
|
|
295
|
+
setError(comoError(err));
|
|
277
296
|
console.error(`Error en la llamada API (WithoutSnackbar) para ${procedureName}:`, err);
|
|
278
297
|
throw err;
|
|
279
298
|
} finally {
|
|
280
299
|
setLoading(false);
|
|
281
300
|
}
|
|
282
301
|
}, []);
|
|
283
|
-
const callApiUpload = useCallback2(async (procedureName, file, params,
|
|
302
|
+
const callApiUpload = useCallback2(async (procedureName, file, params, _opts = { isCritical: true }) => {
|
|
284
303
|
setLoading(true);
|
|
285
304
|
setError(null);
|
|
286
305
|
try {
|
|
287
306
|
const result = await executeBackendUpload(procedureName, file, params);
|
|
288
307
|
return result === null ? void 0 : result;
|
|
289
308
|
} catch (err) {
|
|
290
|
-
setError(err);
|
|
309
|
+
setError(comoError(err));
|
|
291
310
|
console.error(`Error en la subida API (WithoutSnackbar) para ${procedureName}:`, err);
|
|
292
311
|
throw err;
|
|
293
312
|
} finally {
|
|
@@ -300,6 +319,207 @@ var useApiCallWithoutSnackbar = () => {
|
|
|
300
319
|
// src/components/grid/GenericDataGrid.tsx
|
|
301
320
|
import { CircularProgress as CircularProgress4, Typography as Typography8, Box as Box12, Alert as Alert2, useTheme as useTheme4, Dialog as Dialog4 } from "@mui/material";
|
|
302
321
|
|
|
322
|
+
// src/store/index.ts
|
|
323
|
+
import { configureStore, combineReducers } from "@reduxjs/toolkit";
|
|
324
|
+
import {
|
|
325
|
+
persistStore,
|
|
326
|
+
persistReducer,
|
|
327
|
+
FLUSH,
|
|
328
|
+
REHYDRATE,
|
|
329
|
+
PAUSE,
|
|
330
|
+
PERSIST,
|
|
331
|
+
PURGE,
|
|
332
|
+
REGISTER
|
|
333
|
+
} from "redux-persist";
|
|
334
|
+
import storage from "redux-persist/lib/storage";
|
|
335
|
+
|
|
336
|
+
// src/store/clientContextSlice.ts
|
|
337
|
+
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
|
|
338
|
+
var initialState = {
|
|
339
|
+
menu: [],
|
|
340
|
+
procedure: {},
|
|
341
|
+
procedures: [],
|
|
342
|
+
config: {},
|
|
343
|
+
// Inicializa con un objeto vacío o valores por defecto adecuados
|
|
344
|
+
useragent: {},
|
|
345
|
+
// Igual aquí
|
|
346
|
+
username: "",
|
|
347
|
+
status: "idle",
|
|
348
|
+
// Por defecto, sin carga
|
|
349
|
+
error: null
|
|
350
|
+
// Sin error
|
|
351
|
+
};
|
|
352
|
+
var fetchClientContext = createAsyncThunk(
|
|
353
|
+
"clientContext/fetchClientContext",
|
|
354
|
+
async (_, { rejectWithValue }) => {
|
|
355
|
+
try {
|
|
356
|
+
const setupResponse = await fetchApi("/client-setup", { method: "GET" });
|
|
357
|
+
if (!setupResponse.ok) {
|
|
358
|
+
const errorData = await setupResponse.text();
|
|
359
|
+
throw new Error(errorData || "Error al obtener configuraci\xF3n del cliente");
|
|
360
|
+
}
|
|
361
|
+
const clientSetup = await setupResponse.json();
|
|
362
|
+
return clientSetup;
|
|
363
|
+
} catch (error) {
|
|
364
|
+
return rejectWithValue(mensajeDeError(error, "Error desconocido al cargar el contexto"));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
);
|
|
368
|
+
var clientContextSlice = createSlice({
|
|
369
|
+
name: "clientContext",
|
|
370
|
+
initialState,
|
|
371
|
+
reducers: {
|
|
372
|
+
// Un reducer para limpiar el contexto del cliente (ej. al cerrar sesión)
|
|
373
|
+
clearClientContext: (state) => {
|
|
374
|
+
Object.assign(state, initialState);
|
|
375
|
+
}
|
|
376
|
+
// Puedes añadir otros reducers aquí si necesitas modificar partes del clientContext directamente
|
|
377
|
+
// pero el thunk es la forma preferida para la carga inicial.
|
|
378
|
+
},
|
|
379
|
+
// **extraReducers maneja las acciones del thunk asíncrono**
|
|
380
|
+
extraReducers: (builder) => {
|
|
381
|
+
builder.addCase(fetchClientContext.pending, (state) => {
|
|
382
|
+
state.status = "loading";
|
|
383
|
+
state.error = null;
|
|
384
|
+
}).addCase(fetchClientContext.fulfilled, (state, action) => {
|
|
385
|
+
state.status = "succeeded";
|
|
386
|
+
state.menu = action.payload.menu;
|
|
387
|
+
state.procedure = action.payload.procedure;
|
|
388
|
+
state.procedures = action.payload.procedures;
|
|
389
|
+
state.config = action.payload.config;
|
|
390
|
+
state.useragent = action.payload.useragent;
|
|
391
|
+
state.username = action.payload.username;
|
|
392
|
+
state.error = null;
|
|
393
|
+
}).addCase(fetchClientContext.rejected, (state, action) => {
|
|
394
|
+
state.status = "failed";
|
|
395
|
+
state.error = action.payload || "Fallo al cargar el contexto del cliente";
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
var { clearClientContext } = clientContextSlice.actions;
|
|
400
|
+
var clientContextSlice_default = clientContextSlice.reducer;
|
|
401
|
+
|
|
402
|
+
// src/store/routerSlice.ts
|
|
403
|
+
import { createSlice as createSlice2 } from "@reduxjs/toolkit";
|
|
404
|
+
var initialState2 = {
|
|
405
|
+
currentPath: "/",
|
|
406
|
+
previousPath: null,
|
|
407
|
+
redirectPath: null
|
|
408
|
+
// <--- Inicializamos en null
|
|
409
|
+
};
|
|
410
|
+
var routerSlice = createSlice2({
|
|
411
|
+
name: "router",
|
|
412
|
+
initialState: initialState2,
|
|
413
|
+
reducers: {
|
|
414
|
+
setCurrentPath: (state, action) => {
|
|
415
|
+
state.previousPath = state.currentPath;
|
|
416
|
+
state.currentPath = action.payload;
|
|
417
|
+
},
|
|
418
|
+
setRedirectPath: (state, action) => {
|
|
419
|
+
state.redirectPath = action.payload;
|
|
420
|
+
},
|
|
421
|
+
resetRouterState: (state) => {
|
|
422
|
+
state.currentPath = "/";
|
|
423
|
+
state.previousPath = null;
|
|
424
|
+
state.redirectPath = null;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
var { setCurrentPath, setRedirectPath, resetRouterState } = routerSlice.actions;
|
|
429
|
+
var routerSlice_default = routerSlice.reducer;
|
|
430
|
+
|
|
431
|
+
// src/store/menuUiSlice.ts
|
|
432
|
+
import { createSlice as createSlice3 } from "@reduxjs/toolkit";
|
|
433
|
+
var initialState3 = {
|
|
434
|
+
isDrawerOpen: false,
|
|
435
|
+
subMenuOpenStates: {}
|
|
436
|
+
};
|
|
437
|
+
var menuUiSlice = createSlice3({
|
|
438
|
+
name: "menuUi",
|
|
439
|
+
initialState: initialState3,
|
|
440
|
+
reducers: {
|
|
441
|
+
setDrawerOpen: (state, action) => {
|
|
442
|
+
state.isDrawerOpen = action.payload;
|
|
443
|
+
},
|
|
444
|
+
toggleDrawer: (state) => {
|
|
445
|
+
state.isDrawerOpen = !state.isDrawerOpen;
|
|
446
|
+
},
|
|
447
|
+
setSubMenuOpen: (state, action) => {
|
|
448
|
+
state.subMenuOpenStates[action.payload.menuName] = action.payload.isOpen;
|
|
449
|
+
},
|
|
450
|
+
toggleSubMenu: (state, action) => {
|
|
451
|
+
state.subMenuOpenStates[action.payload] = !state.subMenuOpenStates[action.payload];
|
|
452
|
+
},
|
|
453
|
+
// --- NUEVO REDUCER: Establecer el estado de todos los submenús ---
|
|
454
|
+
setAllSubMenusOpen: (state, action) => {
|
|
455
|
+
for (const menuName in state.subMenuOpenStates) {
|
|
456
|
+
if (Object.prototype.hasOwnProperty.call(state.subMenuOpenStates, menuName)) {
|
|
457
|
+
state.subMenuOpenStates[menuName] = action.payload;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
resetMenuUiState: (state) => {
|
|
462
|
+
Object.assign(state, initialState3);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
var {
|
|
467
|
+
setDrawerOpen,
|
|
468
|
+
toggleDrawer,
|
|
469
|
+
setSubMenuOpen,
|
|
470
|
+
toggleSubMenu,
|
|
471
|
+
setAllSubMenusOpen,
|
|
472
|
+
// ¡Exportamos la nueva acción!
|
|
473
|
+
resetMenuUiState
|
|
474
|
+
} = menuUiSlice.actions;
|
|
475
|
+
var menuUiSlice_default = menuUiSlice.reducer;
|
|
476
|
+
|
|
477
|
+
// src/store/index.ts
|
|
478
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
479
|
+
var rootReducer = combineReducers({
|
|
480
|
+
clientContext: clientContextSlice_default,
|
|
481
|
+
router: routerSlice_default,
|
|
482
|
+
menuUi: menuUiSlice_default
|
|
483
|
+
// ...otros slices
|
|
484
|
+
});
|
|
485
|
+
var persistConfig = {
|
|
486
|
+
key: "root",
|
|
487
|
+
storage,
|
|
488
|
+
whitelist: ["clientContext", "router", "menuUi"]
|
|
489
|
+
};
|
|
490
|
+
var persistedReducer = persistReducer(persistConfig, rootReducer);
|
|
491
|
+
var store = configureStore({
|
|
492
|
+
reducer: persistedReducer,
|
|
493
|
+
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
|
|
494
|
+
serializableCheck: {
|
|
495
|
+
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
|
|
496
|
+
}
|
|
497
|
+
})
|
|
498
|
+
});
|
|
499
|
+
var persistor = persistStore(store);
|
|
500
|
+
registrarFuenteDeProcedimientos(() => {
|
|
501
|
+
const { procedure, procedures } = store.getState().clientContext;
|
|
502
|
+
if (procedure && Object.keys(procedure).length > 0) return procedure;
|
|
503
|
+
return procedures?.length ? Object.fromEntries(procedures.map((p) => [p.action, p])) : void 0;
|
|
504
|
+
});
|
|
505
|
+
var useAppDispatch = useDispatch;
|
|
506
|
+
var useAppSelector = useSelector;
|
|
507
|
+
var useClientContext = () => {
|
|
508
|
+
return useAppSelector((state) => state.clientContext);
|
|
509
|
+
};
|
|
510
|
+
var useClientContextStatus = () => {
|
|
511
|
+
return useAppSelector((state) => state.clientContext.status);
|
|
512
|
+
};
|
|
513
|
+
var useIsDrawerOpen = () => {
|
|
514
|
+
return useAppSelector((state) => state.menuUi.isDrawerOpen);
|
|
515
|
+
};
|
|
516
|
+
var useSubMenuOpenState = (menuName) => {
|
|
517
|
+
return useAppSelector((state) => state.menuUi.subMenuOpenStates[menuName] || false);
|
|
518
|
+
};
|
|
519
|
+
var useRedirectPath = () => {
|
|
520
|
+
return useAppSelector((state) => state.router.redirectPath);
|
|
521
|
+
};
|
|
522
|
+
|
|
303
523
|
// src/components/ConfirmDialog.tsx
|
|
304
524
|
import Dialog from "@mui/material/Dialog";
|
|
305
525
|
import DialogTitle from "@mui/material/DialogTitle";
|
|
@@ -443,20 +663,42 @@ var DataGridOptionsDialog = ({
|
|
|
443
663
|
};
|
|
444
664
|
|
|
445
665
|
// src/components/grid/utils/helpers.ts
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
666
|
+
import typeStore from "type-store";
|
|
667
|
+
|
|
668
|
+
// src/utils/routeUtils.ts
|
|
669
|
+
import { Children, isValidElement } from "react";
|
|
670
|
+
var extractPathsFromRoutes = (node) => {
|
|
671
|
+
const paths = [];
|
|
672
|
+
Children.forEach(node, (child) => {
|
|
673
|
+
if (!isValidElement(child)) return;
|
|
674
|
+
if (child.props.path) {
|
|
675
|
+
paths.push(child.props.path);
|
|
676
|
+
}
|
|
677
|
+
if (child.props.children) {
|
|
678
|
+
paths.push(...extractPathsFromRoutes(child.props.children));
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
return paths;
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
// src/types/index.ts
|
|
685
|
+
var DOM_TEMP_ID = Symbol("domTempId");
|
|
686
|
+
|
|
687
|
+
// src/components/grid/utils/helpers.ts
|
|
688
|
+
var typerFrom = (fieldDef) => typeStore.typerFrom(fieldDef);
|
|
689
|
+
var NEW_ROW_INDICATOR = "$new";
|
|
690
|
+
var getPrimaryKeyValues = (row, primaryKey) => {
|
|
691
|
+
if (row[DOM_TEMP_ID]) return String(row[DOM_TEMP_ID]);
|
|
692
|
+
return primaryKey.map((key) => {
|
|
693
|
+
return row[key] !== void 0 && row[key] !== null ? String(row[key]) : "NULL_OR_UNDEFINED";
|
|
694
|
+
}).join("|");
|
|
695
|
+
};
|
|
696
|
+
var sameValue = (a, b) => {
|
|
697
|
+
if (a === b) return true;
|
|
698
|
+
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
|
|
699
|
+
const isAEmpty = a === null || a === void 0;
|
|
700
|
+
const isBEmpty = b === null || b === void 0;
|
|
701
|
+
if (isAEmpty && isBEmpty) return true;
|
|
460
702
|
return false;
|
|
461
703
|
};
|
|
462
704
|
var isNumericType = (typeName) => {
|
|
@@ -466,6 +708,16 @@ var isDateTimeType = (typeName) => {
|
|
|
466
708
|
const t = typeName?.toLowerCase() || "";
|
|
467
709
|
return ["date", "time", "timestamp", "interval", "tsrange", "time_range", "daterange"].some((type) => t.includes(type));
|
|
468
710
|
};
|
|
711
|
+
var compararValores = (a, b) => {
|
|
712
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
713
|
+
if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
|
|
714
|
+
if (typeof a === "string" && typeof b === "string") return a < b ? -1 : a > b ? 1 : 0;
|
|
715
|
+
if (typeof a === "bigint" && typeof b === "bigint") return a < b ? -1 : a > b ? 1 : 0;
|
|
716
|
+
const esNumerico = (v) => typeof v === "string" && v.trim() !== "" && !Number.isNaN(Number(v));
|
|
717
|
+
if (typeof a === "number" && esNumerico(b)) return a - Number(b);
|
|
718
|
+
if (esNumerico(a) && typeof b === "number") return Number(a) - b;
|
|
719
|
+
return null;
|
|
720
|
+
};
|
|
469
721
|
var filterOperators = [
|
|
470
722
|
{ value: "=", label: "=" },
|
|
471
723
|
{ value: "~", label: "~" },
|
|
@@ -632,7 +884,7 @@ var useGridActions = ({
|
|
|
632
884
|
}, 500);
|
|
633
885
|
} catch (err) {
|
|
634
886
|
console.error(`Error al eliminar la fila '${rowId}':`, err);
|
|
635
|
-
showError(`Error al eliminar la fila '${rowId}': ${err
|
|
887
|
+
showError(`Error al eliminar la fila '${rowId}': ${mensajeDeError(err, "Error desconocido")}`);
|
|
636
888
|
setExitingRowIds((prev) => {
|
|
637
889
|
const newSet = new Set(prev);
|
|
638
890
|
newSet.delete(rowId);
|
|
@@ -670,19 +922,19 @@ var useGridActions = ({
|
|
|
670
922
|
if (updated > 0) messages.push(`${updated} fila(s) actualizada(s).`);
|
|
671
923
|
if (skipped > 0) messages.push(`${skipped} fila(s) omitida(s).`);
|
|
672
924
|
if (deleted > 0) messages.push(`${deleted} fila(s) eliminada(s).`);
|
|
673
|
-
if (skippedColumns
|
|
925
|
+
if (skippedColumns && skippedColumns.length > 0) messages.push(`Columnas omitidas: ${skippedColumns.join(", ")}`);
|
|
674
926
|
showSuccess(messages.join("\n") || "Importaci\xF3n finalizada sin cambios detectados.");
|
|
675
|
-
const newData = await callApi("table_data", {
|
|
927
|
+
const newData = requerido(await callApi("table_data", {
|
|
676
928
|
table: tableName,
|
|
677
929
|
fixedFields
|
|
678
|
-
});
|
|
930
|
+
}), "los datos de la tabla");
|
|
679
931
|
setTableData(newData);
|
|
680
932
|
} else if (result && result.message) {
|
|
681
933
|
showSuccess(result.message);
|
|
682
934
|
}
|
|
683
935
|
} catch (err) {
|
|
684
936
|
console.error("Error durante la importaci\xF3n:", err);
|
|
685
|
-
showError(`Importaci\xF3n cancelada: ${err
|
|
937
|
+
showError(`Importaci\xF3n cancelada: ${mensajeDeError(err, "Error desconocido")}`);
|
|
686
938
|
}
|
|
687
939
|
}, [tableName, fixedFields, callApiUpload, callApi, showSuccess, showError, setTableData]);
|
|
688
940
|
return {
|
|
@@ -701,8 +953,8 @@ var useGridActions = ({
|
|
|
701
953
|
};
|
|
702
954
|
|
|
703
955
|
// src/hooks/grid/useGridDataView.ts
|
|
704
|
-
import { useState as useState5, useCallback as useCallback4, useMemo } from "react";
|
|
705
|
-
import
|
|
956
|
+
import { useState as useState5, useCallback as useCallback4, useMemo, useRef } from "react";
|
|
957
|
+
import typeStore2 from "type-store";
|
|
706
958
|
|
|
707
959
|
// src/components/grid/utils/typedControls.ts
|
|
708
960
|
var BestControls = {
|
|
@@ -723,7 +975,7 @@ var BestControls = {
|
|
|
723
975
|
if (plainValue === null || plainValue === void 0) {
|
|
724
976
|
return plainValue;
|
|
725
977
|
}
|
|
726
|
-
return typer.fromUserInput(plainValue);
|
|
978
|
+
return typer.fromUserInput(String(plainValue));
|
|
727
979
|
}
|
|
728
980
|
},
|
|
729
981
|
number: {
|
|
@@ -756,7 +1008,7 @@ var BestControls = {
|
|
|
756
1008
|
}
|
|
757
1009
|
},
|
|
758
1010
|
date: {
|
|
759
|
-
getTypedValue: (plainValue
|
|
1011
|
+
getTypedValue: (plainValue) => {
|
|
760
1012
|
if (plainValue === null || plainValue === void 0 || plainValue === "") return null;
|
|
761
1013
|
if (plainValue instanceof Date) return plainValue;
|
|
762
1014
|
const parts = String(plainValue).trim().split(/[-\/]/).map((s) => s.trim());
|
|
@@ -774,15 +1026,14 @@ var BestControls = {
|
|
|
774
1026
|
}
|
|
775
1027
|
const date = new Date(year, month, day);
|
|
776
1028
|
if (date.getFullYear() === year && date.getMonth() === month && date.getDate() === day) {
|
|
777
|
-
date
|
|
778
|
-
return date;
|
|
1029
|
+
return Object.assign(date, { isRealDate: true });
|
|
779
1030
|
}
|
|
780
1031
|
return null;
|
|
781
1032
|
}
|
|
782
1033
|
}
|
|
783
1034
|
};
|
|
784
|
-
var getBestTypedValue = (
|
|
785
|
-
value =
|
|
1035
|
+
var getBestTypedValue = (valor, typer) => {
|
|
1036
|
+
const value = valor === "" ? typer.emptyValue : valor;
|
|
786
1037
|
const typeName = typer.typeName;
|
|
787
1038
|
if (["integer", "bigint", "decimal", "double", "float", "number"].includes(typeName)) {
|
|
788
1039
|
return BestControls.number.getTypedValue(value);
|
|
@@ -791,12 +1042,13 @@ var getBestTypedValue = (value, typer) => {
|
|
|
791
1042
|
return BestControls.boolean.getTypedValue(value);
|
|
792
1043
|
}
|
|
793
1044
|
if (typeName === "date" || typeName && typeName.toLowerCase().includes("timestamp")) {
|
|
794
|
-
return BestControls.date.getTypedValue(value
|
|
1045
|
+
return BestControls.date.getTypedValue(value);
|
|
795
1046
|
}
|
|
796
1047
|
return BestControls.text.getTypedValue(value, typer);
|
|
797
1048
|
};
|
|
798
1049
|
|
|
799
1050
|
// src/hooks/grid/useGridDataView.ts
|
|
1051
|
+
var MAXIMO_FILAS_EDICION_PUNTUAL = 3;
|
|
800
1052
|
var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
801
1053
|
const [sortColumns, setSortColumns] = useState5([]);
|
|
802
1054
|
const getInitialSortColumns = useCallback4((def) => {
|
|
@@ -835,7 +1087,20 @@ var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
|
835
1087
|
return !prev;
|
|
836
1088
|
});
|
|
837
1089
|
}, []);
|
|
1090
|
+
const vistaAnteriorRef = useRef(null);
|
|
838
1091
|
const filteredRows = useMemo(() => {
|
|
1092
|
+
const anterior = vistaAnteriorRef.current;
|
|
1093
|
+
if (anterior && anterior.filters === filters && anterior.isFilterRowVisible === isFilterRowVisible && anterior.sortColumns === sortColumns && anterior.tableDefinition === tableDefinition && anterior.tableData.length === tableData.length) {
|
|
1094
|
+
const reemplazos = /* @__PURE__ */ new Map();
|
|
1095
|
+
for (let i = 0; i < tableData.length && reemplazos.size <= MAXIMO_FILAS_EDICION_PUNTUAL; i++) {
|
|
1096
|
+
if (anterior.tableData[i] !== tableData[i]) reemplazos.set(anterior.tableData[i], tableData[i]);
|
|
1097
|
+
}
|
|
1098
|
+
if (reemplazos.size <= MAXIMO_FILAS_EDICION_PUNTUAL) {
|
|
1099
|
+
const filas = reemplazos.size === 0 ? anterior.filas : anterior.filas.map((fila) => reemplazos.get(fila) ?? fila);
|
|
1100
|
+
vistaAnteriorRef.current = { ...anterior, tableData, filas };
|
|
1101
|
+
return filas;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
839
1104
|
let rows = [...tableData];
|
|
840
1105
|
if (isFilterRowVisible) {
|
|
841
1106
|
Object.keys(filters).forEach((key) => {
|
|
@@ -851,7 +1116,7 @@ var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
|
851
1116
|
}
|
|
852
1117
|
if (filterValue === "" && operator !== "\u2205" && operator !== "!=\u2205") return;
|
|
853
1118
|
const fieldDef = tableDefinition?.fields.find((f) => f.name === key);
|
|
854
|
-
const typer = fieldDef ?
|
|
1119
|
+
const typer = fieldDef ? typeStore2.typerFrom(fieldDef) : null;
|
|
855
1120
|
let parsedFilterValue = filterValue;
|
|
856
1121
|
if (typer && filterValue !== "" && !["~", "!~", "\u2205", "!=\u2205"].includes(operator)) {
|
|
857
1122
|
try {
|
|
@@ -885,14 +1150,22 @@ var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
|
885
1150
|
return rawValue === null || rawValue === void 0 || rawValue === "";
|
|
886
1151
|
case "!=\u2205":
|
|
887
1152
|
return rawValue !== null && rawValue !== void 0 && rawValue !== "";
|
|
888
|
-
case ">":
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
case "
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1153
|
+
case ">": {
|
|
1154
|
+
const orden = compararValores(rawValue, parsedFilterValue);
|
|
1155
|
+
return orden !== null && orden > 0;
|
|
1156
|
+
}
|
|
1157
|
+
case ">=": {
|
|
1158
|
+
const orden = compararValores(rawValue, parsedFilterValue);
|
|
1159
|
+
return orden !== null && orden >= 0;
|
|
1160
|
+
}
|
|
1161
|
+
case "<": {
|
|
1162
|
+
const orden = compararValores(rawValue, parsedFilterValue);
|
|
1163
|
+
return orden !== null && orden < 0;
|
|
1164
|
+
}
|
|
1165
|
+
case "<=": {
|
|
1166
|
+
const orden = compararValores(rawValue, parsedFilterValue);
|
|
1167
|
+
return orden !== null && orden <= 0;
|
|
1168
|
+
}
|
|
896
1169
|
default:
|
|
897
1170
|
return cellValue.includes(fValLower);
|
|
898
1171
|
}
|
|
@@ -919,6 +1192,7 @@ var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
|
919
1192
|
return 0;
|
|
920
1193
|
});
|
|
921
1194
|
}
|
|
1195
|
+
vistaAnteriorRef.current = { tableData, filas: rows, filters, isFilterRowVisible, sortColumns, tableDefinition };
|
|
922
1196
|
return rows;
|
|
923
1197
|
}, [tableData, filters, isFilterRowVisible, tableDefinition, sortColumns]);
|
|
924
1198
|
const summaryData = useMemo(() => {
|
|
@@ -931,10 +1205,10 @@ var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
|
931
1205
|
if (values.length === 0 && agg !== "count" && agg !== "countTrue") return;
|
|
932
1206
|
switch (agg) {
|
|
933
1207
|
case "sum":
|
|
934
|
-
result[field.name] = { type: "sum", value: values.reduce((a, b) =>
|
|
1208
|
+
result[field.name] = { type: "sum", value: values.reduce((a, b) => a + Number(b), 0) };
|
|
935
1209
|
break;
|
|
936
1210
|
case "avg":
|
|
937
|
-
const sum = values.reduce((a, b) =>
|
|
1211
|
+
const sum = values.reduce((a, b) => a + Number(b), 0);
|
|
938
1212
|
result[field.name] = { type: "avg", value: sum / values.length };
|
|
939
1213
|
break;
|
|
940
1214
|
case "min":
|
|
@@ -979,29 +1253,195 @@ var useGridDataView = ({ tableData, tableDefinition }) => {
|
|
|
979
1253
|
};
|
|
980
1254
|
|
|
981
1255
|
// src/hooks/grid/useGridEvents.ts
|
|
982
|
-
import { useCallback as useCallback5 } from "react";
|
|
1256
|
+
import { useCallback as useCallback5, useRef as useRef3 } from "react";
|
|
1257
|
+
|
|
1258
|
+
// src/components/grid/detalles.tsx
|
|
1259
|
+
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
1260
|
+
import { IconButton, Tooltip } from "@mui/material";
|
|
1261
|
+
import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight";
|
|
1262
|
+
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
|
1263
|
+
|
|
1264
|
+
// src/pages/WScreens.tsx
|
|
1265
|
+
import { Box as Box2, Typography, Paper as Paper2 } from "@mui/material";
|
|
1266
|
+
import ConstructionIcon from "@mui/icons-material/Construction";
|
|
1267
|
+
import WarningAmberIcon from "@mui/icons-material/WarningAmber";
|
|
1268
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1269
|
+
var MyCustomDashboard = ({ screenName }) => {
|
|
1270
|
+
return /* @__PURE__ */ jsx4(Box2, { sx: { p: 4, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%" }, children: /* @__PURE__ */ jsxs4(Paper2, { elevation: 3, sx: { p: 4, textAlign: "center", maxWidth: 600 }, children: [
|
|
1271
|
+
/* @__PURE__ */ jsxs4(Typography, { variant: "h5", component: "h1", gutterBottom: true, children: [
|
|
1272
|
+
"\xA1Bienvenido a tu WScreen: ",
|
|
1273
|
+
screenName,
|
|
1274
|
+
"!"
|
|
1275
|
+
] }),
|
|
1276
|
+
/* @__PURE__ */ jsx4(Typography, { variant: "body1", color: "text.secondary", children: "Esta es una pantalla de interfaz de usuario personalizada." }),
|
|
1277
|
+
/* @__PURE__ */ jsx4(Box2, { sx: { mt: 3 }, children: /* @__PURE__ */ jsx4(ConstructionIcon, { sx: { fontSize: 80, color: "primary.main" } }) })
|
|
1278
|
+
] }) });
|
|
1279
|
+
};
|
|
1280
|
+
var FallbackWScreen = ({ screenName }) => {
|
|
1281
|
+
return /* @__PURE__ */ jsx4(Box2, { sx: { p: 4, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%" }, children: /* @__PURE__ */ jsxs4(Paper2, { elevation: 3, sx: { p: 4, textAlign: "center", maxWidth: 600, backgroundColor: "warning.light", border: "1px solid orange" }, children: [
|
|
1282
|
+
/* @__PURE__ */ jsx4(Typography, { variant: "h5", component: "h1", gutterBottom: true, color: "warning.dark", children: "WScreen No Implementada" }),
|
|
1283
|
+
/* @__PURE__ */ jsxs4(Typography, { variant: "body1", color: "warning.dark", children: [
|
|
1284
|
+
'No se encontr\xF3 un componente implementado para la **WScreen**: **`"$',
|
|
1285
|
+
screenName,
|
|
1286
|
+
'"`**. Por favor, verifica el `menuType` en la definici\xF3n del men\xFA o aseg\xFArate de que el componente est\xE9 correctamente importado y mapeado en el frontend.'
|
|
1287
|
+
] }),
|
|
1288
|
+
/* @__PURE__ */ jsx4(Box2, { sx: { mt: 3 }, children: /* @__PURE__ */ jsx4(WarningAmberIcon, { sx: { fontSize: 80, color: "warning.dark" } }) })
|
|
1289
|
+
] }) });
|
|
1290
|
+
};
|
|
1291
|
+
var wScreens = {
|
|
1292
|
+
"MyCustomDashboard": MyCustomDashboard
|
|
1293
|
+
// Agrega más componentes de wScreen aquí:
|
|
1294
|
+
// 'AnotherWScreen': AnotherWScreenComponent,
|
|
1295
|
+
};
|
|
1296
|
+
var extendWScreens = (newWScreens) => {
|
|
1297
|
+
wScreens = { ...wScreens, ...newWScreens };
|
|
1298
|
+
console.log("wScreens extendidos:", wScreens);
|
|
1299
|
+
};
|
|
1300
|
+
|
|
1301
|
+
// src/components/grid/condiciones.ts
|
|
1302
|
+
var condiciones = {};
|
|
1303
|
+
var extendConditions = (nuevas) => {
|
|
1304
|
+
condiciones = { ...condiciones, ...nuevas };
|
|
1305
|
+
};
|
|
1306
|
+
var avisadas = /* @__PURE__ */ new Set();
|
|
1307
|
+
function cumpleCondicion(nombre, fila) {
|
|
1308
|
+
if (!nombre) return true;
|
|
1309
|
+
const condicion = condiciones[nombre];
|
|
1310
|
+
if (!condicion) {
|
|
1311
|
+
if (!avisadas.has(nombre)) {
|
|
1312
|
+
avisadas.add(nombre);
|
|
1313
|
+
console.warn(`La condici\xF3n '${nombre}' de un detalle no est\xE1 registrada (extendConditions / myConditions): se muestra el detalle.`);
|
|
1314
|
+
}
|
|
1315
|
+
return true;
|
|
1316
|
+
}
|
|
1317
|
+
return condicion(fila);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// src/components/grid/detalles.tsx
|
|
1321
|
+
import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
|
|
1322
|
+
var DETALLE = Symbol("detalle");
|
|
1323
|
+
var esFilaDetalle = (row) => typeof row === "object" && row !== null && row[DETALLE] === true;
|
|
1324
|
+
var claveDetalle = (rowId, detailTable) => `${rowId}|${detailTable.abr}`;
|
|
1325
|
+
var ALTO_INICIAL_DETALLE = 140;
|
|
1326
|
+
var ALTO_MINIMO_DETALLE = 80;
|
|
1327
|
+
var normalizarCampoDeDetalle = (campo) => {
|
|
1328
|
+
if (typeof campo === "string") return { target: campo, source: campo, tieneValor: false };
|
|
1329
|
+
if ("value" in campo) return { target: campo.target, value: campo.value, tieneValor: true, until: campo.until };
|
|
1330
|
+
return { target: campo.target, source: campo.source, tieneValor: false, nullMeansAll: campo.nullMeansAll, until: campo.until };
|
|
1331
|
+
};
|
|
1332
|
+
function calcularFixedFieldsDetalle(detailTable, row) {
|
|
1333
|
+
return detailTable.fields.map(normalizarCampoDeDetalle).filter((campo) => !campo.nullMeansAll || campo.source !== void 0 && row[campo.source] != null).map((campo) => {
|
|
1334
|
+
const fixedField = {
|
|
1335
|
+
fieldName: campo.target,
|
|
1336
|
+
value: campo.tieneValor ? campo.value : row[campo.source]
|
|
1337
|
+
};
|
|
1338
|
+
if (campo.until !== void 0) fixedField.until = campo.until;
|
|
1339
|
+
return fixedField;
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
var CacheGrillasContext = createContext2(null);
|
|
1343
|
+
var DetallesGrillaContext = createContext2(null);
|
|
1344
|
+
var useDetallesGrilla = () => {
|
|
1345
|
+
const detalles = useContext2(DetallesGrillaContext);
|
|
1346
|
+
if (!detalles) throw new Error("falta DetallesGrillaContext.Provider");
|
|
1347
|
+
return detalles;
|
|
1348
|
+
};
|
|
1349
|
+
function BotonDetalle({ row, rowId, detailTable, deshabilitado }) {
|
|
1350
|
+
const { abiertos, alternarDetalle } = useDetallesGrilla();
|
|
1351
|
+
if (!cumpleCondicion(detailTable.condition, row)) return /* @__PURE__ */ jsx5("div", { className: "fpr-boton-detalle" });
|
|
1352
|
+
const abierto = abiertos.has(claveDetalle(rowId, detailTable));
|
|
1353
|
+
const titulo = deshabilitado ? "Grab\xE1 la fila para ver sus detalles" : `${detailTable.label || detailTable.abr}${abierto ? " (replegar)" : ""} \u2014 Ctrl+click: en otra pesta\xF1a`;
|
|
1354
|
+
return /* @__PURE__ */ jsx5(Tooltip, { title: titulo, children: /* @__PURE__ */ jsx5("span", { className: "fpr-boton-detalle", children: /* @__PURE__ */ jsx5(
|
|
1355
|
+
IconButton,
|
|
1356
|
+
{
|
|
1357
|
+
size: "small",
|
|
1358
|
+
disabled: deshabilitado,
|
|
1359
|
+
onClick: (e) => alternarDetalle(row, rowId, detailTable, e.ctrlKey || e.metaKey),
|
|
1360
|
+
onAuxClick: (e) => {
|
|
1361
|
+
if (e.button === 1) alternarDetalle(row, rowId, detailTable, true);
|
|
1362
|
+
},
|
|
1363
|
+
children: abierto ? /* @__PURE__ */ jsx5(KeyboardArrowDownIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx5(KeyboardArrowRightIcon, { fontSize: "small" })
|
|
1364
|
+
}
|
|
1365
|
+
) }) });
|
|
1366
|
+
}
|
|
1367
|
+
var AltoDisponibleContext = createContext2(void 0);
|
|
1368
|
+
var MARGEN_VERTICAL_DETALLE = 8;
|
|
1369
|
+
function DetalleWScreen({ fila, altoMaximo, onAlto, onAncho }) {
|
|
1370
|
+
const nombre = fila.detailTable.wScreen ?? "";
|
|
1371
|
+
const Pantalla = wScreens[nombre];
|
|
1372
|
+
const params = useMemo2(
|
|
1373
|
+
() => Object.fromEntries(fila.fixedFields.map((fixedField) => [fixedField.fieldName, fixedField.value])),
|
|
1374
|
+
[fila.fixedFields]
|
|
1375
|
+
);
|
|
1376
|
+
const contenido = useRef2(null);
|
|
1377
|
+
useEffect2(() => {
|
|
1378
|
+
const elemento = contenido.current;
|
|
1379
|
+
if (!elemento) return;
|
|
1380
|
+
const medir = () => {
|
|
1381
|
+
onAlto(elemento.offsetHeight + MARGEN_VERTICAL_DETALLE);
|
|
1382
|
+
onAncho(elemento.offsetWidth);
|
|
1383
|
+
};
|
|
1384
|
+
medir();
|
|
1385
|
+
const observador = new ResizeObserver(medir);
|
|
1386
|
+
observador.observe(elemento);
|
|
1387
|
+
return () => observador.disconnect();
|
|
1388
|
+
}, [onAlto, onAncho]);
|
|
1389
|
+
return /* @__PURE__ */ jsx5(AltoDisponibleContext.Provider, { value: altoMaximo === void 0 ? void 0 : altoMaximo - MARGEN_VERTICAL_DETALLE, children: /* @__PURE__ */ jsx5("div", { className: "fpr-detalle-wscreen", children: /* @__PURE__ */ jsx5("div", { ref: contenido, className: "fpr-detalle-wscreen-contenido", children: Pantalla ? /* @__PURE__ */ jsx5(Pantalla, { screenName: nombre, params }) : /* @__PURE__ */ jsx5(FallbackWScreen, { screenName: nombre }) }) }) });
|
|
1390
|
+
}
|
|
1391
|
+
function CeldaDetalle({ fila }) {
|
|
1392
|
+
const { renderDetalle } = useDetallesGrilla();
|
|
1393
|
+
return /* @__PURE__ */ jsx5(Fragment2, { children: renderDetalle(fila) });
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
// src/hooks/grid/useGridEvents.ts
|
|
1397
|
+
var VIGENCIA_TECLA_PENDIENTE = 400;
|
|
1398
|
+
var VIGENCIA_VALOR_PENDIENTE_F4 = 1e3;
|
|
983
1399
|
var useGridEvents = ({ dataGridRef, tableDefinition, filteredRows, tableData, fixedFields, setSelectedCell, setTableData, setSortColumns }) => {
|
|
1400
|
+
const filteredRowsRef = useRef3(filteredRows);
|
|
1401
|
+
filteredRowsRef.current = filteredRows;
|
|
1402
|
+
const tableDefinitionRef = useRef3(tableDefinition);
|
|
1403
|
+
tableDefinitionRef.current = tableDefinition;
|
|
1404
|
+
const valoresF4Pendientes = useRef3(/* @__PURE__ */ new Map());
|
|
1405
|
+
const teclasPendientes = useRef3([]);
|
|
1406
|
+
const editorActivo = useRef3(null);
|
|
1407
|
+
const registrarEditor = useCallback5((procesar) => {
|
|
1408
|
+
editorActivo.current = procesar;
|
|
1409
|
+
const cola = teclasPendientes.current;
|
|
1410
|
+
while (cola.length > 0 && Date.now() - cola[0].cuando > VIGENCIA_TECLA_PENDIENTE) cola.shift();
|
|
1411
|
+
const pendiente = cola.shift();
|
|
1412
|
+
if (pendiente) procesar(pendiente.key);
|
|
1413
|
+
return () => {
|
|
1414
|
+
if (editorActivo.current === procesar) editorActivo.current = null;
|
|
1415
|
+
};
|
|
1416
|
+
}, []);
|
|
984
1417
|
const handleKeyPressInEditor = useCallback5((rowIndex, columnKey, event, currentColumns, handleCommit) => {
|
|
985
|
-
|
|
1418
|
+
const tableDefinition2 = tableDefinitionRef.current;
|
|
1419
|
+
const filteredRows2 = filteredRowsRef.current;
|
|
1420
|
+
if (dataGridRef.current && tableDefinition2) {
|
|
986
1421
|
const currentColumnIndex = currentColumns.findIndex((col) => col.key === columnKey);
|
|
987
1422
|
const editableColumns = currentColumns.filter((col) => {
|
|
988
|
-
const fieldDefinition =
|
|
989
|
-
return col.key !== "actionsColumn" && col.customType
|
|
1423
|
+
const fieldDefinition = tableDefinition2.fields.find((f) => f.name === col.key);
|
|
1424
|
+
return col.key !== "actionsColumn" && !(esColumnaPropia(col) && col.customType === "detail") && (fieldDefinition?.editable !== false && !fieldDefinition?.clientSide);
|
|
990
1425
|
});
|
|
991
1426
|
const { key, target } = event;
|
|
992
1427
|
const input = target;
|
|
993
1428
|
if (currentColumnIndex !== -1 && editableColumns.length > 0) {
|
|
994
1429
|
const editableColumnKeys = editableColumns.map((col) => col.key);
|
|
995
1430
|
let currentEditableColumnIndex = editableColumnKeys.indexOf(columnKey);
|
|
996
|
-
const hacerFoco = ({ rowIdx, idx }) =>
|
|
1431
|
+
const hacerFoco = ({ rowIdx, idx }) => dataGridRef.current?.selectCell({ rowIdx, idx }, { enableEditor: true, shouldFocusCell: true });
|
|
1432
|
+
const filaDeDatos = (desde, paso) => {
|
|
1433
|
+
let i = desde + paso;
|
|
1434
|
+
while (i >= 0 && i < filteredRows2.length && esFilaDetalle(filteredRows2[i])) i += paso;
|
|
1435
|
+
return i >= 0 && i < filteredRows2.length ? i : -1;
|
|
1436
|
+
};
|
|
997
1437
|
const calcularColumnaSiguiente = () => {
|
|
998
1438
|
let nextEditableColumnIndex = currentEditableColumnIndex + 1;
|
|
999
1439
|
let nextRowIndex = rowIndex;
|
|
1000
1440
|
if (nextEditableColumnIndex >= editableColumns.length) {
|
|
1001
1441
|
nextEditableColumnIndex = 0;
|
|
1002
|
-
nextRowIndex
|
|
1003
|
-
if (nextRowIndex
|
|
1004
|
-
nextRowIndex =
|
|
1442
|
+
nextRowIndex = filaDeDatos(rowIndex, 1);
|
|
1443
|
+
if (nextRowIndex === -1) {
|
|
1444
|
+
nextRowIndex = filaDeDatos(-1, 1);
|
|
1005
1445
|
}
|
|
1006
1446
|
}
|
|
1007
1447
|
const nextColumnKey = editableColumnKeys[nextEditableColumnIndex];
|
|
@@ -1019,20 +1459,12 @@ var useGridEvents = ({ dataGridRef, tableDefinition, filteredRows, tableData, fi
|
|
|
1019
1459
|
return { rowIdx: nextRowIndex, idx: nextColumnIndex };
|
|
1020
1460
|
};
|
|
1021
1461
|
const calcularFilaSiguiente = () => {
|
|
1022
|
-
|
|
1023
|
-
nextRowIndex
|
|
1024
|
-
if (nextRowIndex >= filteredRows.length) {
|
|
1025
|
-
return { rowIdx: rowIndex, idx: currentColumnIndex };
|
|
1026
|
-
}
|
|
1027
|
-
return { rowIdx: nextRowIndex, idx: currentColumnIndex };
|
|
1462
|
+
const nextRowIndex = filaDeDatos(rowIndex, 1);
|
|
1463
|
+
return { rowIdx: nextRowIndex === -1 ? rowIndex : nextRowIndex, idx: currentColumnIndex };
|
|
1028
1464
|
};
|
|
1029
1465
|
const calcularFilaAnterior = () => {
|
|
1030
|
-
|
|
1031
|
-
nextRowIndex
|
|
1032
|
-
if (nextRowIndex < 0) {
|
|
1033
|
-
return { rowIdx: rowIndex, idx: currentColumnIndex };
|
|
1034
|
-
}
|
|
1035
|
-
return { rowIdx: nextRowIndex, idx: currentColumnIndex };
|
|
1466
|
+
const nextRowIndex = filaDeDatos(rowIndex, -1);
|
|
1467
|
+
return { rowIdx: nextRowIndex === -1 ? rowIndex : nextRowIndex, idx: currentColumnIndex };
|
|
1036
1468
|
};
|
|
1037
1469
|
if (currentEditableColumnIndex !== -1) {
|
|
1038
1470
|
switch (true) {
|
|
@@ -1068,11 +1500,16 @@ var useGridEvents = ({ dataGridRef, tableDefinition, filteredRows, tableData, fi
|
|
|
1068
1500
|
break;
|
|
1069
1501
|
}
|
|
1070
1502
|
case key === "F4": {
|
|
1071
|
-
setSortColumns([]);
|
|
1072
1503
|
const { rowIdx, idx } = calcularFilaSiguiente();
|
|
1073
|
-
const
|
|
1504
|
+
const indiceAnterior = filaDeDatos(rowIndex, -1);
|
|
1505
|
+
const previousRow = indiceAnterior === -1 ? void 0 : filteredRows2[indiceAnterior];
|
|
1074
1506
|
if (previousRow) {
|
|
1075
|
-
|
|
1507
|
+
const pendiente = valoresF4Pendientes.current.get(`${indiceAnterior}|${columnKey}`);
|
|
1508
|
+
const valorACopiar = pendiente && Date.now() - pendiente.cuando < VIGENCIA_VALOR_PENDIENTE_F4 ? pendiente.valor : previousRow[columnKey];
|
|
1509
|
+
valoresF4Pendientes.current.set(`${rowIndex}|${columnKey}`, { valor: valorACopiar, cuando: Date.now() });
|
|
1510
|
+
void handleCommit(valorACopiar, true, true);
|
|
1511
|
+
editorActivo.current = null;
|
|
1512
|
+
hacerFoco({ rowIdx, idx });
|
|
1076
1513
|
}
|
|
1077
1514
|
break;
|
|
1078
1515
|
}
|
|
@@ -1082,8 +1519,17 @@ var useGridEvents = ({ dataGridRef, tableDefinition, filteredRows, tableData, fi
|
|
|
1082
1519
|
}
|
|
1083
1520
|
}
|
|
1084
1521
|
}
|
|
1085
|
-
}, [
|
|
1522
|
+
}, [dataGridRef]);
|
|
1086
1523
|
const handleCellKeyDown = useCallback5((args, event) => {
|
|
1524
|
+
if (event.key === "F4" && !(event.target instanceof HTMLInputElement) && !esFilaDetalle(args.row)) {
|
|
1525
|
+
const fieldDefinition = tableDefinitionRef.current?.fields.find((f) => f.name === args.column.key);
|
|
1526
|
+
if (fieldDefinition && fieldDefinition.editable !== false && !fieldDefinition.clientSide) {
|
|
1527
|
+
if (editorActivo.current) editorActivo.current(event.key);
|
|
1528
|
+
else teclasPendientes.current.push({ key: event.key, cuando: Date.now() });
|
|
1529
|
+
event.preventGridDefault();
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1087
1533
|
if (["Enter", "Tab", "ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft"].includes(event.key)) {
|
|
1088
1534
|
event.preventGridDefault();
|
|
1089
1535
|
}
|
|
@@ -1098,23 +1544,27 @@ var useGridEvents = ({ dataGridRef, tableDefinition, filteredRows, tableData, fi
|
|
|
1098
1544
|
setSelectedCell(args);
|
|
1099
1545
|
}, [setSelectedCell]);
|
|
1100
1546
|
const handleCellClick = useCallback5((args, _event) => {
|
|
1547
|
+
if (esFilaDetalle(args.row)) return;
|
|
1101
1548
|
const fieldDefinition = tableDefinition?.fields.find((f) => f.name === args.column.key);
|
|
1102
1549
|
const isFixedField = fixedFields?.some((f) => f.fieldName === args.column.key);
|
|
1103
1550
|
const isEditable = fieldDefinition?.editable !== false && !isFixedField;
|
|
1104
1551
|
if (isEditable) {
|
|
1105
|
-
setSortColumns([]);
|
|
1106
1552
|
args.selectCell(true);
|
|
1107
1553
|
}
|
|
1108
|
-
}, [tableDefinition, fixedFields
|
|
1554
|
+
}, [tableDefinition, fixedFields]);
|
|
1109
1555
|
const handleRowsChange = useCallback5((updatedRows, data) => {
|
|
1556
|
+
const reemplazos = /* @__PURE__ */ new Map();
|
|
1110
1557
|
data.indexes.forEach((index) => {
|
|
1111
1558
|
const oldRow = filteredRows[index];
|
|
1112
1559
|
const newRow = updatedRows[index];
|
|
1113
|
-
if (oldRow
|
|
1560
|
+
if (!oldRow || !newRow || esFilaDetalle(oldRow)) return;
|
|
1561
|
+
if (oldRow[DOM_TEMP_ID] && !newRow[DOM_TEMP_ID]) {
|
|
1114
1562
|
newRow[DOM_TEMP_ID] = oldRow[DOM_TEMP_ID];
|
|
1115
1563
|
}
|
|
1564
|
+
reemplazos.set(oldRow, newRow);
|
|
1116
1565
|
});
|
|
1117
|
-
|
|
1566
|
+
if (reemplazos.size === 0) return;
|
|
1567
|
+
setTableData((prevData) => prevData.map((row) => reemplazos.get(row) ?? row));
|
|
1118
1568
|
}, [setTableData, filteredRows]);
|
|
1119
1569
|
return {
|
|
1120
1570
|
handleCellMouseDown,
|
|
@@ -1122,33 +1572,42 @@ var useGridEvents = ({ dataGridRef, tableDefinition, filteredRows, tableData, fi
|
|
|
1122
1572
|
handleCellClick,
|
|
1123
1573
|
handleCellKeyDown,
|
|
1124
1574
|
handleKeyPressInEditor,
|
|
1575
|
+
registrarEditor,
|
|
1125
1576
|
handleSelectedCellChange,
|
|
1126
1577
|
handleRowsChange
|
|
1127
1578
|
};
|
|
1128
1579
|
};
|
|
1129
1580
|
|
|
1130
1581
|
// src/hooks/grid/useGridLayout.ts
|
|
1131
|
-
import { useMemo as
|
|
1582
|
+
import { useMemo as useMemo3 } from "react";
|
|
1132
1583
|
var useGridLayout = ({
|
|
1133
1584
|
filteredRows,
|
|
1134
1585
|
isFilterRowVisible,
|
|
1135
1586
|
tableData,
|
|
1136
1587
|
summaryData,
|
|
1137
1588
|
filters,
|
|
1138
|
-
setFilters
|
|
1589
|
+
setFilters,
|
|
1590
|
+
altoDetalles = 0,
|
|
1591
|
+
altoMinimoCuerpo = MIN_BODY_HEIGHT,
|
|
1592
|
+
// 24 px de margen inferior de la caja que contiene la grilla + lo que ocupa una barra de scroll horizontal (que le quita
|
|
1593
|
+
// alto a la grilla y, si no sobra lugar, hace aparecer una barra vertical aunque haya una sola fila)
|
|
1594
|
+
holgura = 24 + 24,
|
|
1595
|
+
filasVisiblesMax,
|
|
1596
|
+
conPie = true
|
|
1139
1597
|
}) => {
|
|
1140
|
-
const gridHeight =
|
|
1598
|
+
const gridHeight = useMemo3(() => {
|
|
1141
1599
|
const filterHeight2 = isFilterRowVisible ? FILTER_ROW_HEIGHT : 0;
|
|
1142
|
-
|
|
1600
|
+
const filasParaAlto = filasVisiblesMax === void 0 ? filteredRows.length : Math.min(filteredRows.length, filasVisiblesMax);
|
|
1601
|
+
let calculatedHeight = filasParaAlto * ROW_HEIGHT + altoDetalles + HEADER_ROW_HEIGHT + filterHeight2 + (conPie ? SUMMARY_ROW_HEIGHT : 0) + holgura;
|
|
1143
1602
|
if (tableData.length > 0 && filteredRows.length === 0 && isFilterRowVisible || tableData.length === 0) {
|
|
1144
|
-
calculatedHeight = Math.max(calculatedHeight,
|
|
1603
|
+
calculatedHeight = Math.max(calculatedHeight, altoMinimoCuerpo) + filterHeight2;
|
|
1145
1604
|
}
|
|
1146
1605
|
return calculatedHeight;
|
|
1147
|
-
}, [filteredRows.length, isFilterRowVisible, tableData.length]);
|
|
1148
|
-
const bottomSummaryRow =
|
|
1149
|
-
return { id: "bottomSummaryRow",
|
|
1606
|
+
}, [filteredRows.length, isFilterRowVisible, tableData.length, altoDetalles, altoMinimoCuerpo, holgura, filasVisiblesMax, conPie]);
|
|
1607
|
+
const bottomSummaryRow = useMemo3(() => {
|
|
1608
|
+
return { id: "bottomSummaryRow", totales: summaryData };
|
|
1150
1609
|
}, [summaryData]);
|
|
1151
|
-
const summaryRows =
|
|
1610
|
+
const summaryRows = useMemo3(() => {
|
|
1152
1611
|
if (!isFilterRowVisible) return void 0;
|
|
1153
1612
|
return [{ id: "filterRow", filters, setFilters }];
|
|
1154
1613
|
}, [isFilterRowVisible, filters, setFilters]);
|
|
@@ -1157,7 +1616,7 @@ var useGridLayout = ({
|
|
|
1157
1616
|
};
|
|
1158
1617
|
|
|
1159
1618
|
// src/hooks/grid/useGridMenu.ts
|
|
1160
|
-
import
|
|
1619
|
+
import React4, { useMemo as useMemo4 } from "react";
|
|
1161
1620
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
|
1162
1621
|
import ViewColumnIcon from "@mui/icons-material/ViewColumn";
|
|
1163
1622
|
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
|
@@ -1176,21 +1635,21 @@ var useGridMenu = ({
|
|
|
1176
1635
|
triggerExport
|
|
1177
1636
|
}) => {
|
|
1178
1637
|
const { showSuccess, showError, showWarning } = useSnackbar();
|
|
1179
|
-
const menuOptions =
|
|
1638
|
+
const menuOptions = useMemo4(() => {
|
|
1180
1639
|
if (!tableDefinition) return [];
|
|
1181
1640
|
const options = [];
|
|
1182
1641
|
options.push({
|
|
1183
1642
|
id: "refresh",
|
|
1184
1643
|
label: "refrescar la grilla desde la base de datos",
|
|
1185
|
-
icon:
|
|
1644
|
+
icon: React4.createElement(RefreshIcon),
|
|
1186
1645
|
handler: async () => {
|
|
1187
1646
|
try {
|
|
1188
|
-
const data = await callApi("table_data", { table: tableName, fixedFields });
|
|
1647
|
+
const data = requerido(await callApi("table_data", { table: tableName, fixedFields }), "los datos de la tabla");
|
|
1189
1648
|
setTableData(data);
|
|
1190
1649
|
if (resetSorting) resetSorting();
|
|
1191
1650
|
showSuccess("Grilla refrescada correctamente");
|
|
1192
1651
|
} catch (err) {
|
|
1193
|
-
showError(`Error al refrescar: ${err
|
|
1652
|
+
showError(`Error al refrescar: ${mensajeDeError(err, "Error desconocido")}`);
|
|
1194
1653
|
}
|
|
1195
1654
|
},
|
|
1196
1655
|
visible: true
|
|
@@ -1198,7 +1657,7 @@ var useGridMenu = ({
|
|
|
1198
1657
|
options.push({
|
|
1199
1658
|
id: "showColumns",
|
|
1200
1659
|
label: "mostrar las columnas relacionadas",
|
|
1201
|
-
icon:
|
|
1660
|
+
icon: React4.createElement(ViewColumnIcon),
|
|
1202
1661
|
handler: async () => {
|
|
1203
1662
|
console.log("Mostrar columnas relacionadas");
|
|
1204
1663
|
},
|
|
@@ -1207,7 +1666,7 @@ var useGridMenu = ({
|
|
|
1207
1666
|
options.push({
|
|
1208
1667
|
id: "hideColumns",
|
|
1209
1668
|
label: "ocultar o mostrar columnas",
|
|
1210
|
-
icon:
|
|
1669
|
+
icon: React4.createElement(VisibilityOffIcon),
|
|
1211
1670
|
handler: async () => {
|
|
1212
1671
|
console.log("Ocultar/mostrar columnas");
|
|
1213
1672
|
},
|
|
@@ -1217,7 +1676,7 @@ var useGridMenu = ({
|
|
|
1217
1676
|
options.push({
|
|
1218
1677
|
id: "export",
|
|
1219
1678
|
label: "exportar",
|
|
1220
|
-
icon:
|
|
1679
|
+
icon: React4.createElement(FileDownloadIcon),
|
|
1221
1680
|
handler: async () => {
|
|
1222
1681
|
if (triggerExport) triggerExport();
|
|
1223
1682
|
else showWarning("La funcionalidad de exportaci\xF3n no est\xE1 disponible en este momento.");
|
|
@@ -1229,7 +1688,7 @@ var useGridMenu = ({
|
|
|
1229
1688
|
options.push({
|
|
1230
1689
|
id: "import",
|
|
1231
1690
|
label: "importar (Excel/Tab)",
|
|
1232
|
-
icon:
|
|
1691
|
+
icon: React4.createElement(FileUploadIcon),
|
|
1233
1692
|
handler: async () => {
|
|
1234
1693
|
if (triggerImport) triggerImport();
|
|
1235
1694
|
else showWarning("La funcionalidad de importaci\xF3n no est\xE1 disponible en este momento.");
|
|
@@ -1241,7 +1700,7 @@ var useGridMenu = ({
|
|
|
1241
1700
|
options.push({
|
|
1242
1701
|
id: "deleteAll",
|
|
1243
1702
|
label: "borrar todos los registros",
|
|
1244
|
-
icon:
|
|
1703
|
+
icon: React4.createElement(DeleteSweepIcon),
|
|
1245
1704
|
handler: async () => {
|
|
1246
1705
|
showWarning("Esta operaci\xF3n eliminar\xE1 TODOS los registros de la tabla");
|
|
1247
1706
|
},
|
|
@@ -1251,7 +1710,7 @@ var useGridMenu = ({
|
|
|
1251
1710
|
options.push({
|
|
1252
1711
|
id: "completeTable",
|
|
1253
1712
|
label: "tabla completa y filtrada",
|
|
1254
|
-
icon:
|
|
1713
|
+
icon: React4.createElement(FilterAltIcon),
|
|
1255
1714
|
handler: async () => {
|
|
1256
1715
|
console.log("Toggle tabla completa/filtrada");
|
|
1257
1716
|
},
|
|
@@ -1263,220 +1722,77 @@ var useGridMenu = ({
|
|
|
1263
1722
|
};
|
|
1264
1723
|
|
|
1265
1724
|
// src/hooks/grid/useGridColumns.ts
|
|
1266
|
-
import { useMemo as
|
|
1725
|
+
import React9, { useMemo as useMemo7 } from "react";
|
|
1267
1726
|
|
|
1268
1727
|
// src/utils/functions.tsx
|
|
1269
1728
|
import * as JSON4all2 from "json4all";
|
|
1729
|
+
var cambiarGuionesBajosPorEspacios = (texto) => texto.replace(/_/g, " ");
|
|
1270
1730
|
|
|
1271
|
-
// src/
|
|
1272
|
-
import {
|
|
1273
|
-
import
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
REHYDRATE,
|
|
1278
|
-
PAUSE,
|
|
1279
|
-
PERSIST,
|
|
1280
|
-
PURGE,
|
|
1281
|
-
REGISTER
|
|
1282
|
-
} from "redux-persist";
|
|
1283
|
-
import storage from "redux-persist/lib/storage";
|
|
1731
|
+
// src/components/grid/renderers/headerCellRenderers.tsx
|
|
1732
|
+
import { Box as Box3, IconButton as IconButton2, Tooltip as Tooltip2, Typography as Typography2 } from "@mui/material";
|
|
1733
|
+
import SearchIcon from "@mui/icons-material/Search";
|
|
1734
|
+
import SearchOffIcon from "@mui/icons-material/SearchOff";
|
|
1735
|
+
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
|
1736
|
+
import AddIcon from "@mui/icons-material/Add";
|
|
1284
1737
|
|
|
1285
|
-
// src/
|
|
1286
|
-
import {
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
};
|
|
1301
|
-
var fetchClientContext = createAsyncThunk(
|
|
1302
|
-
"clientContext/fetchClientContext",
|
|
1303
|
-
async (_, { rejectWithValue }) => {
|
|
1304
|
-
try {
|
|
1305
|
-
const setupResponse = await fetchApi("/client-setup", { method: "GET" });
|
|
1306
|
-
if (!setupResponse.ok) {
|
|
1307
|
-
const errorData = await setupResponse.text();
|
|
1308
|
-
throw new Error(errorData || "Error al obtener configuraci\xF3n del cliente");
|
|
1738
|
+
// src/components/grid/estadoGrilla.ts
|
|
1739
|
+
import { createContext as createContext3, useContext as useContext3, useSyncExternalStore } from "react";
|
|
1740
|
+
function crearEstadoGrilla() {
|
|
1741
|
+
let feedback = /* @__PURE__ */ new Map();
|
|
1742
|
+
let cambiosLocales = /* @__PURE__ */ new Map();
|
|
1743
|
+
const suscriptores = /* @__PURE__ */ new Set();
|
|
1744
|
+
const avisar = () => suscriptores.forEach((alCambiar) => alCambiar());
|
|
1745
|
+
return {
|
|
1746
|
+
obtenerFeedback: () => feedback,
|
|
1747
|
+
obtenerCambiosLocales: () => cambiosLocales,
|
|
1748
|
+
setFeedback(actualizacion) {
|
|
1749
|
+
const nuevo = typeof actualizacion === "function" ? actualizacion(feedback) : actualizacion;
|
|
1750
|
+
if (nuevo !== feedback) {
|
|
1751
|
+
feedback = nuevo;
|
|
1752
|
+
avisar();
|
|
1309
1753
|
}
|
|
1310
|
-
const clientSetup = await setupResponse.json();
|
|
1311
|
-
return clientSetup;
|
|
1312
|
-
} catch (error) {
|
|
1313
|
-
return rejectWithValue(error.message || "Error desconocido al cargar el contexto");
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
);
|
|
1317
|
-
var clientContextSlice = createSlice({
|
|
1318
|
-
name: "clientContext",
|
|
1319
|
-
initialState,
|
|
1320
|
-
reducers: {
|
|
1321
|
-
// Un reducer para limpiar el contexto del cliente (ej. al cerrar sesión)
|
|
1322
|
-
clearClientContext: (state) => {
|
|
1323
|
-
Object.assign(state, initialState);
|
|
1324
|
-
}
|
|
1325
|
-
// Puedes añadir otros reducers aquí si necesitas modificar partes del clientContext directamente
|
|
1326
|
-
// pero el thunk es la forma preferida para la carga inicial.
|
|
1327
|
-
},
|
|
1328
|
-
// **extraReducers maneja las acciones del thunk asíncrono**
|
|
1329
|
-
extraReducers: (builder) => {
|
|
1330
|
-
builder.addCase(fetchClientContext.pending, (state) => {
|
|
1331
|
-
state.status = "loading";
|
|
1332
|
-
state.error = null;
|
|
1333
|
-
}).addCase(fetchClientContext.fulfilled, (state, action) => {
|
|
1334
|
-
state.status = "succeeded";
|
|
1335
|
-
state.menu = action.payload.menu;
|
|
1336
|
-
state.procedure = action.payload.procedure;
|
|
1337
|
-
state.procedures = action.payload.procedures;
|
|
1338
|
-
state.config = action.payload.config;
|
|
1339
|
-
state.useragent = action.payload.useragent;
|
|
1340
|
-
state.username = action.payload.username;
|
|
1341
|
-
state.error = null;
|
|
1342
|
-
}).addCase(fetchClientContext.rejected, (state, action) => {
|
|
1343
|
-
state.status = "failed";
|
|
1344
|
-
state.error = action.payload || "Fallo al cargar el contexto del cliente";
|
|
1345
|
-
});
|
|
1346
|
-
}
|
|
1347
|
-
});
|
|
1348
|
-
var { clearClientContext } = clientContextSlice.actions;
|
|
1349
|
-
var clientContextSlice_default = clientContextSlice.reducer;
|
|
1350
|
-
|
|
1351
|
-
// src/store/routerSlice.ts
|
|
1352
|
-
import { createSlice as createSlice2 } from "@reduxjs/toolkit";
|
|
1353
|
-
var initialState2 = {
|
|
1354
|
-
currentPath: "/",
|
|
1355
|
-
previousPath: null,
|
|
1356
|
-
redirectPath: null
|
|
1357
|
-
// <--- Inicializamos en null
|
|
1358
|
-
};
|
|
1359
|
-
var routerSlice = createSlice2({
|
|
1360
|
-
name: "router",
|
|
1361
|
-
initialState: initialState2,
|
|
1362
|
-
reducers: {
|
|
1363
|
-
setCurrentPath: (state, action) => {
|
|
1364
|
-
state.previousPath = state.currentPath;
|
|
1365
|
-
state.currentPath = action.payload;
|
|
1366
|
-
},
|
|
1367
|
-
setRedirectPath: (state, action) => {
|
|
1368
|
-
state.redirectPath = action.payload;
|
|
1369
|
-
},
|
|
1370
|
-
resetRouterState: (state) => {
|
|
1371
|
-
state.currentPath = "/";
|
|
1372
|
-
state.previousPath = null;
|
|
1373
|
-
state.redirectPath = null;
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
});
|
|
1377
|
-
var { setCurrentPath, setRedirectPath, resetRouterState } = routerSlice.actions;
|
|
1378
|
-
var routerSlice_default = routerSlice.reducer;
|
|
1379
|
-
|
|
1380
|
-
// src/store/menuUiSlice.ts
|
|
1381
|
-
import { createSlice as createSlice3 } from "@reduxjs/toolkit";
|
|
1382
|
-
var initialState3 = {
|
|
1383
|
-
isDrawerOpen: false,
|
|
1384
|
-
subMenuOpenStates: {}
|
|
1385
|
-
};
|
|
1386
|
-
var menuUiSlice = createSlice3({
|
|
1387
|
-
name: "menuUi",
|
|
1388
|
-
initialState: initialState3,
|
|
1389
|
-
reducers: {
|
|
1390
|
-
setDrawerOpen: (state, action) => {
|
|
1391
|
-
state.isDrawerOpen = action.payload;
|
|
1392
|
-
},
|
|
1393
|
-
toggleDrawer: (state) => {
|
|
1394
|
-
state.isDrawerOpen = !state.isDrawerOpen;
|
|
1395
|
-
},
|
|
1396
|
-
setSubMenuOpen: (state, action) => {
|
|
1397
|
-
state.subMenuOpenStates[action.payload.menuName] = action.payload.isOpen;
|
|
1398
1754
|
},
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
for (const menuName in state.subMenuOpenStates) {
|
|
1405
|
-
if (Object.prototype.hasOwnProperty.call(state.subMenuOpenStates, menuName)) {
|
|
1406
|
-
state.subMenuOpenStates[menuName] = action.payload;
|
|
1407
|
-
}
|
|
1755
|
+
setCambiosLocales(actualizacion) {
|
|
1756
|
+
const nuevo = typeof actualizacion === "function" ? actualizacion(cambiosLocales) : actualizacion;
|
|
1757
|
+
if (nuevo !== cambiosLocales) {
|
|
1758
|
+
cambiosLocales = nuevo;
|
|
1759
|
+
avisar();
|
|
1408
1760
|
}
|
|
1409
1761
|
},
|
|
1410
|
-
|
|
1411
|
-
|
|
1762
|
+
suscribir(alCambiar) {
|
|
1763
|
+
suscriptores.add(alCambiar);
|
|
1764
|
+
return () => {
|
|
1765
|
+
suscriptores.delete(alCambiar);
|
|
1766
|
+
};
|
|
1412
1767
|
}
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
var EstadoGrillaContext = createContext3(null);
|
|
1771
|
+
function useEstadoGrilla() {
|
|
1772
|
+
const estado = useContext3(EstadoGrillaContext);
|
|
1773
|
+
if (!estado) {
|
|
1774
|
+
throw new Error("useEstadoGrilla debe usarse dentro de EstadoGrillaContext.Provider");
|
|
1413
1775
|
}
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
}
|
|
1424
|
-
var
|
|
1425
|
-
|
|
1426
|
-
// src/store/index.ts
|
|
1427
|
-
import { useDispatch, useSelector } from "react-redux";
|
|
1428
|
-
var rootReducer = combineReducers({
|
|
1429
|
-
clientContext: clientContextSlice_default,
|
|
1430
|
-
router: routerSlice_default,
|
|
1431
|
-
menuUi: menuUiSlice_default
|
|
1432
|
-
// ...otros slices
|
|
1433
|
-
});
|
|
1434
|
-
var persistConfig = {
|
|
1435
|
-
key: "root",
|
|
1436
|
-
storage,
|
|
1437
|
-
whitelist: ["clientContext", "router", "menuUi"]
|
|
1438
|
-
};
|
|
1439
|
-
var persistedReducer = persistReducer(persistConfig, rootReducer);
|
|
1440
|
-
var store = configureStore({
|
|
1441
|
-
reducer: persistedReducer,
|
|
1442
|
-
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
|
|
1443
|
-
serializableCheck: {
|
|
1444
|
-
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
|
|
1445
|
-
}
|
|
1446
|
-
})
|
|
1447
|
-
});
|
|
1448
|
-
var persistor = persistStore(store);
|
|
1449
|
-
var useAppDispatch = useDispatch;
|
|
1450
|
-
var useAppSelector = useSelector;
|
|
1451
|
-
var useClientContextStatus = () => {
|
|
1452
|
-
return useAppSelector((state) => state.clientContext.status);
|
|
1453
|
-
};
|
|
1454
|
-
var useIsDrawerOpen = () => {
|
|
1455
|
-
return useAppSelector((state) => state.menuUi.isDrawerOpen);
|
|
1456
|
-
};
|
|
1457
|
-
var useSubMenuOpenState = (menuName) => {
|
|
1458
|
-
return useAppSelector((state) => state.menuUi.subMenuOpenStates[menuName] || false);
|
|
1459
|
-
};
|
|
1460
|
-
var useRedirectPath = () => {
|
|
1461
|
-
return useAppSelector((state) => state.router.redirectPath);
|
|
1462
|
-
};
|
|
1463
|
-
|
|
1464
|
-
// src/utils/functions.tsx
|
|
1465
|
-
var cambiarGuionesBajosPorEspacios = (texto) => texto.replace(/_/g, " ");
|
|
1776
|
+
return estado;
|
|
1777
|
+
}
|
|
1778
|
+
function useFeedbackCelda(cellKey) {
|
|
1779
|
+
const estado = useEstadoGrilla();
|
|
1780
|
+
return useSyncExternalStore(estado.suscribir, () => estado.obtenerFeedback().get(cellKey));
|
|
1781
|
+
}
|
|
1782
|
+
function useCeldaPendiente(rowId, columnKey) {
|
|
1783
|
+
const estado = useEstadoGrilla();
|
|
1784
|
+
return useSyncExternalStore(estado.suscribir, () => estado.obtenerCambiosLocales().get(rowId)?.has(columnKey) ?? false);
|
|
1785
|
+
}
|
|
1786
|
+
var VistaGrillaContext = createContext3({ isFilterRowVisible: false });
|
|
1787
|
+
var useVistaGrilla = () => useContext3(VistaGrillaContext);
|
|
1466
1788
|
|
|
1467
|
-
// src/components/grid/renderers/headerCellRenderers.tsx
|
|
1468
|
-
import {
|
|
1469
|
-
import SearchIcon from "@mui/icons-material/Search";
|
|
1470
|
-
import SearchOffIcon from "@mui/icons-material/SearchOff";
|
|
1471
|
-
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
|
1472
|
-
import AddIcon from "@mui/icons-material/Add";
|
|
1473
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1789
|
+
// src/components/grid/renderers/headerCellRenderers.tsx
|
|
1790
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1474
1791
|
var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
|
|
1475
|
-
const { column,
|
|
1792
|
+
const { column, sortDirection, priority } = props;
|
|
1476
1793
|
const isPrimaryKey = fieldDef.isPk;
|
|
1477
|
-
const
|
|
1478
|
-
const
|
|
1479
|
-
const sortColumn = sorted ? sortColumns[sortIndex] : null;
|
|
1794
|
+
const sorted = sortDirection !== void 0;
|
|
1795
|
+
const sortIndex = (priority ?? 1) - 1;
|
|
1480
1796
|
const getSortColor = (index) => {
|
|
1481
1797
|
if (index === 0) return "#000000";
|
|
1482
1798
|
if (index === 1) return "#555555";
|
|
@@ -1484,8 +1800,8 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
|
|
|
1484
1800
|
return "#AAAAAA";
|
|
1485
1801
|
};
|
|
1486
1802
|
const sortColor = sorted ? getSortColor(sortIndex) : "transparent";
|
|
1487
|
-
return /* @__PURE__ */
|
|
1488
|
-
|
|
1803
|
+
return /* @__PURE__ */ jsxs5(
|
|
1804
|
+
Box3,
|
|
1489
1805
|
{
|
|
1490
1806
|
sx: {
|
|
1491
1807
|
display: "flex",
|
|
@@ -1497,8 +1813,8 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
|
|
|
1497
1813
|
width: "100%"
|
|
1498
1814
|
},
|
|
1499
1815
|
children: [
|
|
1500
|
-
/* @__PURE__ */
|
|
1501
|
-
|
|
1816
|
+
/* @__PURE__ */ jsx6(
|
|
1817
|
+
Typography2,
|
|
1502
1818
|
{
|
|
1503
1819
|
variant: "body2",
|
|
1504
1820
|
sx: {
|
|
@@ -1514,55 +1830,61 @@ var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
|
|
|
1514
1830
|
children: column.name
|
|
1515
1831
|
}
|
|
1516
1832
|
),
|
|
1517
|
-
sorted && /* @__PURE__ */
|
|
1833
|
+
sorted && /* @__PURE__ */ jsx6(Box3, { sx: { color: sortColor, display: "flex", alignItems: "center", ml: 0.5, fontSize: "0.7rem" }, children: sortDirection === "ASC" ? "\u25B2" : "\u25BC" })
|
|
1518
1834
|
]
|
|
1519
1835
|
}
|
|
1520
1836
|
);
|
|
1521
1837
|
};
|
|
1522
|
-
var
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1838
|
+
var ActionsColumnHeaderCell = ({
|
|
1839
|
+
toggleFilterVisibility,
|
|
1840
|
+
handleDataGridOptions,
|
|
1841
|
+
handleAddRow,
|
|
1842
|
+
allowInsert
|
|
1843
|
+
}) => {
|
|
1844
|
+
const { isFilterRowVisible } = useVistaGrilla();
|
|
1845
|
+
return /* @__PURE__ */ jsxs5(Box3, { sx: { display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 0.2 }, children: [
|
|
1846
|
+
allowInsert && /* @__PURE__ */ jsx6(
|
|
1847
|
+
IconButton2,
|
|
1526
1848
|
{
|
|
1527
1849
|
color: "inherit",
|
|
1528
|
-
onClick: handleAddRow,
|
|
1850
|
+
onClick: () => handleAddRow(),
|
|
1529
1851
|
size: "small",
|
|
1530
1852
|
title: "A\xF1adir registro",
|
|
1531
1853
|
sx: { p: 0.25 },
|
|
1532
|
-
children: /* @__PURE__ */
|
|
1854
|
+
children: /* @__PURE__ */ jsx6(AddIcon, { sx: { fontSize: 18, color: "success.main" } })
|
|
1533
1855
|
}
|
|
1534
1856
|
),
|
|
1535
|
-
/* @__PURE__ */
|
|
1536
|
-
|
|
1857
|
+
/* @__PURE__ */ jsx6(
|
|
1858
|
+
IconButton2,
|
|
1537
1859
|
{
|
|
1538
1860
|
color: "inherit",
|
|
1539
1861
|
onClick: toggleFilterVisibility,
|
|
1540
1862
|
size: "small",
|
|
1541
1863
|
title: isFilterRowVisible ? "Ocultar filtros" : "Mostrar filtros",
|
|
1542
1864
|
sx: { p: 0.25 },
|
|
1543
|
-
children: isFilterRowVisible ? /* @__PURE__ */
|
|
1865
|
+
children: isFilterRowVisible ? /* @__PURE__ */ jsx6(SearchOffIcon, { sx: { fontSize: 18 } }) : /* @__PURE__ */ jsx6(SearchIcon, { sx: { fontSize: 18 } })
|
|
1544
1866
|
}
|
|
1545
1867
|
),
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
|
|
1868
|
+
/* @__PURE__ */ jsx6(
|
|
1869
|
+
IconButton2,
|
|
1548
1870
|
{
|
|
1549
1871
|
onClick: (event) => handleDataGridOptions(event),
|
|
1550
1872
|
size: "small",
|
|
1551
1873
|
title: "Opciones de esta tabla",
|
|
1552
1874
|
sx: { p: 0.25 },
|
|
1553
|
-
children: /* @__PURE__ */
|
|
1875
|
+
children: /* @__PURE__ */ jsx6(MoreVertIcon, { sx: { fontSize: 20, variant: "filled", size: "small" } })
|
|
1554
1876
|
}
|
|
1555
1877
|
)
|
|
1556
1878
|
] });
|
|
1557
1879
|
};
|
|
1558
|
-
var detailColumnCellHeaderRenderer = (props, detailTable) => /* @__PURE__ */
|
|
1880
|
+
var detailColumnCellHeaderRenderer = (props, detailTable) => /* @__PURE__ */ jsx6(Tooltip2, { title: detailTable.label, children: /* @__PURE__ */ jsx6(Typography2, { variant: "caption", sx: { fontSize: "0.75rem", fontWeight: "bold" }, children: detailTable.abr.toUpperCase() }) });
|
|
1559
1881
|
|
|
1560
1882
|
// src/components/grid/FilterInputRender.tsx
|
|
1561
|
-
import { InputBase, Box as
|
|
1562
|
-
import
|
|
1883
|
+
import { InputBase, Box as Box4 } from "@mui/material";
|
|
1884
|
+
import React6 from "react";
|
|
1563
1885
|
|
|
1564
1886
|
// src/components/forms/TypedField.tsx
|
|
1565
|
-
import { useState as useState7, useEffect as
|
|
1887
|
+
import { useState as useState7, useEffect as useEffect3, useMemo as useMemo5, useCallback as useCallback7 } from "react";
|
|
1566
1888
|
import {
|
|
1567
1889
|
TextField,
|
|
1568
1890
|
FormControl,
|
|
@@ -1573,12 +1895,12 @@ import {
|
|
|
1573
1895
|
InputAdornment,
|
|
1574
1896
|
useTheme
|
|
1575
1897
|
} from "@mui/material";
|
|
1576
|
-
import
|
|
1577
|
-
import { useRef } from "react";
|
|
1578
|
-
import { jsx as
|
|
1898
|
+
import typeStore3 from "type-store";
|
|
1899
|
+
import { useRef as useRef4 } from "react";
|
|
1900
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1579
1901
|
var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode = false, feedback, isMandatory = false }) => {
|
|
1580
1902
|
const theme = useTheme();
|
|
1581
|
-
const typer =
|
|
1903
|
+
const typer = useMemo5(() => typeStore3.typerFrom(fieldDef), [fieldDef]);
|
|
1582
1904
|
const isBoolean = fieldDef.typeName === "boolean";
|
|
1583
1905
|
const [localString, setLocalString] = useState7(() => {
|
|
1584
1906
|
if (isBoolean) return "";
|
|
@@ -1590,9 +1912,9 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
1590
1912
|
}
|
|
1591
1913
|
});
|
|
1592
1914
|
const [errorMsg, setErrorMsg] = useState7(null);
|
|
1593
|
-
const lastValueRef =
|
|
1594
|
-
const lastCommittedStringRef =
|
|
1595
|
-
|
|
1915
|
+
const lastValueRef = useRef4(value);
|
|
1916
|
+
const lastCommittedStringRef = useRef4(localString);
|
|
1917
|
+
useEffect3(() => {
|
|
1596
1918
|
if (!isBoolean) {
|
|
1597
1919
|
if (value !== lastValueRef.current) {
|
|
1598
1920
|
lastValueRef.current = value;
|
|
@@ -1623,7 +1945,7 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
1623
1945
|
typer.validateTypedData(parsedValue);
|
|
1624
1946
|
} catch (err) {
|
|
1625
1947
|
isValid = false;
|
|
1626
|
-
pErrorMsg = err
|
|
1948
|
+
pErrorMsg = mensajeDeError(err);
|
|
1627
1949
|
}
|
|
1628
1950
|
}
|
|
1629
1951
|
setErrorMsg(pErrorMsg);
|
|
@@ -1682,28 +2004,28 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
1682
2004
|
}
|
|
1683
2005
|
const cellBackgroundColor2 = feedback === "error" ? theme.palette.error.light : feedback === "success" ? theme.palette.success.light : defaultBgColor;
|
|
1684
2006
|
const transitionStyle2 = "background-color 0.3s ease-in-out";
|
|
1685
|
-
return /* @__PURE__ */
|
|
1686
|
-
!isFilterMode && /* @__PURE__ */
|
|
1687
|
-
/* @__PURE__ */
|
|
2007
|
+
return /* @__PURE__ */ jsxs6(FormControl, { fullWidth: true, error: !!errorMsg && !isFilterMode, disabled: isDisabled, size: "small", margin: "dense", children: [
|
|
2008
|
+
!isFilterMode && /* @__PURE__ */ jsx7(InputLabel, { shrink: true, children: fieldDef.name }),
|
|
2009
|
+
/* @__PURE__ */ jsxs6(
|
|
1688
2010
|
Select,
|
|
1689
2011
|
{
|
|
1690
2012
|
value: boolVal,
|
|
1691
2013
|
label: !isFilterMode ? fieldDef.name : void 0,
|
|
1692
2014
|
onChange: handleBooleanChange,
|
|
1693
|
-
startAdornment: isMandatory && isEmpty && !isFilterMode ? /* @__PURE__ */
|
|
2015
|
+
startAdornment: isMandatory && isEmpty && !isFilterMode ? /* @__PURE__ */ jsx7(InputAdornment, { position: "start", sx: { color: "text.secondary", ml: 0.5 }, children: "*" }) : void 0,
|
|
1694
2016
|
displayEmpty: true,
|
|
1695
2017
|
sx: isFilterMode ? { height: 25, fontSize: "0.8rem", backgroundColor: "background.paper" } : {
|
|
1696
2018
|
backgroundColor: cellBackgroundColor2,
|
|
1697
2019
|
transition: transitionStyle2
|
|
1698
2020
|
},
|
|
1699
2021
|
children: [
|
|
1700
|
-
fieldDef.nullable !== false && /* @__PURE__ */
|
|
1701
|
-
/* @__PURE__ */
|
|
1702
|
-
/* @__PURE__ */
|
|
2022
|
+
fieldDef.nullable !== false && /* @__PURE__ */ jsx7(MenuItem, { value: "", children: /* @__PURE__ */ jsx7("em", { children: "Nulo / Sin Especificar" }) }),
|
|
2023
|
+
/* @__PURE__ */ jsx7(MenuItem, { value: "true", children: "S\xED (Verdadero)" }),
|
|
2024
|
+
/* @__PURE__ */ jsx7(MenuItem, { value: "false", children: "No (Falso)" })
|
|
1703
2025
|
]
|
|
1704
2026
|
}
|
|
1705
2027
|
),
|
|
1706
|
-
errorMsg && !isFilterMode && /* @__PURE__ */
|
|
2028
|
+
errorMsg && !isFilterMode && /* @__PURE__ */ jsx7(FormHelperText, { children: errorMsg })
|
|
1707
2029
|
] });
|
|
1708
2030
|
}
|
|
1709
2031
|
let inputType = "text";
|
|
@@ -1717,7 +2039,7 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
1717
2039
|
}
|
|
1718
2040
|
const cellBackgroundColor = feedback === "error" ? theme.palette.error.light : feedback === "success" ? theme.palette.success.light : defaultTextBgColor;
|
|
1719
2041
|
const transitionStyle = "background-color 0.3s ease-in-out";
|
|
1720
|
-
return /* @__PURE__ */
|
|
2042
|
+
return /* @__PURE__ */ jsx7(
|
|
1721
2043
|
TextField,
|
|
1722
2044
|
{
|
|
1723
2045
|
fullWidth: true,
|
|
@@ -1733,7 +2055,7 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
1733
2055
|
helperText: !isFilterMode ? errorMsg || (isMandatory ? "Obligatorio" : "") : void 0,
|
|
1734
2056
|
InputLabelProps: !isFilterMode ? { shrink: true } : void 0,
|
|
1735
2057
|
InputProps: !isFilterMode && isMandatory && isEmptyText ? {
|
|
1736
|
-
startAdornment: /* @__PURE__ */
|
|
2058
|
+
startAdornment: /* @__PURE__ */ jsx7(InputAdornment, { position: "start", sx: { color: "text.secondary", mr: 0.5 }, children: "*" })
|
|
1737
2059
|
} : {},
|
|
1738
2060
|
inputProps: {
|
|
1739
2061
|
style: {
|
|
@@ -1764,7 +2086,7 @@ var TypedField = ({ fieldDef, value, onChange, onCommit, disabled, isFilterMode
|
|
|
1764
2086
|
};
|
|
1765
2087
|
|
|
1766
2088
|
// src/components/grid/FilterInputRender.tsx
|
|
1767
|
-
import { jsx as
|
|
2089
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1768
2090
|
function FilterInputRenderer({
|
|
1769
2091
|
columnKey,
|
|
1770
2092
|
currentFilter,
|
|
@@ -1787,8 +2109,8 @@ function FilterInputRenderer({
|
|
|
1787
2109
|
[columnKey]: { operator: newOp, value: formattedVal }
|
|
1788
2110
|
}));
|
|
1789
2111
|
};
|
|
1790
|
-
return /* @__PURE__ */
|
|
1791
|
-
/* @__PURE__ */
|
|
2112
|
+
return /* @__PURE__ */ jsxs7(Box4, { sx: { mt: 0, display: "flex", alignItems: "center", gap: 0.5, pr: 1 }, children: [
|
|
2113
|
+
/* @__PURE__ */ jsx8(
|
|
1792
2114
|
"select",
|
|
1793
2115
|
{
|
|
1794
2116
|
value: operator,
|
|
@@ -1804,10 +2126,10 @@ function FilterInputRenderer({
|
|
|
1804
2126
|
textAlign: "center",
|
|
1805
2127
|
cursor: "pointer"
|
|
1806
2128
|
},
|
|
1807
|
-
children: filterOperators.map((op) => /* @__PURE__ */
|
|
2129
|
+
children: filterOperators.map((op) => /* @__PURE__ */ jsx8("option", { value: op.value, children: op.label }, op.value))
|
|
1808
2130
|
}
|
|
1809
2131
|
),
|
|
1810
|
-
/* @__PURE__ */
|
|
2132
|
+
/* @__PURE__ */ jsx8(
|
|
1811
2133
|
TypedField,
|
|
1812
2134
|
{
|
|
1813
2135
|
fieldDef,
|
|
@@ -1818,7 +2140,7 @@ function FilterInputRenderer({
|
|
|
1818
2140
|
)
|
|
1819
2141
|
] });
|
|
1820
2142
|
}
|
|
1821
|
-
return /* @__PURE__ */
|
|
2143
|
+
return /* @__PURE__ */ jsx8(
|
|
1822
2144
|
InputBase,
|
|
1823
2145
|
{
|
|
1824
2146
|
value: currentFilter || "",
|
|
@@ -1841,19 +2163,19 @@ function FilterInputRenderer({
|
|
|
1841
2163
|
}
|
|
1842
2164
|
);
|
|
1843
2165
|
}
|
|
1844
|
-
var FilterInputRender_default =
|
|
2166
|
+
var FilterInputRender_default = React6.memo(FilterInputRenderer);
|
|
1845
2167
|
|
|
1846
2168
|
// src/components/grid/renderers/summaryCellRenderers.tsx
|
|
1847
|
-
import { Box as
|
|
1848
|
-
import { jsx as
|
|
1849
|
-
var defaultColumnSummaryCellRenderer = (props, fixedFields
|
|
2169
|
+
import { Box as Box5 } from "@mui/material";
|
|
2170
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2171
|
+
var defaultColumnSummaryCellRenderer = (props, fixedFields) => {
|
|
1850
2172
|
const { column, row } = props;
|
|
1851
2173
|
if (row.id === "filterRow") {
|
|
1852
2174
|
const { filters, setFilters } = row;
|
|
1853
2175
|
const fixedFieldEntry = fixedFields?.find((f) => f.fieldName === column.key);
|
|
1854
|
-
if (fixedFieldEntry && fixedFieldEntry.until === void 0
|
|
1855
|
-
const fieldDef = column.fieldDef;
|
|
1856
|
-
return /* @__PURE__ */
|
|
2176
|
+
if (fixedFieldEntry && fixedFieldEntry.until === void 0) return null;
|
|
2177
|
+
const fieldDef = esColumnaPropia(column) && column.customType === "default" ? column.fieldDef : void 0;
|
|
2178
|
+
return /* @__PURE__ */ jsx9(Box5, { sx: { width: "100%", height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(
|
|
1857
2179
|
FilterInputRender_default,
|
|
1858
2180
|
{
|
|
1859
2181
|
columnKey: column.key,
|
|
@@ -1863,8 +2185,8 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields, isFilterRowVisible)
|
|
|
1863
2185
|
}
|
|
1864
2186
|
) });
|
|
1865
2187
|
}
|
|
1866
|
-
const summaryData = row[column.key];
|
|
1867
|
-
if (!summaryData
|
|
2188
|
+
const summaryData = row.totales[column.key];
|
|
2189
|
+
if (!summaryData) return null;
|
|
1868
2190
|
const { type, value } = summaryData;
|
|
1869
2191
|
let label = "";
|
|
1870
2192
|
let formattedValue = value;
|
|
@@ -1895,7 +2217,7 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields, isFilterRowVisible)
|
|
|
1895
2217
|
label = "Cant S\xED: ";
|
|
1896
2218
|
break;
|
|
1897
2219
|
}
|
|
1898
|
-
return /* @__PURE__ */
|
|
2220
|
+
return /* @__PURE__ */ jsxs8(Box5, { sx: {
|
|
1899
2221
|
px: 0,
|
|
1900
2222
|
fontWeight: "bold",
|
|
1901
2223
|
fontSize: "0.875rem",
|
|
@@ -1909,40 +2231,40 @@ var defaultColumnSummaryCellRenderer = (props, fixedFields, isFilterRowVisible)
|
|
|
1909
2231
|
formattedValue
|
|
1910
2232
|
] });
|
|
1911
2233
|
};
|
|
1912
|
-
var actionsColumnSummaryCellRenderer = (
|
|
1913
|
-
var detailColumnCellSummaryRenderer = (
|
|
2234
|
+
var actionsColumnSummaryCellRenderer = (_props) => null;
|
|
2235
|
+
var detailColumnCellSummaryRenderer = (_props) => null;
|
|
1914
2236
|
|
|
1915
2237
|
// src/components/grid/renderers/cellRenderers.tsx
|
|
1916
|
-
import
|
|
1917
|
-
import
|
|
2238
|
+
import React7 from "react";
|
|
2239
|
+
import { Box as Box8, Button as Button2, Tooltip as Tooltip4, useTheme as useTheme2 } from "@mui/material";
|
|
1918
2240
|
import ViewHeadlineIcon from "@mui/icons-material/ViewHeadline";
|
|
1919
2241
|
import DeleteIcon from "@mui/icons-material/Delete";
|
|
1920
2242
|
import AddIcon2 from "@mui/icons-material/Add";
|
|
1921
2243
|
|
|
1922
2244
|
// src/components/grid/ExampleClientSideComponent.tsx
|
|
1923
|
-
import { Box as
|
|
1924
|
-
import { jsx as
|
|
2245
|
+
import { Box as Box6, Typography as Typography3 } from "@mui/material";
|
|
2246
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1925
2247
|
var ExampleClientSideComponent = ({ row, column, fieldDefinition }) => {
|
|
1926
2248
|
const value = row[column.key];
|
|
1927
|
-
return /* @__PURE__ */
|
|
2249
|
+
return /* @__PURE__ */ jsx10(Box6, { sx: {
|
|
1928
2250
|
padding: 0.5,
|
|
1929
2251
|
width: "100%",
|
|
1930
2252
|
height: "100%",
|
|
1931
2253
|
display: "flex",
|
|
1932
2254
|
alignItems: "center",
|
|
1933
2255
|
backgroundColor: value === "Special" ? "lightblue" : "transparent"
|
|
1934
|
-
}, children: /* @__PURE__ */
|
|
2256
|
+
}, children: /* @__PURE__ */ jsx10(Typography3, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
|
|
1935
2257
|
};
|
|
1936
2258
|
var ExampleClientSideComponent_default = ExampleClientSideComponent;
|
|
1937
2259
|
|
|
1938
2260
|
// src/components/grid/FallbackClientSideRenderer.tsx
|
|
1939
|
-
import { Box as
|
|
1940
|
-
import
|
|
1941
|
-
import { jsx as
|
|
2261
|
+
import { Box as Box7, Typography as Typography4, Tooltip as Tooltip3 } from "@mui/material";
|
|
2262
|
+
import WarningAmberIcon2 from "@mui/icons-material/WarningAmber";
|
|
2263
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1942
2264
|
var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
|
|
1943
2265
|
const clientSideName = fieldDefinition?.clientSide || "Desconocido";
|
|
1944
|
-
return /* @__PURE__ */
|
|
1945
|
-
|
|
2266
|
+
return /* @__PURE__ */ jsx11(Tooltip3, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ jsxs9(
|
|
2267
|
+
Box7,
|
|
1946
2268
|
{
|
|
1947
2269
|
sx: {
|
|
1948
2270
|
display: "flex",
|
|
@@ -1962,9 +2284,9 @@ var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
|
|
|
1962
2284
|
// Evita que el contenido se desborde
|
|
1963
2285
|
},
|
|
1964
2286
|
children: [
|
|
1965
|
-
/* @__PURE__ */
|
|
1966
|
-
/* @__PURE__ */
|
|
1967
|
-
|
|
2287
|
+
/* @__PURE__ */ jsx11(Typography4, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: clientSideName + " not found" }),
|
|
2288
|
+
/* @__PURE__ */ jsx11(
|
|
2289
|
+
WarningAmberIcon2,
|
|
1968
2290
|
{
|
|
1969
2291
|
sx: {
|
|
1970
2292
|
fontSize: 18,
|
|
@@ -1991,91 +2313,71 @@ var extendClientSides = (newRenderers) => {
|
|
|
1991
2313
|
};
|
|
1992
2314
|
|
|
1993
2315
|
// src/components/grid/renderers/cellRenderers.tsx
|
|
1994
|
-
import
|
|
1995
|
-
|
|
1996
|
-
var allColumnsCellRenderer = (props, onOpenDetail, ancestors = [], currentFixedFields = []) => {
|
|
2316
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2317
|
+
var CeldaDato = React7.memo(function CeldaDato2({ row, columnKey, defaultColumn }) {
|
|
1997
2318
|
const theme = useTheme2();
|
|
1998
|
-
const
|
|
1999
|
-
const
|
|
2319
|
+
const { primaryKey, fixedFields, typer, isMandatory, isNumeric } = defaultColumn;
|
|
2320
|
+
const rowId = getPrimaryKeyValues(row, primaryKey);
|
|
2321
|
+
const currentCellFeedback = useFeedbackCelda(`${rowId}-${columnKey}`);
|
|
2322
|
+
const pendiente = useCeldaPendiente(rowId, columnKey);
|
|
2323
|
+
const value = row[columnKey];
|
|
2324
|
+
const hasValue = value !== null && value !== void 0 && String(value).trim() !== "";
|
|
2325
|
+
let cellBackgroundColor = "transparent";
|
|
2326
|
+
if (currentCellFeedback) {
|
|
2327
|
+
cellBackgroundColor = currentCellFeedback.type === "error" ? theme.palette.error.light : theme.palette.success.light;
|
|
2328
|
+
} else if (fixedFields?.some((f) => f.fieldName === columnKey)) {
|
|
2329
|
+
cellBackgroundColor = theme.palette.action.selected;
|
|
2330
|
+
} else if (isMandatory && !hasValue || pendiente) {
|
|
2331
|
+
cellBackgroundColor = "#e3f2fd";
|
|
2332
|
+
}
|
|
2333
|
+
let displayValue = value !== null && value !== void 0 ? typer.toLocalString(value) : "";
|
|
2334
|
+
if (!hasValue && isMandatory) {
|
|
2335
|
+
displayValue = "* " + displayValue;
|
|
2336
|
+
}
|
|
2337
|
+
const signal = displayValue === "--" ? "typed-controls-signal-no-data" : displayValue === "//" ? "typed-controls-signal-unknown-data" : "";
|
|
2338
|
+
const celda = /* @__PURE__ */ jsx12(
|
|
2339
|
+
"div",
|
|
2340
|
+
{
|
|
2341
|
+
className: `fpr-celda ${isNumeric ? "fpr-celda-numerica" : ""} ${signal} ${row[NEW_ROW_INDICATOR] ? "new-row-cell-animation" : ""}`,
|
|
2342
|
+
style: { backgroundColor: cellBackgroundColor },
|
|
2343
|
+
children: displayValue
|
|
2344
|
+
}
|
|
2345
|
+
);
|
|
2346
|
+
return currentCellFeedback?.message ? /* @__PURE__ */ jsx12(Tooltip4, { title: currentCellFeedback.message, children: celda }) : celda;
|
|
2347
|
+
});
|
|
2348
|
+
var allColumnsCellRenderer = (props) => {
|
|
2349
|
+
const { row, column } = props;
|
|
2350
|
+
if (!esColumnaPropia(column)) return void 0;
|
|
2351
|
+
if (esFilaDetalle(row)) {
|
|
2352
|
+
return column.customType === "action" ? /* @__PURE__ */ jsx12(CeldaDetalle, { fila: row }) : null;
|
|
2353
|
+
}
|
|
2000
2354
|
switch (column.customType) {
|
|
2001
2355
|
case "default": {
|
|
2002
2356
|
const defaultColumn = column;
|
|
2003
|
-
const { fieldDef, tableDefinition, primaryKey
|
|
2004
|
-
const rowId = getPrimaryKeyValues(row, primaryKey);
|
|
2005
|
-
const cellKey = `${rowId}-${props.column.key}`;
|
|
2006
|
-
const currentCellFeedback = cellFeedbackMap.get(cellKey);
|
|
2357
|
+
const { fieldDef, tableDefinition, primaryKey } = defaultColumn;
|
|
2007
2358
|
if (fieldDef?.clientSide) {
|
|
2008
2359
|
const ClientSideComponent = clientSides[fieldDef.clientSide];
|
|
2009
2360
|
if (ClientSideComponent) {
|
|
2010
|
-
return /* @__PURE__ */
|
|
2011
|
-
}
|
|
2012
|
-
return /* @__PURE__ */ jsx10(FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
|
|
2013
|
-
}
|
|
2014
|
-
let cellBackgroundColor = "transparent";
|
|
2015
|
-
const isMandatory = tableDefinition.primaryKey.includes(props.column.key) || tableDefinition.fields.find((f) => f.name === props.column.key)?.nullable === false;
|
|
2016
|
-
const hasValue = row[props.column.key] !== null && row[props.column.key] !== void 0 && String(row[props.column.key]).trim() !== "";
|
|
2017
|
-
if (currentCellFeedback) {
|
|
2018
|
-
cellBackgroundColor = currentCellFeedback.type === "error" ? theme.palette.error.light : theme.palette.success.light;
|
|
2019
|
-
} else {
|
|
2020
|
-
const isNewRowLocalCheck = row[NEW_ROW_INDICATOR2];
|
|
2021
|
-
const isFixedFieldCurrent = fixedFields?.some((f) => f.fieldName === props.column.key);
|
|
2022
|
-
if (isFixedFieldCurrent) {
|
|
2023
|
-
cellBackgroundColor = theme.palette.action.selected;
|
|
2024
|
-
} else if (isMandatory && !hasValue || localCellChanges.has(rowId) && localCellChanges.get(rowId)?.has(props.column.key)) {
|
|
2025
|
-
cellBackgroundColor = "#e3f2fd";
|
|
2361
|
+
return /* @__PURE__ */ jsx12(ClientSideComponent, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
|
|
2026
2362
|
}
|
|
2363
|
+
return /* @__PURE__ */ jsx12(FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
|
|
2027
2364
|
}
|
|
2028
|
-
|
|
2029
|
-
const typer = typeStore3.typerFrom(fieldDef);
|
|
2030
|
-
let displayValue = value !== null ? typer.toLocalString(value) : "";
|
|
2031
|
-
const isNumeric = isNumericType(fieldDef?.typeName);
|
|
2032
|
-
if (!hasValue && isMandatory) {
|
|
2033
|
-
displayValue = "* " + displayValue;
|
|
2034
|
-
}
|
|
2035
|
-
return /* @__PURE__ */ jsx10(Tooltip3, { title: currentCellFeedback?.message || "", children: /* @__PURE__ */ jsx10(
|
|
2036
|
-
Box7,
|
|
2037
|
-
{
|
|
2038
|
-
className: `${displayValue === "--" ? "typed-controls-signal-no-data" : displayValue === "//" ? "typed-controls-signal-unknown-data" : ""} ${row[NEW_ROW_INDICATOR2] ? "new-row-cell-animation" : ""}`,
|
|
2039
|
-
sx: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", backgroundColor: cellBackgroundColor, transition: "background-color 0.3s ease-in-out", display: "flex", alignItems: "center", justifyContent: isNumeric ? "flex-end" : "flex-start", paddingLeft: "8px", paddingRight: "12px", boxSizing: "border-box" },
|
|
2040
|
-
children: /* @__PURE__ */ jsx10(Typography4, { variant: "body2", sx: { fontSize: "0.875rem", whiteSpace: "nowrap" }, children: displayValue })
|
|
2041
|
-
}
|
|
2042
|
-
) });
|
|
2365
|
+
return /* @__PURE__ */ jsx12(CeldaDato, { row, columnKey: props.column.key, defaultColumn });
|
|
2043
2366
|
}
|
|
2044
2367
|
case "detail": {
|
|
2045
|
-
const
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
IconButton2,
|
|
2368
|
+
const { detailTable, primaryKey } = column;
|
|
2369
|
+
return /* @__PURE__ */ jsx12(
|
|
2370
|
+
BotonDetalle,
|
|
2049
2371
|
{
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
if ("source" in f) return { fieldName: f.target, value: row[f.source] };
|
|
2055
|
-
return { fieldName: f.target, value: f.value };
|
|
2056
|
-
});
|
|
2057
|
-
const rawFixedFields = [...currentFixedFields, ...detailFixedFields];
|
|
2058
|
-
const deduplicatedMap = /* @__PURE__ */ new Map();
|
|
2059
|
-
rawFixedFields.forEach((ff) => deduplicatedMap.set(ff.fieldName, ff));
|
|
2060
|
-
const allFixedFields = Array.from(deduplicatedMap.values());
|
|
2061
|
-
const filterDescription = allFixedFields.map((ff) => `${cambiarGuionesBajosPorEspacios(ff.fieldName)}: ${ff.value}`).join(", ");
|
|
2062
|
-
const label = `${cambiarGuionesBajosPorEspacios(detailTable.table).toUpperCase()} (${filterDescription})`;
|
|
2063
|
-
const newAncestors = [...ancestors, {
|
|
2064
|
-
tableName: tableDefinition.name,
|
|
2065
|
-
row,
|
|
2066
|
-
tableDefinition,
|
|
2067
|
-
fixedFields: allFixedFields
|
|
2068
|
-
}];
|
|
2069
|
-
onOpenDetail(detailTable.table, allFixedFields, label, newAncestors);
|
|
2070
|
-
}
|
|
2071
|
-
},
|
|
2072
|
-
children: /* @__PURE__ */ jsx10(KeyboardArrowRightIcon, {})
|
|
2372
|
+
row,
|
|
2373
|
+
rowId: getPrimaryKeyValues(row, primaryKey),
|
|
2374
|
+
detailTable,
|
|
2375
|
+
deshabilitado: !!row[NEW_ROW_INDICATOR]
|
|
2073
2376
|
}
|
|
2074
|
-
)
|
|
2377
|
+
);
|
|
2075
2378
|
}
|
|
2076
2379
|
case "action": {
|
|
2077
|
-
const
|
|
2078
|
-
const { tableDefinition, handleDeleteRow, handleAddRow, handleVerticalEditRow } = actionColumn;
|
|
2380
|
+
const { tableDefinition, handleDeleteRow, handleAddRow, handleVerticalEditRow } = column;
|
|
2079
2381
|
const gridActionButtons = [
|
|
2080
2382
|
{
|
|
2081
2383
|
action: "insert",
|
|
@@ -2099,7 +2401,7 @@ var allColumnsCellRenderer = (props, onOpenDetail, ancestors = [], currentFixedF
|
|
|
2099
2401
|
color: "primary"
|
|
2100
2402
|
}
|
|
2101
2403
|
];
|
|
2102
|
-
return /* @__PURE__ */
|
|
2404
|
+
return /* @__PURE__ */ jsx12(Box8, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", gap: 0.5 }, children: gridActionButtons.map((actionDef) => tableDefinition.allow[actionDef.action] ? /* @__PURE__ */ jsx12(
|
|
2103
2405
|
Button2,
|
|
2104
2406
|
{
|
|
2105
2407
|
variant: "outlined",
|
|
@@ -2108,7 +2410,7 @@ var allColumnsCellRenderer = (props, onOpenDetail, ancestors = [], currentFixedF
|
|
|
2108
2410
|
onClick: () => actionDef.handler(row),
|
|
2109
2411
|
title: actionDef.title,
|
|
2110
2412
|
sx: { width: 22, minWidth: 22, height: 22, "& .MuiButton-startIcon": { m: 0 } },
|
|
2111
|
-
children: /* @__PURE__ */
|
|
2413
|
+
children: /* @__PURE__ */ jsx12(actionDef.icon, { sx: { fontSize: 18 } })
|
|
2112
2414
|
},
|
|
2113
2415
|
actionDef.action
|
|
2114
2416
|
) : null) });
|
|
@@ -2119,7 +2421,7 @@ var allColumnsCellRenderer = (props, onOpenDetail, ancestors = [], currentFixedF
|
|
|
2119
2421
|
};
|
|
2120
2422
|
|
|
2121
2423
|
// src/components/grid/InputRenderer.tsx
|
|
2122
|
-
import
|
|
2424
|
+
import React8, { useCallback as useCallback9, useEffect as useEffect4, useMemo as useMemo6, useState as useState8 } from "react";
|
|
2123
2425
|
|
|
2124
2426
|
// src/hooks/useTableRecordSave.ts
|
|
2125
2427
|
import { useCallback as useCallback8 } from "react";
|
|
@@ -2167,16 +2469,16 @@ var useTableRecordSave = () => {
|
|
|
2167
2469
|
oldRow: isNewRow ? {} : initialData,
|
|
2168
2470
|
status
|
|
2169
2471
|
});
|
|
2170
|
-
return response;
|
|
2472
|
+
return requerido(response, "la respuesta del guardado");
|
|
2171
2473
|
}, [callApi]);
|
|
2172
2474
|
return { saveRecord, loading, error };
|
|
2173
2475
|
};
|
|
2174
2476
|
|
|
2175
2477
|
// src/components/grid/InputRenderer.tsx
|
|
2176
2478
|
import InputBase2 from "@mui/material/InputBase";
|
|
2177
|
-
import { useTheme as useTheme3 } from "@mui/material";
|
|
2479
|
+
import { Tooltip as Tooltip5, useTheme as useTheme3 } from "@mui/material";
|
|
2178
2480
|
import typeStore4 from "type-store";
|
|
2179
|
-
import { jsx as
|
|
2481
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2180
2482
|
function findChangedValues(oldRowData, newRowData, isNewRow) {
|
|
2181
2483
|
let changes = [];
|
|
2182
2484
|
for (const key in newRowData) {
|
|
@@ -2193,27 +2495,25 @@ function InputRenderer({
|
|
|
2193
2495
|
tableDefinition,
|
|
2194
2496
|
onRowChange,
|
|
2195
2497
|
onClose,
|
|
2196
|
-
cellFeedbackMap,
|
|
2197
|
-
// Tipo: CellFeedbackMap
|
|
2198
|
-
setCellFeedbackMap,
|
|
2199
|
-
// Tipo: Dispatch<SetStateAction<CellFeedbackMap>>
|
|
2200
2498
|
onKeyPress,
|
|
2499
|
+
registrarEditor,
|
|
2201
2500
|
setTableData,
|
|
2202
|
-
setLocalCellChanges,
|
|
2203
|
-
localCellChanges,
|
|
2204
2501
|
primaryKey
|
|
2205
2502
|
}) {
|
|
2206
|
-
const
|
|
2207
|
-
const
|
|
2503
|
+
const estadoGrilla = useEstadoGrilla();
|
|
2504
|
+
const setCellFeedbackMap = estadoGrilla.setFeedback;
|
|
2505
|
+
const setLocalCellChanges = estadoGrilla.setCambiosLocales;
|
|
2506
|
+
const fieldDefinition = requerido(tableDefinition.fields.find((f) => f.name === column.key), `el campo '${column.key}'`);
|
|
2507
|
+
const typer = useMemo6(() => typeStore4.typerFrom(fieldDefinition), [fieldDefinition]);
|
|
2208
2508
|
const [editingValue, setEditingValue] = useState8(() => row[column.key] !== null ? isNumericType(fieldDefinition?.typeName) ? row[column.key] : typer.toLocalString(row[column.key]) : null);
|
|
2209
|
-
const isCommitInProgress =
|
|
2509
|
+
const isCommitInProgress = React8.useRef(false);
|
|
2210
2510
|
const theme = useTheme3();
|
|
2211
2511
|
const { showSuccess, showError } = useSnackbar();
|
|
2212
2512
|
const { saveRecord } = useTableRecordSave();
|
|
2213
2513
|
const tableName = tableDefinition.tableName;
|
|
2214
2514
|
const rowId = getPrimaryKeyValues(row, primaryKey);
|
|
2215
2515
|
const cellKey = `${rowId}-${column.key}`;
|
|
2216
|
-
const currentCellFeedback =
|
|
2516
|
+
const currentCellFeedback = useFeedbackCelda(cellKey);
|
|
2217
2517
|
const isMandatory = tableDefinition.primaryKey.includes(column.key) || fieldDefinition?.nullable === false;
|
|
2218
2518
|
const isEmpty = editingValue === null || editingValue === void 0 || String(editingValue).trim() === "";
|
|
2219
2519
|
let cellBackgroundColor;
|
|
@@ -2222,7 +2522,7 @@ function InputRenderer({
|
|
|
2222
2522
|
cellBackgroundColor = currentCellFeedback.type === "error" ? theme.palette.error.light : theme.palette.success.light;
|
|
2223
2523
|
cellBorderColor = currentCellFeedback.type === "error" ? theme.palette.error.main : theme.palette.success.main;
|
|
2224
2524
|
}
|
|
2225
|
-
const initialRowId =
|
|
2525
|
+
const initialRowId = useMemo6(() => getPrimaryKeyValues(row, primaryKey), [row, primaryKey]);
|
|
2226
2526
|
const handleCommit = useCallback9(async (currentValue, closeEditor, focusNextCell) => {
|
|
2227
2527
|
if (isCommitInProgress.current) return;
|
|
2228
2528
|
isCommitInProgress.current = true;
|
|
@@ -2231,7 +2531,7 @@ function InputRenderer({
|
|
|
2231
2531
|
processedNewValue = getBestTypedValue(currentValue, typer);
|
|
2232
2532
|
typer.validateTypedData(processedNewValue);
|
|
2233
2533
|
} catch (err) {
|
|
2234
|
-
showError(err
|
|
2534
|
+
showError(mensajeDeError(err));
|
|
2235
2535
|
isCommitInProgress.current = false;
|
|
2236
2536
|
return;
|
|
2237
2537
|
}
|
|
@@ -2239,7 +2539,7 @@ function InputRenderer({
|
|
|
2239
2539
|
const arePKValuesFilled = tableDefinition.primaryKey.every(
|
|
2240
2540
|
(key) => potentialUpdatedRow[key] !== void 0 && potentialUpdatedRow[key] !== null && String(potentialUpdatedRow[key]).trim() !== ""
|
|
2241
2541
|
);
|
|
2242
|
-
const isNewRow = !arePKValuesFilled || potentialUpdatedRow[
|
|
2542
|
+
const isNewRow = !arePKValuesFilled || !!potentialUpdatedRow[NEW_ROW_INDICATOR];
|
|
2243
2543
|
const isMandatoryField = tableDefinition.primaryKey.includes(column.key) || tableDefinition.fields.find((f) => f.name === column.key)?.nullable === false;
|
|
2244
2544
|
const isMandatoryFieldEmpty = isNewRow && isMandatoryField && (processedNewValue === null || processedNewValue === void 0 || String(processedNewValue).trim() === "");
|
|
2245
2545
|
if (sameValue(processedNewValue, row[column.key]) && !isNewRow && !isMandatoryFieldEmpty) {
|
|
@@ -2295,7 +2595,7 @@ function InputRenderer({
|
|
|
2295
2595
|
initialData: oldRowData,
|
|
2296
2596
|
targetFieldName: column.key
|
|
2297
2597
|
});
|
|
2298
|
-
const responseRow = response.row;
|
|
2598
|
+
const responseRow = response.row ?? potentialUpdatedRow;
|
|
2299
2599
|
let finalRowIdForFeedback;
|
|
2300
2600
|
let persistedRowData;
|
|
2301
2601
|
if (response.row && isNewRow) {
|
|
@@ -2320,7 +2620,8 @@ function InputRenderer({
|
|
|
2320
2620
|
persistedRowData = responseRow;
|
|
2321
2621
|
const isPrimaryKeyColumn = tableDefinition.primaryKey.includes(column.key);
|
|
2322
2622
|
finalRowIdForFeedback = isPrimaryKeyColumn ? getPrimaryKeyValues(potentialUpdatedRow, tableDefinition.primaryKey) : currentRowIdBeforeUpdate;
|
|
2323
|
-
|
|
2623
|
+
const mismaFila = (fila) => tableDefinition.primaryKey.every((k) => fila[k] === potentialUpdatedRow[k]);
|
|
2624
|
+
setTableData((prevData) => prevData.map((fila) => mismaFila(fila) ? { ...fila, ...responseRow } : fila));
|
|
2324
2625
|
}
|
|
2325
2626
|
const changes = findChangedValues(oldRowData, responseRow, isNewRow);
|
|
2326
2627
|
setCellFeedbackMap((prevFeedback) => {
|
|
@@ -2340,7 +2641,7 @@ function InputRenderer({
|
|
|
2340
2641
|
rowId: currentRowIdBeforeUpdate,
|
|
2341
2642
|
columnKey: column.key,
|
|
2342
2643
|
type: "error",
|
|
2343
|
-
message: err
|
|
2644
|
+
message: mensajeDeError(err)
|
|
2344
2645
|
});
|
|
2345
2646
|
return newFeedback;
|
|
2346
2647
|
});
|
|
@@ -2362,7 +2663,6 @@ function InputRenderer({
|
|
|
2362
2663
|
onClose,
|
|
2363
2664
|
setTableData,
|
|
2364
2665
|
setLocalCellChanges,
|
|
2365
|
-
localCellChanges,
|
|
2366
2666
|
initialRowId,
|
|
2367
2667
|
typer
|
|
2368
2668
|
]);
|
|
@@ -2375,18 +2675,26 @@ function InputRenderer({
|
|
|
2375
2675
|
return;
|
|
2376
2676
|
}
|
|
2377
2677
|
if (["Enter", "Tab", "ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft"].includes(event.key)) {
|
|
2378
|
-
|
|
2678
|
+
void handleCommit(editingValue, true, true);
|
|
2379
2679
|
if (onKeyPress) {
|
|
2380
2680
|
onKeyPress(rowIdx, column.key, event, handleCommit);
|
|
2381
2681
|
}
|
|
2382
2682
|
}
|
|
2383
2683
|
}, [handleCommit, editingValue, column.key, rowIdx, onKeyPress]);
|
|
2684
|
+
const procesarTecla = React8.useRef(() => {
|
|
2685
|
+
});
|
|
2686
|
+
procesarTecla.current = (key) => {
|
|
2687
|
+
if (key === "F4" && onKeyPress) {
|
|
2688
|
+
onKeyPress(rowIdx, column.key, { key, target: document.activeElement ?? document.body }, handleCommit);
|
|
2689
|
+
}
|
|
2690
|
+
};
|
|
2691
|
+
useEffect4(() => registrarEditor?.((key) => procesarTecla.current(key)), []);
|
|
2384
2692
|
const handleBlur = useCallback9(() => {
|
|
2385
2693
|
handleCommit(editingValue, true, false);
|
|
2386
2694
|
}, [handleCommit, editingValue]);
|
|
2387
2695
|
const isFieldEditable = fieldDefinition?.editable !== false;
|
|
2388
2696
|
const isNumeric = isNumericType(fieldDefinition?.typeName);
|
|
2389
|
-
|
|
2697
|
+
const editor = /* @__PURE__ */ jsx13(
|
|
2390
2698
|
InputBase2,
|
|
2391
2699
|
{
|
|
2392
2700
|
autoFocus: true,
|
|
@@ -2413,14 +2721,15 @@ function InputRenderer({
|
|
|
2413
2721
|
disabled: !isFieldEditable
|
|
2414
2722
|
}
|
|
2415
2723
|
);
|
|
2724
|
+
return currentCellFeedback?.message ? /* @__PURE__ */ jsx13(Tooltip5, { title: currentCellFeedback.message, children: /* @__PURE__ */ jsx13("div", { style: { width: "100%" }, children: editor }) }) : editor;
|
|
2416
2725
|
}
|
|
2417
2726
|
var InputRenderer_default = InputRenderer;
|
|
2418
2727
|
|
|
2419
2728
|
// src/components/grid/renderers/editCellRenderers.tsx
|
|
2420
|
-
import {
|
|
2421
|
-
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2729
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2422
2730
|
var allColumnsEditCellRenderer = (props, allColumns) => {
|
|
2423
2731
|
const column = props.column;
|
|
2732
|
+
if (!esColumnaPropia(column)) return void 0;
|
|
2424
2733
|
switch (column.customType) {
|
|
2425
2734
|
case "default": {
|
|
2426
2735
|
const defaultColumn = column;
|
|
@@ -2429,11 +2738,8 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
|
|
|
2429
2738
|
fixedFields,
|
|
2430
2739
|
primaryKey,
|
|
2431
2740
|
setTableData,
|
|
2432
|
-
cellFeedbackMap,
|
|
2433
|
-
setCellFeedbackMap,
|
|
2434
2741
|
handleKeyPressInEditor,
|
|
2435
|
-
|
|
2436
|
-
setLocalCellChanges
|
|
2742
|
+
registrarEditor
|
|
2437
2743
|
} = defaultColumn;
|
|
2438
2744
|
if (column.editable) {
|
|
2439
2745
|
const fieldDefinition = tableDefinition.fields.find((f) => f.name === column.key);
|
|
@@ -2442,25 +2748,16 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
|
|
|
2442
2748
|
if (!isFieldEditableByUI) {
|
|
2443
2749
|
return void 0;
|
|
2444
2750
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
setCellFeedbackMap,
|
|
2456
|
-
cellFeedbackMap,
|
|
2457
|
-
onKeyPress: (rowIndex, columnKey, event, handleCommit) => handleKeyPressInEditor(rowIndex, columnKey, event, allColumns, handleCommit),
|
|
2458
|
-
setTableData,
|
|
2459
|
-
setLocalCellChanges,
|
|
2460
|
-
localCellChanges,
|
|
2461
|
-
primaryKey
|
|
2462
|
-
}
|
|
2463
|
-
) }) })
|
|
2751
|
+
return /* @__PURE__ */ jsx14(
|
|
2752
|
+
InputRenderer_default,
|
|
2753
|
+
{
|
|
2754
|
+
...props,
|
|
2755
|
+
tableDefinition,
|
|
2756
|
+
onKeyPress: (rowIndex, columnKey, event, handleCommit) => handleKeyPressInEditor(rowIndex, columnKey, event, allColumns, handleCommit),
|
|
2757
|
+
registrarEditor,
|
|
2758
|
+
setTableData,
|
|
2759
|
+
primaryKey
|
|
2760
|
+
}
|
|
2464
2761
|
);
|
|
2465
2762
|
}
|
|
2466
2763
|
return void 0;
|
|
@@ -2477,79 +2774,81 @@ var allColumnsEditCellRenderer = (props, allColumns) => {
|
|
|
2477
2774
|
};
|
|
2478
2775
|
|
|
2479
2776
|
// src/hooks/grid/useGridColumns.ts
|
|
2480
|
-
|
|
2777
|
+
var estimateTextWidth = (text) => text.length * 8 + 16;
|
|
2778
|
+
var calcularAnchosDeColumnas = (tableDefinition, filas) => {
|
|
2779
|
+
const anchos = /* @__PURE__ */ new Map();
|
|
2780
|
+
const muestra = filas.slice(0, 50);
|
|
2781
|
+
tableDefinition.fields.forEach((fieldDef) => {
|
|
2782
|
+
const headerLabel = fieldDef.label || fieldDef.name;
|
|
2783
|
+
const type = fieldDef.typeName?.toLowerCase() || "";
|
|
2784
|
+
let typeMinWidth = 60;
|
|
2785
|
+
if (type.includes("boolean") || type.includes("checkbox")) typeMinWidth = 60;
|
|
2786
|
+
else if (type.includes("date") || type.includes("timestamp")) typeMinWidth = 110;
|
|
2787
|
+
else if (type.includes("integer") || type.includes("numeric")) typeMinWidth = 80;
|
|
2788
|
+
const headerWidth = estimateTextWidth(headerLabel) + 20;
|
|
2789
|
+
const typer = typerFrom(fieldDef);
|
|
2790
|
+
const maxDataWidth = muestra.reduce((maxW, row) => {
|
|
2791
|
+
const valor = row[fieldDef.name];
|
|
2792
|
+
if (valor === null || valor === void 0) return maxW;
|
|
2793
|
+
let texto;
|
|
2794
|
+
try {
|
|
2795
|
+
texto = typer.toLocalString(valor);
|
|
2796
|
+
} catch {
|
|
2797
|
+
texto = String(valor);
|
|
2798
|
+
}
|
|
2799
|
+
return Math.max(maxW, estimateTextWidth(texto));
|
|
2800
|
+
}, 0);
|
|
2801
|
+
anchos.set(fieldDef.name, Math.min(Math.max(headerWidth, maxDataWidth, typeMinWidth), 500));
|
|
2802
|
+
});
|
|
2803
|
+
return anchos;
|
|
2804
|
+
};
|
|
2481
2805
|
var useGridColumns = ({
|
|
2482
2806
|
tableDefinition,
|
|
2483
|
-
|
|
2807
|
+
anchosCalculados,
|
|
2484
2808
|
fixedFields,
|
|
2485
|
-
isFilterRowVisible,
|
|
2486
|
-
sortColumns,
|
|
2487
2809
|
primaryKey,
|
|
2488
|
-
localCellChanges,
|
|
2489
|
-
cellFeedbackMap,
|
|
2490
|
-
setCellFeedbackMap,
|
|
2491
2810
|
setTableData,
|
|
2492
|
-
setLocalCellChanges,
|
|
2493
2811
|
handleKeyPressInEditor,
|
|
2812
|
+
registrarEditor,
|
|
2494
2813
|
handleDeleteRow,
|
|
2495
2814
|
handleAddRow,
|
|
2496
2815
|
handleVerticalEditRow,
|
|
2497
2816
|
toggleFilterVisibility,
|
|
2498
|
-
|
|
2499
|
-
setOpenDataGridOptions,
|
|
2500
|
-
onOpenDetail,
|
|
2501
|
-
ancestors
|
|
2817
|
+
abrirOpcionesDeGrilla
|
|
2502
2818
|
}) => {
|
|
2503
|
-
const columns =
|
|
2819
|
+
const columns = useMemo7(() => {
|
|
2504
2820
|
if (!tableDefinition) return [];
|
|
2505
2821
|
const fieldsToShow = tableDefinition.fields.filter((field) => {
|
|
2506
2822
|
const isFixedField = fixedFields?.some((f) => f.fieldName === field.name);
|
|
2507
2823
|
return !isFixedField && field.visible !== false;
|
|
2508
2824
|
});
|
|
2509
|
-
const estimateTextWidth = (text) => text.length * 8 + 16;
|
|
2510
|
-
const getColumnWidthFromData = (fieldDef) => {
|
|
2511
|
-
const headerLabel = fieldDef.label || fieldDef.name;
|
|
2512
|
-
const type = fieldDef.typeName?.toLowerCase() || "";
|
|
2513
|
-
let typeMinWidth = 60;
|
|
2514
|
-
if (type.includes("boolean") || type.includes("checkbox")) typeMinWidth = 60;
|
|
2515
|
-
else if (type.includes("date") || type.includes("timestamp")) typeMinWidth = 110;
|
|
2516
|
-
else if (type.includes("integer") || type.includes("numeric")) typeMinWidth = 80;
|
|
2517
|
-
const headerWidth = estimateTextWidth(headerLabel) + 20;
|
|
2518
|
-
const sampleRows = tableData.slice(0, 50);
|
|
2519
|
-
const maxDataWidth = sampleRows.reduce((maxW, row) => {
|
|
2520
|
-
const typer = typeStore5.typerFrom(fieldDef);
|
|
2521
|
-
const cellValue = row[fieldDef.name] !== null && typer.toLocalString(row[fieldDef.name]);
|
|
2522
|
-
if (cellValue === null || cellValue === void 0) return maxW;
|
|
2523
|
-
return Math.max(maxW, estimateTextWidth(String(cellValue)));
|
|
2524
|
-
}, 0);
|
|
2525
|
-
return Math.min(Math.max(headerWidth, maxDataWidth, typeMinWidth), 500);
|
|
2526
|
-
};
|
|
2527
2825
|
const defaultColumns = fieldsToShow.map((fieldDef) => {
|
|
2528
2826
|
const isFixedField = fixedFields?.some((f) => f.fieldName === fieldDef.name);
|
|
2529
2827
|
const isFieldEditable = fieldDef.editable !== false && !isFixedField;
|
|
2530
|
-
const colWidth =
|
|
2531
|
-
|
|
2828
|
+
const colWidth = anchosCalculados.get(fieldDef.name) ?? estimateTextWidth(fieldDef.label || fieldDef.name) + 20;
|
|
2829
|
+
const column = {
|
|
2532
2830
|
key: fieldDef.name,
|
|
2533
2831
|
customType: "default",
|
|
2534
2832
|
tableDefinition,
|
|
2535
2833
|
fieldDef,
|
|
2536
|
-
|
|
2537
|
-
|
|
2834
|
+
typer: typerFrom(fieldDef),
|
|
2835
|
+
isMandatory: tableDefinition.primaryKey.includes(fieldDef.name) || fieldDef.nullable === false,
|
|
2836
|
+
isNumeric: isNumericType(fieldDef.typeName),
|
|
2538
2837
|
primaryKey,
|
|
2539
2838
|
fixedFields,
|
|
2540
|
-
localCellChanges,
|
|
2541
|
-
setLocalCellChanges,
|
|
2542
2839
|
setTableData,
|
|
2543
2840
|
name: fieldDef.label || cambiarGuionesBajosPorEspacios(fieldDef.name),
|
|
2544
2841
|
resizable: true,
|
|
2545
2842
|
sortable: true,
|
|
2546
2843
|
editable: isFieldEditable,
|
|
2547
2844
|
handleKeyPressInEditor,
|
|
2845
|
+
registrarEditor,
|
|
2548
2846
|
width: colWidth,
|
|
2549
|
-
minWidth:
|
|
2550
|
-
renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(
|
|
2551
|
-
renderSummaryCell: (props) => defaultColumnSummaryCellRenderer(props, fixedFields
|
|
2847
|
+
minWidth: 40,
|
|
2848
|
+
renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(props, fieldDef),
|
|
2849
|
+
renderSummaryCell: (props) => defaultColumnSummaryCellRenderer(props, fixedFields)
|
|
2552
2850
|
};
|
|
2851
|
+
return column;
|
|
2553
2852
|
});
|
|
2554
2853
|
const availableActions = [
|
|
2555
2854
|
tableDefinition.allow?.insert,
|
|
@@ -2569,51 +2868,45 @@ var useGridColumns = ({
|
|
|
2569
2868
|
editable: false,
|
|
2570
2869
|
resizable: false,
|
|
2571
2870
|
sortable: false,
|
|
2572
|
-
renderHeaderCell: (
|
|
2573
|
-
props,
|
|
2574
|
-
isFilterRowVisible,
|
|
2871
|
+
renderHeaderCell: () => React9.createElement(ActionsColumnHeaderCell, {
|
|
2575
2872
|
toggleFilterVisibility,
|
|
2576
|
-
(e) =>
|
|
2577
|
-
setDataGridOptionsAnchorEl(e.currentTarget);
|
|
2578
|
-
setOpenDataGridOptions(true);
|
|
2579
|
-
},
|
|
2873
|
+
handleDataGridOptions: (e) => abrirOpcionesDeGrilla(e.currentTarget),
|
|
2580
2874
|
handleAddRow,
|
|
2581
|
-
tableDefinition.allow?.insert
|
|
2582
|
-
),
|
|
2875
|
+
allowInsert: tableDefinition.allow?.insert
|
|
2876
|
+
}),
|
|
2583
2877
|
renderSummaryCell: (props) => actionsColumnSummaryCellRenderer(props)
|
|
2584
2878
|
};
|
|
2585
|
-
const detailColumns = []
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
renderSummaryCell: (props) => detailColumnCellSummaryRenderer(props)
|
|
2606
|
-
});
|
|
2607
|
-
});
|
|
2608
|
-
}
|
|
2879
|
+
const detailColumns = (tableDefinition.detailTables ?? []).map((detailTable) => {
|
|
2880
|
+
const detailKey = `detail_${detailTable.abr}`;
|
|
2881
|
+
const column = {
|
|
2882
|
+
key: detailKey,
|
|
2883
|
+
customType: "detail",
|
|
2884
|
+
tableDefinition,
|
|
2885
|
+
detailTable,
|
|
2886
|
+
primaryKey,
|
|
2887
|
+
detailKey,
|
|
2888
|
+
name: detailTable.label || `Detalle ${detailTable.abr}`,
|
|
2889
|
+
resizable: false,
|
|
2890
|
+
sortable: false,
|
|
2891
|
+
editable: false,
|
|
2892
|
+
width: 30,
|
|
2893
|
+
minWidth: 30,
|
|
2894
|
+
renderHeaderCell: (props) => detailColumnCellHeaderRenderer(props, detailTable),
|
|
2895
|
+
renderSummaryCell: (props) => detailColumnCellSummaryRenderer(props)
|
|
2896
|
+
};
|
|
2897
|
+
return column;
|
|
2898
|
+
});
|
|
2609
2899
|
const allColumns = [actionsColumn, ...detailColumns, ...defaultColumns];
|
|
2900
|
+
const cantidadDeColumnas = allColumns.length;
|
|
2901
|
+
const colSpanDetalle = (args) => args.type === "ROW" && esFilaDetalle(args.row) ? cantidadDeColumnas : void 0;
|
|
2610
2902
|
return allColumns.map((col) => ({
|
|
2611
2903
|
...col,
|
|
2904
|
+
colSpan: col.customType === "action" ? colSpanDetalle : col.colSpan,
|
|
2612
2905
|
editorOptions: { closeOnExternalRowChange: false },
|
|
2613
2906
|
renderEditCell: (props) => allColumnsEditCellRenderer(props, allColumns),
|
|
2614
|
-
renderCell: (props) => allColumnsCellRenderer(props
|
|
2907
|
+
renderCell: (props) => allColumnsCellRenderer(props)
|
|
2615
2908
|
}));
|
|
2616
|
-
}, [tableDefinition,
|
|
2909
|
+
}, [tableDefinition, anchosCalculados, fixedFields, primaryKey, setTableData, handleKeyPressInEditor, registrarEditor, handleDeleteRow, handleAddRow, handleVerticalEditRow, toggleFilterVisibility, abrirOpcionesDeGrilla]);
|
|
2617
2910
|
return { columns };
|
|
2618
2911
|
};
|
|
2619
2912
|
|
|
@@ -2633,7 +2926,7 @@ import {
|
|
|
2633
2926
|
Divider
|
|
2634
2927
|
} from "@mui/material";
|
|
2635
2928
|
import FileUploadIcon2 from "@mui/icons-material/FileUpload";
|
|
2636
|
-
import { jsx as
|
|
2929
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2637
2930
|
var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
2638
2931
|
const [file, setFile] = useState9(null);
|
|
2639
2932
|
const [options, setOptions] = useState9({
|
|
@@ -2655,15 +2948,15 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
|
2655
2948
|
onClose();
|
|
2656
2949
|
}
|
|
2657
2950
|
};
|
|
2658
|
-
return /* @__PURE__ */
|
|
2659
|
-
/* @__PURE__ */
|
|
2660
|
-
/* @__PURE__ */
|
|
2951
|
+
return /* @__PURE__ */ jsxs10(Dialog2, { open, onClose: loading ? void 0 : onClose, maxWidth: "sm", fullWidth: true, children: [
|
|
2952
|
+
/* @__PURE__ */ jsxs10(DialogTitle2, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
2953
|
+
/* @__PURE__ */ jsx15(FileUploadIcon2, { color: "primary" }),
|
|
2661
2954
|
"Importar datos desde archivo"
|
|
2662
2955
|
] }),
|
|
2663
|
-
/* @__PURE__ */
|
|
2664
|
-
/* @__PURE__ */
|
|
2665
|
-
/* @__PURE__ */
|
|
2666
|
-
/* @__PURE__ */
|
|
2956
|
+
/* @__PURE__ */ jsx15(DialogContent2, { dividers: true, children: /* @__PURE__ */ jsxs10(Stack, { spacing: 3, sx: { mt: 1 }, children: [
|
|
2957
|
+
/* @__PURE__ */ jsxs10(Box9, { children: [
|
|
2958
|
+
/* @__PURE__ */ jsx15(Typography5, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Seleccionar archivo" }),
|
|
2959
|
+
/* @__PURE__ */ jsxs10(
|
|
2667
2960
|
Box9,
|
|
2668
2961
|
{
|
|
2669
2962
|
sx: {
|
|
@@ -2676,7 +2969,7 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
|
2676
2969
|
position: "relative"
|
|
2677
2970
|
},
|
|
2678
2971
|
children: [
|
|
2679
|
-
/* @__PURE__ */
|
|
2972
|
+
/* @__PURE__ */ jsx15(
|
|
2680
2973
|
"input",
|
|
2681
2974
|
{
|
|
2682
2975
|
type: "file",
|
|
@@ -2693,19 +2986,19 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
|
2693
2986
|
}
|
|
2694
2987
|
}
|
|
2695
2988
|
),
|
|
2696
|
-
/* @__PURE__ */
|
|
2989
|
+
/* @__PURE__ */ jsx15(Typography5, { variant: "body2", color: file ? "textPrimary" : "textSecondary", children: file ? file.name : "Haz clic aqu\xED para seleccionar un archivo" })
|
|
2697
2990
|
]
|
|
2698
2991
|
}
|
|
2699
2992
|
)
|
|
2700
2993
|
] }),
|
|
2701
|
-
/* @__PURE__ */
|
|
2702
|
-
/* @__PURE__ */
|
|
2703
|
-
/* @__PURE__ */
|
|
2704
|
-
/* @__PURE__ */
|
|
2705
|
-
/* @__PURE__ */
|
|
2994
|
+
/* @__PURE__ */ jsx15(Divider, {}),
|
|
2995
|
+
/* @__PURE__ */ jsxs10(Box9, { children: [
|
|
2996
|
+
/* @__PURE__ */ jsx15(Typography5, { variant: "subtitle2", gutterBottom: true, fontWeight: "bold", children: "Opciones de importaci\xF3n" }),
|
|
2997
|
+
/* @__PURE__ */ jsxs10(Stack, { children: [
|
|
2998
|
+
/* @__PURE__ */ jsx15(
|
|
2706
2999
|
FormControlLabel,
|
|
2707
3000
|
{
|
|
2708
|
-
control: /* @__PURE__ */
|
|
3001
|
+
control: /* @__PURE__ */ jsx15(
|
|
2709
3002
|
Checkbox,
|
|
2710
3003
|
{
|
|
2711
3004
|
checked: options.skipUnknownFieldsAtImport,
|
|
@@ -2713,13 +3006,13 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
|
2713
3006
|
size: "small"
|
|
2714
3007
|
}
|
|
2715
3008
|
),
|
|
2716
|
-
label: /* @__PURE__ */
|
|
3009
|
+
label: /* @__PURE__ */ jsx15(Typography5, { variant: "body2", children: "Omitir campos desconocidos al importar" })
|
|
2717
3010
|
}
|
|
2718
3011
|
),
|
|
2719
|
-
/* @__PURE__ */
|
|
3012
|
+
/* @__PURE__ */ jsx15(
|
|
2720
3013
|
FormControlLabel,
|
|
2721
3014
|
{
|
|
2722
|
-
control: /* @__PURE__ */
|
|
3015
|
+
control: /* @__PURE__ */ jsx15(
|
|
2723
3016
|
Checkbox,
|
|
2724
3017
|
{
|
|
2725
3018
|
checked: options.simplificateSpaces,
|
|
@@ -2727,13 +3020,13 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
|
2727
3020
|
size: "small"
|
|
2728
3021
|
}
|
|
2729
3022
|
),
|
|
2730
|
-
label: /* @__PURE__ */
|
|
3023
|
+
label: /* @__PURE__ */ jsx15(Typography5, { variant: "body2", children: "Simplificar espacios" })
|
|
2731
3024
|
}
|
|
2732
3025
|
),
|
|
2733
|
-
/* @__PURE__ */
|
|
3026
|
+
/* @__PURE__ */ jsx15(
|
|
2734
3027
|
FormControlLabel,
|
|
2735
3028
|
{
|
|
2736
|
-
control: /* @__PURE__ */
|
|
3029
|
+
control: /* @__PURE__ */ jsx15(
|
|
2737
3030
|
Checkbox,
|
|
2738
3031
|
{
|
|
2739
3032
|
checked: options.replaceNewLineWithSpace,
|
|
@@ -2741,21 +3034,21 @@ var ImportDialog = ({ open, onClose, onImport, loading }) => {
|
|
|
2741
3034
|
size: "small"
|
|
2742
3035
|
}
|
|
2743
3036
|
),
|
|
2744
|
-
label: /* @__PURE__ */
|
|
3037
|
+
label: /* @__PURE__ */ jsx15(Typography5, { variant: "body2", children: "Reemplazar saltos de l\xEDnea con espacios" })
|
|
2745
3038
|
}
|
|
2746
3039
|
)
|
|
2747
3040
|
] })
|
|
2748
3041
|
] })
|
|
2749
3042
|
] }) }),
|
|
2750
|
-
/* @__PURE__ */
|
|
2751
|
-
/* @__PURE__ */
|
|
2752
|
-
/* @__PURE__ */
|
|
3043
|
+
/* @__PURE__ */ jsxs10(DialogActions2, { sx: { px: 3, py: 2 }, children: [
|
|
3044
|
+
/* @__PURE__ */ jsx15(Button3, { onClick: onClose, disabled: loading, children: "Cancelar" }),
|
|
3045
|
+
/* @__PURE__ */ jsx15(
|
|
2753
3046
|
Button3,
|
|
2754
3047
|
{
|
|
2755
3048
|
onClick: handleConfirm,
|
|
2756
3049
|
variant: "contained",
|
|
2757
3050
|
disabled: !file || loading,
|
|
2758
|
-
startIcon: /* @__PURE__ */
|
|
3051
|
+
startIcon: /* @__PURE__ */ jsx15(FileUploadIcon2, {}),
|
|
2759
3052
|
children: loading ? "Procesando..." : "Confirmar Importaci\xF3n"
|
|
2760
3053
|
}
|
|
2761
3054
|
)
|
|
@@ -2783,8 +3076,8 @@ import {
|
|
|
2783
3076
|
CircularProgress as CircularProgress2
|
|
2784
3077
|
} from "@mui/material";
|
|
2785
3078
|
import * as XLSX from "xlsx";
|
|
2786
|
-
import
|
|
2787
|
-
import { jsx as
|
|
3079
|
+
import typeStore5 from "type-store";
|
|
3080
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2788
3081
|
var ExportDialog = ({
|
|
2789
3082
|
open,
|
|
2790
3083
|
onClose,
|
|
@@ -2853,7 +3146,7 @@ var ExportDialog = ({
|
|
|
2853
3146
|
data.push(fieldsToExport.map((fieldDef) => {
|
|
2854
3147
|
const value = row[fieldDef.name];
|
|
2855
3148
|
if (value == null) return "";
|
|
2856
|
-
return
|
|
3149
|
+
return typeStore5.typerFrom(fieldDef).toPlainString(value);
|
|
2857
3150
|
}));
|
|
2858
3151
|
});
|
|
2859
3152
|
const content = data.map((line) => line.map(replacer).join(separator)).join("\r\n");
|
|
@@ -2872,7 +3165,7 @@ var ExportDialog = ({
|
|
|
2872
3165
|
fieldsToExport.forEach((fieldDef, iColumn) => {
|
|
2873
3166
|
const value = row[fieldDef.name];
|
|
2874
3167
|
if (value != null) {
|
|
2875
|
-
const typer =
|
|
3168
|
+
const typer = typeStore5.typerFrom(fieldDef);
|
|
2876
3169
|
const excelValue = typer.toExcelValue(value);
|
|
2877
3170
|
const excelType = typer.toExcelType(value);
|
|
2878
3171
|
const cell = { t: excelType, v: excelValue };
|
|
@@ -2929,63 +3222,63 @@ var ExportDialog = ({
|
|
|
2929
3222
|
URL.revokeObjectURL(url);
|
|
2930
3223
|
}, 0);
|
|
2931
3224
|
};
|
|
2932
|
-
return /* @__PURE__ */
|
|
2933
|
-
/* @__PURE__ */
|
|
2934
|
-
/* @__PURE__ */
|
|
2935
|
-
/* @__PURE__ */
|
|
2936
|
-
/* @__PURE__ */
|
|
2937
|
-
] }) : /* @__PURE__ */
|
|
2938
|
-
/* @__PURE__ */
|
|
2939
|
-
/* @__PURE__ */
|
|
2940
|
-
/* @__PURE__ */
|
|
3225
|
+
return /* @__PURE__ */ jsxs11(Dialog3, { open, onClose, maxWidth: "xs", fullWidth: true, children: [
|
|
3226
|
+
/* @__PURE__ */ jsx16(DialogTitle3, { children: "Exportar Datos" }),
|
|
3227
|
+
/* @__PURE__ */ jsx16(DialogContent3, { children: isPreparing ? /* @__PURE__ */ jsxs11(Box10, { display: "flex", flexDirection: "column", alignItems: "center", py: 4, children: [
|
|
3228
|
+
/* @__PURE__ */ jsx16(CircularProgress2, {}),
|
|
3229
|
+
/* @__PURE__ */ jsx16(Typography6, { sx: { mt: 2 }, children: "Preparando exportaci\xF3n..." })
|
|
3230
|
+
] }) : /* @__PURE__ */ jsxs11(Box10, { sx: { mt: 1 }, children: [
|
|
3231
|
+
/* @__PURE__ */ jsxs11(FormControl2, { component: "fieldset", children: [
|
|
3232
|
+
/* @__PURE__ */ jsx16(FormLabel, { component: "legend", children: "Formato" }),
|
|
3233
|
+
/* @__PURE__ */ jsxs11(
|
|
2941
3234
|
RadioGroup,
|
|
2942
3235
|
{
|
|
2943
3236
|
value: format,
|
|
2944
3237
|
onChange: (e) => setFormat(e.target.value),
|
|
2945
3238
|
children: [
|
|
2946
|
-
/* @__PURE__ */
|
|
2947
|
-
/* @__PURE__ */
|
|
2948
|
-
/* @__PURE__ */
|
|
3239
|
+
/* @__PURE__ */ jsx16(FormControlLabel2, { value: "xlsx", control: /* @__PURE__ */ jsx16(Radio, {}), label: "Excel (.xlsx)" }),
|
|
3240
|
+
/* @__PURE__ */ jsx16(FormControlLabel2, { value: "tab", control: /* @__PURE__ */ jsx16(Radio, {}), label: "Tabulado (.tab | )" }),
|
|
3241
|
+
/* @__PURE__ */ jsx16(FormControlLabel2, { value: "csv", control: /* @__PURE__ */ jsx16(Radio, {}), label: "CSV (.csv , )" })
|
|
2949
3242
|
]
|
|
2950
3243
|
}
|
|
2951
3244
|
)
|
|
2952
3245
|
] }),
|
|
2953
|
-
/* @__PURE__ */
|
|
2954
|
-
/* @__PURE__ */
|
|
2955
|
-
/* @__PURE__ */
|
|
2956
|
-
/* @__PURE__ */
|
|
3246
|
+
/* @__PURE__ */ jsxs11(Box10, { sx: { mt: 3 }, children: [
|
|
3247
|
+
/* @__PURE__ */ jsx16(Typography6, { variant: "subtitle2", gutterBottom: true, children: "Opciones de campos:" }),
|
|
3248
|
+
/* @__PURE__ */ jsxs11(FormGroup, { children: [
|
|
3249
|
+
/* @__PURE__ */ jsx16(
|
|
2957
3250
|
FormControlLabel2,
|
|
2958
3251
|
{
|
|
2959
|
-
control: /* @__PURE__ */
|
|
3252
|
+
control: /* @__PURE__ */ jsx16(Checkbox2, { checked: options.fromOtherTables, onChange: handleOptionChange, name: "fromOtherTables" }),
|
|
2960
3253
|
label: "Desde otras tablas"
|
|
2961
3254
|
}
|
|
2962
3255
|
),
|
|
2963
|
-
/* @__PURE__ */
|
|
3256
|
+
/* @__PURE__ */ jsx16(
|
|
2964
3257
|
FormControlLabel2,
|
|
2965
3258
|
{
|
|
2966
|
-
control: /* @__PURE__ */
|
|
3259
|
+
control: /* @__PURE__ */ jsx16(Checkbox2, { checked: options.readOnly, onChange: handleOptionChange, name: "readOnly" }),
|
|
2967
3260
|
label: "Solo lectura"
|
|
2968
3261
|
}
|
|
2969
3262
|
),
|
|
2970
|
-
/* @__PURE__ */
|
|
3263
|
+
/* @__PURE__ */ jsx16(
|
|
2971
3264
|
FormControlLabel2,
|
|
2972
3265
|
{
|
|
2973
|
-
control: /* @__PURE__ */
|
|
3266
|
+
control: /* @__PURE__ */ jsx16(Checkbox2, { checked: options.hiddens, onChange: handleOptionChange, name: "hiddens" }),
|
|
2974
3267
|
label: "Ocultos"
|
|
2975
3268
|
}
|
|
2976
3269
|
)
|
|
2977
3270
|
] })
|
|
2978
3271
|
] })
|
|
2979
3272
|
] }) }),
|
|
2980
|
-
/* @__PURE__ */
|
|
2981
|
-
/* @__PURE__ */
|
|
2982
|
-
/* @__PURE__ */
|
|
3273
|
+
/* @__PURE__ */ jsxs11(DialogActions3, { children: [
|
|
3274
|
+
/* @__PURE__ */ jsx16(Button4, { onClick: onClose, disabled: isPreparing, children: "Cancelar" }),
|
|
3275
|
+
/* @__PURE__ */ jsx16(Button4, { onClick: handlePrepareExport, variant: "contained", disabled: isPreparing, children: "Descargar" })
|
|
2983
3276
|
] })
|
|
2984
3277
|
] });
|
|
2985
3278
|
};
|
|
2986
3279
|
|
|
2987
3280
|
// src/pages/VerticalEditorPage.tsx
|
|
2988
|
-
import { useState as useState11, useCallback as useCallback10, useMemo as
|
|
3281
|
+
import { useState as useState11, useCallback as useCallback10, useMemo as useMemo8, useRef as useRef5 } from "react";
|
|
2989
3282
|
import {
|
|
2990
3283
|
DialogTitle as DialogTitle4,
|
|
2991
3284
|
DialogContent as DialogContent4,
|
|
@@ -2998,7 +3291,7 @@ import {
|
|
|
2998
3291
|
Typography as Typography7
|
|
2999
3292
|
} from "@mui/material";
|
|
3000
3293
|
import CloseIcon from "@mui/icons-material/Close";
|
|
3001
|
-
import { jsx as
|
|
3294
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3002
3295
|
var VerticalEditorPage = ({
|
|
3003
3296
|
tableName,
|
|
3004
3297
|
tableDefinition,
|
|
@@ -3016,13 +3309,13 @@ var VerticalEditorPage = ({
|
|
|
3016
3309
|
const [globalError, setGlobalError] = useState11(null);
|
|
3017
3310
|
const [isSaving, setIsSaving] = useState11(false);
|
|
3018
3311
|
const [fieldFeedback, setFieldFeedback] = useState11({});
|
|
3019
|
-
const feedbackTimersRef =
|
|
3312
|
+
const feedbackTimersRef = useRef5({});
|
|
3020
3313
|
const handleFieldChange = useCallback10((fieldName, newValue, isValid) => {
|
|
3021
3314
|
setFormData((prev) => ({ ...prev, [fieldName]: newValue }));
|
|
3022
3315
|
setValidityMap((prev) => ({ ...prev, [fieldName]: isValid }));
|
|
3023
3316
|
setGlobalError(null);
|
|
3024
3317
|
}, []);
|
|
3025
|
-
const isFormValid =
|
|
3318
|
+
const isFormValid = useMemo8(() => {
|
|
3026
3319
|
for (const key in validityMap) {
|
|
3027
3320
|
if (validityMap[key] === false) return false;
|
|
3028
3321
|
}
|
|
@@ -3103,7 +3396,7 @@ var VerticalEditorPage = ({
|
|
|
3103
3396
|
}
|
|
3104
3397
|
onSaveSuccess(responseRow, wasNewItem);
|
|
3105
3398
|
} catch (err) {
|
|
3106
|
-
setGlobalError(err
|
|
3399
|
+
setGlobalError(mensajeDeError(err, "Error desconocido al guardar."));
|
|
3107
3400
|
setFieldFeedback((prev) => ({ ...prev, [fieldName]: "error" }));
|
|
3108
3401
|
if (feedbackTimersRef.current[fieldName]) clearTimeout(feedbackTimersRef.current[fieldName]);
|
|
3109
3402
|
feedbackTimersRef.current[fieldName] = setTimeout(
|
|
@@ -3126,21 +3419,21 @@ var VerticalEditorPage = ({
|
|
|
3126
3419
|
tableDefinition,
|
|
3127
3420
|
onSaveSuccess
|
|
3128
3421
|
]);
|
|
3129
|
-
return /* @__PURE__ */
|
|
3130
|
-
/* @__PURE__ */
|
|
3131
|
-
/* @__PURE__ */
|
|
3422
|
+
return /* @__PURE__ */ jsxs12(Box11, { sx: { p: 2, display: "flex", flexDirection: "column", height: "100%" }, children: [
|
|
3423
|
+
/* @__PURE__ */ jsxs12(DialogTitle4, { sx: { px: 0, pt: 0, display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
|
|
3424
|
+
/* @__PURE__ */ jsxs12(Typography7, { component: "div", variant: "h6", children: [
|
|
3132
3425
|
isNewRow ? "Nuevo Registro" : "Editar Registro",
|
|
3133
3426
|
" - ",
|
|
3134
3427
|
tableDefinition.title || tableName
|
|
3135
3428
|
] }),
|
|
3136
|
-
/* @__PURE__ */
|
|
3429
|
+
/* @__PURE__ */ jsx17(IconButton3, { onClick: onClose, size: "small", edge: "end", children: /* @__PURE__ */ jsx17(CloseIcon, {}) })
|
|
3137
3430
|
] }),
|
|
3138
|
-
/* @__PURE__ */
|
|
3139
|
-
globalError && /* @__PURE__ */
|
|
3140
|
-
/* @__PURE__ */
|
|
3431
|
+
/* @__PURE__ */ jsxs12(DialogContent4, { dividers: true, sx: { px: 2, flexGrow: 1, py: 1 }, children: [
|
|
3432
|
+
globalError && /* @__PURE__ */ jsx17(Alert, { severity: "error", sx: { mb: 2 }, children: globalError }),
|
|
3433
|
+
/* @__PURE__ */ jsx17(Box11, { sx: { display: "flex", flexDirection: "column", gap: 0.5 }, children: tableDefinition.fields.map((field) => {
|
|
3141
3434
|
const isFixed = fixedFields?.some((ff) => ff.fieldName === field.name);
|
|
3142
3435
|
const isMandatory = field.nullable === false || tableDefinition.primaryKey.includes(field.name);
|
|
3143
|
-
return /* @__PURE__ */
|
|
3436
|
+
return /* @__PURE__ */ jsx17(Box11, { sx: { width: "100%", maxWidth: "100%" }, children: /* @__PURE__ */ jsx17(
|
|
3144
3437
|
TypedField,
|
|
3145
3438
|
{
|
|
3146
3439
|
fieldDef: field,
|
|
@@ -3154,29 +3447,39 @@ var VerticalEditorPage = ({
|
|
|
3154
3447
|
) }, field.name);
|
|
3155
3448
|
}) })
|
|
3156
3449
|
] }),
|
|
3157
|
-
/* @__PURE__ */
|
|
3158
|
-
/* @__PURE__ */
|
|
3159
|
-
isSaving && /* @__PURE__ */
|
|
3160
|
-
/* @__PURE__ */
|
|
3450
|
+
/* @__PURE__ */ jsxs12(DialogActions4, { sx: { px: 0, pb: 0, pt: 2, justifyContent: "space-between", alignItems: "center" }, children: [
|
|
3451
|
+
/* @__PURE__ */ jsxs12(Box11, { children: [
|
|
3452
|
+
isSaving && /* @__PURE__ */ jsx17(CircularProgress3, { size: 20, sx: { ml: 2 } }),
|
|
3453
|
+
/* @__PURE__ */ jsx17("span", { style: { marginLeft: 10, fontSize: "0.8rem", color: "#666" }, children: isSaving ? "Guardando..." : "Cambios auto-guardados" })
|
|
3161
3454
|
] }),
|
|
3162
|
-
/* @__PURE__ */
|
|
3455
|
+
/* @__PURE__ */ jsx17(Button5, { variant: "outlined", onClick: onClose, children: "Cerrar" })
|
|
3163
3456
|
] })
|
|
3164
3457
|
] });
|
|
3165
3458
|
};
|
|
3166
3459
|
|
|
3167
3460
|
// src/components/grid/GenericDataGrid.tsx
|
|
3168
|
-
import { jsx as
|
|
3461
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3169
3462
|
var SUMMARY_ROW_HEIGHT = 35;
|
|
3170
3463
|
var FILTER_ROW_HEIGHT = 35;
|
|
3171
3464
|
var HEADER_ROW_HEIGHT = 30;
|
|
3172
3465
|
var ROW_HEIGHT = 30;
|
|
3173
3466
|
var MIN_BODY_HEIGHT = 260;
|
|
3174
|
-
var
|
|
3175
|
-
var
|
|
3467
|
+
var DURACION_FEEDBACK_EXITO = 3e3;
|
|
3468
|
+
var ALTO_TITULO_ANIDADA = 26;
|
|
3469
|
+
var ALTO_MINIMO_CUERPO_ANIDADA = 120;
|
|
3470
|
+
var HOLGURA_ANIDADA = 24;
|
|
3471
|
+
var ANCHO_MINIMO_ANIDADA = 240;
|
|
3472
|
+
var SANGRIA_DETALLE = 28 + 8 + 3;
|
|
3473
|
+
var MARGEN_INFERIOR_PAGINA = 24;
|
|
3474
|
+
var PRIMERAS_FILAS_ANIDADA = 20;
|
|
3475
|
+
var LIMITE_PRIMERAS_FILAS_ANIDADA = 30;
|
|
3476
|
+
var esColumnaPropia = (columna) => "customType" in columna;
|
|
3477
|
+
var SIN_ANCESTROS = [];
|
|
3478
|
+
var cargasEnCurso = /* @__PURE__ */ new Map();
|
|
3479
|
+
var StaticAncestorGrid = ({ ancestor, index, fieldsToHide }) => {
|
|
3176
3480
|
const theme = useTheme4();
|
|
3177
3481
|
const { tableDefinition, row } = ancestor;
|
|
3178
|
-
const
|
|
3179
|
-
const columns = useMemo8(() => {
|
|
3482
|
+
const columns = useMemo9(() => {
|
|
3180
3483
|
const filteredFields = tableDefinition.fields.filter(
|
|
3181
3484
|
(field) => !fieldsToHide?.some((ff) => ff.fieldName === field.name)
|
|
3182
3485
|
);
|
|
@@ -3186,8 +3489,8 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide, callApi, showSuccess,
|
|
|
3186
3489
|
key: field.name,
|
|
3187
3490
|
name: field.label || cambiarGuionesBajosPorEspacios(field.name),
|
|
3188
3491
|
width: 150,
|
|
3189
|
-
editable:
|
|
3190
|
-
renderHeaderCell: () => /* @__PURE__ */
|
|
3492
|
+
editable: false,
|
|
3493
|
+
renderHeaderCell: () => /* @__PURE__ */ jsx18(Box12, { sx: { p: 0.5, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx18(
|
|
3191
3494
|
Typography8,
|
|
3192
3495
|
{
|
|
3193
3496
|
variant: "caption",
|
|
@@ -3199,25 +3502,11 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide, callApi, showSuccess,
|
|
|
3199
3502
|
children: field.label || cambiarGuionesBajosPorEspacios(field.name)
|
|
3200
3503
|
}
|
|
3201
3504
|
) }),
|
|
3202
|
-
renderCell: (props) => /* @__PURE__ */
|
|
3505
|
+
renderCell: (props) => /* @__PURE__ */ jsx18(Box12, { sx: { px: 1, height: "100%", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx18(Typography8, { variant: "body2", sx: { fontSize: "0.875rem" }, noWrap: true, children: String(props.row[field.name] ?? "") }) })
|
|
3203
3506
|
};
|
|
3204
3507
|
});
|
|
3205
3508
|
}, [tableDefinition, fieldsToHide]);
|
|
3206
|
-
|
|
3207
|
-
const updatedRow = newRows[0];
|
|
3208
|
-
setRowData(updatedRow);
|
|
3209
|
-
try {
|
|
3210
|
-
await callApi("table_data_save", {
|
|
3211
|
-
table: ancestor.tableName,
|
|
3212
|
-
row: updatedRow
|
|
3213
|
-
});
|
|
3214
|
-
showSuccess(`Registro de ${cambiarGuionesBajosPorEspacios(ancestor.tableName)} actualizado.`);
|
|
3215
|
-
} catch (err) {
|
|
3216
|
-
showError(`Error al actualizar padre: ${err.message}`);
|
|
3217
|
-
setRowData(row);
|
|
3218
|
-
}
|
|
3219
|
-
};
|
|
3220
|
-
return /* @__PURE__ */ jsxs12(Box12, { sx: {
|
|
3509
|
+
return /* @__PURE__ */ jsxs13(Box12, { sx: {
|
|
3221
3510
|
mb: 1.5,
|
|
3222
3511
|
ml: index * 4,
|
|
3223
3512
|
// El primer ancestro (index 0) no tiene margen, los siguientes sí
|
|
@@ -3228,7 +3517,7 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide, callApi, showSuccess,
|
|
|
3228
3517
|
boxShadow: theme.shadows[1],
|
|
3229
3518
|
bgcolor: "background.paper"
|
|
3230
3519
|
}, children: [
|
|
3231
|
-
/* @__PURE__ */
|
|
3520
|
+
/* @__PURE__ */ jsx18(Box12, { sx: {
|
|
3232
3521
|
bgcolor: "primary.main",
|
|
3233
3522
|
color: "primary.contrastText",
|
|
3234
3523
|
px: 1.5,
|
|
@@ -3239,14 +3528,13 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide, callApi, showSuccess,
|
|
|
3239
3528
|
alignItems: "center",
|
|
3240
3529
|
fontWeight: "bold",
|
|
3241
3530
|
gap: 1
|
|
3242
|
-
}, children: /* @__PURE__ */
|
|
3243
|
-
/* @__PURE__ */
|
|
3531
|
+
}, children: /* @__PURE__ */ jsx18(Typography8, { variant: "subtitle2", component: "div", children: cambiarGuionesBajosPorEspacios(ancestor.tableName) }) }),
|
|
3532
|
+
/* @__PURE__ */ jsx18(
|
|
3244
3533
|
DataGrid,
|
|
3245
3534
|
{
|
|
3246
3535
|
className: "rdg-light",
|
|
3247
3536
|
columns,
|
|
3248
|
-
rows: [
|
|
3249
|
-
onRowsChange: handleRowsChange,
|
|
3537
|
+
rows: [row],
|
|
3250
3538
|
headerRowHeight: HEADER_ROW_HEIGHT,
|
|
3251
3539
|
rowHeight: ROW_HEIGHT,
|
|
3252
3540
|
rowKeyGetter: () => "single-row",
|
|
@@ -3257,32 +3545,49 @@ var StaticAncestorGrid = ({ ancestor, index, fieldsToHide, callApi, showSuccess,
|
|
|
3257
3545
|
};
|
|
3258
3546
|
var GenericDataGrid = ({
|
|
3259
3547
|
tableName,
|
|
3260
|
-
fixedFields,
|
|
3548
|
+
fixedFields: fixedFieldsRecibidos,
|
|
3261
3549
|
gridStyles,
|
|
3262
3550
|
onOpenDetail,
|
|
3263
|
-
ancestors =
|
|
3551
|
+
ancestors = SIN_ANCESTROS,
|
|
3552
|
+
anidada = false,
|
|
3553
|
+
titulo,
|
|
3554
|
+
claveCache,
|
|
3555
|
+
onAltoDeseado,
|
|
3556
|
+
onAnchoDeseado,
|
|
3557
|
+
altoDisponible,
|
|
3558
|
+
altoMaximoDetalle
|
|
3264
3559
|
}) => {
|
|
3265
|
-
const
|
|
3266
|
-
const
|
|
3560
|
+
const claveFixedFields = JSON.stringify(fixedFieldsRecibidos ?? null);
|
|
3561
|
+
const fixedFields = useMemo9(() => fixedFieldsRecibidos, [claveFixedFields]);
|
|
3562
|
+
const cacheHeredado = useContext4(CacheGrillasContext);
|
|
3563
|
+
const [cachePropio] = useState12(() => /* @__PURE__ */ new Map());
|
|
3564
|
+
const cache = cacheHeredado ?? cachePropio;
|
|
3565
|
+
const [guardada] = useState12(() => claveCache ? cache.get(claveCache) : void 0);
|
|
3566
|
+
const claveCargadaRef = useRef6(guardada ? `${tableName}|${claveFixedFields}` : null);
|
|
3567
|
+
const [tableDefinition, setTableDefinition] = useState12(guardada?.tableDefinition ?? null);
|
|
3568
|
+
const [tableData, setTableData] = useState12(guardada?.tableData ?? []);
|
|
3569
|
+
const [cargandoInicial, setCargandoInicial] = useState12(!guardada);
|
|
3570
|
+
const [errorDeCarga, setErrorDeCarga] = useState12(null);
|
|
3571
|
+
const [anchosCalculados, setAnchosCalculados] = useState12(() => guardada?.anchosCalculados ?? /* @__PURE__ */ new Map());
|
|
3572
|
+
const [detallesAbiertos, setDetallesAbiertos] = useState12(guardada?.detallesAbiertos ?? []);
|
|
3573
|
+
const [altosDetalle, setAltosDetalle] = useState12(() => guardada?.altosDetalle ?? /* @__PURE__ */ new Map());
|
|
3574
|
+
const [anchosDetalle, setAnchosDetalle] = useState12(() => /* @__PURE__ */ new Map());
|
|
3267
3575
|
const [selectedRows, setSelectedRows] = useState12(() => /* @__PURE__ */ new Set());
|
|
3268
|
-
const [
|
|
3269
|
-
const [
|
|
3270
|
-
const [localCellChanges, setLocalCellChanges] = useState12(/* @__PURE__ */ new Map());
|
|
3576
|
+
const [, setSelectedCell] = useState12(void 0);
|
|
3577
|
+
const [estadoGrilla] = useState12(crearEstadoGrilla);
|
|
3271
3578
|
const theme = useTheme4();
|
|
3272
3579
|
const [openDataGridOptions, setOpenDataGridOptions] = useState12(false);
|
|
3273
3580
|
const [dataGridOptionsAnchorEl, setDataGridOptionsAnchorEl] = useState12(null);
|
|
3274
3581
|
const [exitingRowIds, setExitingRowIds] = useState12(/* @__PURE__ */ new Set());
|
|
3275
|
-
const {
|
|
3276
|
-
const
|
|
3277
|
-
const dataGridRef =
|
|
3278
|
-
const rowAtEditStartRef =
|
|
3582
|
+
const { showError } = useSnackbar();
|
|
3583
|
+
const { username: usuario } = useClientContext();
|
|
3584
|
+
const dataGridRef = useRef6(null);
|
|
3585
|
+
const rowAtEditStartRef = useRef6(null);
|
|
3279
3586
|
const [openImportDialog, setOpenImportDialog] = useState12(false);
|
|
3280
3587
|
const [openExportDialog, setOpenExportDialog] = useState12(false);
|
|
3281
3588
|
const [columnWidths, setColumnWidths] = useState12(() => /* @__PURE__ */ new Map());
|
|
3282
|
-
const { callApi, callApiUpload, loading
|
|
3283
|
-
const
|
|
3284
|
-
const getFilteredRowCount = () => filteredRows.length;
|
|
3285
|
-
const primaryKey = useMemo8(() => {
|
|
3589
|
+
const { callApi, callApiUpload, loading } = useApiCall();
|
|
3590
|
+
const primaryKey = useMemo9(() => {
|
|
3286
3591
|
if (!tableDefinition) return ["id"];
|
|
3287
3592
|
return tableDefinition.primaryKey && tableDefinition.primaryKey.length > 0 ? tableDefinition.primaryKey : ["id"];
|
|
3288
3593
|
}, [tableDefinition]);
|
|
@@ -3300,6 +3605,40 @@ var GenericDataGrid = ({
|
|
|
3300
3605
|
summaryData,
|
|
3301
3606
|
resetView
|
|
3302
3607
|
} = useGridDataView({ tableData, tableDefinition });
|
|
3608
|
+
const abiertos = useMemo9(() => new Set(detallesAbiertos), [detallesAbiertos]);
|
|
3609
|
+
const filasDetalleRef = useRef6(/* @__PURE__ */ new Map());
|
|
3610
|
+
const filasMostradas = useMemo9(() => {
|
|
3611
|
+
const detailTables = tableDefinition?.detailTables ?? [];
|
|
3612
|
+
if (abiertos.size === 0 || detailTables.length === 0) return filteredRows;
|
|
3613
|
+
const anteriores = filasDetalleRef.current;
|
|
3614
|
+
const nuevas = /* @__PURE__ */ new Map();
|
|
3615
|
+
const filas = [];
|
|
3616
|
+
filteredRows.forEach((row) => {
|
|
3617
|
+
filas.push(row);
|
|
3618
|
+
const rowId = getPrimaryKeyValues(row, primaryKey);
|
|
3619
|
+
detailTables.forEach((detailTable) => {
|
|
3620
|
+
const clave = claveDetalle(rowId, detailTable);
|
|
3621
|
+
if (!abiertos.has(clave)) return;
|
|
3622
|
+
const anterior = anteriores.get(clave);
|
|
3623
|
+
const filaDetalle = anterior && anterior.filaPadre === row ? anterior : {
|
|
3624
|
+
[DETALLE]: true,
|
|
3625
|
+
clave,
|
|
3626
|
+
filaPadre: row,
|
|
3627
|
+
detailTable,
|
|
3628
|
+
fixedFields: calcularFixedFieldsDetalle(detailTable, row)
|
|
3629
|
+
};
|
|
3630
|
+
nuevas.set(clave, filaDetalle);
|
|
3631
|
+
filas.push(filaDetalle);
|
|
3632
|
+
});
|
|
3633
|
+
});
|
|
3634
|
+
filasDetalleRef.current = nuevas;
|
|
3635
|
+
return filas;
|
|
3636
|
+
}, [filteredRows, abiertos, tableDefinition, primaryKey]);
|
|
3637
|
+
const altoDeDetalle = useCallback11((clave) => altosDetalle.get(clave) ?? ALTO_INICIAL_DETALLE, [altosDetalle]);
|
|
3638
|
+
const altoDetalles = useMemo9(
|
|
3639
|
+
() => filasMostradas.reduce((total, row) => esFilaDetalle(row) ? total + altoDeDetalle(row.clave) : total, 0),
|
|
3640
|
+
[filasMostradas, altoDeDetalle]
|
|
3641
|
+
);
|
|
3303
3642
|
const {
|
|
3304
3643
|
handleAddRow,
|
|
3305
3644
|
handleConfirmDelete,
|
|
@@ -3318,24 +3657,33 @@ var GenericDataGrid = ({
|
|
|
3318
3657
|
primaryKey,
|
|
3319
3658
|
fixedFields,
|
|
3320
3659
|
setExitingRowIds,
|
|
3321
|
-
setLocalCellChanges,
|
|
3660
|
+
setLocalCellChanges: estadoGrilla.setCambiosLocales,
|
|
3322
3661
|
setSelectedRows,
|
|
3323
3662
|
setTableData,
|
|
3324
3663
|
callApi,
|
|
3325
3664
|
callApiUpload,
|
|
3326
3665
|
resetView
|
|
3327
3666
|
});
|
|
3667
|
+
const firstDisplayCount = tableDefinition?.firstDisplayCount ?? PRIMERAS_FILAS_ANIDADA;
|
|
3668
|
+
const firstDisplayOverLimit = tableDefinition?.firstDisplayOverLimit ?? LIMITE_PRIMERAS_FILAS_ANIDADA;
|
|
3669
|
+
const filasVisiblesMax = anidada ? filteredRows.length <= firstDisplayOverLimit ? filteredRows.length : firstDisplayCount : void 0;
|
|
3670
|
+
const conPie = !anidada || !!tableDefinition?.fields.some((field) => field.aggregate);
|
|
3328
3671
|
const { gridHeight, bottomSummaryRow, summaryRows, filterHeight } = useGridLayout({
|
|
3329
3672
|
filteredRows,
|
|
3330
3673
|
isFilterRowVisible,
|
|
3331
3674
|
tableData,
|
|
3332
3675
|
summaryData,
|
|
3333
3676
|
filters,
|
|
3334
|
-
setFilters
|
|
3677
|
+
setFilters,
|
|
3678
|
+
altoDetalles,
|
|
3679
|
+
altoMinimoCuerpo: anidada ? ALTO_MINIMO_CUERPO_ANIDADA : MIN_BODY_HEIGHT,
|
|
3680
|
+
holgura: anidada ? HOLGURA_ANIDADA : void 0,
|
|
3681
|
+
filasVisiblesMax,
|
|
3682
|
+
conPie
|
|
3335
3683
|
});
|
|
3336
|
-
const { handleCellDoubleClick, handleCellClick, handleCellKeyDown, handleCellMouseDown, handleKeyPressInEditor, handleSelectedCellChange, handleRowsChange } = useGridEvents({
|
|
3684
|
+
const { handleCellDoubleClick, handleCellClick, handleCellKeyDown, handleCellMouseDown, handleKeyPressInEditor, registrarEditor, handleSelectedCellChange, handleRowsChange } = useGridEvents({
|
|
3337
3685
|
dataGridRef,
|
|
3338
|
-
filteredRows,
|
|
3686
|
+
filteredRows: filasMostradas,
|
|
3339
3687
|
fixedFields,
|
|
3340
3688
|
tableData,
|
|
3341
3689
|
tableDefinition,
|
|
@@ -3343,103 +3691,273 @@ var GenericDataGrid = ({
|
|
|
3343
3691
|
setTableData,
|
|
3344
3692
|
setSortColumns
|
|
3345
3693
|
});
|
|
3346
|
-
|
|
3694
|
+
const tableNameAnteriorRef = useRef6(tableName);
|
|
3695
|
+
useEffect5(() => {
|
|
3696
|
+
if (tableNameAnteriorRef.current === tableName) return;
|
|
3697
|
+
tableNameAnteriorRef.current = tableName;
|
|
3698
|
+
setDetallesAbiertos([]);
|
|
3699
|
+
setAltosDetalle(/* @__PURE__ */ new Map());
|
|
3347
3700
|
resetView();
|
|
3348
3701
|
setSelectedRows(/* @__PURE__ */ new Set());
|
|
3349
3702
|
setTableDefinition(null);
|
|
3350
3703
|
setTableData([]);
|
|
3351
|
-
|
|
3352
|
-
|
|
3704
|
+
estadoGrilla.setFeedback(/* @__PURE__ */ new Map());
|
|
3705
|
+
estadoGrilla.setCambiosLocales(/* @__PURE__ */ new Map());
|
|
3353
3706
|
setExitingRowIds(/* @__PURE__ */ new Set());
|
|
3354
3707
|
setColumnWidths(/* @__PURE__ */ new Map());
|
|
3355
|
-
|
|
3356
|
-
|
|
3708
|
+
}, [tableName, estadoGrilla, resetView]);
|
|
3709
|
+
useEffect5(() => {
|
|
3710
|
+
const claveCarga = `${tableName}|${claveFixedFields}`;
|
|
3711
|
+
if (claveCargadaRef.current === claveCarga) {
|
|
3712
|
+
if (guardada) setSortColumns(guardada.sortColumns);
|
|
3713
|
+
return;
|
|
3357
3714
|
}
|
|
3358
|
-
|
|
3359
|
-
useEffect3(() => {
|
|
3715
|
+
let vigente = true;
|
|
3360
3716
|
const fetchDataAndDefinition = async () => {
|
|
3717
|
+
setCargandoInicial(true);
|
|
3718
|
+
setErrorDeCarga(null);
|
|
3361
3719
|
try {
|
|
3362
|
-
const
|
|
3720
|
+
const clavePedido = `${tableName}|${claveFixedFields}`;
|
|
3721
|
+
let pedido = cargasEnCurso.get(clavePedido);
|
|
3722
|
+
if (!pedido) {
|
|
3723
|
+
const nuevo = (async () => {
|
|
3724
|
+
const definition2 = requerido(
|
|
3725
|
+
await callApi("table_structure", { table: tableName }, { isCritical: true }),
|
|
3726
|
+
`la estructura de '${tableName}'`
|
|
3727
|
+
);
|
|
3728
|
+
const validFixedFields = fixedFields?.filter(
|
|
3729
|
+
(ff) => definition2.fields.some((field) => field.name === ff.fieldName)
|
|
3730
|
+
);
|
|
3731
|
+
const data2 = requerido(
|
|
3732
|
+
await callApi("table_data", {
|
|
3733
|
+
table: tableName,
|
|
3734
|
+
fixedFields: validFixedFields ?? []
|
|
3735
|
+
}, { isCritical: true }),
|
|
3736
|
+
`los datos de '${tableName}'`
|
|
3737
|
+
);
|
|
3738
|
+
return { definition: definition2, data: data2 };
|
|
3739
|
+
})();
|
|
3740
|
+
cargasEnCurso.set(clavePedido, nuevo);
|
|
3741
|
+
const sacar = () => {
|
|
3742
|
+
cargasEnCurso.delete(clavePedido);
|
|
3743
|
+
};
|
|
3744
|
+
nuevo.then(sacar, sacar);
|
|
3745
|
+
pedido = nuevo;
|
|
3746
|
+
}
|
|
3747
|
+
const { definition, data } = await pedido;
|
|
3748
|
+
if (!vigente) return;
|
|
3749
|
+
claveCargadaRef.current = claveCarga;
|
|
3363
3750
|
setTableDefinition(definition);
|
|
3364
3751
|
setSortColumns(getInitialSortColumns(definition));
|
|
3365
|
-
|
|
3366
|
-
(ff) => definition.fields.some((field) => field.name === ff.fieldName)
|
|
3367
|
-
);
|
|
3368
|
-
const data = await callApi("table_data", {
|
|
3369
|
-
table: tableName,
|
|
3370
|
-
fixedFields: validFixedFields
|
|
3371
|
-
}, { isCritical: true });
|
|
3752
|
+
setAnchosCalculados(calcularAnchosDeColumnas(definition, data));
|
|
3372
3753
|
setTableData(data);
|
|
3373
3754
|
} catch (err) {
|
|
3755
|
+
if (!vigente) return;
|
|
3374
3756
|
setTableDefinition(null);
|
|
3375
3757
|
setTableData([]);
|
|
3376
|
-
|
|
3758
|
+
const mensaje = `Error al cargar datos para la tabla '${tableName}': ${mensajeDeError(err)}`;
|
|
3759
|
+
setErrorDeCarga(mensaje);
|
|
3760
|
+
showError(mensaje);
|
|
3761
|
+
} finally {
|
|
3762
|
+
if (vigente) setCargandoInicial(false);
|
|
3377
3763
|
}
|
|
3378
3764
|
};
|
|
3379
3765
|
fetchDataAndDefinition();
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3766
|
+
return () => {
|
|
3767
|
+
vigente = false;
|
|
3768
|
+
};
|
|
3769
|
+
}, [tableName, claveFixedFields, fixedFields, showError, callApi, getInitialSortColumns, setSortColumns, guardada]);
|
|
3770
|
+
useEffect5(() => {
|
|
3771
|
+
if (!claveCache || !tableDefinition || cargandoInicial) return;
|
|
3772
|
+
cache.set(claveCache, { tableDefinition, tableData, anchosCalculados, sortColumns, detallesAbiertos, altosDetalle });
|
|
3773
|
+
}, [cache, claveCache, tableDefinition, tableData, anchosCalculados, sortColumns, detallesAbiertos, altosDetalle, cargandoInicial]);
|
|
3774
|
+
useEffect5(() => {
|
|
3775
|
+
let timer = null;
|
|
3776
|
+
const desuscribir = estadoGrilla.suscribir(() => {
|
|
3777
|
+
const hayExitos = Array.from(estadoGrilla.obtenerFeedback().values()).some((f) => f.type === "success");
|
|
3778
|
+
if (!hayExitos || timer) return;
|
|
3779
|
+
timer = setTimeout(() => {
|
|
3780
|
+
timer = null;
|
|
3781
|
+
estadoGrilla.setFeedback((anterior) => {
|
|
3782
|
+
const nuevo = new Map(anterior);
|
|
3783
|
+
let cambio = false;
|
|
3784
|
+
for (const [cellId, feedback] of anterior.entries()) {
|
|
3392
3785
|
if (feedback.type === "success") {
|
|
3393
|
-
|
|
3394
|
-
|
|
3786
|
+
nuevo.delete(cellId);
|
|
3787
|
+
cambio = true;
|
|
3395
3788
|
}
|
|
3396
3789
|
}
|
|
3397
|
-
return
|
|
3790
|
+
return cambio ? nuevo : anterior;
|
|
3398
3791
|
});
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
}
|
|
3792
|
+
}, DURACION_FEEDBACK_EXITO);
|
|
3793
|
+
});
|
|
3402
3794
|
return () => {
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
}
|
|
3795
|
+
desuscribir();
|
|
3796
|
+
if (timer) clearTimeout(timer);
|
|
3406
3797
|
};
|
|
3407
|
-
}, [
|
|
3798
|
+
}, [estadoGrilla]);
|
|
3799
|
+
const resetSortingDeLaTabla = useCallback11(() => {
|
|
3800
|
+
if (tableDefinition) resetSorting(tableDefinition);
|
|
3801
|
+
}, [tableDefinition, resetSorting]);
|
|
3802
|
+
const abrirImportacion = useCallback11(() => setOpenImportDialog(true), []);
|
|
3803
|
+
const abrirExportacion = useCallback11(() => setOpenExportDialog(true), []);
|
|
3408
3804
|
const { menuOptions } = useGridMenu({
|
|
3409
3805
|
tableDefinition,
|
|
3410
3806
|
tableName,
|
|
3411
3807
|
fixedFields,
|
|
3412
3808
|
setTableData,
|
|
3413
3809
|
callApi,
|
|
3414
|
-
resetSorting: tableDefinition ?
|
|
3415
|
-
triggerImport:
|
|
3416
|
-
triggerExport:
|
|
3810
|
+
resetSorting: tableDefinition ? resetSortingDeLaTabla : void 0,
|
|
3811
|
+
triggerImport: abrirImportacion,
|
|
3812
|
+
triggerExport: abrirExportacion
|
|
3417
3813
|
});
|
|
3814
|
+
const abrirOpcionesDeGrilla = useCallback11((anchorEl) => {
|
|
3815
|
+
setDataGridOptionsAnchorEl(anchorEl);
|
|
3816
|
+
setOpenDataGridOptions(true);
|
|
3817
|
+
}, []);
|
|
3818
|
+
const editarEnFicha = useCallback11((row) => {
|
|
3819
|
+
rowAtEditStartRef.current = { ...row };
|
|
3820
|
+
handleVerticalEditRow(row);
|
|
3821
|
+
}, [handleVerticalEditRow]);
|
|
3418
3822
|
const { columns } = useGridColumns({
|
|
3419
3823
|
tableDefinition,
|
|
3420
|
-
|
|
3824
|
+
anchosCalculados,
|
|
3421
3825
|
fixedFields,
|
|
3422
|
-
isFilterRowVisible,
|
|
3423
|
-
sortColumns,
|
|
3424
3826
|
primaryKey,
|
|
3425
|
-
localCellChanges,
|
|
3426
|
-
cellFeedbackMap,
|
|
3427
|
-
setCellFeedbackMap,
|
|
3428
3827
|
setTableData,
|
|
3429
|
-
setLocalCellChanges,
|
|
3430
3828
|
handleKeyPressInEditor,
|
|
3829
|
+
registrarEditor,
|
|
3431
3830
|
handleDeleteRow,
|
|
3432
3831
|
handleAddRow,
|
|
3433
|
-
handleVerticalEditRow:
|
|
3434
|
-
rowAtEditStartRef.current = { ...row };
|
|
3435
|
-
handleVerticalEditRow(row);
|
|
3436
|
-
},
|
|
3832
|
+
handleVerticalEditRow: editarEnFicha,
|
|
3437
3833
|
toggleFilterVisibility,
|
|
3438
|
-
|
|
3439
|
-
setOpenDataGridOptions,
|
|
3440
|
-
onOpenDetail,
|
|
3441
|
-
ancestors: ancestors ?? []
|
|
3834
|
+
abrirOpcionesDeGrilla
|
|
3442
3835
|
});
|
|
3836
|
+
const abrirDetalleEnPestana = useCallback11((row, detailTable) => {
|
|
3837
|
+
if (!onOpenDetail || !tableDefinition || !detailTable.table) return;
|
|
3838
|
+
const porCampo = /* @__PURE__ */ new Map();
|
|
3839
|
+
[...fixedFields ?? [], ...calcularFixedFieldsDetalle(detailTable, row)].forEach((ff) => porCampo.set(ff.fieldName, ff));
|
|
3840
|
+
const allFixedFields = Array.from(porCampo.values());
|
|
3841
|
+
const filterDescription = allFixedFields.map((ff) => `${cambiarGuionesBajosPorEspacios(ff.fieldName)}: ${ff.value}`).join(", ");
|
|
3842
|
+
const label = `${cambiarGuionesBajosPorEspacios(detailTable.table).toUpperCase()} (${filterDescription})`;
|
|
3843
|
+
const newAncestors = [...ancestors, { tableName: tableDefinition.name, row, tableDefinition, fixedFields: allFixedFields }];
|
|
3844
|
+
onOpenDetail(detailTable.table, allFixedFields, label, newAncestors);
|
|
3845
|
+
}, [onOpenDetail, tableDefinition, fixedFields, ancestors]);
|
|
3846
|
+
const abrirWScreenEnPestana = useCallback11((row, detailTable) => {
|
|
3847
|
+
const parametros = new URLSearchParams();
|
|
3848
|
+
calcularFixedFieldsDetalle(detailTable, row).forEach((ff) => parametros.set(ff.fieldName, String(ff.value)));
|
|
3849
|
+
window.open(`${window.location.origin}/wScreens/${detailTable.wScreen}?${parametros}`, "_blank");
|
|
3850
|
+
}, []);
|
|
3851
|
+
const alternarDetalle = useCallback11((row, rowId, detailTable, enOtraPestana) => {
|
|
3852
|
+
if (enOtraPestana && detailTable.wScreen) {
|
|
3853
|
+
abrirWScreenEnPestana(row, detailTable);
|
|
3854
|
+
return;
|
|
3855
|
+
}
|
|
3856
|
+
if (enOtraPestana && onOpenDetail) {
|
|
3857
|
+
abrirDetalleEnPestana(row, detailTable);
|
|
3858
|
+
return;
|
|
3859
|
+
}
|
|
3860
|
+
const clave = claveDetalle(rowId, detailTable);
|
|
3861
|
+
setDetallesAbiertos((anteriores) => anteriores.includes(clave) ? anteriores.filter((c) => c !== clave) : [...anteriores, clave]);
|
|
3862
|
+
}, [onOpenDetail, abrirDetalleEnPestana, abrirWScreenEnPestana]);
|
|
3863
|
+
const [medidas, setMedidas] = useState12(null);
|
|
3864
|
+
useEffect5(() => {
|
|
3865
|
+
const elemento = dataGridRef.current?.element;
|
|
3866
|
+
if (!elemento) return;
|
|
3867
|
+
const medir = () => setMedidas((anteriores) => {
|
|
3868
|
+
const nuevas = { ancho: elemento.clientWidth, alto: elemento.clientHeight, barra: elemento.offsetWidth - elemento.clientWidth };
|
|
3869
|
+
return anteriores && anteriores.ancho === nuevas.ancho && anteriores.alto === nuevas.alto && anteriores.barra === nuevas.barra ? anteriores : nuevas;
|
|
3870
|
+
});
|
|
3871
|
+
medir();
|
|
3872
|
+
const observador = new ResizeObserver(medir);
|
|
3873
|
+
observador.observe(elemento);
|
|
3874
|
+
return () => observador.disconnect();
|
|
3875
|
+
}, [tableDefinition, cargandoInicial]);
|
|
3876
|
+
const anchoVisible = medidas?.ancho ?? null;
|
|
3877
|
+
const [altoDeVentana, setAltoDeVentana] = useState12(null);
|
|
3878
|
+
useEffect5(() => {
|
|
3879
|
+
if (anidada) return;
|
|
3880
|
+
const elemento = dataGridRef.current?.element;
|
|
3881
|
+
if (!elemento) return;
|
|
3882
|
+
const calcular = () => setAltoDeVentana(Math.max(0, Math.round(window.innerHeight - elemento.getBoundingClientRect().top - MARGEN_INFERIOR_PAGINA)));
|
|
3883
|
+
calcular();
|
|
3884
|
+
window.addEventListener("resize", calcular);
|
|
3885
|
+
return () => window.removeEventListener("resize", calcular);
|
|
3886
|
+
}, [anidada, tableDefinition, cargandoInicial]);
|
|
3887
|
+
const altoDeContexto = useContext4(AltoDisponibleContext);
|
|
3888
|
+
const altoDeEstaGrilla = anidada ? altoDisponible ?? (altoDeContexto === void 0 ? void 0 : altoDeContexto - ALTO_TITULO_ANIDADA) : altoDeVentana ?? void 0;
|
|
3889
|
+
const altoMaximoDetalleEfectivo = altoMaximoDetalle ?? (altoDeEstaGrilla !== void 0 ? Math.max(ALTO_MINIMO_DETALLE, altoDeEstaGrilla - HEADER_ROW_HEIGHT - (conPie ? SUMMARY_ROW_HEIGHT : 0) - ROW_HEIGHT - (isFilterRowVisible ? FILTER_ROW_HEIGHT : 0)) : void 0);
|
|
3890
|
+
const cambiarAnchoDetalle = useCallback11((clave, ancho) => {
|
|
3891
|
+
setAnchosDetalle((anteriores) => anteriores.get(clave) === ancho ? anteriores : new Map(anteriores).set(clave, ancho));
|
|
3892
|
+
}, []);
|
|
3893
|
+
const cambiarAltoDetalle = useCallback11((clave, altoDeseado2) => {
|
|
3894
|
+
const alto = Math.min(Math.max(Math.round(altoDeseado2), ALTO_MINIMO_DETALLE), altoMaximoDetalleEfectivo ?? Infinity);
|
|
3895
|
+
setAltosDetalle((anteriores) => anteriores.get(clave) === alto ? anteriores : new Map(anteriores).set(clave, alto));
|
|
3896
|
+
}, [altoMaximoDetalleEfectivo]);
|
|
3897
|
+
const renderDetalle = useCallback11((fila) => {
|
|
3898
|
+
const { detailTable } = fila;
|
|
3899
|
+
return /* @__PURE__ */ jsx18(
|
|
3900
|
+
"div",
|
|
3901
|
+
{
|
|
3902
|
+
className: "fpr-detalle",
|
|
3903
|
+
style: { maxWidth: anchoVisible ? anchoVisible - 2 : void 0 },
|
|
3904
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
3905
|
+
children: detailTable.table ? /* @__PURE__ */ jsx18(
|
|
3906
|
+
GenericDataGrid,
|
|
3907
|
+
{
|
|
3908
|
+
tableName: detailTable.table,
|
|
3909
|
+
fixedFields: fila.fixedFields,
|
|
3910
|
+
anidada: true,
|
|
3911
|
+
claveCache: `${claveCache ?? tableName}>${fila.clave}`,
|
|
3912
|
+
onAltoDeseado: (alto) => cambiarAltoDetalle(fila.clave, alto),
|
|
3913
|
+
onAnchoDeseado: (ancho) => cambiarAnchoDetalle(fila.clave, ancho),
|
|
3914
|
+
altoDisponible: altoMaximoDetalleEfectivo === void 0 ? void 0 : altoMaximoDetalleEfectivo - ALTO_TITULO_ANIDADA - 8,
|
|
3915
|
+
onOpenDetail,
|
|
3916
|
+
ancestors: tableDefinition ? [...ancestors, { tableName: tableDefinition.name, row: fila.filaPadre, tableDefinition, fixedFields: fila.fixedFields }] : ancestors
|
|
3917
|
+
}
|
|
3918
|
+
) : detailTable.wScreen ? /* @__PURE__ */ jsx18(
|
|
3919
|
+
DetalleWScreen,
|
|
3920
|
+
{
|
|
3921
|
+
fila,
|
|
3922
|
+
altoMaximo: altoMaximoDetalleEfectivo,
|
|
3923
|
+
onAlto: (alto) => cambiarAltoDetalle(fila.clave, alto),
|
|
3924
|
+
onAncho: (ancho) => cambiarAnchoDetalle(fila.clave, ancho)
|
|
3925
|
+
}
|
|
3926
|
+
) : /* @__PURE__ */ jsxs13(Alert2, { severity: "warning", children: [
|
|
3927
|
+
"El detalle '",
|
|
3928
|
+
detailTable.abr,
|
|
3929
|
+
"' no tiene ni tabla ni wScreen."
|
|
3930
|
+
] })
|
|
3931
|
+
}
|
|
3932
|
+
);
|
|
3933
|
+
}, [anchoVisible, claveCache, tableName, cambiarAltoDetalle, cambiarAnchoDetalle, altoMaximoDetalleEfectivo, onOpenDetail, tableDefinition, ancestors]);
|
|
3934
|
+
const detallesGrilla = useMemo9(() => ({ abiertos, alternarDetalle, renderDetalle }), [abiertos, alternarDetalle, renderDetalle]);
|
|
3935
|
+
const altoDeseado = cargandoInicial ? ALTO_INICIAL_DETALLE : gridHeight + ALTO_TITULO_ANIDADA + 8;
|
|
3936
|
+
useEffect5(() => {
|
|
3937
|
+
onAltoDeseado?.(altoDeseado);
|
|
3938
|
+
}, [onAltoDeseado, altoDeseado]);
|
|
3939
|
+
const rowKeyGetter = useCallback11((row) => esFilaDetalle(row) ? `detalle:${row.clave}` : getPrimaryKeyValues(row, primaryKey), [primaryKey]);
|
|
3940
|
+
const rowHeight = useCallback11((row) => esFilaDetalle(row) ? altoDeDetalle(row.clave) : ROW_HEIGHT, [altoDeDetalle]);
|
|
3941
|
+
const rowClass = useCallback11(
|
|
3942
|
+
(row) => esFilaDetalle(row) ? "fpr-fila-detalle" : exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? "fpr-fila-saliendo" : void 0,
|
|
3943
|
+
[exitingRowIds, primaryKey]
|
|
3944
|
+
);
|
|
3945
|
+
const anchoContenido = useMemo9(() => {
|
|
3946
|
+
if (!anidada || columns.length === 0) return void 0;
|
|
3947
|
+
const sumaColumnas = columns.reduce((total, col) => {
|
|
3948
|
+
const medido = columnWidths.get(col.key)?.width;
|
|
3949
|
+
return total + (typeof medido === "number" ? medido : typeof col.width === "number" ? col.width : 100);
|
|
3950
|
+
}, 0);
|
|
3951
|
+
const propio = sumaColumnas + (medidas?.barra ?? 0) + 2;
|
|
3952
|
+
const anchoDetalleMax = detallesAbiertos.reduce((max, clave) => Math.max(max, anchosDetalle.get(clave) ?? 0), 0);
|
|
3953
|
+
return Math.max(ANCHO_MINIMO_ANIDADA, propio, anchoDetalleMax > 0 ? anchoDetalleMax + SANGRIA_DETALLE + (medidas?.barra ?? 0) + 2 : 0);
|
|
3954
|
+
}, [anidada, columns, columnWidths, medidas?.barra, detallesAbiertos, anchosDetalle]);
|
|
3955
|
+
useEffect5(() => {
|
|
3956
|
+
if (anchoContenido !== void 0) onAnchoDeseado?.(anchoContenido);
|
|
3957
|
+
}, [onAnchoDeseado, anchoContenido]);
|
|
3958
|
+
const estiloGrilla = useMemo9(() => ({ height: "100%", width: "100%", boxSizing: "border-box", ...gridStyles }), [gridStyles]);
|
|
3959
|
+
const bottomSummaryRows = useMemo9(() => conPie ? [bottomSummaryRow] : [], [conPie, bottomSummaryRow]);
|
|
3960
|
+
const vistaGrilla = useMemo9(() => ({ isFilterRowVisible }), [isFilterRowVisible]);
|
|
3443
3961
|
const getFallBackMessage = () => {
|
|
3444
3962
|
if (tableData.length === 0) {
|
|
3445
3963
|
return "No hay filas para mostrar";
|
|
@@ -3450,32 +3968,29 @@ var GenericDataGrid = ({
|
|
|
3450
3968
|
return null;
|
|
3451
3969
|
};
|
|
3452
3970
|
const fallBackMessage = getFallBackMessage();
|
|
3453
|
-
if (
|
|
3454
|
-
return /* @__PURE__ */
|
|
3455
|
-
/* @__PURE__ */
|
|
3456
|
-
/* @__PURE__ */
|
|
3971
|
+
if (cargandoInicial) {
|
|
3972
|
+
return /* @__PURE__ */ jsxs13(Box12, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: [
|
|
3973
|
+
/* @__PURE__ */ jsx18(CircularProgress4, {}),
|
|
3974
|
+
/* @__PURE__ */ jsx18(Typography8, { variant: "h6", sx: { ml: 2 }, children: "Cargando tabla..." })
|
|
3457
3975
|
] });
|
|
3458
3976
|
}
|
|
3459
|
-
if (
|
|
3460
|
-
return /* @__PURE__ */
|
|
3977
|
+
if (errorDeCarga) {
|
|
3978
|
+
return /* @__PURE__ */ jsx18(Box12, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsx18(Alert2, { severity: "error", children: errorDeCarga }) });
|
|
3461
3979
|
}
|
|
3462
3980
|
if (!tableDefinition) {
|
|
3463
|
-
return /* @__PURE__ */
|
|
3981
|
+
return /* @__PURE__ */ jsx18(Box12, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsx18(Alert2, { severity: "warning", children: "No se pudo cargar la definici\xF3n de la tabla." }) });
|
|
3464
3982
|
}
|
|
3465
|
-
return /* @__PURE__ */
|
|
3466
|
-
|
|
3983
|
+
return /* @__PURE__ */ jsx18(CacheGrillasContext.Provider, { value: cache, children: /* @__PURE__ */ jsxs13(Box12, { sx: { pt: anidada ? 0 : 2, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box", width: anchoContenido ?? void 0, maxWidth: "100%" }, children: [
|
|
3984
|
+
!anidada && ancestors.length > 0 && /* @__PURE__ */ jsx18(Box12, { sx: { px: 2, pt: 0, pb: 1, display: "flex", flexDirection: "column" }, children: ancestors.map((ancestor, index) => /* @__PURE__ */ jsx18(
|
|
3467
3985
|
StaticAncestorGrid,
|
|
3468
3986
|
{
|
|
3469
3987
|
ancestor,
|
|
3470
3988
|
index,
|
|
3471
|
-
fieldsToHide: index > 0 ? ancestors[index - 1].fixedFields : []
|
|
3472
|
-
callApi,
|
|
3473
|
-
showSuccess,
|
|
3474
|
-
showError
|
|
3989
|
+
fieldsToHide: index > 0 ? ancestors[index - 1].fixedFields : []
|
|
3475
3990
|
},
|
|
3476
3991
|
index
|
|
3477
3992
|
)) }),
|
|
3478
|
-
/* @__PURE__ */
|
|
3993
|
+
/* @__PURE__ */ jsxs13(
|
|
3479
3994
|
Box12,
|
|
3480
3995
|
{
|
|
3481
3996
|
sx: {
|
|
@@ -3488,75 +4003,81 @@ var GenericDataGrid = ({
|
|
|
3488
4003
|
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
3489
4004
|
borderTopLeftRadius: theme.shape.borderRadius,
|
|
3490
4005
|
borderTopRightRadius: theme.shape.borderRadius,
|
|
3491
|
-
ml: 2 + ancestors.length * 4,
|
|
4006
|
+
ml: anidada ? 0 : 2 + ancestors.length * 4,
|
|
3492
4007
|
// Margen dinámico basado en jerarquía
|
|
3493
|
-
mr: 2
|
|
4008
|
+
mr: anidada ? 0 : 2,
|
|
4009
|
+
minHeight: anidada ? ALTO_TITULO_ANIDADA : void 0,
|
|
4010
|
+
boxSizing: "border-box",
|
|
4011
|
+
display: "flex",
|
|
4012
|
+
alignItems: "center",
|
|
4013
|
+
gap: 1
|
|
3494
4014
|
},
|
|
3495
|
-
children:
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
4015
|
+
children: [
|
|
4016
|
+
/* @__PURE__ */ jsxs13(Typography8, { variant: "subtitle2", component: "div", children: [
|
|
4017
|
+
titulo ?? cambiarGuionesBajosPorEspacios(tableDefinition.title || tableDefinition.name),
|
|
4018
|
+
" - ",
|
|
4019
|
+
filteredRows.length === tableData.length ? `${tableData.length} registros` : `${filteredRows.length} (F)`
|
|
4020
|
+
] }),
|
|
4021
|
+
loading && /* @__PURE__ */ jsx18(CircularProgress4, { size: 14, color: "inherit" })
|
|
4022
|
+
]
|
|
3500
4023
|
}
|
|
3501
4024
|
),
|
|
3502
|
-
/* @__PURE__ */
|
|
4025
|
+
/* @__PURE__ */ jsxs13(
|
|
3503
4026
|
Box12,
|
|
3504
4027
|
{
|
|
3505
4028
|
sx: {
|
|
3506
|
-
|
|
3507
|
-
//
|
|
4029
|
+
// Una grilla anidada se acota con px (el alto que le dio la de arriba, o el de una wScreen): una wScreen
|
|
4030
|
+
// tiene alto automático y ahí un porcentaje no se resuelve. La principal ocupa lo que quede de la pantalla.
|
|
4031
|
+
height: anidada ? `${altoDeEstaGrilla === void 0 ? gridHeight : Math.min(gridHeight, altoDeEstaGrilla)}px` : `min(${gridHeight}px, 100%)`,
|
|
3508
4032
|
maxHeight: "100%",
|
|
3509
4033
|
boxSizing: "border-box",
|
|
3510
4034
|
position: "relative",
|
|
3511
4035
|
// CRÍTICO para el centrado del fallback
|
|
3512
4036
|
overflowX: "auto",
|
|
3513
4037
|
overflowY: "auto",
|
|
3514
|
-
px: 2,
|
|
3515
|
-
ml: ancestors.length * 4,
|
|
4038
|
+
px: anidada ? 0 : 2,
|
|
4039
|
+
ml: anidada ? 0 : ancestors.length * 4,
|
|
3516
4040
|
// Indentación de la grilla principal
|
|
3517
|
-
pb: 3
|
|
4041
|
+
pb: anidada ? 0 : 3
|
|
3518
4042
|
},
|
|
3519
4043
|
children: [
|
|
3520
|
-
/* @__PURE__ */
|
|
4044
|
+
/* @__PURE__ */ jsx18(EstadoGrillaContext.Provider, { value: estadoGrilla, children: /* @__PURE__ */ jsx18(VistaGrillaContext.Provider, { value: vistaGrilla, children: /* @__PURE__ */ jsx18(DetallesGrillaContext.Provider, { value: detallesGrilla, children: /* @__PURE__ */ jsx18(
|
|
3521
4045
|
DataGrid,
|
|
3522
4046
|
{
|
|
3523
4047
|
className: "rdg-light",
|
|
3524
4048
|
ref: dataGridRef,
|
|
3525
4049
|
columns,
|
|
3526
|
-
rows:
|
|
3527
|
-
|
|
3528
|
-
style: exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? { maxHeight: 0, opacity: 0, overflow: "hidden" } : { maxHeight: "35px", opacity: 1 }
|
|
3529
|
-
})),
|
|
4050
|
+
rows: filasMostradas,
|
|
4051
|
+
rowClass,
|
|
3530
4052
|
columnWidths,
|
|
3531
4053
|
onColumnWidthsChange: setColumnWidths,
|
|
3532
4054
|
enableVirtualization: true,
|
|
3533
|
-
rowKeyGetter
|
|
4055
|
+
rowKeyGetter,
|
|
3534
4056
|
onSelectedRowsChange: setSelectedRows,
|
|
3535
4057
|
onSelectedCellChange: handleSelectedCellChange,
|
|
3536
4058
|
onRowsChange: handleRowsChange,
|
|
3537
4059
|
sortColumns,
|
|
3538
4060
|
onSortColumnsChange: handleSortColumnsChange,
|
|
3539
4061
|
selectedRows,
|
|
3540
|
-
rowHeight
|
|
3541
|
-
style:
|
|
4062
|
+
rowHeight,
|
|
4063
|
+
style: estiloGrilla,
|
|
3542
4064
|
headerRowHeight: HEADER_ROW_HEIGHT,
|
|
3543
4065
|
topSummaryRows: summaryRows,
|
|
3544
|
-
bottomSummaryRows
|
|
4066
|
+
bottomSummaryRows,
|
|
3545
4067
|
summaryRowHeight: SUMMARY_ROW_HEIGHT,
|
|
3546
|
-
renderers: void 0,
|
|
3547
4068
|
onCellMouseDown: handleCellMouseDown,
|
|
3548
4069
|
onCellDoubleClick: handleCellDoubleClick,
|
|
3549
4070
|
onCellClick: handleCellClick,
|
|
3550
4071
|
onCellKeyDown: handleCellKeyDown
|
|
3551
4072
|
}
|
|
3552
|
-
),
|
|
3553
|
-
fallBackMessage && /* @__PURE__ */
|
|
4073
|
+
) }) }) }),
|
|
4074
|
+
fallBackMessage && /* @__PURE__ */ jsx18(
|
|
3554
4075
|
Box12,
|
|
3555
4076
|
{
|
|
3556
4077
|
sx: {
|
|
3557
4078
|
position: "absolute",
|
|
3558
4079
|
top: filterHeight + HEADER_ROW_HEIGHT + 1,
|
|
3559
|
-
bottom: 102,
|
|
4080
|
+
bottom: anidada ? (conPie ? SUMMARY_ROW_HEIGHT : 0) + 4 : 102,
|
|
3560
4081
|
left: 18,
|
|
3561
4082
|
right: 0,
|
|
3562
4083
|
display: "flex",
|
|
@@ -3567,13 +4088,13 @@ var GenericDataGrid = ({
|
|
|
3567
4088
|
zIndex: tableData.length === 0 ? 10 : 1
|
|
3568
4089
|
// Mantenemos el zIndex superior para el estado vacío total
|
|
3569
4090
|
},
|
|
3570
|
-
children: /* @__PURE__ */
|
|
4091
|
+
children: /* @__PURE__ */ jsx18(Typography8, { variant: "body2", color: "textSecondary", children: fallBackMessage })
|
|
3571
4092
|
}
|
|
3572
4093
|
)
|
|
3573
4094
|
]
|
|
3574
4095
|
}
|
|
3575
4096
|
),
|
|
3576
|
-
/* @__PURE__ */
|
|
4097
|
+
/* @__PURE__ */ jsx18(
|
|
3577
4098
|
ExportDialog,
|
|
3578
4099
|
{
|
|
3579
4100
|
open: openExportDialog,
|
|
@@ -3581,19 +4102,19 @@ var GenericDataGrid = ({
|
|
|
3581
4102
|
tableDefinition,
|
|
3582
4103
|
tableData,
|
|
3583
4104
|
filteredRows,
|
|
3584
|
-
username:
|
|
4105
|
+
username: usuario || "anonymous"
|
|
3585
4106
|
}
|
|
3586
4107
|
),
|
|
3587
|
-
/* @__PURE__ */
|
|
4108
|
+
/* @__PURE__ */ jsx18(
|
|
3588
4109
|
ConfirmDialog,
|
|
3589
4110
|
{
|
|
3590
4111
|
open: openConfirmDialog,
|
|
3591
4112
|
onClose: handleConfirmDelete,
|
|
3592
4113
|
title: "Confirmar Eliminaci\xF3n",
|
|
3593
|
-
message: rowToDelete && rowToDelete[
|
|
4114
|
+
message: rowToDelete && rowToDelete[NEW_ROW_INDICATOR] ? `\xBFEst\xE1s seguro de que quieres eliminar esta nueva fila (ID: ${getPrimaryKeyValues(rowToDelete, primaryKey)}) localmente?` : rowToDelete ? `\xBFEst\xE1s seguro de que quieres eliminar la fila con ID: ${getPrimaryKeyValues(rowToDelete, primaryKey)} de la base de datos? Esta acci\xF3n es irreversible.` : "\xBFEst\xE1s seguro de que quieres eliminar este registro? Esta acci\xF3n es irreversible."
|
|
3594
4115
|
}
|
|
3595
4116
|
),
|
|
3596
|
-
/* @__PURE__ */
|
|
4117
|
+
/* @__PURE__ */ jsx18(
|
|
3597
4118
|
DataGridOptionsDialog,
|
|
3598
4119
|
{
|
|
3599
4120
|
open: openDataGridOptions,
|
|
@@ -3602,7 +4123,7 @@ var GenericDataGrid = ({
|
|
|
3602
4123
|
anchorEl: dataGridOptionsAnchorEl
|
|
3603
4124
|
}
|
|
3604
4125
|
),
|
|
3605
|
-
/* @__PURE__ */
|
|
4126
|
+
/* @__PURE__ */ jsx18(
|
|
3606
4127
|
ImportDialog,
|
|
3607
4128
|
{
|
|
3608
4129
|
open: openImportDialog,
|
|
@@ -3611,21 +4132,21 @@ var GenericDataGrid = ({
|
|
|
3611
4132
|
loading
|
|
3612
4133
|
}
|
|
3613
4134
|
),
|
|
3614
|
-
|
|
4135
|
+
/* @__PURE__ */ jsx18(
|
|
3615
4136
|
Dialog4,
|
|
3616
4137
|
{
|
|
3617
4138
|
open: openVerticalEditDialog,
|
|
3618
4139
|
onClose: () => setOpenVerticalEditDialog(false),
|
|
3619
4140
|
maxWidth: "sm",
|
|
3620
4141
|
fullWidth: true,
|
|
3621
|
-
children: rowToEditVertical && /* @__PURE__ */
|
|
4142
|
+
children: rowToEditVertical && /* @__PURE__ */ jsx18(
|
|
3622
4143
|
VerticalEditorPage,
|
|
3623
4144
|
{
|
|
3624
4145
|
tableName,
|
|
3625
4146
|
tableDefinition,
|
|
3626
4147
|
initialData: rowToEditVertical,
|
|
3627
4148
|
fixedFields,
|
|
3628
|
-
isNewRow: !!rowToEditVertical[
|
|
4149
|
+
isNewRow: !!rowToEditVertical[NEW_ROW_INDICATOR],
|
|
3629
4150
|
onSaveSuccess: (savedRow, isNewItem) => {
|
|
3630
4151
|
setRowToEditVertical(savedRow);
|
|
3631
4152
|
setTableData((prevData) => {
|
|
@@ -3643,11 +4164,11 @@ var GenericDataGrid = ({
|
|
|
3643
4164
|
onClose: () => {
|
|
3644
4165
|
const originalRow = rowAtEditStartRef.current;
|
|
3645
4166
|
const serverRow = rowToEditVertical;
|
|
3646
|
-
if (originalRow && serverRow
|
|
4167
|
+
if (originalRow && serverRow) {
|
|
3647
4168
|
const rowId = getPrimaryKeyValues(serverRow, primaryKey);
|
|
3648
4169
|
const changedFields = tableDefinition.fields.filter((f) => !sameValue(originalRow[f.name], serverRow[f.name])).map((f) => f.name);
|
|
3649
4170
|
if (changedFields.length > 0) {
|
|
3650
|
-
|
|
4171
|
+
estadoGrilla.setFeedback((prev) => {
|
|
3651
4172
|
const next = new Map(prev);
|
|
3652
4173
|
changedFields.forEach((fieldName) => {
|
|
3653
4174
|
next.set(`${rowId}-${fieldName}`, { rowId, columnKey: fieldName, type: "success" });
|
|
@@ -3663,23 +4184,23 @@ var GenericDataGrid = ({
|
|
|
3663
4184
|
)
|
|
3664
4185
|
}
|
|
3665
4186
|
)
|
|
3666
|
-
] });
|
|
4187
|
+
] }) });
|
|
3667
4188
|
};
|
|
3668
4189
|
var GenericDataGrid_default = GenericDataGrid;
|
|
3669
4190
|
|
|
3670
4191
|
// src/App.tsx
|
|
3671
|
-
import
|
|
4192
|
+
import React25, { useEffect as useEffect13, useMemo as useMemo14 } from "react";
|
|
3672
4193
|
import { BrowserRouter, Routes, Route, useLocation as useLocation6, Navigate as Navigate2, Outlet as Outlet2 } from "react-router-dom";
|
|
3673
4194
|
|
|
3674
4195
|
// src/components/MainLayout.tsx
|
|
3675
|
-
import { useEffect as
|
|
4196
|
+
import { useEffect as useEffect8 } from "react";
|
|
3676
4197
|
import { Outlet } from "react-router-dom";
|
|
3677
4198
|
import {
|
|
3678
|
-
Box as
|
|
4199
|
+
Box as Box14,
|
|
3679
4200
|
AppBar,
|
|
3680
4201
|
Toolbar,
|
|
3681
|
-
Typography as
|
|
3682
|
-
Button as
|
|
4202
|
+
Typography as Typography10,
|
|
4203
|
+
Button as Button6,
|
|
3683
4204
|
Drawer,
|
|
3684
4205
|
CssBaseline,
|
|
3685
4206
|
IconButton as IconButton4,
|
|
@@ -3688,13 +4209,13 @@ import {
|
|
|
3688
4209
|
} from "@mui/material";
|
|
3689
4210
|
|
|
3690
4211
|
// src/contexts/AppContext.tsx
|
|
3691
|
-
import { createContext as
|
|
4212
|
+
import { createContext as createContext4, useContext as useContext5, useState as useState13, useEffect as useEffect6, useCallback as useCallback12, useMemo as useMemo10, useRef as useRef7 } from "react";
|
|
3692
4213
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
3693
4214
|
import { useSelector as useSelector2, useDispatch as useDispatch2 } from "react-redux";
|
|
3694
|
-
import { jsx as
|
|
3695
|
-
var AuthContext =
|
|
4215
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
4216
|
+
var AuthContext = createContext4(void 0);
|
|
3696
4217
|
var useApp = () => {
|
|
3697
|
-
const context =
|
|
4218
|
+
const context = useContext5(AuthContext);
|
|
3698
4219
|
if (!context) {
|
|
3699
4220
|
throw new Error("useApp must be used within an AppProvider");
|
|
3700
4221
|
}
|
|
@@ -3705,9 +4226,11 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
3705
4226
|
console.log("AppProvider rendered/re-rendered");
|
|
3706
4227
|
const [isLoggedIn, setIsLoggedIn] = useState13(false);
|
|
3707
4228
|
const [showSessionExpiredMessage, setShowSessionExpiredMessage] = useState13(false);
|
|
3708
|
-
const isRedirectingRef =
|
|
4229
|
+
const isRedirectingRef = useRef7(false);
|
|
4230
|
+
const huboSesionRef = useRef7(false);
|
|
3709
4231
|
const dispatch = useDispatch2();
|
|
3710
4232
|
const clientContext = useSelector2((state) => state.clientContext);
|
|
4233
|
+
if (clientContext.status === "succeeded") huboSesionRef.current = true;
|
|
3711
4234
|
const navigate = useNavigate();
|
|
3712
4235
|
const handleExpiredSessionRedirect = useCallback12(() => {
|
|
3713
4236
|
isRedirectingRef.current = true;
|
|
@@ -3729,6 +4252,7 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
3729
4252
|
const response = await fetchApi("/keep-alive.json", { method: "GET" });
|
|
3730
4253
|
if (isRedirectingRef.current) return;
|
|
3731
4254
|
if (response.ok) {
|
|
4255
|
+
huboSesionRef.current = true;
|
|
3732
4256
|
setIsLoggedIn(true);
|
|
3733
4257
|
setShowSessionExpiredMessage(false);
|
|
3734
4258
|
if (clientContext.status === "idle" || clientContext.status === "failed") {
|
|
@@ -3743,11 +4267,11 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
3743
4267
|
} else {
|
|
3744
4268
|
setIsLoggedIn(false);
|
|
3745
4269
|
dispatch(clearClientContext());
|
|
3746
|
-
if (!showSessionExpiredMessage && !isCurrentPathPublic()) {
|
|
4270
|
+
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current) {
|
|
3747
4271
|
console.warn("Sesi\xF3n inv\xE1lida en ruta protegida. Mostrando modal.");
|
|
3748
4272
|
setShowSessionExpiredMessage(true);
|
|
3749
4273
|
} else {
|
|
3750
|
-
console.log("Sesi\xF3n inv\xE1lida, pero
|
|
4274
|
+
console.log("Sesi\xF3n inv\xE1lida, pero no hay nada que avisar (ruta p\xFAblica o nunca hubo sesi\xF3n).");
|
|
3751
4275
|
}
|
|
3752
4276
|
}
|
|
3753
4277
|
} catch (error) {
|
|
@@ -3755,19 +4279,19 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
3755
4279
|
setIsLoggedIn(false);
|
|
3756
4280
|
dispatch(clearClientContext());
|
|
3757
4281
|
const isPublic = publicPaths.some((p) => location.pathname === p || location.pathname.startsWith(p + "/"));
|
|
3758
|
-
if (!showSessionExpiredMessage && !isCurrentPathPublic()) {
|
|
4282
|
+
if (!showSessionExpiredMessage && !isCurrentPathPublic() && huboSesionRef.current) {
|
|
3759
4283
|
setShowSessionExpiredMessage(true);
|
|
3760
4284
|
}
|
|
3761
4285
|
}
|
|
3762
|
-
}, [dispatch, clientContext.status, showSessionExpiredMessage]);
|
|
3763
|
-
|
|
4286
|
+
}, [dispatch, clientContext.status, showSessionExpiredMessage, isCurrentPathPublic]);
|
|
4287
|
+
useEffect6(() => {
|
|
3764
4288
|
checkSession();
|
|
3765
4289
|
const intervalId = setInterval(checkSession, 15 * 1e3);
|
|
3766
4290
|
return () => {
|
|
3767
4291
|
clearInterval(intervalId);
|
|
3768
4292
|
};
|
|
3769
4293
|
}, [checkSession]);
|
|
3770
|
-
const authContextValue =
|
|
4294
|
+
const authContextValue = useMemo10(() => ({
|
|
3771
4295
|
isLoggedIn,
|
|
3772
4296
|
setIsLoggedIn,
|
|
3773
4297
|
checkSession,
|
|
@@ -3782,7 +4306,7 @@ var AppProvider = ({ children, publicPaths = [] }) => {
|
|
|
3782
4306
|
setShowSessionExpiredMessage,
|
|
3783
4307
|
handleExpiredSessionRedirect
|
|
3784
4308
|
]);
|
|
3785
|
-
return /* @__PURE__ */
|
|
4309
|
+
return /* @__PURE__ */ jsx19(AuthContext.Provider, { value: authContextValue, children });
|
|
3786
4310
|
};
|
|
3787
4311
|
|
|
3788
4312
|
// src/components/MainLayout.tsx
|
|
@@ -3791,8 +4315,8 @@ import MenuIcon from "@mui/icons-material/Menu";
|
|
|
3791
4315
|
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
|
|
3792
4316
|
|
|
3793
4317
|
// src/components/SideMenu.tsx
|
|
3794
|
-
import
|
|
3795
|
-
import { List as List2, ListItem, ListItemButton as ListItemButton2, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, Divider as Divider2, Box as
|
|
4318
|
+
import React15, { useEffect as useEffect7 } from "react";
|
|
4319
|
+
import { List as List2, ListItem, ListItemButton as ListItemButton2, ListItemIcon as ListItemIcon2, ListItemText as ListItemText2, Divider as Divider2, Box as Box13, Typography as Typography9, Collapse } from "@mui/material";
|
|
3796
4320
|
import ExpandLess from "@mui/icons-material/ExpandLess";
|
|
3797
4321
|
import ExpandMore from "@mui/icons-material/ExpandMore";
|
|
3798
4322
|
import TableChartIcon from "@mui/icons-material/TableChart";
|
|
@@ -3805,46 +4329,7 @@ import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
|
|
|
3805
4329
|
import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
|
|
3806
4330
|
import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
|
|
3807
4331
|
import { blue, orange, teal, red, grey } from "@mui/material/colors";
|
|
3808
|
-
|
|
3809
|
-
// src/pages/WScreens.tsx
|
|
3810
|
-
import { Box as Box13, Typography as Typography9, Paper as Paper2 } from "@mui/material";
|
|
3811
|
-
import ConstructionIcon from "@mui/icons-material/Construction";
|
|
3812
|
-
import WarningAmberIcon2 from "@mui/icons-material/WarningAmber";
|
|
3813
|
-
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3814
|
-
var MyCustomDashboard = ({ screenName }) => {
|
|
3815
|
-
return /* @__PURE__ */ jsx18(Box13, { sx: { p: 4, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%" }, children: /* @__PURE__ */ jsxs13(Paper2, { elevation: 3, sx: { p: 4, textAlign: "center", maxWidth: 600 }, children: [
|
|
3816
|
-
/* @__PURE__ */ jsxs13(Typography9, { variant: "h5", component: "h1", gutterBottom: true, children: [
|
|
3817
|
-
"\xA1Bienvenido a tu WScreen: ",
|
|
3818
|
-
screenName,
|
|
3819
|
-
"!"
|
|
3820
|
-
] }),
|
|
3821
|
-
/* @__PURE__ */ jsx18(Typography9, { variant: "body1", color: "text.secondary", children: "Esta es una pantalla de interfaz de usuario personalizada." }),
|
|
3822
|
-
/* @__PURE__ */ jsx18(Box13, { sx: { mt: 3 }, children: /* @__PURE__ */ jsx18(ConstructionIcon, { sx: { fontSize: 80, color: "primary.main" } }) })
|
|
3823
|
-
] }) });
|
|
3824
|
-
};
|
|
3825
|
-
var FallbackWScreen = ({ screenName }) => {
|
|
3826
|
-
return /* @__PURE__ */ jsx18(Box13, { sx: { p: 4, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%" }, children: /* @__PURE__ */ jsxs13(Paper2, { elevation: 3, sx: { p: 4, textAlign: "center", maxWidth: 600, backgroundColor: "warning.light", border: "1px solid orange" }, children: [
|
|
3827
|
-
/* @__PURE__ */ jsx18(Typography9, { variant: "h5", component: "h1", gutterBottom: true, color: "warning.dark", children: "WScreen No Implementada" }),
|
|
3828
|
-
/* @__PURE__ */ jsxs13(Typography9, { variant: "body1", color: "warning.dark", children: [
|
|
3829
|
-
'No se encontr\xF3 un componente implementado para la **WScreen**: **`"$',
|
|
3830
|
-
screenName,
|
|
3831
|
-
'"`**. Por favor, verifica el `menuType` en la definici\xF3n del men\xFA o aseg\xFArate de que el componente est\xE9 correctamente importado y mapeado en el frontend.'
|
|
3832
|
-
] }),
|
|
3833
|
-
/* @__PURE__ */ jsx18(Box13, { sx: { mt: 3 }, children: /* @__PURE__ */ jsx18(WarningAmberIcon2, { sx: { fontSize: 80, color: "warning.dark" } }) })
|
|
3834
|
-
] }) });
|
|
3835
|
-
};
|
|
3836
|
-
var wScreens = {
|
|
3837
|
-
"MyCustomDashboard": MyCustomDashboard
|
|
3838
|
-
// Agrega más componentes de wScreen aquí:
|
|
3839
|
-
// 'AnotherWScreen': AnotherWScreenComponent,
|
|
3840
|
-
};
|
|
3841
|
-
var extendWScreens = (newWScreens) => {
|
|
3842
|
-
wScreens = { ...wScreens, ...newWScreens };
|
|
3843
|
-
console.log("wScreens extendidos:", wScreens);
|
|
3844
|
-
};
|
|
3845
|
-
|
|
3846
|
-
// src/components/SideMenu.tsx
|
|
3847
|
-
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4332
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3848
4333
|
var MenuListItem = ({ item, level, onMenuItemClick }) => {
|
|
3849
4334
|
const navigate = useNavigate2();
|
|
3850
4335
|
const location = useLocation2();
|
|
@@ -3885,17 +4370,17 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
|
|
|
3885
4370
|
const getIcon = (item2) => {
|
|
3886
4371
|
switch (item2.menuType) {
|
|
3887
4372
|
case "table":
|
|
3888
|
-
return /* @__PURE__ */
|
|
4373
|
+
return /* @__PURE__ */ jsx20(TableChartIcon, { sx: { color: blue[700] } });
|
|
3889
4374
|
case "proc":
|
|
3890
|
-
return /* @__PURE__ */
|
|
4375
|
+
return /* @__PURE__ */ jsx20(DnsIcon, { sx: { color: teal[700] } });
|
|
3891
4376
|
case "menu":
|
|
3892
|
-
return /* @__PURE__ */
|
|
4377
|
+
return /* @__PURE__ */ jsx20(FolderIcon, { sx: { color: orange[800] } });
|
|
3893
4378
|
default:
|
|
3894
4379
|
const WScreenComponent = wScreens[item2.menuType];
|
|
3895
4380
|
if (WScreenComponent !== void 0) {
|
|
3896
|
-
return /* @__PURE__ */
|
|
4381
|
+
return /* @__PURE__ */ jsx20(DesktopWindowsIcon, { sx: { color: grey[700] } });
|
|
3897
4382
|
}
|
|
3898
|
-
return /* @__PURE__ */
|
|
4383
|
+
return /* @__PURE__ */ jsx20(WarningAmberIcon3, { sx: { color: red[500] } });
|
|
3899
4384
|
}
|
|
3900
4385
|
};
|
|
3901
4386
|
const currentPath = location.pathname;
|
|
@@ -3909,8 +4394,8 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
|
|
|
3909
4394
|
} else if (item.menuType !== "menu") {
|
|
3910
4395
|
isSelected = currentPath.startsWith(`/wScreens/${item.menuType}`) || currentPath.startsWith(`/wScreens-fallback/${item.menuType}`);
|
|
3911
4396
|
}
|
|
3912
|
-
const itemRef =
|
|
3913
|
-
|
|
4397
|
+
const itemRef = React15.useRef(null);
|
|
4398
|
+
useEffect7(() => {
|
|
3914
4399
|
if (isSelected && itemRef.current) {
|
|
3915
4400
|
itemRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
3916
4401
|
}
|
|
@@ -3923,13 +4408,13 @@ var MenuListItem = ({ item, level, onMenuItemClick }) => {
|
|
|
3923
4408
|
sx: { pl: level * 2 },
|
|
3924
4409
|
selected: isSelected,
|
|
3925
4410
|
children: [
|
|
3926
|
-
/* @__PURE__ */
|
|
3927
|
-
/* @__PURE__ */
|
|
3928
|
-
item.menuType === "menu" ? open ? /* @__PURE__ */
|
|
4411
|
+
/* @__PURE__ */ jsx20(ListItemIcon2, { sx: { minWidth: "38px" }, children: getIcon(item) }),
|
|
4412
|
+
/* @__PURE__ */ jsx20(ListItemText2, { primary: item.label || item.name }),
|
|
4413
|
+
item.menuType === "menu" ? open ? /* @__PURE__ */ jsx20(ExpandLess, {}) : /* @__PURE__ */ jsx20(ExpandMore, {}) : null
|
|
3929
4414
|
]
|
|
3930
4415
|
}
|
|
3931
4416
|
),
|
|
3932
|
-
item.menuType === "menu" && /* @__PURE__ */
|
|
4417
|
+
item.menuType === "menu" && /* @__PURE__ */ jsx20(Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ jsx20(List2, { component: "div", disablePadding: true, children: item.menuContent.map((subItem) => /* @__PURE__ */ jsx20(
|
|
3933
4418
|
MenuListItem,
|
|
3934
4419
|
{
|
|
3935
4420
|
item: subItem,
|
|
@@ -3959,10 +4444,10 @@ var SideMenu = ({ onMenuItemClick }) => {
|
|
|
3959
4444
|
dispatch(setAllSubMenusOpen(!isMostlyOpen));
|
|
3960
4445
|
};
|
|
3961
4446
|
if (!clientContext || !clientContext.menu) {
|
|
3962
|
-
return /* @__PURE__ */
|
|
4447
|
+
return /* @__PURE__ */ jsx20(Box13, { sx: { p: 2, textAlign: "center" }, children: /* @__PURE__ */ jsx20(Typography9, { variant: "body2", color: "text.secondary", children: "Cargando men\xFA..." }) });
|
|
3963
4448
|
}
|
|
3964
4449
|
const isHomeSelected = location.pathname === "/home";
|
|
3965
|
-
|
|
4450
|
+
useEffect7(() => {
|
|
3966
4451
|
if (!clientContext?.menu) return;
|
|
3967
4452
|
const expandParents = (items, targetPath, parentNames = []) => {
|
|
3968
4453
|
const pathParts = targetPath.split("/");
|
|
@@ -3991,19 +4476,19 @@ var SideMenu = ({ onMenuItemClick }) => {
|
|
|
3991
4476
|
};
|
|
3992
4477
|
expandParents(clientContext.menu, location.pathname);
|
|
3993
4478
|
}, [location.pathname, clientContext, dispatch]);
|
|
3994
|
-
return /* @__PURE__ */ jsxs14(
|
|
3995
|
-
clientContext.menu.some((item) => item.menuType === "menu") && /* @__PURE__ */
|
|
3996
|
-
/* @__PURE__ */
|
|
3997
|
-
/* @__PURE__ */
|
|
4479
|
+
return /* @__PURE__ */ jsxs14(Box13, { sx: { width: "100%", flexShrink: 0 }, children: [
|
|
4480
|
+
clientContext.menu.some((item) => item.menuType === "menu") && /* @__PURE__ */ jsx20(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxs14(ListItemButton2, { onClick: handleToggleAllSubMenus, children: [
|
|
4481
|
+
/* @__PURE__ */ jsx20(ListItemIcon2, { sx: { minWidth: "38px" }, children: isMostlyOpen ? /* @__PURE__ */ jsx20(UnfoldLessIcon, {}) : /* @__PURE__ */ jsx20(UnfoldMoreIcon, {}) }),
|
|
4482
|
+
/* @__PURE__ */ jsx20(ListItemText2, { primary: isMostlyOpen ? "colapsar " : "expandir" })
|
|
3998
4483
|
] }) }),
|
|
3999
|
-
/* @__PURE__ */
|
|
4484
|
+
/* @__PURE__ */ jsx20(Divider2, {}),
|
|
4000
4485
|
/* @__PURE__ */ jsxs14(List2, { children: [
|
|
4001
|
-
/* @__PURE__ */
|
|
4002
|
-
/* @__PURE__ */
|
|
4003
|
-
/* @__PURE__ */
|
|
4486
|
+
/* @__PURE__ */ jsx20(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxs14(ListItemButton2, { onClick: handleHomeClick, selected: isHomeSelected, children: [
|
|
4487
|
+
/* @__PURE__ */ jsx20(ListItemIcon2, { sx: { minWidth: "38px" }, children: /* @__PURE__ */ jsx20(HomeIcon, {}) }),
|
|
4488
|
+
/* @__PURE__ */ jsx20(ListItemText2, { primary: "Inicio" })
|
|
4004
4489
|
] }) }),
|
|
4005
|
-
/* @__PURE__ */
|
|
4006
|
-
clientContext.menu.map((menuItem) => /* @__PURE__ */
|
|
4490
|
+
/* @__PURE__ */ jsx20(Divider2, {}),
|
|
4491
|
+
clientContext.menu.map((menuItem) => /* @__PURE__ */ jsx20(
|
|
4007
4492
|
MenuListItem,
|
|
4008
4493
|
{
|
|
4009
4494
|
item: menuItem,
|
|
@@ -4046,7 +4531,7 @@ var useLogout = () => {
|
|
|
4046
4531
|
var useLogout_default = useLogout;
|
|
4047
4532
|
|
|
4048
4533
|
// src/components/MainLayout.tsx
|
|
4049
|
-
import { jsx as
|
|
4534
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4050
4535
|
var drawerWidth = 240;
|
|
4051
4536
|
var MainLayout = () => {
|
|
4052
4537
|
const { clientContext } = useApp();
|
|
@@ -4055,7 +4540,7 @@ var MainLayout = () => {
|
|
|
4055
4540
|
const dispatch = useAppDispatch();
|
|
4056
4541
|
const theme = useTheme5();
|
|
4057
4542
|
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
|
4058
|
-
|
|
4543
|
+
useEffect8(() => {
|
|
4059
4544
|
if (isMobile && isDrawerOpen) {
|
|
4060
4545
|
dispatch(setDrawerOpen(false));
|
|
4061
4546
|
}
|
|
@@ -4069,12 +4554,12 @@ var MainLayout = () => {
|
|
|
4069
4554
|
}
|
|
4070
4555
|
};
|
|
4071
4556
|
if (!clientContext) {
|
|
4072
|
-
return /* @__PURE__ */
|
|
4557
|
+
return /* @__PURE__ */ jsx21(Box14, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx21(Typography10, { children: "Cargando dise\xF1o de la aplicaci\xF3n..." }) });
|
|
4073
4558
|
}
|
|
4074
4559
|
const appBarOffset = theme.mixins.toolbar;
|
|
4075
|
-
return /* @__PURE__ */ jsxs15(
|
|
4076
|
-
/* @__PURE__ */
|
|
4077
|
-
/* @__PURE__ */
|
|
4560
|
+
return /* @__PURE__ */ jsxs15(Box14, { sx: { display: "flex", height: "100vh" }, children: [
|
|
4561
|
+
/* @__PURE__ */ jsx21(CssBaseline, {}),
|
|
4562
|
+
/* @__PURE__ */ jsx21(
|
|
4078
4563
|
AppBar,
|
|
4079
4564
|
{
|
|
4080
4565
|
position: "fixed",
|
|
@@ -4094,7 +4579,7 @@ var MainLayout = () => {
|
|
|
4094
4579
|
}
|
|
4095
4580
|
},
|
|
4096
4581
|
children: /* @__PURE__ */ jsxs15(Toolbar, { children: [
|
|
4097
|
-
/* @__PURE__ */
|
|
4582
|
+
/* @__PURE__ */ jsx21(
|
|
4098
4583
|
IconButton4,
|
|
4099
4584
|
{
|
|
4100
4585
|
color: "inherit",
|
|
@@ -4104,10 +4589,10 @@ var MainLayout = () => {
|
|
|
4104
4589
|
sx: {
|
|
4105
4590
|
marginRight: 2
|
|
4106
4591
|
},
|
|
4107
|
-
children: isDrawerOpen ? /* @__PURE__ */
|
|
4592
|
+
children: isDrawerOpen ? /* @__PURE__ */ jsx21(ChevronLeftIcon, {}) : /* @__PURE__ */ jsx21(MenuIcon, {})
|
|
4108
4593
|
}
|
|
4109
4594
|
),
|
|
4110
|
-
!isDrawerOpen && /* @__PURE__ */
|
|
4595
|
+
!isDrawerOpen && /* @__PURE__ */ jsx21(
|
|
4111
4596
|
"img",
|
|
4112
4597
|
{
|
|
4113
4598
|
src: `${envConfig.backendUrl}/img/logo-128.png`,
|
|
@@ -4115,14 +4600,14 @@ var MainLayout = () => {
|
|
|
4115
4600
|
style: { height: "32px", marginRight: "12px", objectFit: "contain" }
|
|
4116
4601
|
}
|
|
4117
4602
|
),
|
|
4118
|
-
/* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4120
|
-
/* @__PURE__ */
|
|
4121
|
-
|
|
4603
|
+
/* @__PURE__ */ jsx21(Typography10, { variant: "h6", noWrap: true, component: "div", sx: { flexGrow: 1 }, children: isDrawerOpen ? "" : clientContext.config.title }),
|
|
4604
|
+
/* @__PURE__ */ jsx21(Typography10, { variant: "subtitle1", component: "div", sx: { mr: 2 }, children: clientContext.username }),
|
|
4605
|
+
/* @__PURE__ */ jsx21(
|
|
4606
|
+
Button6,
|
|
4122
4607
|
{
|
|
4123
4608
|
color: "inherit",
|
|
4124
4609
|
onClick: logout,
|
|
4125
|
-
startIcon: /* @__PURE__ */
|
|
4610
|
+
startIcon: /* @__PURE__ */ jsx21(LogoutIcon, {}),
|
|
4126
4611
|
children: "Salir"
|
|
4127
4612
|
}
|
|
4128
4613
|
)
|
|
@@ -4159,7 +4644,7 @@ var MainLayout = () => {
|
|
|
4159
4644
|
gap: 1.5
|
|
4160
4645
|
},
|
|
4161
4646
|
children: [
|
|
4162
|
-
/* @__PURE__ */
|
|
4647
|
+
/* @__PURE__ */ jsx21(
|
|
4163
4648
|
"img",
|
|
4164
4649
|
{
|
|
4165
4650
|
src: `${envConfig.backendUrl}/img/logo-128.png`,
|
|
@@ -4167,16 +4652,16 @@ var MainLayout = () => {
|
|
|
4167
4652
|
style: { height: "32px", objectFit: "contain" }
|
|
4168
4653
|
}
|
|
4169
4654
|
),
|
|
4170
|
-
/* @__PURE__ */
|
|
4655
|
+
/* @__PURE__ */ jsx21(Typography10, { variant: "h6", sx: { fontWeight: "bold" }, children: clientContext.config.title })
|
|
4171
4656
|
]
|
|
4172
4657
|
}
|
|
4173
4658
|
),
|
|
4174
|
-
/* @__PURE__ */
|
|
4659
|
+
/* @__PURE__ */ jsx21(SideMenu_default, { onMenuItemClick: handleDrawerCloseMobile })
|
|
4175
4660
|
]
|
|
4176
4661
|
}
|
|
4177
4662
|
),
|
|
4178
|
-
/* @__PURE__ */
|
|
4179
|
-
|
|
4663
|
+
/* @__PURE__ */ jsx21(
|
|
4664
|
+
Box14,
|
|
4180
4665
|
{
|
|
4181
4666
|
component: "main",
|
|
4182
4667
|
sx: {
|
|
@@ -4203,7 +4688,7 @@ var MainLayout = () => {
|
|
|
4203
4688
|
flexDirection: "column",
|
|
4204
4689
|
width: isDrawerOpen ? `calc(100% - ${drawerWidth}px)` : "100%"
|
|
4205
4690
|
},
|
|
4206
|
-
children: /* @__PURE__ */
|
|
4691
|
+
children: /* @__PURE__ */ jsx21(Outlet, {})
|
|
4207
4692
|
}
|
|
4208
4693
|
)
|
|
4209
4694
|
] });
|
|
@@ -4211,8 +4696,8 @@ var MainLayout = () => {
|
|
|
4211
4696
|
var MainLayout_default = MainLayout;
|
|
4212
4697
|
|
|
4213
4698
|
// src/components/SessionExpiredMessage.tsx
|
|
4214
|
-
import { Box as
|
|
4215
|
-
import { jsx as
|
|
4699
|
+
import { Box as Box15, Typography as Typography11, Button as Button7, Modal } from "@mui/material";
|
|
4700
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4216
4701
|
var style = {
|
|
4217
4702
|
position: "absolute",
|
|
4218
4703
|
top: "50%",
|
|
@@ -4231,7 +4716,7 @@ var SessionExpiredMessage = () => {
|
|
|
4231
4716
|
const handleClose = () => {
|
|
4232
4717
|
handleExpiredSessionRedirect();
|
|
4233
4718
|
};
|
|
4234
|
-
return /* @__PURE__ */
|
|
4719
|
+
return /* @__PURE__ */ jsx22(
|
|
4235
4720
|
Modal,
|
|
4236
4721
|
{
|
|
4237
4722
|
open: showSessionExpiredMessage,
|
|
@@ -4251,10 +4736,10 @@ var SessionExpiredMessage = () => {
|
|
|
4251
4736
|
}
|
|
4252
4737
|
}
|
|
4253
4738
|
},
|
|
4254
|
-
children: /* @__PURE__ */ jsxs16(
|
|
4255
|
-
/* @__PURE__ */
|
|
4256
|
-
/* @__PURE__ */
|
|
4257
|
-
/* @__PURE__ */
|
|
4739
|
+
children: /* @__PURE__ */ jsxs16(Box15, { sx: style, children: [
|
|
4740
|
+
/* @__PURE__ */ jsx22(Typography11, { id: "session-expired-modal-title", variant: "h6", component: "h2", gutterBottom: true, children: "\xA1Sesi\xF3n Expirada!" }),
|
|
4741
|
+
/* @__PURE__ */ jsx22(Typography11, { id: "session-expired-modal-description", sx: { mt: 2, mb: 3 }, children: "Tu sesi\xF3n ha expirado por inactividad o por seguridad. Por favor, inicia sesi\xF3n de nuevo." }),
|
|
4742
|
+
/* @__PURE__ */ jsx22(Button7, { variant: "contained", color: "primary", onClick: handleClose, children: "Ir al Login" })
|
|
4258
4743
|
] })
|
|
4259
4744
|
}
|
|
4260
4745
|
);
|
|
@@ -4262,27 +4747,27 @@ var SessionExpiredMessage = () => {
|
|
|
4262
4747
|
var SessionExpiredMessage_default = SessionExpiredMessage;
|
|
4263
4748
|
|
|
4264
4749
|
// src/pages/HomePage.tsx
|
|
4265
|
-
import { Box as
|
|
4266
|
-
import { jsx as
|
|
4750
|
+
import { Box as Box16, Typography as Typography12 } from "@mui/material";
|
|
4751
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4267
4752
|
var HomePage = () => {
|
|
4268
4753
|
const { clientContext } = useApp();
|
|
4269
|
-
return /* @__PURE__ */ jsxs17(
|
|
4270
|
-
/* @__PURE__ */
|
|
4271
|
-
/* @__PURE__ */
|
|
4754
|
+
return /* @__PURE__ */ jsxs17(Box16, { sx: { p: 3 }, children: [
|
|
4755
|
+
/* @__PURE__ */ jsx23(Typography12, { variant: "h4", component: "h1", gutterBottom: true, children: `Bienvenido/a ${clientContext?.username}` }),
|
|
4756
|
+
/* @__PURE__ */ jsx23(Typography12, { variant: "body1", children: "Usa el men\xFA lateral para navegar por las diferentes secciones." })
|
|
4272
4757
|
] });
|
|
4273
4758
|
};
|
|
4274
4759
|
var HomePage_default = HomePage;
|
|
4275
4760
|
|
|
4276
4761
|
// src/pages/LogoutPage.tsx
|
|
4277
|
-
import { useEffect as
|
|
4278
|
-
import { Box as
|
|
4279
|
-
import { jsx as
|
|
4762
|
+
import { useEffect as useEffect9 } from "react";
|
|
4763
|
+
import { Box as Box17, Typography as Typography13, CircularProgress as CircularProgress5 } from "@mui/material";
|
|
4764
|
+
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4280
4765
|
var LogoutPage = () => {
|
|
4281
4766
|
const logout = useLogout_default();
|
|
4282
|
-
|
|
4767
|
+
useEffect9(() => {
|
|
4283
4768
|
logout();
|
|
4284
4769
|
}, [logout]);
|
|
4285
|
-
return /* @__PURE__ */ jsxs18(
|
|
4770
|
+
return /* @__PURE__ */ jsxs18(Box17, { sx: {
|
|
4286
4771
|
display: "flex",
|
|
4287
4772
|
flexDirection: "column",
|
|
4288
4773
|
justifyContent: "center",
|
|
@@ -4290,21 +4775,21 @@ var LogoutPage = () => {
|
|
|
4290
4775
|
height: "100vh",
|
|
4291
4776
|
textAlign: "center"
|
|
4292
4777
|
}, children: [
|
|
4293
|
-
/* @__PURE__ */
|
|
4294
|
-
/* @__PURE__ */
|
|
4778
|
+
/* @__PURE__ */ jsx24(CircularProgress5, { size: 60 }),
|
|
4779
|
+
/* @__PURE__ */ jsx24(Typography13, { variant: "h6", sx: { mt: 2 }, children: "Cerrando sesi\xF3n..." })
|
|
4295
4780
|
] });
|
|
4296
4781
|
};
|
|
4297
4782
|
var LogoutPage_default = LogoutPage;
|
|
4298
4783
|
|
|
4299
4784
|
// src/pages/LoginPage.tsx
|
|
4300
4785
|
import { useState as useState14 } from "react";
|
|
4301
|
-
import { Button as
|
|
4786
|
+
import { Button as Button8, TextField as TextField2, Typography as Typography14, Alert as Alert3, AlertTitle, Box as Box18, CircularProgress as CircularProgress6 } from "@mui/material";
|
|
4302
4787
|
import { useForm, Controller } from "react-hook-form";
|
|
4303
4788
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
4304
4789
|
import * as z from "zod";
|
|
4305
4790
|
import { useNavigate as useNavigate4 } from "react-router-dom";
|
|
4306
4791
|
import { useDispatch as useDispatch4 } from "react-redux";
|
|
4307
|
-
import { Fragment as
|
|
4792
|
+
import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4308
4793
|
var loginSchema = z.object({
|
|
4309
4794
|
username: z.string().min(1, "El usuario es requerido"),
|
|
4310
4795
|
// Añadir validación básica
|
|
@@ -4355,13 +4840,13 @@ var LoginPage = () => {
|
|
|
4355
4840
|
} catch (error) {
|
|
4356
4841
|
console.error("Error al iniciar sesi\xF3n:", error);
|
|
4357
4842
|
setIsLoggedIn(false);
|
|
4358
|
-
setLoginError(error
|
|
4843
|
+
setLoginError(mensajeDeError(error, "Ocurri\xF3 un error al iniciar sesi\xF3n. Int\xE9ntalo de nuevo."));
|
|
4359
4844
|
} finally {
|
|
4360
4845
|
setIsSubmitting(false);
|
|
4361
4846
|
}
|
|
4362
4847
|
};
|
|
4363
|
-
return /* @__PURE__ */
|
|
4364
|
-
|
|
4848
|
+
return /* @__PURE__ */ jsx25(
|
|
4849
|
+
Box18,
|
|
4365
4850
|
{
|
|
4366
4851
|
display: "flex",
|
|
4367
4852
|
alignItems: "center",
|
|
@@ -4369,7 +4854,7 @@ var LoginPage = () => {
|
|
|
4369
4854
|
minHeight: "100vh",
|
|
4370
4855
|
bgcolor: "#f5f5f5",
|
|
4371
4856
|
children: /* @__PURE__ */ jsxs19(
|
|
4372
|
-
|
|
4857
|
+
Box18,
|
|
4373
4858
|
{
|
|
4374
4859
|
width: "100%",
|
|
4375
4860
|
maxWidth: "400px",
|
|
@@ -4378,24 +4863,24 @@ var LoginPage = () => {
|
|
|
4378
4863
|
borderRadius: 8,
|
|
4379
4864
|
boxShadow: 3,
|
|
4380
4865
|
children: [
|
|
4381
|
-
/* @__PURE__ */
|
|
4866
|
+
/* @__PURE__ */ jsx25(Box18, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ jsx25(
|
|
4382
4867
|
"img",
|
|
4383
4868
|
{
|
|
4384
4869
|
src: `${envConfig.backendUrl}/img/login-logo-icon.png`,
|
|
4385
4870
|
alt: "Logo",
|
|
4386
|
-
style: { height: "
|
|
4871
|
+
style: { height: "192px", maxWidth: "100%", objectFit: "contain" }
|
|
4387
4872
|
}
|
|
4388
4873
|
) }),
|
|
4389
|
-
/* @__PURE__ */
|
|
4874
|
+
/* @__PURE__ */ jsx25(Typography14, { variant: "h5", align: "center", gutterBottom: true, sx: { fontWeight: "bold", color: "primary.main" }, children: "Iniciar Sesi\xF3n" }),
|
|
4390
4875
|
/* @__PURE__ */ jsxs19("form", { onSubmit: handleSubmit(onSubmit), className: "space-y-4", children: [
|
|
4391
4876
|
/* @__PURE__ */ jsxs19("div", { children: [
|
|
4392
|
-
/* @__PURE__ */
|
|
4393
|
-
/* @__PURE__ */
|
|
4877
|
+
/* @__PURE__ */ jsx25("label", { htmlFor: "username", children: /* @__PURE__ */ jsx25(Typography14, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Usuario" }) }),
|
|
4878
|
+
/* @__PURE__ */ jsx25(
|
|
4394
4879
|
Controller,
|
|
4395
4880
|
{
|
|
4396
4881
|
name: "username",
|
|
4397
4882
|
control,
|
|
4398
|
-
render: ({ field }) => /* @__PURE__ */
|
|
4883
|
+
render: ({ field }) => /* @__PURE__ */ jsx25(
|
|
4399
4884
|
TextField2,
|
|
4400
4885
|
{
|
|
4401
4886
|
...field,
|
|
@@ -4412,13 +4897,13 @@ var LoginPage = () => {
|
|
|
4412
4897
|
)
|
|
4413
4898
|
] }),
|
|
4414
4899
|
/* @__PURE__ */ jsxs19("div", { children: [
|
|
4415
|
-
/* @__PURE__ */
|
|
4416
|
-
/* @__PURE__ */
|
|
4900
|
+
/* @__PURE__ */ jsx25("label", { htmlFor: "password", children: /* @__PURE__ */ jsx25(Typography14, { variant: "subtitle1", component: "div", sx: { fontWeight: "medium" }, children: "Contrase\xF1a" }) }),
|
|
4901
|
+
/* @__PURE__ */ jsx25(
|
|
4417
4902
|
Controller,
|
|
4418
4903
|
{
|
|
4419
4904
|
name: "password",
|
|
4420
4905
|
control,
|
|
4421
|
-
render: ({ field }) => /* @__PURE__ */
|
|
4906
|
+
render: ({ field }) => /* @__PURE__ */ jsx25(
|
|
4422
4907
|
TextField2,
|
|
4423
4908
|
{
|
|
4424
4909
|
...field,
|
|
@@ -4434,14 +4919,14 @@ var LoginPage = () => {
|
|
|
4434
4919
|
}
|
|
4435
4920
|
)
|
|
4436
4921
|
] }),
|
|
4437
|
-
/* @__PURE__ */
|
|
4438
|
-
/* @__PURE__ */
|
|
4922
|
+
/* @__PURE__ */ jsx25(Button8, { type: "submit", fullWidth: true, variant: "contained", color: "primary", disabled: isSubmitting, sx: { mt: 2 }, children: isSubmitting ? /* @__PURE__ */ jsxs19(Fragment3, { children: [
|
|
4923
|
+
/* @__PURE__ */ jsx25(CircularProgress6, { size: 20, sx: { mr: 1 } }),
|
|
4439
4924
|
"Iniciando sesi\xF3n..."
|
|
4440
4925
|
] }) : "Iniciar Sesi\xF3n" })
|
|
4441
4926
|
] }),
|
|
4442
4927
|
loginError && /* @__PURE__ */ jsxs19(Alert3, { severity: "error", sx: { mt: 2, maxHeight: "200px" }, children: [
|
|
4443
4928
|
" ",
|
|
4444
|
-
/* @__PURE__ */
|
|
4929
|
+
/* @__PURE__ */ jsx25(AlertTitle, { children: "Error" }),
|
|
4445
4930
|
loginError
|
|
4446
4931
|
] })
|
|
4447
4932
|
]
|
|
@@ -4453,11 +4938,11 @@ var LoginPage = () => {
|
|
|
4453
4938
|
var LoginPage_default = LoginPage;
|
|
4454
4939
|
|
|
4455
4940
|
// src/components/ProcedureForm.tsx
|
|
4456
|
-
import
|
|
4941
|
+
import React19, { useState as useState15, useCallback as useCallback14, useMemo as useMemo11 } from "react";
|
|
4457
4942
|
import { useParams } from "react-router-dom";
|
|
4458
4943
|
import {
|
|
4459
4944
|
TextField as TextField3,
|
|
4460
|
-
Button as
|
|
4945
|
+
Button as Button9,
|
|
4461
4946
|
FormControl as FormControl3,
|
|
4462
4947
|
InputLabel as InputLabel2,
|
|
4463
4948
|
Select as Select2,
|
|
@@ -4465,8 +4950,8 @@ import {
|
|
|
4465
4950
|
Checkbox as Checkbox3,
|
|
4466
4951
|
FormControlLabel as FormControlLabel3,
|
|
4467
4952
|
FormHelperText as FormHelperText2,
|
|
4468
|
-
Typography as
|
|
4469
|
-
Box as
|
|
4953
|
+
Typography as Typography16,
|
|
4954
|
+
Box as Box20,
|
|
4470
4955
|
CircularProgress as CircularProgress7,
|
|
4471
4956
|
Alert as Alert4,
|
|
4472
4957
|
Divider as Divider3,
|
|
@@ -4474,14 +4959,14 @@ import {
|
|
|
4474
4959
|
} from "@mui/material";
|
|
4475
4960
|
|
|
4476
4961
|
// src/pages/procedure-results/SuccessDisplay.tsx
|
|
4477
|
-
import { Box as
|
|
4478
|
-
import { jsx as
|
|
4962
|
+
import { Box as Box19, Typography as Typography15, Paper as Paper3 } from "@mui/material";
|
|
4963
|
+
import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4479
4964
|
var SuccessDisplay = ({ data }) => {
|
|
4480
4965
|
return /* @__PURE__ */ jsxs20(Paper3, { elevation: 2, sx: { p: 2, mt: 2, bgcolor: "success.light", color: "success.contrastText" }, children: [
|
|
4481
|
-
/* @__PURE__ */
|
|
4482
|
-
/* @__PURE__ */
|
|
4483
|
-
/* @__PURE__ */
|
|
4484
|
-
/* @__PURE__ */
|
|
4966
|
+
/* @__PURE__ */ jsx26(Typography15, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: "\xA1Operaci\xF3n Exitosa!" }),
|
|
4967
|
+
/* @__PURE__ */ jsx26(Typography15, { variant: "body2", sx: { fontSize: "0.85rem" }, children: "Detalles del resultado:" }),
|
|
4968
|
+
/* @__PURE__ */ jsx26(Box19, { sx: { bgcolor: "success.dark", p: 1, borderRadius: 1, mt: 1, overflowX: "auto" }, children: /* @__PURE__ */ jsx26("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(data, null, 2) }) }),
|
|
4969
|
+
/* @__PURE__ */ jsx26(Typography15, { variant: "body2", sx: { fontSize: "0.8rem", mt: 1 }, children: "Puedes revisar los detalles anteriores o cerrar este mensaje." })
|
|
4485
4970
|
] });
|
|
4486
4971
|
};
|
|
4487
4972
|
var SuccessDisplay_default = SuccessDisplay;
|
|
@@ -4495,7 +4980,7 @@ var extendResultsOk = (newComponents) => {
|
|
|
4495
4980
|
};
|
|
4496
4981
|
|
|
4497
4982
|
// src/components/ProcedureForm.tsx
|
|
4498
|
-
import { jsx as
|
|
4983
|
+
import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4499
4984
|
var ProcedureForm = () => {
|
|
4500
4985
|
const { procedureName } = useParams();
|
|
4501
4986
|
const { clientContext } = useApp();
|
|
@@ -4504,7 +4989,7 @@ var ProcedureForm = () => {
|
|
|
4504
4989
|
const [successMessage, setSuccessMessage] = useState15(null);
|
|
4505
4990
|
const [executionLog, setExecutionLog] = useState15([]);
|
|
4506
4991
|
const [procedureResultData, setProcedureResultData] = useState15(null);
|
|
4507
|
-
const procedure =
|
|
4992
|
+
const procedure = useMemo11(() => {
|
|
4508
4993
|
if (procedureName && clientContext?.procedure) {
|
|
4509
4994
|
return clientContext.procedure[procedureName];
|
|
4510
4995
|
}
|
|
@@ -4535,7 +5020,7 @@ var ProcedureForm = () => {
|
|
|
4535
5020
|
});
|
|
4536
5021
|
return initialValues;
|
|
4537
5022
|
});
|
|
4538
|
-
|
|
5023
|
+
React19.useEffect(() => {
|
|
4539
5024
|
if (procedure) {
|
|
4540
5025
|
setValidationErrors({});
|
|
4541
5026
|
setSuccessMessage(null);
|
|
@@ -4607,8 +5092,8 @@ var ProcedureForm = () => {
|
|
|
4607
5092
|
if (value === "" || value === null) {
|
|
4608
5093
|
processedValue = null;
|
|
4609
5094
|
} else {
|
|
4610
|
-
processedValue = parseFloat(value);
|
|
4611
|
-
if (isNaN(processedValue)) {
|
|
5095
|
+
processedValue = parseFloat(String(value));
|
|
5096
|
+
if (typeof processedValue === "number" && isNaN(processedValue)) {
|
|
4612
5097
|
paramError = `El valor para "${param.label || param.name}" no es un n\xFAmero v\xE1lido.`;
|
|
4613
5098
|
}
|
|
4614
5099
|
}
|
|
@@ -4618,8 +5103,8 @@ var ProcedureForm = () => {
|
|
|
4618
5103
|
if (value === "" || value === null) {
|
|
4619
5104
|
processedValue = null;
|
|
4620
5105
|
} else {
|
|
4621
|
-
processedValue = parseInt(value, 10);
|
|
4622
|
-
if (isNaN(processedValue)) {
|
|
5106
|
+
processedValue = parseInt(String(value), 10);
|
|
5107
|
+
if (typeof processedValue === "number" && isNaN(processedValue)) {
|
|
4623
5108
|
paramError = `El valor para "${param.label || param.name}" no es un entero v\xE1lido.`;
|
|
4624
5109
|
}
|
|
4625
5110
|
}
|
|
@@ -4633,9 +5118,9 @@ var ProcedureForm = () => {
|
|
|
4633
5118
|
processedValue = null;
|
|
4634
5119
|
} else {
|
|
4635
5120
|
try {
|
|
4636
|
-
processedValue = JSON.parse(value);
|
|
5121
|
+
processedValue = JSON.parse(String(value));
|
|
4637
5122
|
} catch (jsonError) {
|
|
4638
|
-
paramError = `Error en el formato JSON para "${param.label || param.name}": ${jsonError
|
|
5123
|
+
paramError = `Error en el formato JSON para "${param.label || param.name}": ${mensajeDeError(jsonError)}`;
|
|
4639
5124
|
}
|
|
4640
5125
|
}
|
|
4641
5126
|
break;
|
|
@@ -4686,7 +5171,7 @@ var ProcedureForm = () => {
|
|
|
4686
5171
|
}
|
|
4687
5172
|
} catch (err) {
|
|
4688
5173
|
console.error("Error al ejecutar el procedimiento (capturado en ProcedureForm):", err);
|
|
4689
|
-
addLogMessage(`Error en la ejecuci\xF3n: ${err
|
|
5174
|
+
addLogMessage(`Error en la ejecuci\xF3n: ${mensajeDeError(err, "Error desconocido.")}`, true);
|
|
4690
5175
|
} finally {
|
|
4691
5176
|
addLogMessage("Ejecuci\xF3n finalizada.");
|
|
4692
5177
|
}
|
|
@@ -4711,7 +5196,7 @@ var ProcedureForm = () => {
|
|
|
4711
5196
|
};
|
|
4712
5197
|
if (param.options && param.options.length > 0) {
|
|
4713
5198
|
return /* @__PURE__ */ jsxs21(FormControl3, { fullWidth: true, margin: "dense", size: "small", error: hasError, required: commonProps.required, children: [
|
|
4714
|
-
/* @__PURE__ */
|
|
5199
|
+
/* @__PURE__ */ jsx27(InputLabel2, { id: `${param.name}-label`, sx: { fontSize: "0.8rem" }, children: param.label || param.name }),
|
|
4715
5200
|
/* @__PURE__ */ jsxs21(
|
|
4716
5201
|
Select2,
|
|
4717
5202
|
{
|
|
@@ -4723,14 +5208,14 @@ var ProcedureForm = () => {
|
|
|
4723
5208
|
label: param.label || param.name,
|
|
4724
5209
|
disabled: apiLoading,
|
|
4725
5210
|
sx: { fontSize: "0.8rem" },
|
|
4726
|
-
renderValue: (selected) => /* @__PURE__ */
|
|
5211
|
+
renderValue: (selected) => /* @__PURE__ */ jsx27(Typography16, { sx: { fontSize: "0.8rem" }, children: selected }),
|
|
4727
5212
|
children: [
|
|
4728
|
-
(!commonProps.required || formValues[param.name] === "") && /* @__PURE__ */
|
|
4729
|
-
param.options.map((option) => /* @__PURE__ */
|
|
5213
|
+
(!commonProps.required || formValues[param.name] === "") && /* @__PURE__ */ jsx27(MenuItem2, { value: "", sx: { fontSize: "0.8rem" }, children: /* @__PURE__ */ jsx27("em", { children: "Seleccione..." }) }),
|
|
5214
|
+
param.options.map((option) => /* @__PURE__ */ jsx27(MenuItem2, { value: option, sx: { fontSize: "0.8rem" }, children: option }, option))
|
|
4730
5215
|
]
|
|
4731
5216
|
}
|
|
4732
5217
|
),
|
|
4733
|
-
(param.description || errorMessage) && /* @__PURE__ */
|
|
5218
|
+
(param.description || errorMessage) && /* @__PURE__ */ jsx27(FormHelperText2, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
|
|
4734
5219
|
] });
|
|
4735
5220
|
}
|
|
4736
5221
|
switch (param.typeName) {
|
|
@@ -4739,18 +5224,18 @@ var ProcedureForm = () => {
|
|
|
4739
5224
|
case "tsrange":
|
|
4740
5225
|
case "time_range":
|
|
4741
5226
|
case "daterange":
|
|
4742
|
-
return /* @__PURE__ */
|
|
5227
|
+
return /* @__PURE__ */ jsx27(TextField3, { type: "text", value: formValues[param.name] || "", ...commonProps });
|
|
4743
5228
|
case "decimal":
|
|
4744
5229
|
case "double":
|
|
4745
|
-
return /* @__PURE__ */
|
|
5230
|
+
return /* @__PURE__ */ jsx27(TextField3, { type: "number", inputProps: { step: "any", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
|
|
4746
5231
|
case "integer":
|
|
4747
5232
|
case "bigint":
|
|
4748
|
-
return /* @__PURE__ */
|
|
5233
|
+
return /* @__PURE__ */ jsx27(TextField3, { type: "number", inputProps: { step: "1", style: { fontSize: "0.8rem" } }, value: formValues[param.name] || "", ...commonProps });
|
|
4749
5234
|
case "boolean":
|
|
4750
|
-
return /* @__PURE__ */
|
|
5235
|
+
return /* @__PURE__ */ jsx27(
|
|
4751
5236
|
FormControlLabel3,
|
|
4752
5237
|
{
|
|
4753
|
-
control: /* @__PURE__ */
|
|
5238
|
+
control: /* @__PURE__ */ jsx27(
|
|
4754
5239
|
Checkbox3,
|
|
4755
5240
|
{
|
|
4756
5241
|
checked: !!formValues[param.name],
|
|
@@ -4761,21 +5246,21 @@ var ProcedureForm = () => {
|
|
|
4761
5246
|
size: "small"
|
|
4762
5247
|
}
|
|
4763
5248
|
),
|
|
4764
|
-
label: /* @__PURE__ */
|
|
5249
|
+
label: /* @__PURE__ */ jsx27(Typography16, { sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "inherit" }, children: param.label || param.name }),
|
|
4765
5250
|
sx: { mt: 1, mb: 0 }
|
|
4766
5251
|
}
|
|
4767
5252
|
);
|
|
4768
5253
|
case "date":
|
|
4769
5254
|
case "timestamp":
|
|
4770
5255
|
case "time":
|
|
4771
|
-
return /* @__PURE__ */
|
|
5256
|
+
return /* @__PURE__ */ jsx27(TextField3, { type: param.typeName === "date" ? "date" : param.typeName === "timestamp" ? "datetime-local" : "time", value: formValues[param.name] || "", ...commonProps, InputLabelProps: { shrink: true, sx: { fontSize: "0.8rem" } } });
|
|
4772
5257
|
case "jsonb":
|
|
4773
5258
|
case "jsona":
|
|
4774
|
-
return /* @__PURE__ */
|
|
5259
|
+
return /* @__PURE__ */ jsx27(TextField3, { multiline: true, rows: 5, value: formValues[param.name] || "", ...commonProps, InputProps: { sx: { fontSize: "0.8rem" } } });
|
|
4775
5260
|
case "bytea":
|
|
4776
5261
|
return /* @__PURE__ */ jsxs21(FormControl3, { fullWidth: true, margin: "dense", error: hasError, required: commonProps.required, children: [
|
|
4777
|
-
/* @__PURE__ */
|
|
4778
|
-
/* @__PURE__ */
|
|
5262
|
+
/* @__PURE__ */ jsx27(Typography16, { variant: "body2", color: "textSecondary", component: "label", htmlFor: param.name, sx: { fontSize: "0.8rem", color: hasError ? "error.main" : "text.secondary" }, children: param.label || param.name }),
|
|
5263
|
+
/* @__PURE__ */ jsx27(
|
|
4779
5264
|
"input",
|
|
4780
5265
|
{
|
|
4781
5266
|
type: "file",
|
|
@@ -4789,34 +5274,34 @@ var ProcedureForm = () => {
|
|
|
4789
5274
|
style: { padding: "6px 0", fontSize: "0.8rem" }
|
|
4790
5275
|
}
|
|
4791
5276
|
),
|
|
4792
|
-
(param.description || errorMessage) && /* @__PURE__ */
|
|
5277
|
+
(param.description || errorMessage) && /* @__PURE__ */ jsx27(FormHelperText2, { sx: { fontSize: "0.7rem" }, children: errorMessage || param.description })
|
|
4793
5278
|
] });
|
|
4794
5279
|
default:
|
|
4795
|
-
return /* @__PURE__ */
|
|
5280
|
+
return /* @__PURE__ */ jsx27(TextField3, { type: "text", value: formValues[param.name] || "", ...commonProps });
|
|
4796
5281
|
}
|
|
4797
5282
|
}, [formValues, handleChange, apiLoading, validationErrors]);
|
|
4798
|
-
const ResultDisplayContent =
|
|
5283
|
+
const ResultDisplayContent = useMemo11(() => {
|
|
4799
5284
|
if (!procedureResultData || !procedure?.resultOk) return null;
|
|
4800
5285
|
const ComponentToRender = resultsOk[procedure.resultOk];
|
|
4801
5286
|
if (ComponentToRender) {
|
|
4802
|
-
return /* @__PURE__ */
|
|
5287
|
+
return /* @__PURE__ */ jsx27(ComponentToRender, { data: procedureResultData });
|
|
4803
5288
|
} else {
|
|
4804
5289
|
return /* @__PURE__ */ jsxs21(Paper4, { elevation: 2, sx: { p: 2, mt: 0, bgcolor: "warning.light" }, children: [
|
|
4805
|
-
/* @__PURE__ */ jsxs21(
|
|
5290
|
+
/* @__PURE__ */ jsxs21(Typography16, { variant: "h6", sx: { fontSize: "1rem", mb: 1 }, children: [
|
|
4806
5291
|
"el componente para resolver el resultOk: '",
|
|
4807
5292
|
procedure.resultOk,
|
|
4808
5293
|
"' definido en el procedure no existe o no est\xE1 mapeado."
|
|
4809
5294
|
] }),
|
|
4810
|
-
/* @__PURE__ */
|
|
5295
|
+
/* @__PURE__ */ jsx27(Box20, { sx: {
|
|
4811
5296
|
bgcolor: "warning.dark",
|
|
4812
5297
|
p: 1,
|
|
4813
5298
|
borderRadius: 1
|
|
4814
|
-
}, children: /* @__PURE__ */
|
|
5299
|
+
}, children: /* @__PURE__ */ jsx27("pre", { style: { margin: 0, fontSize: "0.75rem", color: "white" }, children: JSON.stringify(procedureResultData, null, 2) }) })
|
|
4815
5300
|
] });
|
|
4816
5301
|
}
|
|
4817
5302
|
}, [procedureResultData, procedure]);
|
|
4818
5303
|
if (!procedure) {
|
|
4819
|
-
return /* @__PURE__ */ jsxs21(
|
|
5304
|
+
return /* @__PURE__ */ jsxs21(Box20, { sx: {
|
|
4820
5305
|
p: 2,
|
|
4821
5306
|
width: "100%",
|
|
4822
5307
|
boxSizing: "border-box",
|
|
@@ -4826,13 +5311,13 @@ var ProcedureForm = () => {
|
|
|
4826
5311
|
boxShadow: 3,
|
|
4827
5312
|
textAlign: "center"
|
|
4828
5313
|
}, children: [
|
|
4829
|
-
/* @__PURE__ */
|
|
4830
|
-
/* @__PURE__ */
|
|
5314
|
+
/* @__PURE__ */ jsx27(CircularProgress7, { sx: { mb: 2 } }),
|
|
5315
|
+
/* @__PURE__ */ jsx27(Typography16, { variant: "h6", color: "text.secondary", children: "Cargando procedimiento o no encontrado..." })
|
|
4831
5316
|
] });
|
|
4832
5317
|
}
|
|
4833
5318
|
return (
|
|
4834
5319
|
// Esta es la Box más externa que ahora controlará el scroll
|
|
4835
|
-
/* @__PURE__ */ jsxs21(
|
|
5320
|
+
/* @__PURE__ */ jsxs21(Box20, { sx: {
|
|
4836
5321
|
p: 2,
|
|
4837
5322
|
ml: 1,
|
|
4838
5323
|
mt: 2,
|
|
@@ -4849,17 +5334,17 @@ var ProcedureForm = () => {
|
|
|
4849
5334
|
overflowX: "hidden"
|
|
4850
5335
|
// Oculta el scroll horizontal si no es necesario para el contenedor principal
|
|
4851
5336
|
}, children: [
|
|
4852
|
-
/* @__PURE__ */
|
|
5337
|
+
/* @__PURE__ */ jsx27(Typography16, { variant: "h5", component: "h2", gutterBottom: true, align: "left", children: cambiarGuionesBajosPorEspacios(procedure.proceedLabel || procedure.action) }),
|
|
4853
5338
|
Object.values(validationErrors).some((err) => err !== null) && /* @__PURE__ */ jsxs21(Alert4, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: [
|
|
4854
5339
|
"Por favor, corrige los errores en el formulario antes de enviar.",
|
|
4855
|
-
/* @__PURE__ */
|
|
5340
|
+
/* @__PURE__ */ jsx27("ul", { children: Object.values(validationErrors).map((err, idx) => err && /* @__PURE__ */ jsx27("li", { children: err }, idx)) })
|
|
4856
5341
|
] }),
|
|
4857
|
-
!Object.values(validationErrors).some((err) => err !== null) && apiError && /* @__PURE__ */
|
|
4858
|
-
!Object.values(validationErrors).some((err) => err !== null) && !apiError && successMessage && /* @__PURE__ */
|
|
5342
|
+
!Object.values(validationErrors).some((err) => err !== null) && apiError && /* @__PURE__ */ jsx27(Alert4, { severity: "error", sx: { mb: 2, fontSize: "0.8rem" }, children: apiError.message }),
|
|
5343
|
+
!Object.values(validationErrors).some((err) => err !== null) && !apiError && successMessage && /* @__PURE__ */ jsx27(Alert4, { severity: "success", sx: { mb: 2, fontSize: "0.8rem" }, children: successMessage }),
|
|
4859
5344
|
/* @__PURE__ */ jsxs21("form", { onSubmit: handleSubmit, children: [
|
|
4860
|
-
procedure.parameters.map((param) => /* @__PURE__ */
|
|
4861
|
-
/* @__PURE__ */
|
|
4862
|
-
|
|
5345
|
+
procedure.parameters.map((param) => /* @__PURE__ */ jsx27("div", { children: renderInputField(param) }, param.name)),
|
|
5346
|
+
/* @__PURE__ */ jsx27(
|
|
5347
|
+
Button9,
|
|
4863
5348
|
{
|
|
4864
5349
|
type: "submit",
|
|
4865
5350
|
variant: "contained",
|
|
@@ -4867,20 +5352,20 @@ var ProcedureForm = () => {
|
|
|
4867
5352
|
disabled: apiLoading || Object.values(validationErrors).some((err) => err !== null),
|
|
4868
5353
|
sx: { mt: 2 },
|
|
4869
5354
|
size: "medium",
|
|
4870
|
-
startIcon: apiLoading ? /* @__PURE__ */
|
|
5355
|
+
startIcon: apiLoading ? /* @__PURE__ */ jsx27(CircularProgress7, { size: 20, color: "inherit" }) : null,
|
|
4871
5356
|
children: apiLoading ? "Ejecutando..." : procedure.proceedLabel || "Ejecutar"
|
|
4872
5357
|
}
|
|
4873
5358
|
)
|
|
4874
5359
|
] }),
|
|
4875
|
-
ResultDisplayContent && /* @__PURE__ */ jsxs21(
|
|
5360
|
+
ResultDisplayContent && /* @__PURE__ */ jsxs21(Box20, { sx: { mt: 2 }, children: [
|
|
4876
5361
|
" ",
|
|
4877
5362
|
ResultDisplayContent
|
|
4878
5363
|
] }),
|
|
4879
|
-
executionLog.length > 0 && /* @__PURE__ */ jsxs21(
|
|
4880
|
-
/* @__PURE__ */
|
|
4881
|
-
/* @__PURE__ */
|
|
4882
|
-
/* @__PURE__ */
|
|
4883
|
-
|
|
5364
|
+
executionLog.length > 0 && /* @__PURE__ */ jsxs21(Box20, { sx: { mt: 3 }, children: [
|
|
5365
|
+
/* @__PURE__ */ jsx27(Divider3, { sx: { mb: 2 } }),
|
|
5366
|
+
/* @__PURE__ */ jsx27(Typography16, { variant: "h6", gutterBottom: true, sx: { fontSize: "0.9rem" }, children: "Registro de Ejecuci\xF3n" }),
|
|
5367
|
+
/* @__PURE__ */ jsx27(
|
|
5368
|
+
Box20,
|
|
4884
5369
|
{
|
|
4885
5370
|
sx: {
|
|
4886
5371
|
bgcolor: "grey.100",
|
|
@@ -4893,8 +5378,8 @@ var ProcedureForm = () => {
|
|
|
4893
5378
|
fontSize: "0.75rem",
|
|
4894
5379
|
whiteSpace: "pre-wrap"
|
|
4895
5380
|
},
|
|
4896
|
-
children: executionLog.map((log, index) => /* @__PURE__ */
|
|
4897
|
-
|
|
5381
|
+
children: executionLog.map((log, index) => /* @__PURE__ */ jsx27(
|
|
5382
|
+
Typography16,
|
|
4898
5383
|
{
|
|
4899
5384
|
component: "pre",
|
|
4900
5385
|
sx: {
|
|
@@ -4919,9 +5404,9 @@ import { Provider } from "react-redux";
|
|
|
4919
5404
|
import { PersistGate } from "redux-persist/integration/react";
|
|
4920
5405
|
|
|
4921
5406
|
// src/components/PrivateRoute.tsx
|
|
4922
|
-
import { useEffect as
|
|
5407
|
+
import { useEffect as useEffect10 } from "react";
|
|
4923
5408
|
import { Navigate, useLocation as useLocation3 } from "react-router-dom";
|
|
4924
|
-
import { Fragment as
|
|
5409
|
+
import { Fragment as Fragment4, jsx as jsx28 } from "react/jsx-runtime";
|
|
4925
5410
|
var PrivateRoute = ({ children }) => {
|
|
4926
5411
|
const location = useLocation3();
|
|
4927
5412
|
const dispatch = useAppDispatch();
|
|
@@ -4929,7 +5414,7 @@ var PrivateRoute = ({ children }) => {
|
|
|
4929
5414
|
const isAuthenticated = clientContextStatus === "succeeded";
|
|
4930
5415
|
const isLoadingAuth = clientContextStatus === "loading";
|
|
4931
5416
|
console.log(`[PrivateRoute] Render: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
|
|
4932
|
-
|
|
5417
|
+
useEffect10(() => {
|
|
4933
5418
|
console.log(`[PrivateRoute] Effect: Path=${location.pathname}, AuthStatus=${clientContextStatus}, IsAuthenticated=${isAuthenticated}, IsLoadingAuth=${isLoadingAuth}`);
|
|
4934
5419
|
if (!isAuthenticated && !isLoadingAuth && location.pathname !== "/login") {
|
|
4935
5420
|
const path = location.pathname + location.search;
|
|
@@ -4945,19 +5430,19 @@ var PrivateRoute = ({ children }) => {
|
|
|
4945
5430
|
}, [isAuthenticated, isLoadingAuth, location, dispatch, clientContextStatus]);
|
|
4946
5431
|
if (isLoadingAuth) {
|
|
4947
5432
|
console.log(`[PrivateRoute] Returning loading state...`);
|
|
4948
|
-
return /* @__PURE__ */
|
|
5433
|
+
return /* @__PURE__ */ jsx28("p", { children: "Verificando autenticaci\xF3n..." });
|
|
4949
5434
|
}
|
|
4950
5435
|
if (!isAuthenticated) {
|
|
4951
5436
|
console.log(`[PrivateRoute] User not authenticated, navigating to /login`);
|
|
4952
|
-
return /* @__PURE__ */
|
|
5437
|
+
return /* @__PURE__ */ jsx28(Navigate, { to: "/login", replace: true });
|
|
4953
5438
|
}
|
|
4954
5439
|
console.log(`[PrivateRoute] User authenticated, rendering children.`);
|
|
4955
|
-
return /* @__PURE__ */
|
|
5440
|
+
return /* @__PURE__ */ jsx28(Fragment4, { children });
|
|
4956
5441
|
};
|
|
4957
5442
|
var PrivateRoute_default = PrivateRoute;
|
|
4958
5443
|
|
|
4959
5444
|
// src/components/InitialRedirectHandler.tsx
|
|
4960
|
-
import { useEffect as
|
|
5445
|
+
import { useEffect as useEffect11, useRef as useRef8 } from "react";
|
|
4961
5446
|
import { useLocation as useLocation4, useNavigate as useNavigate5 } from "react-router-dom";
|
|
4962
5447
|
var InitialRedirectHandler = () => {
|
|
4963
5448
|
const location = useLocation4();
|
|
@@ -4965,16 +5450,21 @@ var InitialRedirectHandler = () => {
|
|
|
4965
5450
|
const dispatch = useAppDispatch();
|
|
4966
5451
|
const redirectPath = useRedirectPath();
|
|
4967
5452
|
const clientContextStatus = useClientContextStatus();
|
|
4968
|
-
|
|
5453
|
+
useEffect11(() => {
|
|
4969
5454
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
4970
5455
|
}, [location, dispatch]);
|
|
4971
|
-
|
|
5456
|
+
const navegandoRef = useRef8(false);
|
|
5457
|
+
useEffect11(() => {
|
|
5458
|
+
navegandoRef.current = false;
|
|
5459
|
+
}, [location.pathname]);
|
|
5460
|
+
useEffect11(() => {
|
|
4972
5461
|
if (clientContextStatus === "succeeded") {
|
|
4973
5462
|
if (redirectPath && redirectPath !== "/login") {
|
|
4974
5463
|
console.log("Redirigiendo a la ruta guardada:", redirectPath);
|
|
5464
|
+
navegandoRef.current = true;
|
|
4975
5465
|
navigate(redirectPath);
|
|
4976
5466
|
dispatch(setRedirectPath(null));
|
|
4977
|
-
} else if (location.pathname === "/login" || location.pathname === "/") {
|
|
5467
|
+
} else if (!navegandoRef.current && (location.pathname === "/login" || location.pathname === "/")) {
|
|
4978
5468
|
console.log("Usuario autenticado, redirigiendo a /home por defecto.");
|
|
4979
5469
|
navigate("/home");
|
|
4980
5470
|
}
|
|
@@ -4985,11 +5475,11 @@ var InitialRedirectHandler = () => {
|
|
|
4985
5475
|
var InitialRedirectHandler_default = InitialRedirectHandler;
|
|
4986
5476
|
|
|
4987
5477
|
// src/pages/GenericDataGridPage.tsx
|
|
4988
|
-
import
|
|
5478
|
+
import React22, { useState as useState16, useCallback as useCallback15 } from "react";
|
|
4989
5479
|
import { useParams as useParams2, useLocation as useLocation5 } from "react-router-dom";
|
|
4990
|
-
import { Box as
|
|
5480
|
+
import { Box as Box21, Alert as Alert5, Typography as Typography17, Tabs, Tab, IconButton as IconButton5 } from "@mui/material";
|
|
4991
5481
|
import CloseIcon2 from "@mui/icons-material/Close";
|
|
4992
|
-
import { jsx as
|
|
5482
|
+
import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4993
5483
|
var GenericDataGridPage = ({
|
|
4994
5484
|
initialTableName,
|
|
4995
5485
|
initialFixedFields = []
|
|
@@ -5000,7 +5490,7 @@ var GenericDataGridPage = ({
|
|
|
5000
5490
|
const [activeTabIdx, setActiveTabIdx] = useState16(0);
|
|
5001
5491
|
const ffKey = JSON.stringify(initialFixedFields);
|
|
5002
5492
|
const location = useLocation5();
|
|
5003
|
-
|
|
5493
|
+
React22.useEffect(() => {
|
|
5004
5494
|
if (effectiveTableName) {
|
|
5005
5495
|
setTabs([{
|
|
5006
5496
|
id: `main-${effectiveTableName}-${ffKey}`,
|
|
@@ -5035,26 +5525,26 @@ var GenericDataGridPage = ({
|
|
|
5035
5525
|
else if (activeTabIdx === index) setActiveTabIdx(index - 1);
|
|
5036
5526
|
};
|
|
5037
5527
|
if (!effectiveTableName) {
|
|
5038
|
-
return /* @__PURE__ */
|
|
5528
|
+
return /* @__PURE__ */ jsx29(Box21, { p: 3, children: /* @__PURE__ */ jsx29(Alert5, { severity: "error", children: "No se especific\xF3 una tabla." }) });
|
|
5039
5529
|
}
|
|
5040
|
-
return /* @__PURE__ */ jsxs22(
|
|
5041
|
-
/* @__PURE__ */
|
|
5530
|
+
return /* @__PURE__ */ jsxs22(Box21, { sx: { width: "100%", height: "calc(100vh - 64px)", display: "flex", flexDirection: "column" }, children: [
|
|
5531
|
+
/* @__PURE__ */ jsx29(Box21, { sx: { borderBottom: 1, borderColor: "divider", bgcolor: "background.paper" }, children: /* @__PURE__ */ jsx29(Tabs, { value: activeTabIdx, onChange: (_, v) => setActiveTabIdx(v), variant: "scrollable", children: tabs.map((tab, index) => /* @__PURE__ */ jsx29(
|
|
5042
5532
|
Tab,
|
|
5043
5533
|
{
|
|
5044
|
-
label: /* @__PURE__ */ jsxs22(
|
|
5045
|
-
/* @__PURE__ */
|
|
5046
|
-
index !== 0 && /* @__PURE__ */
|
|
5534
|
+
label: /* @__PURE__ */ jsxs22(Box21, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
5535
|
+
/* @__PURE__ */ jsx29(Typography17, { variant: "caption", sx: { fontWeight: "bold" }, children: tab.label }),
|
|
5536
|
+
index !== 0 && /* @__PURE__ */ jsx29(IconButton5, { size: "small", onClick: (e) => handleCloseTab(index, e), children: /* @__PURE__ */ jsx29(CloseIcon2, { fontSize: "inherit" }) })
|
|
5047
5537
|
] })
|
|
5048
5538
|
},
|
|
5049
5539
|
tab.id
|
|
5050
5540
|
)) }) }),
|
|
5051
|
-
tabs.map((tab, index) => /* @__PURE__ */
|
|
5052
|
-
|
|
5541
|
+
tabs.map((tab, index) => /* @__PURE__ */ jsx29(
|
|
5542
|
+
Box21,
|
|
5053
5543
|
{
|
|
5054
5544
|
role: "tabpanel",
|
|
5055
5545
|
hidden: activeTabIdx !== index,
|
|
5056
5546
|
sx: { flexGrow: 1, display: activeTabIdx === index ? "flex" : "none", flexDirection: "column", overflow: "hidden" },
|
|
5057
|
-
children: /* @__PURE__ */
|
|
5547
|
+
children: /* @__PURE__ */ jsx29(
|
|
5058
5548
|
GenericDataGrid_default,
|
|
5059
5549
|
{
|
|
5060
5550
|
tableName: tab.tableName,
|
|
@@ -5070,11 +5560,30 @@ var GenericDataGridPage = ({
|
|
|
5070
5560
|
};
|
|
5071
5561
|
var GenericDataGridPage_default = GenericDataGridPage;
|
|
5072
5562
|
|
|
5563
|
+
// src/pages/PantallaDeRuta.tsx
|
|
5564
|
+
import { useMemo as useMemo12 } from "react";
|
|
5565
|
+
import { useSearchParams } from "react-router-dom";
|
|
5566
|
+
import { Box as Box22 } from "@mui/material";
|
|
5567
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
5568
|
+
var PantallaDeRuta = ({ screenName }) => {
|
|
5569
|
+
const [busqueda] = useSearchParams();
|
|
5570
|
+
const params = useMemo12(() => Object.fromEntries(busqueda.entries()), [busqueda]);
|
|
5571
|
+
const Pantalla = wScreens[screenName];
|
|
5572
|
+
return /* @__PURE__ */ jsx30(Box22, { sx: { pt: 3, pl: 4 }, children: Pantalla ? /* @__PURE__ */ jsx30(Pantalla, { screenName, params }) : /* @__PURE__ */ jsx30(FallbackWScreen, { screenName }) });
|
|
5573
|
+
};
|
|
5574
|
+
|
|
5073
5575
|
// src/pages/MenuTablePage.tsx
|
|
5074
|
-
import { useMemo as
|
|
5576
|
+
import { useMemo as useMemo13 } from "react";
|
|
5075
5577
|
import { useParams as useParams3 } from "react-router-dom";
|
|
5076
|
-
import { Box as Box23, Alert as Alert6, Typography as
|
|
5077
|
-
import { jsx as
|
|
5578
|
+
import { Box as Box23, Alert as Alert6, Typography as Typography18 } from "@mui/material";
|
|
5579
|
+
import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5580
|
+
function fixedFieldsDeMenu(ff) {
|
|
5581
|
+
if (!ff) return [];
|
|
5582
|
+
if (Array.isArray(ff)) {
|
|
5583
|
+
return ff.map(({ fieldName, value }) => ({ fieldName, value }));
|
|
5584
|
+
}
|
|
5585
|
+
return Object.entries(ff).map(([fieldName, value]) => ({ fieldName, value }));
|
|
5586
|
+
}
|
|
5078
5587
|
var MenuTablePage = () => {
|
|
5079
5588
|
const { menuName } = useParams3();
|
|
5080
5589
|
const { clientContext } = useApp();
|
|
@@ -5090,22 +5599,14 @@ var MenuTablePage = () => {
|
|
|
5090
5599
|
}
|
|
5091
5600
|
return void 0;
|
|
5092
5601
|
};
|
|
5093
|
-
const { currentTableName, currentFixedFields } =
|
|
5602
|
+
const { currentTableName, currentFixedFields } = useMemo13(() => {
|
|
5094
5603
|
let tableName = void 0;
|
|
5095
5604
|
let fixedFields = [];
|
|
5096
5605
|
if (menuName && clientContext && clientContext.menu) {
|
|
5097
5606
|
const menuItem = findMenuItem(clientContext.menu, menuName);
|
|
5098
5607
|
if (menuItem) {
|
|
5099
5608
|
tableName = menuItem.table || menuItem.name;
|
|
5100
|
-
|
|
5101
|
-
Object.keys(menuItem.ff || []).forEach((fixedFieldKey) => {
|
|
5102
|
-
fixedFields.push({
|
|
5103
|
-
fieldName: fixedFieldKey,
|
|
5104
|
-
//@ts-ignore
|
|
5105
|
-
value: menuItem.ff[fixedFieldKey]
|
|
5106
|
-
});
|
|
5107
|
-
});
|
|
5108
|
-
}
|
|
5609
|
+
fixedFields = fixedFieldsDeMenu(menuItem.ff);
|
|
5109
5610
|
} else {
|
|
5110
5611
|
console.warn(`[${menuName}] \xCDtem de men\xFA '${menuName}' no encontrado o no es de tipo 'table' en clientContext.menu.`);
|
|
5111
5612
|
}
|
|
@@ -5116,12 +5617,12 @@ var MenuTablePage = () => {
|
|
|
5116
5617
|
};
|
|
5117
5618
|
}, [menuName, clientContext]);
|
|
5118
5619
|
if (!currentTableName) {
|
|
5119
|
-
return /* @__PURE__ */
|
|
5120
|
-
/* @__PURE__ */
|
|
5121
|
-
/* @__PURE__ */
|
|
5620
|
+
return /* @__PURE__ */ jsx31(Box23, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ jsxs23(Alert6, { severity: "error", children: [
|
|
5621
|
+
/* @__PURE__ */ jsx31(Typography18, { variant: "h6", children: "Error: No se pudo cargar la informaci\xF3n de la tabla." }),
|
|
5622
|
+
/* @__PURE__ */ jsx31(Typography18, { variant: "body1", children: "Verifique la configuraci\xF3n del men\xFA o el nombre de la tabla en la URL." })
|
|
5122
5623
|
] }) });
|
|
5123
5624
|
}
|
|
5124
|
-
return /* @__PURE__ */
|
|
5625
|
+
return /* @__PURE__ */ jsx31(
|
|
5125
5626
|
GenericDataGridPage_default,
|
|
5126
5627
|
{
|
|
5127
5628
|
initialTableName: currentTableName,
|
|
@@ -5133,84 +5634,60 @@ var MenuTablePage_default = MenuTablePage;
|
|
|
5133
5634
|
|
|
5134
5635
|
// src/App.tsx
|
|
5135
5636
|
import { Box as Box24 } from "@mui/material";
|
|
5136
|
-
import
|
|
5137
|
-
|
|
5138
|
-
// src/utils/routeUtils.ts
|
|
5139
|
-
import { Children, isValidElement } from "react";
|
|
5140
|
-
var extractPathsFromRoutes = (node) => {
|
|
5141
|
-
const paths = [];
|
|
5142
|
-
Children.forEach(node, (child) => {
|
|
5143
|
-
if (!isValidElement(child)) return;
|
|
5144
|
-
if (child.props.path) {
|
|
5145
|
-
paths.push(child.props.path);
|
|
5146
|
-
}
|
|
5147
|
-
if (child.props.children) {
|
|
5148
|
-
paths.push(...extractPathsFromRoutes(child.props.children));
|
|
5149
|
-
}
|
|
5150
|
-
});
|
|
5151
|
-
return paths;
|
|
5152
|
-
};
|
|
5153
|
-
|
|
5154
|
-
// src/App.tsx
|
|
5155
|
-
import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5637
|
+
import typeStore6 from "type-store";
|
|
5638
|
+
import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5156
5639
|
var LocationTracker = () => {
|
|
5157
5640
|
const location = useLocation6();
|
|
5158
5641
|
const dispatch = useAppDispatch();
|
|
5159
|
-
|
|
5642
|
+
useEffect13(() => {
|
|
5160
5643
|
dispatch(setCurrentPath(location.pathname + location.search));
|
|
5161
5644
|
}, [location, dispatch]);
|
|
5162
5645
|
return null;
|
|
5163
5646
|
};
|
|
5164
5647
|
function FrontendPlusReactRoutes({ myRoutes, myUnloggedRoutes, layout: Layout = MainLayout_default, unloggedLayout: UnloggedLayout }) {
|
|
5165
|
-
return /* @__PURE__ */ jsxs24(
|
|
5166
|
-
/* @__PURE__ */
|
|
5167
|
-
|
|
5168
|
-
/* @__PURE__ */
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
/* @__PURE__ */
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
Route,
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
}
|
|
5200
|
-
),
|
|
5201
|
-
myRoutes,
|
|
5202
|
-
/* @__PURE__ */ jsx30(Route, { path: "*", element: /* @__PURE__ */ jsx30("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
|
|
5203
|
-
] }),
|
|
5204
|
-
/* @__PURE__ */ jsx30(Route, { path: "*", element: /* @__PURE__ */ jsx30(Navigate2, { to: "/", replace: true }) })
|
|
5648
|
+
return /* @__PURE__ */ jsxs24(Fragment5, { children: [
|
|
5649
|
+
/* @__PURE__ */ jsx32(InitialRedirectHandler_default, {}),
|
|
5650
|
+
/* @__PURE__ */ jsxs24(Routes, { children: [
|
|
5651
|
+
/* @__PURE__ */ jsxs24(Route, { element: UnloggedLayout ? /* @__PURE__ */ jsx32(UnloggedLayout, {}) : /* @__PURE__ */ jsx32(Outlet2, {}), children: [
|
|
5652
|
+
/* @__PURE__ */ jsx32(Route, { path: "/login", element: /* @__PURE__ */ jsx32(LoginPage_default, {}) }),
|
|
5653
|
+
/* @__PURE__ */ jsx32(Route, { path: "/logout", element: /* @__PURE__ */ jsx32(LogoutPage_default, {}) }),
|
|
5654
|
+
myUnloggedRoutes
|
|
5655
|
+
] }),
|
|
5656
|
+
/* @__PURE__ */ jsxs24(Route, { element: /* @__PURE__ */ jsx32(PrivateRoute_default, { children: /* @__PURE__ */ jsx32(Layout, {}) }), children: [
|
|
5657
|
+
/* @__PURE__ */ jsx32(Route, { path: "/", element: /* @__PURE__ */ jsx32(HomePage_default, {}) }),
|
|
5658
|
+
/* @__PURE__ */ jsx32(Route, { path: "/home", element: /* @__PURE__ */ jsx32(HomePage_default, {}) }),
|
|
5659
|
+
/* @__PURE__ */ jsx32(Route, { path: "/table/:tableName", element: /* @__PURE__ */ jsx32(GenericDataGridPage_default, {}) }),
|
|
5660
|
+
/* @__PURE__ */ jsx32(Route, { path: "/menu/:menuName", element: /* @__PURE__ */ jsx32(MenuTablePage_default, {}) }),
|
|
5661
|
+
/* @__PURE__ */ jsx32(Route, { path: "/procedures/:procedureName", element: /* @__PURE__ */ jsx32(ProcedureForm_default, {}) }),
|
|
5662
|
+
Object.keys(wScreens).map((screenName) => /* @__PURE__ */ jsx32(
|
|
5663
|
+
Route,
|
|
5664
|
+
{
|
|
5665
|
+
path: `/wScreens/${screenName}`,
|
|
5666
|
+
element: /* @__PURE__ */ jsx32(PantallaDeRuta, { screenName })
|
|
5667
|
+
},
|
|
5668
|
+
screenName
|
|
5669
|
+
)),
|
|
5670
|
+
/* @__PURE__ */ jsx32(
|
|
5671
|
+
Route,
|
|
5672
|
+
{
|
|
5673
|
+
path: "/wScreens-fallback/:screenName",
|
|
5674
|
+
element: /* @__PURE__ */ jsx32(Box24, { sx: { p: 3 }, children: /* @__PURE__ */ jsx32(FallbackWScreen, { screenName: ":screenName" }) })
|
|
5675
|
+
}
|
|
5676
|
+
),
|
|
5677
|
+
myRoutes,
|
|
5678
|
+
/* @__PURE__ */ jsx32(Route, { path: "*", element: /* @__PURE__ */ jsx32("div", { style: { marginTop: "20px", marginLeft: "10px" }, children: "404 - Recurso No Encontrado" }) })
|
|
5679
|
+
] }),
|
|
5680
|
+
/* @__PURE__ */ jsx32(Route, { path: "*", element: /* @__PURE__ */ jsx32(Navigate2, { to: "/", replace: true }) })
|
|
5681
|
+
] })
|
|
5205
5682
|
] });
|
|
5206
5683
|
}
|
|
5207
5684
|
var FrontendPlusProviders = ({ children, publicPaths }) => {
|
|
5208
|
-
return /* @__PURE__ */
|
|
5209
|
-
/* @__PURE__ */
|
|
5685
|
+
return /* @__PURE__ */ jsx32(Provider, { store, children: /* @__PURE__ */ jsx32(PersistGate, { loading: null, persistor, children: /* @__PURE__ */ jsxs24(BrowserRouter, { children: [
|
|
5686
|
+
/* @__PURE__ */ jsx32(LocationTracker, {}),
|
|
5210
5687
|
" ",
|
|
5211
|
-
/* @__PURE__ */
|
|
5688
|
+
/* @__PURE__ */ jsx32(AppProvider, { publicPaths, children: /* @__PURE__ */ jsxs24(SnackbarProvider, { children: [
|
|
5212
5689
|
children,
|
|
5213
|
-
/* @__PURE__ */
|
|
5690
|
+
/* @__PURE__ */ jsx32(SessionExpiredMessage_default, {})
|
|
5214
5691
|
] }) })
|
|
5215
5692
|
] }) }) });
|
|
5216
5693
|
};
|
|
@@ -5220,11 +5697,10 @@ var App = ({
|
|
|
5220
5697
|
unloggedLayout,
|
|
5221
5698
|
myWScreens,
|
|
5222
5699
|
myClientSides,
|
|
5223
|
-
myResultsOk
|
|
5700
|
+
myResultsOk,
|
|
5701
|
+
myConditions
|
|
5224
5702
|
}) => {
|
|
5225
|
-
|
|
5226
|
-
typeStore7.messages = typeStore7.i18n.messages.es;
|
|
5227
|
-
typeStore7.locale = typeStore7.i18n.locale.es;
|
|
5703
|
+
useMemo14(() => {
|
|
5228
5704
|
if (myClientSides) {
|
|
5229
5705
|
extendClientSides(myClientSides);
|
|
5230
5706
|
}
|
|
@@ -5234,17 +5710,24 @@ var App = ({
|
|
|
5234
5710
|
if (myWScreens) {
|
|
5235
5711
|
extendWScreens(myWScreens);
|
|
5236
5712
|
}
|
|
5713
|
+
if (myConditions) {
|
|
5714
|
+
extendConditions(myConditions);
|
|
5715
|
+
}
|
|
5716
|
+
}, [myClientSides, myResultsOk, myWScreens, myConditions]);
|
|
5717
|
+
useEffect13(() => {
|
|
5718
|
+
typeStore6.messages = typeStore6.i18n.messages.es;
|
|
5719
|
+
typeStore6.locale = typeStore6.i18n.locale.es;
|
|
5237
5720
|
const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
|
|
5238
5721
|
link.type = "image/png";
|
|
5239
5722
|
link.rel = "shortcut icon";
|
|
5240
5723
|
link.href = `${envConfig.backendUrl}/img/logo-128.png`;
|
|
5241
5724
|
document.getElementsByTagName("head")[0].appendChild(link);
|
|
5242
|
-
}, [
|
|
5243
|
-
const safePaths =
|
|
5725
|
+
}, []);
|
|
5726
|
+
const safePaths = React25.useMemo(() => {
|
|
5244
5727
|
const extracted = extractPathsFromRoutes(myUnloggedRoutes);
|
|
5245
5728
|
return ["/login", "/logout", ...extracted];
|
|
5246
5729
|
}, [myUnloggedRoutes]);
|
|
5247
|
-
return /* @__PURE__ */
|
|
5730
|
+
return /* @__PURE__ */ jsx32(FrontendPlusProviders, { publicPaths: safePaths, children: /* @__PURE__ */ jsx32(
|
|
5248
5731
|
FrontendPlusReactRoutes,
|
|
5249
5732
|
{
|
|
5250
5733
|
myRoutes,
|
|
@@ -5258,6 +5741,7 @@ export {
|
|
|
5258
5741
|
App_default as App,
|
|
5259
5742
|
AppProvider,
|
|
5260
5743
|
ConfirmDialog,
|
|
5744
|
+
DOM_TEMP_ID,
|
|
5261
5745
|
FrontendPlusProviders,
|
|
5262
5746
|
FrontendPlusReactRoutes,
|
|
5263
5747
|
GenericDataGrid_default as GenericDataGrid,
|
|
@@ -5266,6 +5750,7 @@ export {
|
|
|
5266
5750
|
cambiarGuionesBajosPorEspacios,
|
|
5267
5751
|
clientSides,
|
|
5268
5752
|
extendClientSides,
|
|
5753
|
+
extendConditions,
|
|
5269
5754
|
extendResultsOk,
|
|
5270
5755
|
extendWScreens,
|
|
5271
5756
|
extractPathsFromRoutes,
|