dmencu 2.2.8 → 2.2.10

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.
@@ -6,7 +6,8 @@ import {
6
6
  ICON,
7
7
  scrollToTop,
8
8
  materialIoIconsSvgPath,
9
- useOnlineStatus
9
+ useOnlineStatus,
10
+ RenderizadorJSON
10
11
  } from "./render-general";
11
12
  import {
12
13
  Bloque, BotonFormulario,
@@ -1144,6 +1145,7 @@ var botonFormularioConResumen = (
1144
1145
  className: "boton-borrar-ua-vacia",
1145
1146
  color: "default",
1146
1147
  variant: "outlined",
1148
+ style: { marginLeft: '8px' },
1147
1149
  children:
1148
1150
  html.svg({ focusable: false, viewbox: "0 0 24 24", "aria-hidden": "true", style: styleToCss({ fill: "currentColor" }) }, [
1149
1151
  html.path({ d: materialIoIconsSvgPath.DeleteForever, style: styleToCss({ fill: 'currentColor' }) })
@@ -1444,7 +1446,7 @@ function BotonFormularioDespliegue(props: { casillero: BotonFormulario, formular
1444
1446
  <DialogTitle>Advertencia: Se perderán datos</DialogTitle>
1445
1447
  <DialogContent>
1446
1448
  <DialogContentText>
1447
- Está por borrar un formulario que no cumple las condiciones habituales de borrado. Los datos a continuación y todos sus registros asociados se perderán por completo. ¿Desea continuar?
1449
+ Está por borrar un formulario. Los datos del mismo y todos sus registros asociados se perderán. ¿Desea continuar?
1448
1450
  </DialogContentText>
1449
1451
 
1450
1452
  <div style={{ marginTop: '20px', marginBottom: '20px' }}>
@@ -1467,9 +1469,9 @@ function BotonFormularioDespliegue(props: { casillero: BotonFormulario, formular
1467
1469
  </div>
1468
1470
 
1469
1471
  <Typography variant="h6" style={{ marginTop: '10px', fontWeight: 'bold' }}>Datos que se perderán:</Typography>
1470
- <pre style={{maxWidth: '100%', overflowX: 'auto', background: '#f5f5f5', padding: '10px', marginTop: '10px', marginBottom: '20px'}}>
1471
- {JSON.stringify(confirmacionBorrado.datos, null, 2)}
1472
- </pre>
1472
+ <div style={{ maxWidth: '600px', margin: '0 auto', fontFamily: 'sans-serif' }}>
1473
+ <RenderizadorJSON datos={confirmacionBorrado.datos} />
1474
+ </div>
1473
1475
  </DialogContent>
1474
1476
  <DialogActions>
1475
1477
  <Button
@@ -132,6 +132,108 @@ export function focusToId(id: string, opts: FocusOpts, cb?: (e: HTMLElement) =>
132
132
 
133
133
  export type IDispatchers = { RESET_OPCIONES: Function };
134
134
 
135
+ function getBadgeStyle(estado: string): React.CSSProperties {
136
+ const base: React.CSSProperties = {
137
+ padding: '2px 6px',
138
+ borderRadius: '4px',
139
+ fontSize: '11px',
140
+ fontWeight: 'bold',
141
+ display: 'inline-block',
142
+ textTransform: 'uppercase'
143
+ };
144
+ if (estado === 'ok') return { ...base, backgroundColor: '#c6f6d5', color: '#22543d' };
145
+ if (estado === 'incompleto' || estado === 'con problemas') return { ...base, backgroundColor: '#feebc8', color: '#744210' };
146
+ return { ...base, backgroundColor: '#edf2f7', color: '#4a5568' };
147
+ }
148
+ interface RenderizadorJSONProps {
149
+ datos: Record<string, any>;
150
+ nivel?: number;
151
+ }
152
+
153
+ export const RenderizadorJSON: React.FC<RenderizadorJSONProps> = ({ datos, nivel = 0 }) => {
154
+
155
+ const clavesFiltradas = Object.keys(datos).filter(
156
+ clave => !clave.startsWith('$') && clave !== 'timestampEstructura'
157
+ );
158
+
159
+ return (
160
+ <div style={{ paddingLeft: nivel > 0 ? '16px' : '0px' }}>
161
+ {clavesFiltradas.map(clave => {
162
+ const valor = datos[clave];
163
+
164
+ // DETECCIÓN DE SUB-UNIDADES DE ANÁLISIS (hogares, personas, etc.)
165
+ if (Array.isArray(valor) && valor.length > 0 && typeof valor[0] === 'object') {
166
+ return (
167
+ <div
168
+ key={clave}
169
+ style={{
170
+ margin: '12px 0',
171
+ borderLeft: '4px solid #3182ce',
172
+ backgroundColor: '#f7fafc',
173
+ borderRadius: '0 6px 6px 0',
174
+ padding: '8px 12px'
175
+ }}
176
+ >
177
+ {/* Título de la UA */}
178
+ <div style={{ fontWeight: 'bold', color: '#2b6cb0', fontSize: '13px', textTransform: 'uppercase', marginBottom: '6px' }}>
179
+ Unidad de Análisis: {clave} ({valor.length})
180
+ </div>
181
+
182
+ {valor.map((registro, filaIndex) => (
183
+ <div
184
+ key={filaIndex}
185
+ style={{
186
+ marginBottom: filaIndex < valor.length - 1 ? '10px' : '0',
187
+ paddingTop: filaIndex > 0 ? '6px' : '0',
188
+ borderTop: filaIndex > 0 ? '1px dashed #e2e8f0' : 'none'
189
+ }}
190
+ >
191
+ <RenderizadorJSON datos={registro} nivel={nivel + 1} />
192
+ </div>
193
+ ))}
194
+ </div>
195
+ );
196
+ }
197
+
198
+ // Si por las dudas es un objeto directo que no es array, lo salteamos
199
+ if (typeof valor === 'object' && valor !== null) return null;
200
+
201
+ // VARIABLES ESTÁNDAR (Clave y valor juntos)
202
+ return (
203
+ <div
204
+ key={clave}
205
+ style={{
206
+ display: 'flex',
207
+ flexDirection: 'row',
208
+ flexWrap: 'wrap', // Por si el valor es muy largo, que baje limpio
209
+ padding: '4px 0',
210
+ fontSize: '13px',
211
+ alignItems: 'center',
212
+ lineHeight: '1.4'
213
+ }}
214
+ >
215
+ {/* Clave: ahora sin ancho fijo, se adapta al texto */}
216
+ <div style={{ color: '#4a5568', fontWeight: 500, marginRight: '6px' }}>
217
+ {clave}:
218
+ </div>
219
+
220
+ {/* Valor: pegado inmediatamente a la clave */}
221
+ <div style={{ color: '#1a202c', fontWeight: 600 }}>
222
+ {clave.startsWith('resumenEstado') ? (
223
+ <span style={getBadgeStyle(String(valor))}>
224
+ {String(valor)}
225
+ </span>
226
+ ) : (
227
+ String(valor ?? '')
228
+ )}
229
+ </div>
230
+ </div>
231
+ );
232
+ })}
233
+ </div>
234
+ );
235
+ };
236
+
135
237
  export function ReseterForm(props: { onTryAgain: () => void, dispatchers: IDispatchers, mensaje: string }) {
136
238
  const dispatch = useDispatch();
137
239
  return <>
@@ -172,6 +172,7 @@ export declare function verificarSorteo(opts: {
172
172
  forPk: ForPk;
173
173
  variableActual: IdVariable;
174
174
  }): void;
175
+ export declare function recalcularTodoElArbol(respuestasRaiz: RespuestasRaiz, forPkRaiz: ForPk): void;
175
176
  export declare function calcularFeedbackUnidadAnalisis(feedbackRowValidator: {
176
177
  [formulario in PlainForPk]: FormStructureState<IdVariable, Valor, IdFin>;
177
178
  }, formularios: {