frontend-plus-react 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -788,7 +788,6 @@ var useApiCall = () => {
788
788
 
789
789
 
790
790
 
791
-
792
791
  var _material = require('@mui/material');
793
792
 
794
793
  // src/utils/functions.tsx
@@ -991,16 +990,44 @@ var useRedirectPath = () => {
991
990
  var cambiarGuionesBajosPorEspacios = (texto) => texto.replace(/_/g, " ");
992
991
 
993
992
  // src/components/grid/GenericDataGrid.tsx
994
- var _Search = require('@mui/icons-material/Search'); var _Search2 = _interopRequireDefault(_Search);
995
- var _SearchOff = require('@mui/icons-material/SearchOff'); var _SearchOff2 = _interopRequireDefault(_SearchOff);
996
993
  var _Add = require('@mui/icons-material/Add'); var _Add2 = _interopRequireDefault(_Add);
997
994
 
998
- // src/components/grid/PkHeaderRenderer.tsx
995
+ // src/components/ConfirmDialog.tsx
996
+ var _Dialog = require('@mui/material/Dialog'); var _Dialog2 = _interopRequireDefault(_Dialog);
997
+ var _DialogTitle = require('@mui/material/DialogTitle'); var _DialogTitle2 = _interopRequireDefault(_DialogTitle);
998
+ var _DialogContent = require('@mui/material/DialogContent'); var _DialogContent2 = _interopRequireDefault(_DialogContent);
999
+ var _DialogContentText = require('@mui/material/DialogContentText'); var _DialogContentText2 = _interopRequireDefault(_DialogContentText);
1000
+ var _DialogActions = require('@mui/material/DialogActions'); var _DialogActions2 = _interopRequireDefault(_DialogActions);
1001
+ var _Button = require('@mui/material/Button'); var _Button2 = _interopRequireDefault(_Button);
1002
+
1003
+ var ConfirmDialog = ({ open, onClose, title, message }) => {
1004
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1005
+ _Dialog2.default,
1006
+ {
1007
+ open,
1008
+ onClose: () => onClose(false),
1009
+ "aria-labelledby": "confirm-dialog-title",
1010
+ "aria-describedby": "confirm-dialog-description",
1011
+ children: [
1012
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DialogTitle2.default, { id: "confirm-dialog-title", children: title }),
1013
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DialogContent2.default, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DialogContentText2.default, { id: "confirm-dialog-description", children: message }) }),
1014
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _DialogActions2.default, { children: [
1015
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Button2.default, { onClick: () => onClose(false), color: "primary", children: "Cancelar" }),
1016
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Button2.default, { onClick: () => onClose(true), color: "error", autoFocus: true, children: "Confirmar" })
1017
+ ] })
1018
+ ]
1019
+ }
1020
+ );
1021
+ };
1022
+
1023
+ // src/components/grid/renderers/headerCellRenderers.tsx
999
1024
 
1025
+ var _Search = require('@mui/icons-material/Search'); var _Search2 = _interopRequireDefault(_Search);
1026
+ var _SearchOff = require('@mui/icons-material/SearchOff'); var _SearchOff2 = _interopRequireDefault(_SearchOff);
1000
1027
 
1001
- function PkHeaderRenderer(props) {
1028
+ var defaultColumnHeaderCellRenderer = (props, fieldDef) => {
1002
1029
  const { column } = props;
1003
- const isPrimaryKey = column.isPK;
1030
+ const isPrimaryKey = fieldDef.isPk;
1004
1031
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1005
1032
  _material.Box,
1006
1033
  {
@@ -1028,63 +1055,19 @@ function PkHeaderRenderer(props) {
1028
1055
  )
1029
1056
  }
1030
1057
  );
1031
- }
1032
- var PkHeaderRenderer_default = PkHeaderRenderer;
1033
-
1034
- // src/components/grid/PkCellRenderer.tsx
1035
-
1036
-
1037
- function PkCellRenderer(props) {
1038
- const { column, row } = props;
1039
- const isPrimaryKey = column.isPK;
1040
- const rowAsRecord = row;
1041
- const value = rowAsRecord[column.key];
1042
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1043
- _material.Typography,
1044
- {
1045
- variant: "body2",
1046
- sx: {
1047
- //fontWeight: isPrimaryKey ? 'bold' : 'normal',
1048
- fontSize: "0.875rem",
1049
- // Ajusta el tamaño si es necesario
1050
- whiteSpace: "nowrap",
1051
- overflow: "hidden",
1052
- textOverflow: "ellipsis",
1053
- width: "100%"
1054
- },
1055
- children: value === null || value === void 0 ? "" : String(value)
1056
- }
1057
- );
1058
- }
1059
- var PkCellRenderer_default = PkCellRenderer;
1060
-
1061
- // src/components/ConfirmDialog.tsx
1062
- var _Dialog = require('@mui/material/Dialog'); var _Dialog2 = _interopRequireDefault(_Dialog);
1063
- var _DialogTitle = require('@mui/material/DialogTitle'); var _DialogTitle2 = _interopRequireDefault(_DialogTitle);
1064
- var _DialogContent = require('@mui/material/DialogContent'); var _DialogContent2 = _interopRequireDefault(_DialogContent);
1065
- var _DialogContentText = require('@mui/material/DialogContentText'); var _DialogContentText2 = _interopRequireDefault(_DialogContentText);
1066
- var _DialogActions = require('@mui/material/DialogActions'); var _DialogActions2 = _interopRequireDefault(_DialogActions);
1067
- var _Button = require('@mui/material/Button'); var _Button2 = _interopRequireDefault(_Button);
1068
-
1069
- var ConfirmDialog = ({ open, onClose, title, message }) => {
1070
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1071
- _Dialog2.default,
1072
- {
1073
- open,
1074
- onClose: () => onClose(false),
1075
- "aria-labelledby": "confirm-dialog-title",
1076
- "aria-describedby": "confirm-dialog-description",
1077
- children: [
1078
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DialogTitle2.default, { id: "confirm-dialog-title", children: title }),
1079
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DialogContent2.default, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DialogContentText2.default, { id: "confirm-dialog-description", children: message }) }),
1080
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _DialogActions2.default, { children: [
1081
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Button2.default, { onClick: () => onClose(false), color: "primary", children: "Cancelar" }),
1082
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Button2.default, { onClick: () => onClose(true), color: "error", autoFocus: true, children: "Confirmar" })
1083
- ] })
1084
- ]
1085
- }
1086
- );
1087
1058
  };
1059
+ var actionsColumnHeaderCellRenderer = (props, isFilterRowVisible, toggleFilterVisibility) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1060
+ _material.IconButton,
1061
+ {
1062
+ color: "inherit",
1063
+ onClick: toggleFilterVisibility,
1064
+ size: "small",
1065
+ title: isFilterRowVisible ? "Ocultar filtros" : "Mostrar filtros",
1066
+ sx: { p: 0.5 },
1067
+ children: isFilterRowVisible ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _SearchOff2.default, { sx: { fontSize: 20 } }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Search2.default, { sx: { fontSize: 20 } })
1068
+ }
1069
+ );
1070
+ var detailColumnCellHeaderRenderer = (props, detailTable) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Tooltip, { title: detailTable.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "caption", sx: { fontSize: "0.75rem", fontWeight: "bold" }, children: detailTable.abr.toUpperCase() }) });
1088
1071
 
1089
1072
  // src/components/grid/FilterInputRender.tsx
1090
1073
 
@@ -1117,7 +1100,209 @@ function FilterInputRenderer({
1117
1100
  }
1118
1101
  var FilterInputRender_default = FilterInputRenderer;
1119
1102
 
1120
- // src/components/grid/InputRendered.tsx
1103
+ // src/components/grid/renderers/summaryCellRenderers.tsx
1104
+
1105
+ var defaultColumnSummaryCellRenderer = (props, fixedFields, isFilterRowVisible, filters, setFilters) => {
1106
+ const { column } = props;
1107
+ const fixedFieldEntry = _optionalChain([fixedFields, 'optionalAccess', _3 => _3.find, 'call', _4 => _4((f) => f.fieldName === column.key)]);
1108
+ if (fixedFieldEntry && fixedFieldEntry.until === void 0 || !isFilterRowVisible) return null;
1109
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1110
+ FilterInputRender_default,
1111
+ {
1112
+ column,
1113
+ filters,
1114
+ setFilters
1115
+ }
1116
+ );
1117
+ };
1118
+ var actionsColumnSummaryCellRenderer = (props) => null;
1119
+ var detailColumnCellSummaryRenderer = (props) => null;
1120
+
1121
+ // src/components/grid/renderers/cellRenderers.tsx
1122
+
1123
+ var _KeyboardArrowDown = require('@mui/icons-material/KeyboardArrowDown'); var _KeyboardArrowDown2 = _interopRequireDefault(_KeyboardArrowDown);
1124
+ var _KeyboardArrowUp = require('@mui/icons-material/KeyboardArrowUp'); var _KeyboardArrowUp2 = _interopRequireDefault(_KeyboardArrowUp);
1125
+ var _Delete = require('@mui/icons-material/Delete'); var _Delete2 = _interopRequireDefault(_Delete);
1126
+
1127
+ // src/components/grid/ExampleClientSideComponent.tsx
1128
+
1129
+
1130
+ var ExampleClientSideComponent = ({ row, column, fieldDefinition }) => {
1131
+ const value = row[column.key];
1132
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: {
1133
+ padding: 0.5,
1134
+ width: "100%",
1135
+ height: "100%",
1136
+ display: "flex",
1137
+ alignItems: "center",
1138
+ backgroundColor: value === "Special" ? "lightblue" : "transparent"
1139
+ }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
1140
+ };
1141
+ var ExampleClientSideComponent_default = ExampleClientSideComponent;
1142
+
1143
+ // src/components/grid/FallbackClientSideRenderer.tsx
1144
+
1145
+ var _WarningAmber = require('@mui/icons-material/WarningAmber'); var _WarningAmber2 = _interopRequireDefault(_WarningAmber);
1146
+
1147
+ var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
1148
+ const value = row[column.key];
1149
+ const clientSideName = _optionalChain([fieldDefinition, 'optionalAccess', _5 => _5.clientSide]) || "Desconocido";
1150
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Tooltip, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1151
+ _material.Box,
1152
+ {
1153
+ sx: {
1154
+ display: "flex",
1155
+ alignItems: "center",
1156
+ justifyContent: "space-between",
1157
+ // Para espaciar el valor y el icono
1158
+ gap: 1,
1159
+ // Espacio entre elementos
1160
+ width: "100%",
1161
+ height: "100%",
1162
+ paddingLeft: "8px",
1163
+ backgroundColor: "rgba(255, 193, 7, 0.1)",
1164
+ // Amarillo claro para advertencia
1165
+ border: "1px dashed rgba(255, 193, 7, 0.5)",
1166
+ boxSizing: "border-box",
1167
+ overflow: "hidden"
1168
+ // Evita que el contenido se desborde
1169
+ },
1170
+ children: [
1171
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: value !== null && value !== void 0 ? String(value) : "*Vac\xEDo*" }),
1172
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1173
+ _WarningAmber2.default,
1174
+ {
1175
+ sx: {
1176
+ fontSize: 18,
1177
+ color: "warning.main",
1178
+ marginRight: "4px"
1179
+ // Pequeño margen a la derecha del icono
1180
+ }
1181
+ }
1182
+ )
1183
+ ]
1184
+ }
1185
+ ) });
1186
+ };
1187
+ var FallbackClientSideRenderer_default = FallbackClientSideRenderer;
1188
+
1189
+ // src/components/grid/clientSides.ts
1190
+ var clientSides = {
1191
+ "ExampleClientSideComponent": ExampleClientSideComponent_default,
1192
+ // Aseguramos el tipo aquí también
1193
+ "FallbackClientSideRenderer": FallbackClientSideRenderer_default
1194
+ // Y aquí
1195
+ };
1196
+ var extendClientSides = (newRenderers) => {
1197
+ clientSides = exports.clientSides = { ...clientSides, ...newRenderers };
1198
+ console.log("clientSides extendidos:", clientSides);
1199
+ };
1200
+
1201
+ // src/components/grid/renderers/cellRenderers.tsx
1202
+
1203
+ var allColumnsCellRenderer = (props) => {
1204
+ const theme = _material.useTheme.call(void 0, );
1205
+ const column = props.column;
1206
+ const { row, rowIdx } = props;
1207
+ if (row[DETAIL_ROW_INDICATOR]) {
1208
+ const detailTableAbr = row[DETAIL_ROW_INDICATOR];
1209
+ const detailColumn = column;
1210
+ if (column.customType === "detail" && detailColumn.detailTable.abr === detailTableAbr) {
1211
+ const detailTable = detailColumn.tableDefinition.detailTables.find((dt) => dt.abr === detailTableAbr);
1212
+ let fixedFields = [];
1213
+ detailTable.fields.forEach((field) => {
1214
+ if (typeof field === "string") {
1215
+ fixedFields.push({ fieldName: field, value: row[field] });
1216
+ } else {
1217
+ fixedFields.push({ fieldName: field.target, value: row[field.source] });
1218
+ }
1219
+ });
1220
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: {
1221
+ // Se eliminó el padding para que la sub-grilla se extienda por completo
1222
+ minHeight: "200px",
1223
+ width: "100%",
1224
+ height: "100%",
1225
+ //display: 'flex',
1226
+ //flexDirection: 'column',
1227
+ boxSizing: "border-box"
1228
+ }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GenericDataGrid_default, { tableName: detailTable.table, fixedFields }) });
1229
+ }
1230
+ return void 0;
1231
+ }
1232
+ switch (column.customType) {
1233
+ case "default": {
1234
+ const defaultColumn = column;
1235
+ const { fieldDef, tableDefinition, primaryKey, cellFeedback, fixedFields, localCellChanges } = defaultColumn;
1236
+ const rowId = getPrimaryKeyValues(row, primaryKey);
1237
+ if (_optionalChain([fieldDef, 'optionalAccess', _6 => _6.clientSide])) {
1238
+ const ClientSideComponent = clientSides[fieldDef.clientSide];
1239
+ if (ClientSideComponent) {
1240
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ClientSideComponent, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
1241
+ }
1242
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FallbackClientSideRenderer_default, { ...props, fieldDefinition: fieldDef, tableDefinition, primaryKey });
1243
+ }
1244
+ let cellBackgroundColor = "transparent";
1245
+ if (cellFeedback && cellFeedback.rowId === rowId && cellFeedback.columnKey === props.column.key) {
1246
+ cellBackgroundColor = cellFeedback.type === "error" ? theme.palette.error.light : theme.palette.success.light;
1247
+ } else {
1248
+ const isNewRowLocalCheck = row[NEW_ROW_INDICATOR];
1249
+ const isMandatory = tableDefinition.primaryKey.includes(props.column.key) || _optionalChain([tableDefinition, 'access', _7 => _7.fields, 'access', _8 => _8.find, 'call', _9 => _9((f) => f.name === props.column.key), 'optionalAccess', _10 => _10.nullable]) === false;
1250
+ const hasValue = row[props.column.key] !== null && row[props.column.key] !== void 0 && String(row[props.column.key]).trim() !== "";
1251
+ const isFixedFieldCurrent = _optionalChain([fixedFields, 'optionalAccess', _11 => _11.some, 'call', _12 => _12((f) => f.fieldName === props.column.key)]);
1252
+ if (isFixedFieldCurrent) {
1253
+ cellBackgroundColor = theme.palette.action.selected;
1254
+ } else if (isNewRowLocalCheck && isMandatory && !hasValue || localCellChanges.has(rowId) && _optionalChain([localCellChanges, 'access', _13 => _13.get, 'call', _14 => _14(rowId), 'optionalAccess', _15 => _15.has, 'call', _16 => _16(props.column.key)])) {
1255
+ cellBackgroundColor = theme.palette.info.light;
1256
+ }
1257
+ }
1258
+ const value = row[props.column.key];
1259
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { 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", paddingLeft: "8px", boxSizing: "border-box" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "body2", sx: { fontSize: "0.875rem", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", width: "100%" }, children: value === null || value === void 0 ? "" : String(value) }) });
1260
+ }
1261
+ case "detail": {
1262
+ const detailColumn = column;
1263
+ const { detailTable, primaryKey, tableData, setTableData, detailKey } = detailColumn;
1264
+ const isExpanded = tableData.some(
1265
+ (r) => r[DETAIL_ROW_INDICATOR] === detailTable.abr && getPrimaryKeyValues(r, primaryKey) === getPrimaryKeyValues({ ...row, [DETAIL_ROW_INDICATOR]: detailTable.abr }, primaryKey)
1266
+ );
1267
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Tooltip, { title: detailTable.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1268
+ _material.IconButton,
1269
+ {
1270
+ size: "small",
1271
+ onClick: (event) => {
1272
+ let rows = [...tableData];
1273
+ const rowId = getPrimaryKeyValues({ ...row, [DETAIL_ROW_INDICATOR]: detailTable.abr }, primaryKey);
1274
+ if (isExpanded) {
1275
+ setTableData(rows.filter(
1276
+ (r) => !(r[DETAIL_ROW_INDICATOR] === detailTable.abr && getPrimaryKeyValues(r, primaryKey) === rowId)
1277
+ ));
1278
+ } else {
1279
+ const parentRowIndex = rowIdx;
1280
+ rows.splice(parentRowIndex + 1, 0, {
1281
+ ...row,
1282
+ [DETAIL_ROW_INDICATOR]: detailTable.abr
1283
+ });
1284
+ setTableData(rows);
1285
+ }
1286
+ event.stopPropagation();
1287
+ },
1288
+ title: isExpanded ? "Contraer detalle" : "Expandir detalle",
1289
+ sx: { p: 0.5 },
1290
+ children: isExpanded ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _KeyboardArrowUp2.default, { sx: { fontSize: 20 } }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _KeyboardArrowDown2.default, { sx: { fontSize: 20 } })
1291
+ }
1292
+ ) }) });
1293
+ }
1294
+ case "action": {
1295
+ const actionColumn = column;
1296
+ const { tableDefinition, handleDeleteRow } = actionColumn;
1297
+ if (!_optionalChain([tableDefinition, 'access', _17 => _17.allow, 'optionalAccess', _18 => _18.delete])) return void 0;
1298
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Button, { variant: "outlined", color: "error", size: "small", onClick: () => handleDeleteRow(row), title: "Eliminar fila", sx: { minWidth: 35, height: 30, p: 0.5, "& .MuiButton-startIcon": { m: 0 } }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Delete2.default, { sx: { fontSize: 18 } }) }) });
1299
+ }
1300
+ default:
1301
+ return void 0;
1302
+ }
1303
+ };
1304
+
1305
+ // src/components/grid/InputRenderer.tsx
1121
1306
 
1122
1307
  var _InputBase = require('@mui/material/InputBase'); var _InputBase2 = _interopRequireDefault(_InputBase);
1123
1308
 
@@ -1139,7 +1324,7 @@ function InputRenderer({
1139
1324
  const [editingValue, setEditingValue] = _react.useState.call(void 0, row[column.key]);
1140
1325
  const { showSuccess, showError } = useSnackbar();
1141
1326
  const initialRowId = _react.useMemo.call(void 0, () => getPrimaryKeyValues(row, primaryKey), [row, primaryKey]);
1142
- const { callApi, loading, error } = useApiCall();
1327
+ const { callApi } = useApiCall();
1143
1328
  const handleCommit = _react.useCallback.call(void 0, async (currentValue, closeEditor, focusNextCell) => {
1144
1329
  const processedNewValue = typeof currentValue === "string" ? currentValue.trim() === "" ? null : currentValue.trim() : currentValue;
1145
1330
  const potentialUpdatedRow = { ...row, [column.key]: processedNewValue };
@@ -1147,7 +1332,7 @@ function InputRenderer({
1147
1332
  (key) => potentialUpdatedRow[key] !== void 0 && potentialUpdatedRow[key] !== null && String(potentialUpdatedRow[key]).trim() !== ""
1148
1333
  );
1149
1334
  const isNewRow = !arePKValuesFilled || potentialUpdatedRow[NEW_ROW_INDICATOR];
1150
- const isMandatoryField = tableDefinition.primaryKey.includes(column.key) || _optionalChain([tableDefinition, 'access', _3 => _3.fields, 'access', _4 => _4.find, 'call', _5 => _5((f) => f.name === column.key), 'optionalAccess', _6 => _6.nullable]) === false;
1335
+ const isMandatoryField = tableDefinition.primaryKey.includes(column.key) || _optionalChain([tableDefinition, 'access', _19 => _19.fields, 'access', _20 => _20.find, 'call', _21 => _21((f) => f.name === column.key), 'optionalAccess', _22 => _22.nullable]) === false;
1151
1336
  const isMandatoryFieldEmpty = isNewRow && isMandatoryField && (processedNewValue === null || processedNewValue === void 0 || String(processedNewValue).trim() === "");
1152
1337
  if (processedNewValue === row[column.key] && !isNewRow && !isMandatoryFieldEmpty) {
1153
1338
  console.log("No se guard\xF3: el valor no cambi\xF3 (y no es una nueva fila o campo obligatorio vac\xEDo que se est\xE1 iniciando).");
@@ -1218,7 +1403,7 @@ function InputRenderer({
1218
1403
  }
1219
1404
  });
1220
1405
  if (localCellChanges.has(initialRowId)) {
1221
- _optionalChain([localCellChanges, 'access', _7 => _7.get, 'call', _8 => _8(initialRowId), 'optionalAccess', _9 => _9.forEach, 'call', _10 => _10((colKey) => {
1406
+ _optionalChain([localCellChanges, 'access', _23 => _23.get, 'call', _24 => _24(initialRowId), 'optionalAccess', _25 => _25.forEach, 'call', _26 => _26((colKey) => {
1222
1407
  if (!rowToSend.hasOwnProperty(colKey)) {
1223
1408
  rowToSend[colKey] = potentialUpdatedRow[colKey];
1224
1409
  }
@@ -1316,7 +1501,7 @@ function InputRenderer({
1316
1501
  handleCommit(editingValue, true, false);
1317
1502
  }, [handleCommit, editingValue]);
1318
1503
  const fieldDefinition = tableDefinition.fields.find((f) => f.name === column.key);
1319
- const isFieldEditable = _optionalChain([fieldDefinition, 'optionalAccess', _11 => _11.editable]) !== false;
1504
+ const isFieldEditable = _optionalChain([fieldDefinition, 'optionalAccess', _27 => _27.editable]) !== false;
1320
1505
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1321
1506
  _InputBase2.default,
1322
1507
  {
@@ -1340,90 +1525,65 @@ function InputRenderer({
1340
1525
  }
1341
1526
  );
1342
1527
  }
1343
- var InputRendered_default = InputRenderer;
1344
-
1345
- // src/components/grid/ExampleClientSideComponent.tsx
1528
+ var InputRenderer_default = InputRenderer;
1346
1529
 
1530
+ // src/components/grid/renderers/editCellRenderers.tsx
1347
1531
 
1348
- var ExampleClientSideComponent = ({ row, column, fieldDefinition }) => {
1349
- const value = row[column.key];
1350
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: {
1351
- padding: 0.5,
1352
- width: "100%",
1353
- height: "100%",
1354
- display: "flex",
1355
- alignItems: "center",
1356
- backgroundColor: value === "Special" ? "lightblue" : "transparent"
1357
- }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "body2", sx: { fontWeight: "bold" }, children: value ? `CS: ${value}` : "N/A" }) });
1358
- };
1359
- var ExampleClientSideComponent_default = ExampleClientSideComponent;
1360
-
1361
- // src/components/grid/FallbackClientSideRenderer.tsx
1362
-
1363
- var _WarningAmber = require('@mui/icons-material/WarningAmber'); var _WarningAmber2 = _interopRequireDefault(_WarningAmber);
1364
-
1365
- var FallbackClientSideRenderer = ({ column, row, fieldDefinition }) => {
1366
- const value = row[column.key];
1367
- const clientSideName = _optionalChain([fieldDefinition, 'optionalAccess', _12 => _12.clientSide]) || "Desconocido";
1368
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Tooltip, { title: `Componente clientSide '${clientSideName}' no implementado. Mostrando valor por defecto.`, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1369
- _material.Box,
1370
- {
1371
- sx: {
1372
- display: "flex",
1373
- alignItems: "center",
1374
- justifyContent: "space-between",
1375
- // Para espaciar el valor y el icono
1376
- gap: 1,
1377
- // Espacio entre elementos
1378
- width: "100%",
1379
- height: "100%",
1380
- paddingLeft: "8px",
1381
- backgroundColor: "rgba(255, 193, 7, 0.1)",
1382
- // Amarillo claro para advertencia
1383
- border: "1px dashed rgba(255, 193, 7, 0.5)",
1384
- boxSizing: "border-box",
1385
- overflow: "hidden"
1386
- // Evita que el contenido se desborde
1387
- },
1388
- children: [
1389
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "body2", noWrap: true, sx: { flexGrow: 1 }, children: value !== null && value !== void 0 ? String(value) : "*Vac\xEDo*" }),
1390
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1391
- _WarningAmber2.default,
1392
- {
1393
- sx: {
1394
- fontSize: 18,
1395
- color: "warning.main",
1396
- marginRight: "4px"
1397
- // Pequeño margen a la derecha del icono
1398
- }
1399
- }
1400
- )
1401
- ]
1532
+ var defaultColumnEditCellRenderer = (props, tableDefinition, fixedFields, primaryKey, setCellFeedback, setTableData, localCellChanges, setLocalCellChanges, handleEnterKeyPressInEditor, allColumns) => {
1533
+ const { column } = props;
1534
+ if (column.editable) {
1535
+ const fieldDefinition = tableDefinition.fields.find((f) => f.name === column.key);
1536
+ const isFixedField = _optionalChain([fixedFields, 'optionalAccess', _28 => _28.some, 'call', _29 => _29((f) => f.fieldName === column.key)]);
1537
+ const isFieldEditableByUI = _optionalChain([fieldDefinition, 'optionalAccess', _30 => _30.editable]) !== false && !isFixedField;
1538
+ if (!isFieldEditableByUI) {
1539
+ return void 0;
1402
1540
  }
1403
- ) });
1541
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1542
+ InputRenderer_default,
1543
+ {
1544
+ ...props,
1545
+ tableDefinition,
1546
+ setCellFeedback,
1547
+ onEnterPress: (rowIndex, columnKey) => handleEnterKeyPressInEditor(rowIndex, columnKey, allColumns),
1548
+ setTableData,
1549
+ setLocalCellChanges,
1550
+ localCellChanges,
1551
+ primaryKey
1552
+ }
1553
+ );
1554
+ }
1404
1555
  };
1405
- var FallbackClientSideRenderer_default = FallbackClientSideRenderer;
1406
1556
 
1407
- // src/components/grid/clientSides.ts
1408
- var clientSides = {
1409
- "ExampleClientSideComponent": ExampleClientSideComponent_default,
1410
- // Aseguramos el tipo aquí también
1411
- "FallbackClientSideRenderer": FallbackClientSideRenderer_default
1412
- // Y aquí
1413
- };
1414
- var extendClientSides = (newRenderers) => {
1415
- clientSides = exports.clientSides = { ...clientSides, ...newRenderers };
1416
- console.log("clientSides extendidos:", clientSides);
1417
- };
1557
+ // src/components/grid/renderers/emptyRowRenderer.tsx
1558
+
1559
+ function EmptyRowsRenderer() {
1560
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: {
1561
+ // Posicionamiento absoluto respecto a la pantalla
1562
+ position: "fixed",
1563
+ top: "50%",
1564
+ // Centrado verticalmente
1565
+ left: "50%",
1566
+ // Centrado horizontalmente
1567
+ transform: "translate(-50%, -50%)",
1568
+ // Ajuste para el 50% del tamaño del div
1569
+ // Estilos de visualización
1570
+ backgroundColor: "rgba(255, 255, 255, 0.9)",
1571
+ border: "1px solid #ccc",
1572
+ borderRadius: "4px",
1573
+ padding: "16px 24px",
1574
+ boxShadow: "0 2px 10px rgba(0,0,0,0.1)"
1575
+ }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { textAlign: "center" }, children: "No hay filas para mostrar" }) });
1576
+ }
1418
1577
 
1419
1578
  // src/components/grid/GenericDataGrid.tsx
1420
1579
 
1421
1580
  var getPrimaryKeyValues = (row, primaryKey) => {
1422
- return primaryKey.map((key) => {
1581
+ return primaryKey.concat(DETAIL_ROW_INDICATOR).map((key) => {
1423
1582
  return row[key] !== void 0 && row[key] !== null ? String(row[key]) : "NULL_OR_UNDEFINED";
1424
1583
  }).join("|");
1425
1584
  };
1426
- var NEW_ROW_INDICATOR = ".$new";
1585
+ var NEW_ROW_INDICATOR = "$new";
1586
+ var DETAIL_ROW_INDICATOR = "$detail";
1427
1587
  var GenericDataGrid = ({
1428
1588
  tableName,
1429
1589
  fixedFields
@@ -1443,6 +1603,8 @@ var GenericDataGrid = ({
1443
1603
  const feedbackTimerRef = _react.useRef.call(void 0, null);
1444
1604
  const dataGridRef = _react.useRef.call(void 0, null);
1445
1605
  const { callApi, loading, error } = useApiCall();
1606
+ const getRowCount = () => tableData.filter((row) => !row[DETAIL_ROW_INDICATOR]).length;
1607
+ const getFilteredRowCount = () => filteredRows.filter((row) => !row[DETAIL_ROW_INDICATOR]).length;
1446
1608
  _react.useEffect.call(void 0, () => {
1447
1609
  setFilters({});
1448
1610
  setIsFilterRowVisible(false);
@@ -1466,7 +1628,6 @@ var GenericDataGrid = ({
1466
1628
  const data = await callApi("table_data", {
1467
1629
  table: tableName,
1468
1630
  fixedFields
1469
- // Envía el array fixedFields directamente a la API
1470
1631
  });
1471
1632
  setTableData(data);
1472
1633
  } catch (err) {
@@ -1483,7 +1644,7 @@ var GenericDataGrid = ({
1483
1644
  if (feedbackTimerRef.current) {
1484
1645
  clearTimeout(feedbackTimerRef.current);
1485
1646
  }
1486
- const timerDuration = cellFeedback.type === "success" ? 4e3 : 3e3;
1647
+ const timerDuration = 3e3;
1487
1648
  feedbackTimerRef.current = setTimeout(() => {
1488
1649
  setCellFeedback(null);
1489
1650
  }, timerDuration);
@@ -1637,37 +1798,25 @@ var GenericDataGrid = ({
1637
1798
  const handleEnterKeyPressInEditor = _react.useCallback.call(void 0, (rowIndex, columnKey, currentColumns) => {
1638
1799
  if (dataGridRef.current && tableDefinition) {
1639
1800
  const currentColumnIndex = currentColumns.findIndex((col) => col.key === columnKey);
1640
- if (currentColumnIndex !== -1) {
1641
- let nextColumnIndex = currentColumnIndex + 1;
1642
- let nextRowIndex = rowIndex;
1643
- let foundNextTarget = false;
1644
- while (!foundNextTarget) {
1645
- if (nextColumnIndex >= currentColumns.length) {
1646
- nextColumnIndex = 0;
1801
+ const editableColumns = currentColumns.filter((col) => {
1802
+ const fieldDefinition = tableDefinition.fields.find((f) => f.name === col.key);
1803
+ return col.key !== "filterToggle" && col.key !== "deleteAction" && (_optionalChain([fieldDefinition, 'optionalAccess', _31 => _31.editable]) !== false && !_optionalChain([fieldDefinition, 'optionalAccess', _32 => _32.clientSide]));
1804
+ });
1805
+ if (currentColumnIndex !== -1 && editableColumns.length > 0) {
1806
+ const editableColumnKeys = editableColumns.map((col) => col.key);
1807
+ let currentEditableColumnIndex = editableColumnKeys.indexOf(columnKey);
1808
+ if (currentEditableColumnIndex !== -1) {
1809
+ let nextEditableColumnIndex = currentEditableColumnIndex + 1;
1810
+ let nextRowIndex = rowIndex;
1811
+ if (nextEditableColumnIndex >= editableColumns.length) {
1812
+ nextEditableColumnIndex = 0;
1647
1813
  nextRowIndex++;
1648
1814
  if (nextRowIndex >= filteredRows.length) {
1649
1815
  nextRowIndex = 0;
1650
- nextColumnIndex = 0;
1651
- if (filteredRows.length === 0 || rowIndex === filteredRows.length - 1 && currentColumnIndex === currentColumns.length - 1) {
1652
- foundNextTarget = true;
1653
- break;
1654
- }
1655
1816
  }
1656
1817
  }
1657
- const nextColumn = currentColumns[nextColumnIndex];
1658
- if (nextColumn) {
1659
- const fieldDefinition = tableDefinition.fields.find((f) => f.name === nextColumn.key);
1660
- const isEditableField = _optionalChain([fieldDefinition, 'optionalAccess', _13 => _13.editable]) !== false;
1661
- if (nextColumn.key !== "filterToggle" && nextColumn.key !== "deleteAction" && isEditableField) {
1662
- foundNextTarget = true;
1663
- } else {
1664
- nextColumnIndex++;
1665
- }
1666
- } else {
1667
- nextColumnIndex++;
1668
- }
1669
- }
1670
- if (foundNextTarget) {
1818
+ const nextColumnKey = editableColumnKeys[nextEditableColumnIndex];
1819
+ const nextColumnIndex = currentColumns.findIndex((col) => col.key === nextColumnKey);
1671
1820
  dataGridRef.current.selectCell({ rowIdx: nextRowIndex, idx: nextColumnIndex }, { enableEditor: false, scrollIntoView: true });
1672
1821
  }
1673
1822
  }
@@ -1676,185 +1825,87 @@ var GenericDataGrid = ({
1676
1825
  const columns = _react.useMemo.call(void 0, () => {
1677
1826
  if (!tableDefinition) return [];
1678
1827
  const fieldsToShow = tableDefinition.fields.filter((field) => {
1679
- const fixedFieldEntry = _optionalChain([fixedFields, 'optionalAccess', _14 => _14.find, 'call', _15 => _15((f) => f.fieldName === field.name)]);
1828
+ const fixedFieldEntry = _optionalChain([fixedFields, 'optionalAccess', _33 => _33.find, 'call', _34 => _34((f) => f.fieldName === field.name)]);
1680
1829
  return !(fixedFieldEntry && fixedFieldEntry.until === void 0);
1681
1830
  });
1682
- const defaultColumns = fieldsToShow.map((field) => {
1683
- const isFixedField = _optionalChain([fixedFields, 'optionalAccess', _16 => _16.some, 'call', _17 => _17((f) => f.fieldName === field.name)]);
1684
- const isFieldEditable = field.editable !== false && !isFixedField;
1831
+ const defaultColumns = fieldsToShow.map((fieldDef) => {
1832
+ const isFixedField = _optionalChain([fixedFields, 'optionalAccess', _35 => _35.some, 'call', _36 => _36((f) => f.fieldName === fieldDef.name)]);
1833
+ const isFieldEditable = fieldDef.editable !== false && !isFixedField;
1685
1834
  return {
1686
- key: field.name,
1687
- name: field.label || cambiarGuionesBajosPorEspacios(field.name),
1835
+ key: fieldDef.name,
1836
+ customType: "default",
1837
+ tableDefinition,
1838
+ fieldDef,
1839
+ cellFeedback,
1840
+ primaryKey,
1841
+ fixedFields,
1842
+ localCellChanges,
1843
+ name: fieldDef.label || cambiarGuionesBajosPorEspacios(fieldDef.name),
1688
1844
  resizable: true,
1689
1845
  sortable: true,
1846
+ //frozen: true,
1690
1847
  editable: isFieldEditable,
1691
- // Usar la nueva bandera de editable
1692
1848
  flexGrow: 1,
1693
1849
  minWidth: 60,
1694
- isPK: field.isPk,
1695
- renderHeaderCell: (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PkHeaderRenderer_default, { ...props }),
1696
- renderSummaryCell: ({ column }) => {
1697
- const fixedFieldEntry = _optionalChain([fixedFields, 'optionalAccess', _18 => _18.find, 'call', _19 => _19((f) => f.fieldName === column.key)]);
1698
- if (fixedFieldEntry && fixedFieldEntry.until === void 0) return null;
1699
- return isFilterRowVisible ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1700
- FilterInputRender_default,
1701
- {
1702
- column,
1703
- filters,
1704
- setFilters
1705
- }
1706
- ) : null;
1707
- },
1708
- renderCell: (props) => {
1709
- const rowId = getPrimaryKeyValues(props.row, primaryKey);
1710
- const fieldDefinition = tableDefinition.fields.find((f) => f.name === props.column.key);
1711
- if (_optionalChain([fieldDefinition, 'optionalAccess', _20 => _20.clientSide])) {
1712
- const ClientSideComponent = clientSides[fieldDefinition.clientSide];
1713
- if (ClientSideComponent) {
1714
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1715
- ClientSideComponent,
1716
- {
1717
- ...props,
1718
- fieldDefinition,
1719
- tableDefinition,
1720
- primaryKey
1721
- }
1722
- );
1723
- } else {
1724
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1725
- FallbackClientSideRenderer_default,
1726
- {
1727
- ...props,
1728
- fieldDefinition,
1729
- tableDefinition,
1730
- primaryKey
1731
- }
1732
- );
1733
- }
1734
- }
1735
- let cellBackgroundColor = "transparent";
1736
- if (cellFeedback && cellFeedback.rowId === rowId && cellFeedback.columnKey === props.column.key) {
1737
- cellBackgroundColor = cellFeedback.type === "error" ? theme.palette.error.light : theme.palette.success.light;
1738
- } else {
1739
- const isNewRowLocalCheck = props.row[NEW_ROW_INDICATOR];
1740
- const isMandatory = tableDefinition.primaryKey.includes(props.column.key) || _optionalChain([tableDefinition, 'access', _21 => _21.fields, 'access', _22 => _22.find, 'call', _23 => _23((f) => f.name === props.column.key), 'optionalAccess', _24 => _24.nullable]) === false;
1741
- const hasValue = props.row[props.column.key] !== null && props.row[props.column.key] !== void 0 && String(props.row[props.column.key]).trim() !== "";
1742
- const isFixedFieldCurrent = _optionalChain([fixedFields, 'optionalAccess', _25 => _25.some, 'call', _26 => _26((f) => f.fieldName === props.column.key)]);
1743
- if (isFixedFieldCurrent) {
1744
- cellBackgroundColor = theme.palette.action.selected;
1745
- } else if (isNewRowLocalCheck && isMandatory && !hasValue || localCellChanges.has(rowId) && _optionalChain([localCellChanges, 'access', _27 => _27.get, 'call', _28 => _28(rowId), 'optionalAccess', _29 => _29.has, 'call', _30 => _30(props.column.key)])) {
1746
- cellBackgroundColor = theme.palette.info.light;
1747
- }
1748
- }
1749
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1750
- _material.Box,
1751
- {
1752
- sx: {
1753
- position: "absolute",
1754
- top: 0,
1755
- left: 0,
1756
- width: "100%",
1757
- height: "100%",
1758
- backgroundColor: cellBackgroundColor,
1759
- transition: "background-color 0.3s ease-in-out",
1760
- display: "flex",
1761
- alignItems: "center",
1762
- paddingLeft: "8px",
1763
- boxSizing: "border-box"
1764
- },
1765
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1766
- PkCellRenderer_default,
1767
- {
1768
- ...props,
1769
- column: { ...props.column, isPK: !!field.isPk }
1770
- }
1771
- )
1772
- }
1773
- );
1774
- }
1850
+ renderHeaderCell: (props) => defaultColumnHeaderCellRenderer(props, fieldDef),
1851
+ renderSummaryCell: (props) => defaultColumnSummaryCellRenderer(props, fixedFields, isFilterRowVisible, filters, setFilters)
1775
1852
  };
1776
1853
  });
1777
- const filterToggleColumn = {
1854
+ const actionsColumn = {
1778
1855
  key: "filterToggle",
1779
- name: "",
1856
+ customType: "action",
1857
+ tableDefinition,
1858
+ handleDeleteRow,
1859
+ name: "filterCol",
1780
1860
  width: 50,
1781
1861
  resizable: false,
1782
1862
  sortable: false,
1783
- frozen: true,
1784
- renderHeaderCell: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1785
- _material.IconButton,
1786
- {
1787
- color: "inherit",
1788
- onClick: toggleFilterVisibility,
1789
- size: "small",
1790
- title: isFilterRowVisible ? "Ocultar filtros" : "Mostrar filtros",
1791
- sx: { p: 0.5 },
1792
- children: isFilterRowVisible ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _SearchOff2.default, { sx: { fontSize: 20 } }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Search2.default, { sx: { fontSize: 20 } })
1793
- }
1794
- ),
1795
- renderSummaryCell: () => null
1863
+ //frozen: true,
1864
+ renderHeaderCell: (props) => actionsColumnHeaderCellRenderer(props, isFilterRowVisible, toggleFilterVisibility),
1865
+ renderSummaryCell: (props) => actionsColumnSummaryCellRenderer(props)
1796
1866
  };
1797
- const deleteActionColumn = {
1798
- key: "deleteAction",
1799
- name: "",
1800
- width: 50,
1801
- resizable: false,
1802
- sortable: false,
1803
- frozen: true,
1804
- renderHeaderCell: () => null,
1805
- renderSummaryCell: () => null,
1806
- renderCell: ({ row }) => {
1807
- if (!_optionalChain([tableDefinition, 'access', _31 => _31.allow, 'optionalAccess', _32 => _32.delete])) {
1808
- return null;
1809
- }
1810
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1811
- _material.Button,
1812
- {
1813
- variant: "outlined",
1814
- color: "error",
1815
- size: "small",
1816
- onClick: () => handleDeleteRow(row),
1817
- title: "Eliminar fila",
1818
- sx: {
1819
- minWidth: 35,
1820
- height: 30,
1821
- p: 0.5,
1822
- "& .MuiButton-startIcon": { m: 0 }
1823
- }
1867
+ const detailColumns = [];
1868
+ if (tableDefinition.detailTables && tableDefinition.detailTables.length > 0) {
1869
+ tableDefinition.detailTables.forEach((detailTable) => {
1870
+ const detailKey = `detail_${detailTable.abr}`;
1871
+ detailColumns.push({
1872
+ key: detailKey,
1873
+ customType: "detail",
1874
+ tableDefinition,
1875
+ detailTable,
1876
+ primaryKey,
1877
+ tableData,
1878
+ setTableData,
1879
+ detailKey,
1880
+ name: detailTable.label || `Detalle ${detailTable.abr}`,
1881
+ resizable: false,
1882
+ sortable: false,
1883
+ width: 50,
1884
+ //frozen: true,
1885
+ renderHeaderCell: (props) => detailColumnCellHeaderRenderer(props, detailTable),
1886
+ renderSummaryCell: (props) => detailColumnCellSummaryRenderer(props)
1887
+ });
1888
+ });
1889
+ }
1890
+ const allColumns = [
1891
+ actionsColumn,
1892
+ ...detailColumns,
1893
+ ...defaultColumns
1894
+ ];
1895
+ return allColumns.map((col) => ({
1896
+ ...col,
1897
+ colSpan: (args) => {
1898
+ if (args.type === "ROW") {
1899
+ const detailTableAbr = args.row[DETAIL_ROW_INDICATOR];
1900
+ if (col.key === `detail_${detailTableAbr}`) {
1901
+ return allColumns.length;
1824
1902
  }
1825
- ) });
1826
- }
1827
- };
1828
- const allColumns = [filterToggleColumn, deleteActionColumn, ...defaultColumns];
1829
- return allColumns.map((col) => {
1830
- if (col.editable) {
1831
- const fieldDefinition = tableDefinition.fields.find((f) => f.name === col.key);
1832
- const isFixedField = _optionalChain([fixedFields, 'optionalAccess', _33 => _33.some, 'call', _34 => _34((f) => f.fieldName === col.key)]);
1833
- const isFieldEditableByUI = _optionalChain([fieldDefinition, 'optionalAccess', _35 => _35.editable]) !== false && !isFixedField;
1834
- if (!isFieldEditableByUI) {
1835
- return { ...col, renderEditCell: void 0 };
1836
1903
  }
1837
- return {
1838
- ...col,
1839
- renderEditCell: (props) => {
1840
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1841
- InputRendered_default,
1842
- {
1843
- ...props,
1844
- tableDefinition,
1845
- setCellFeedback,
1846
- onEnterPress: (rowIndex, columnKey) => handleEnterKeyPressInEditor(rowIndex, columnKey, allColumns),
1847
- setTableData,
1848
- setLocalCellChanges,
1849
- localCellChanges,
1850
- primaryKey
1851
- }
1852
- );
1853
- }
1854
- };
1855
- }
1856
- return col;
1857
- });
1904
+ return void 0;
1905
+ },
1906
+ renderEditCell: (props) => defaultColumnEditCellRenderer(props, tableDefinition, fixedFields, primaryKey, setCellFeedback, setTableData, localCellChanges, setLocalCellChanges, handleEnterKeyPressInEditor, allColumns),
1907
+ renderCell: (props) => allColumnsCellRenderer(props)
1908
+ }));
1858
1909
  }, [
1859
1910
  tableDefinition,
1860
1911
  isFilterRowVisible,
@@ -1866,22 +1917,20 @@ var GenericDataGrid = ({
1866
1917
  theme.palette.error.light,
1867
1918
  theme.palette.info.light,
1868
1919
  theme.palette.action.selected,
1869
- // Añade el color de campos fijos
1870
1920
  handleEnterKeyPressInEditor,
1871
1921
  setTableData,
1872
1922
  localCellChanges,
1873
1923
  handleDeleteRow,
1874
- fixedFields
1875
- // Añade fixedFields como dependencia
1924
+ fixedFields,
1925
+ tableData
1876
1926
  ]);
1877
- const showNoRowsMessage = filteredRows.length === 0 && !loading && !error;
1878
1927
  const handleRowsChange = _react.useCallback.call(void 0, (updatedRows) => {
1879
1928
  setTableData(updatedRows);
1880
1929
  }, []);
1881
1930
  const handleCellClick = _react.useCallback.call(void 0, (args) => {
1882
- const fieldDefinition = _optionalChain([tableDefinition, 'optionalAccess', _36 => _36.fields, 'access', _37 => _37.find, 'call', _38 => _38((f) => f.name === args.column.key)]);
1883
- const isFixedField = _optionalChain([fixedFields, 'optionalAccess', _39 => _39.some, 'call', _40 => _40((f) => f.fieldName === args.column.key)]);
1884
- const isEditable = _optionalChain([fieldDefinition, 'optionalAccess', _41 => _41.editable]) !== false && !isFixedField;
1931
+ const fieldDefinition = _optionalChain([tableDefinition, 'optionalAccess', _37 => _37.fields, 'access', _38 => _38.find, 'call', _39 => _39((f) => f.name === args.column.key)]);
1932
+ const isFixedField = _optionalChain([fixedFields, 'optionalAccess', _40 => _40.some, 'call', _41 => _41((f) => f.fieldName === args.column.key)]);
1933
+ const isEditable = _optionalChain([fieldDefinition, 'optionalAccess', _42 => _42.editable]) !== false && !isFixedField;
1885
1934
  console.log("Clicked column index:", args.column.idx);
1886
1935
  console.log("Clicked row index:", args.rowIdx);
1887
1936
  console.log("Is editable:", isEditable);
@@ -1898,9 +1947,8 @@ var GenericDataGrid = ({
1898
1947
  if (!tableDefinition) {
1899
1948
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "200px", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Alert, { severity: "warning", children: "No se pudo cargar la definici\xF3n de la tabla." }) });
1900
1949
  }
1901
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _material.Box, { sx: { p: 0, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box" }, children: [
1902
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", px: 2, pt: 2, pb: 1 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "h4", gutterBottom: true, sx: { m: 0 }, children: cambiarGuionesBajosPorEspacios(tableDefinition.title || tableDefinition.name) }) }),
1903
- _optionalChain([tableDefinition, 'access', _42 => _42.allow, 'optionalAccess', _43 => _43.insert]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { display: "flex", px: 2 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1950
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _material.Box, { sx: { pt: 2, display: "flex", flexDirection: "column", height: "100%", boxSizing: "border-box" }, children: [
1951
+ _optionalChain([tableDefinition, 'access', _43 => _43.allow, 'optionalAccess', _44 => _44.insert]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { display: "flex", px: 2, pb: 1 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1904
1952
  _material.Button,
1905
1953
  {
1906
1954
  variant: "contained",
@@ -1909,19 +1957,33 @@ var GenericDataGrid = ({
1909
1957
  children: "Nuevo Registro"
1910
1958
  }
1911
1959
  ) }),
1912
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Box, { sx: { px: 2, pt: 2, pb: 1, fontSize: "0.9rem" }, children: filteredRows.length === tableData.length ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _material.Box, { children: [
1913
- "mostrando ",
1914
- `${tableData.length} registros`
1915
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _material.Box, { children: [
1916
- "mostrando ",
1917
- `${filteredRows.length} registros filtrados`
1918
- ] }) }) }),
1919
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1960
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1920
1961
  _material.Box,
1921
1962
  {
1922
1963
  sx: {
1923
- flexGrow: showNoRowsMessage ? 0 : 1,
1924
- height: showNoRowsMessage ? "150px" : "100%",
1964
+ backgroundColor: theme.palette.primary.main,
1965
+ color: theme.palette.primary.contrastText,
1966
+ padding: theme.spacing(1),
1967
+ textAlign: "left",
1968
+ fontWeight: "bold",
1969
+ borderBottom: `1px solid ${theme.palette.divider}`,
1970
+ borderTopLeftRadius: theme.shape.borderRadius,
1971
+ borderTopRightRadius: theme.shape.borderRadius,
1972
+ ml: 2,
1973
+ mr: 2
1974
+ },
1975
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _material.Typography, { variant: "subtitle1", component: "div", children: [
1976
+ cambiarGuionesBajosPorEspacios(tableDefinition.title || tableDefinition.name),
1977
+ " - mostrando ",
1978
+ getFilteredRowCount() === getRowCount() ? `${getRowCount()} registros` : `${getFilteredRowCount()} registros filtrados`
1979
+ ] })
1980
+ }
1981
+ ),
1982
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1983
+ _material.Box,
1984
+ {
1985
+ sx: {
1986
+ flexGrow: 1,
1925
1987
  boxSizing: "border-box",
1926
1988
  position: "relative",
1927
1989
  overflowX: "auto",
@@ -1929,51 +1991,29 @@ var GenericDataGrid = ({
1929
1991
  px: 2,
1930
1992
  pb: 2
1931
1993
  },
1932
- children: [
1933
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1934
- _reactdatagrid.DataGrid,
1935
- {
1936
- ref: dataGridRef,
1937
- columns,
1938
- rows: filteredRows.map((row) => ({
1939
- ...row,
1940
- style: exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? { maxHeight: 0, opacity: 0, overflow: "hidden" } : { maxHeight: "35px", opacity: 1 }
1941
- })),
1942
- enableVirtualization: true,
1943
- rowKeyGetter: (row) => getPrimaryKeyValues(row, primaryKey),
1944
- onSelectedRowsChange: setSelectedRows,
1945
- onRowsChange: handleRowsChange,
1946
- selectedRows,
1947
- rowHeight: (row) => exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? 0 : 35,
1948
- style: { height: "100%", width: "100%", boxSizing: "border-box" },
1949
- headerRowHeight: 35,
1950
- topSummaryRows: isFilterRowVisible ? [{ id: "filterRow" }] : void 0,
1951
- summaryRowHeight: isFilterRowVisible ? 35 : 0,
1952
- onCellClick: handleCellClick
1953
- }
1954
- ),
1955
- showNoRowsMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1956
- _material.Box,
1957
- {
1958
- sx: {
1959
- position: "absolute",
1960
- top: isFilterRowVisible ? "70px" : "36px",
1961
- left: (theme2) => theme2.spacing(2),
1962
- right: (theme2) => theme2.spacing(2),
1963
- bottom: (theme2) => theme2.spacing(2),
1964
- display: "flex",
1965
- justifyContent: "center",
1966
- alignItems: "center",
1967
- backgroundColor: "rgba(255, 255, 255, 0.9)",
1968
- color: (theme2) => theme2.palette.text.secondary,
1969
- border: (theme2) => `1px solid ${theme2.palette.divider}`,
1970
- borderRadius: "4px",
1971
- zIndex: 1
1972
- },
1973
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "h6", children: "No hay filas para mostrar." })
1974
- }
1975
- )
1976
- ]
1994
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1995
+ _reactdatagrid.DataGrid,
1996
+ {
1997
+ ref: dataGridRef,
1998
+ columns,
1999
+ rows: filteredRows.map((row) => ({
2000
+ ...row,
2001
+ style: exitingRowIds.has(getPrimaryKeyValues(row, primaryKey)) ? { maxHeight: 0, opacity: 0, overflow: "hidden" } : { maxHeight: "35px", opacity: 1 }
2002
+ })),
2003
+ enableVirtualization: true,
2004
+ rowKeyGetter: (row) => getPrimaryKeyValues(row, primaryKey),
2005
+ onSelectedRowsChange: setSelectedRows,
2006
+ onRowsChange: handleRowsChange,
2007
+ selectedRows,
2008
+ rowHeight: (row) => row[DETAIL_ROW_INDICATOR] ? 400 : 35,
2009
+ style: { height: "100%", width: "100%", boxSizing: "border-box" },
2010
+ headerRowHeight: 35,
2011
+ topSummaryRows: isFilterRowVisible ? [{ id: "filterRow" }] : void 0,
2012
+ summaryRowHeight: isFilterRowVisible ? 35 : 0,
2013
+ onCellClick: handleCellClick,
2014
+ renderers: { noRowsFallback: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EmptyRowsRenderer, {}) }
2015
+ }
2016
+ )
1977
2017
  }
1978
2018
  ),
1979
2019
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -2510,7 +2550,7 @@ var SessionExpiredMessage_default = SessionExpiredMessage;
2510
2550
  var HomePage = () => {
2511
2551
  const { clientContext } = useApp();
2512
2552
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _material.Box, { sx: { p: 3 }, children: [
2513
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "h4", component: "h1", gutterBottom: true, children: `Bienvenido/a ${_optionalChain([clientContext, 'optionalAccess', _44 => _44.username])}` }),
2553
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "h4", component: "h1", gutterBottom: true, children: `Bienvenido/a ${_optionalChain([clientContext, 'optionalAccess', _45 => _45.username])}` }),
2514
2554
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.Typography, { variant: "body1", children: "Usa el men\xFA lateral para navegar por las diferentes secciones." })
2515
2555
  ] });
2516
2556
  };
@@ -2639,7 +2679,7 @@ var LoginPage = () => {
2639
2679
  fullWidth: true,
2640
2680
  margin: "normal",
2641
2681
  error: !!errors.username,
2642
- helperText: _optionalChain([errors, 'access', _45 => _45.username, 'optionalAccess', _46 => _46.message]),
2682
+ helperText: _optionalChain([errors, 'access', _46 => _46.username, 'optionalAccess', _47 => _47.message]),
2643
2683
  disabled: isSubmitting
2644
2684
  }
2645
2685
  )
@@ -2662,7 +2702,7 @@ var LoginPage = () => {
2662
2702
  fullWidth: true,
2663
2703
  margin: "normal",
2664
2704
  error: !!errors.password,
2665
- helperText: _optionalChain([errors, 'access', _47 => _47.password, 'optionalAccess', _48 => _48.message]),
2705
+ helperText: _optionalChain([errors, 'access', _48 => _48.password, 'optionalAccess', _49 => _49.message]),
2666
2706
  disabled: isSubmitting
2667
2707
  }
2668
2708
  )
@@ -2740,7 +2780,7 @@ var ProcedureForm = () => {
2740
2780
  const [executionLog, setExecutionLog] = _react.useState.call(void 0, []);
2741
2781
  const [procedureResultData, setProcedureResultData] = _react.useState.call(void 0, null);
2742
2782
  const procedure = _react.useMemo.call(void 0, () => {
2743
- if (procedureName && _optionalChain([clientContext, 'optionalAccess', _49 => _49.procedure])) {
2783
+ if (procedureName && _optionalChain([clientContext, 'optionalAccess', _50 => _50.procedure])) {
2744
2784
  return clientContext.procedure[procedureName];
2745
2785
  }
2746
2786
  return void 0;
@@ -3031,7 +3071,7 @@ var ProcedureForm = () => {
3031
3071
  }
3032
3072
  }, [formValues, handleChange, apiLoading, validationErrors]);
3033
3073
  const ResultDisplayContent = _react.useMemo.call(void 0, () => {
3034
- if (!procedureResultData || !_optionalChain([procedure, 'optionalAccess', _50 => _50.resultOk])) return null;
3074
+ if (!procedureResultData || !_optionalChain([procedure, 'optionalAccess', _51 => _51.resultOk])) return null;
3035
3075
  const ComponentToRender = resultsOk[procedure.resultOk];
3036
3076
  if (ComponentToRender) {
3037
3077
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ComponentToRender, { data: procedureResultData });