aarnal80 commited on
Commit
315da52
·
verified ·
1 Parent(s): 7b53631

Update js/main.js

Browse files
Files changed (1) hide show
  1. js/main.js +226 -40
js/main.js CHANGED
@@ -1,92 +1,278 @@
1
  // js/main.js
2
- import { renderIaConfigForm, transcriptionProviders } from './iaConfigModule.js';
 
 
3
  import { initRecorder } from './recordingModule.js';
4
  import { analyzeMedical } from './analysisModule.js';
5
  import { copyText } from './clipboardModule.js';
 
 
 
6
 
 
7
  window.addEventListener('DOMContentLoaded', () => {
 
 
 
 
 
 
 
 
8
  function updateModelLabels() {
9
- const cfg = JSON.parse(localStorage.getItem('iaConfig'));
10
- const transModel = cfg?.transcription?.models?.[cfg.transcription.provider] || '';
11
- const llmModel = cfg?.llm?.model || '';
 
 
 
 
12
  const transLabel = document.getElementById('trans-model-label');
13
  if (transLabel) transLabel.textContent = transModel ? `(${transModel})` : '';
 
 
14
  const analysisLabel = document.getElementById('analysis-model-label');
15
  if (analysisLabel) analysisLabel.textContent = llmModel ? `(${llmModel})` : '';
 
 
 
 
16
  }
 
17
  updateModelLabels();
 
18
  document.addEventListener('iaConfigChanged', updateModelLabels);
 
19
 
20
- // Elements
 
21
  const btnConfig = document.getElementById('btnConfig');
22
  const modal = document.getElementById('configModal');
 
 
 
23
  const transcriptEl = document.getElementById('transcript');
24
  const outputEnfermedadEl = document.getElementById('output-enfermedad');
25
  const outputExploracionEl = document.getElementById('output-exploracion');
26
- let iaConfig = renderIaConfigForm('iaConfigContainer'); // render initial form, returns config if modified
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- // Open modal and render form
 
 
 
 
29
  btnConfig.addEventListener('click', () => {
30
- renderIaConfigForm('iaConfigContainer');
31
  modal.classList.add('active');
32
  });
33
- // Close modal clicking outside or on close button (handled in module)
34
  modal.addEventListener('mousedown', e => {
35
  if (e.target === modal) modal.classList.remove('active');
36
  });
 
37
 
38
- // Análisis médico automático tras recibir transcripción usando módulo local
 
39
  document.addEventListener('transcriptionReady', async e => {
 
 
 
 
 
 
 
40
  try {
41
- const result = await analyzeMedical(e.detail);
42
- // Dividir en dos párrafos y mostrar en UI
43
- const sections = result.split(/\n\s*\n/);
44
- outputEnfermedadEl.textContent = sections[0] || '';
45
- outputExploracionEl.textContent = sections[1] || '';
46
  } catch (err) {
47
- console.error(err);
48
- alert('Error en análisis médico');
 
 
49
  }
50
  });
51
 
52
- // Initialize recorder
53
- const btnStart = document.getElementById('btnStart');
54
- const btnStop = document.getElementById('btnStop');
55
- const transcript = transcriptEl;
56
- function getProvider() {
57
- const cfg = JSON.parse(localStorage.getItem('iaConfig'));
58
- if (cfg && cfg.transcription && cfg.transcription.provider) {
59
- const prov = transcriptionProviders.find(p => p.value === cfg.transcription.provider);
60
- if (prov && prov.url) return prov.url;
61
  }
62
- alert('Debes configurar un proveedor de transcripción primero.');
63
- return '';
 
64
  }
65
- initRecorder({ btnStart, btnStop, transcriptEl: transcript, getProvider });
 
 
 
 
 
 
66
 
67
- // Copiar transcripción
68
- const btnCopyTranscript = document.getElementById('btnCopyTranscript');
69
  if (btnCopyTranscript) {
70
  btnCopyTranscript.addEventListener('click', async () => {
71
  try {
72
  await copyText(transcriptEl.value);
73
- console.log('Transcripción copiada al portapapeles');
74
- } catch {
75
- console.error('Error al copiar transcripción');
 
 
 
 
 
76
  }
77
  });
78
  }
79
- // Copiar análisis médico
80
- const btnCopyAnalysis = document.getElementById('btnCopyAnalysis');
81
  if (btnCopyAnalysis) {
82
  btnCopyAnalysis.addEventListener('click', async () => {
83
  try {
84
  const text = `${outputEnfermedadEl.textContent}\n\n${outputExploracionEl.textContent}`;
85
  await copyText(text);
86
- console.log('Análisis médico copiado al portapapeles');
87
- } catch {
88
- console.error('Error al copiar análisis médico');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
90
  });
91
  }
92
- });
 
 
 
1
  // js/main.js
2
+
3
+ // --- INICIO: Importaciones de Módulos ---
4
+ import { renderIaConfigForm, transcriptionProviders, getIaConfig } from './iaConfigModule.js'; // Añadido getIaConfig
5
  import { initRecorder } from './recordingModule.js';
6
  import { analyzeMedical } from './analysisModule.js';
7
  import { copyText } from './clipboardModule.js';
8
+ // NUEVO: Importar funciones del módulo de análisis de laboratorio
9
+ import { analyzeLabResults, displayLabResults } from './labAnalysisModule.js';
10
+ // --- FIN: Importaciones de Módulos ---
11
 
12
+ // Esperar a que el DOM esté completamente cargado
13
  window.addEventListener('DOMContentLoaded', () => {
14
+
15
+ // --- INICIO: Variables y Estado Global (dentro del scope del DOMContentLoaded) ---
16
+ // Variable para guardar el último resultado completo del análisis de laboratorio (para re-filtrar)
17
+ let lastLabResultText = '';
18
+ // --- FIN: Variables y Estado Global ---
19
+
20
+ // --- INICIO: Función para Actualizar Etiquetas de Modelo ---
21
+ // Actualiza las etiquetas que muestran qué modelo IA se está usando
22
  function updateModelLabels() {
23
+ const cfg = getIaConfig(); // Usar la función importada para obtener config
24
+ const transProvider = cfg?.transcription?.provider;
25
+ const transModel = cfg?.transcription?.models?.[transProvider] || 'N/A';
26
+ const llmProvider = cfg?.llm?.provider;
27
+ const llmModel = cfg?.llm?.model || 'N/A'; // Usar el modelo LLM general
28
+
29
+ // Etiqueta modelo Transcripción
30
  const transLabel = document.getElementById('trans-model-label');
31
  if (transLabel) transLabel.textContent = transModel ? `(${transModel})` : '';
32
+
33
+ // Etiqueta modelo Análisis Médico
34
  const analysisLabel = document.getElementById('analysis-model-label');
35
  if (analysisLabel) analysisLabel.textContent = llmModel ? `(${llmModel})` : '';
36
+
37
+ // NUEVO: Etiqueta modelo Análisis Laboratorio
38
+ const labLabel = document.getElementById('lab-model-label');
39
+ if (labLabel) labLabel.textContent = llmModel ? `(${llmModel})` : '';
40
  }
41
+ // Llamada inicial para establecer las etiquetas
42
  updateModelLabels();
43
+ // Escuchar cambios en la config para actualizar etiquetas
44
  document.addEventListener('iaConfigChanged', updateModelLabels);
45
+ // --- FIN: Función para Actualizar Etiquetas de Modelo ---
46
 
47
+ // --- INICIO: Selección de Elementos DOM ---
48
+ // Configuración
49
  const btnConfig = document.getElementById('btnConfig');
50
  const modal = document.getElementById('configModal');
51
+ const iaConfigContainer = document.getElementById('iaConfigContainer');
52
+
53
+ // Pestaña Análisis Médico
54
  const transcriptEl = document.getElementById('transcript');
55
  const outputEnfermedadEl = document.getElementById('output-enfermedad');
56
  const outputExploracionEl = document.getElementById('output-exploracion');
57
+ const btnStart = document.getElementById('btnStart');
58
+ const btnStop = document.getElementById('btnStop');
59
+ const btnCopyTranscript = document.getElementById('btnCopyTranscript');
60
+ const btnCopyAnalysis = document.getElementById('btnCopyAnalysis');
61
+
62
+ // NUEVO: Elementos de Pestañas
63
+ const tabMedicalAnalysis = document.getElementById('tab-medical-analysis');
64
+ const tabLabAnalysis = document.getElementById('tab-lab-analysis');
65
+ const contentMedicalAnalysis = document.getElementById('content-medical-analysis');
66
+ const contentLabAnalysis = document.getElementById('content-lab-analysis');
67
+
68
+ // NUEVO: Elementos Pestaña Análisis de Exámenes
69
+ const labInputText = document.getElementById('lab-input-text');
70
+ const btnAnalyzeLabs = document.getElementById('btnAnalyzeLabs');
71
+ const labLoadingIndicator = document.getElementById('lab-loading-indicator');
72
+ const filterAlteredLabsCheckbox = document.getElementById('filterAlteredLabs');
73
+ const labResultsOutput = document.getElementById('lab-results-output');
74
+ const btnCopyLabResults = document.getElementById('btnCopyLabResults');
75
+ // --- FIN: Selección de Elementos DOM ---
76
 
77
+ // --- INICIO: Lógica Modal Configuración ---
78
+ // Renderizar formulario inicial (no debería modificar config aún)
79
+ renderIaConfigForm(iaConfigContainer);
80
+
81
+ // Abrir modal y renderizar formulario actualizado
82
  btnConfig.addEventListener('click', () => {
83
+ renderIaConfigForm(iaConfigContainer); // Re-renderizar al abrir por si algo cambió
84
  modal.classList.add('active');
85
  });
86
+ // Cerrar modal clicando fuera (manejado en módulo) o en botón X (manejado en módulo)
87
  modal.addEventListener('mousedown', e => {
88
  if (e.target === modal) modal.classList.remove('active');
89
  });
90
+ // --- FIN: Lógica Modal Configuración ---
91
 
92
+ // --- INICIO: Lógica Pestaña Análisis Médico (Transcripción y Análisis) ---
93
+ // Evento: Transcripción lista -> Iniciar Análisis Médico
94
  document.addEventListener('transcriptionReady', async e => {
95
+ const transcriptText = e.detail;
96
+ if (!transcriptText) return; // No analizar si no hay transcripción
97
+
98
+ // Limpiar análisis previo y mostrar estado (opcional)
99
+ outputEnfermedadEl.textContent = 'Analizando...';
100
+ outputExploracionEl.textContent = '';
101
+
102
  try {
103
+ const result = await analyzeMedical(transcriptText); // Llama al módulo de análisis
104
+ // Dividir en dos párrafos (o como esté estructurado) y mostrar en UI
105
+ const sections = result.split(/\n\s*\n/); // Asume división por doble salto de línea
106
+ outputEnfermedadEl.textContent = sections[0]?.trim() || '(No se generó Enfermedad Actual)';
107
+ outputExploracionEl.textContent = sections.slice(1).join('\n\n').trim() || '(No se generó Exploración/Actuación)';
108
  } catch (err) {
109
+ console.error("Error en análisis médico:", err);
110
+ outputEnfermedadEl.textContent = `Error en análisis: ${err.message}`;
111
+ outputExploracionEl.textContent = '';
112
+ alert(`Error en análisis médico: ${err.message}`); // Notificar al usuario
113
  }
114
  });
115
 
116
+ // Inicializar Grabadora de Audio
117
+ function getTranscriptionProviderUrl() { // Renombrado para claridad
118
+ const cfg = getIaConfig();
119
+ const providerValue = cfg?.transcription?.provider;
120
+ if (providerValue) {
121
+ const prov = transcriptionProviders.find(p => p.value === providerValue);
122
+ if (prov?.url) return prov.url;
 
 
123
  }
124
+ console.warn('No se pudo obtener la URL del proveedor de transcripción desde la configuración.');
125
+ alert('Configuración de transcripción incompleta. Por favor, configura un proveedor y API key.');
126
+ return ''; // Retornar vacío para prevenir error si no hay config
127
  }
128
+ // Pasar elementos y función para obtener URL del proveedor al módulo de grabación
129
+ initRecorder({
130
+ btnStart: btnStart,
131
+ btnStop: btnStop,
132
+ transcriptEl: transcriptEl,
133
+ getProvider: getTranscriptionProviderUrl // Pasar la función renombrada
134
+ });
135
 
136
+ // Copiar Transcripción
 
137
  if (btnCopyTranscript) {
138
  btnCopyTranscript.addEventListener('click', async () => {
139
  try {
140
  await copyText(transcriptEl.value);
141
+ console.log('Transcripción copiada');
142
+ // Feedback visual rápido (opcional)
143
+ const originalText = btnCopyTranscript.innerHTML;
144
+ btnCopyTranscript.innerHTML = '<i class="fas fa-check mr-2"></i>Copiado';
145
+ setTimeout(() => { btnCopyTranscript.innerHTML = originalText; }, 1500);
146
+ } catch (err) {
147
+ console.error('Error al copiar transcripción:', err);
148
+ alert('Error al copiar la transcripción.');
149
  }
150
  });
151
  }
152
+
153
+ // Copiar Análisis Médico
154
  if (btnCopyAnalysis) {
155
  btnCopyAnalysis.addEventListener('click', async () => {
156
  try {
157
  const text = `${outputEnfermedadEl.textContent}\n\n${outputExploracionEl.textContent}`;
158
  await copyText(text);
159
+ console.log('Análisis médico copiado');
160
+ // Feedback visual rápido (opcional)
161
+ const originalText = btnCopyAnalysis.innerHTML;
162
+ btnCopyAnalysis.innerHTML = '<i class="fas fa-check mr-2"></i>Copiado';
163
+ setTimeout(() => { btnCopyAnalysis.innerHTML = originalText; }, 1500);
164
+ } catch (err) {
165
+ console.error('Error al copiar análisis médico:', err);
166
+ alert('Error al copiar el análisis médico.');
167
+ }
168
+ });
169
+ }
170
+ // --- FIN: Lógica Pestaña Análisis Médico ---
171
+
172
+ // --- INICIO: Lógica de Cambio de Pestañas ---
173
+ function switchTab(event) {
174
+ // Obtener el botón de pestaña que fue clickeado
175
+ const clickedTab = event.currentTarget;
176
+ // Obtener el ID del contenido asociado desde el atributo data-target
177
+ const targetContentId = clickedTab.dataset.target;
178
+ const targetContent = document.getElementById(targetContentId);
179
+
180
+ // Si el target existe y no está ya activo
181
+ if (targetContent && !clickedTab.classList.contains('active')) {
182
+ // 1. Quitar 'active' de todos los botones de pestaña y contenidos
183
+ document.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active'));
184
+ document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
185
+
186
+ // 2. Añadir 'active' al botón clickeado y a su contenido asociado
187
+ clickedTab.classList.add('active');
188
+ targetContent.classList.add('active');
189
+
190
+ console.log(`Cambiado a pestaña: ${targetContentId}`);
191
+ }
192
+ }
193
+
194
+ // Añadir el event listener a cada botón de pestaña
195
+ if (tabMedicalAnalysis) tabMedicalAnalysis.addEventListener('click', switchTab);
196
+ if (tabLabAnalysis) tabLabAnalysis.addEventListener('click', switchTab);
197
+ // --- FIN: Lógica de Cambio de Pestañas ---
198
+
199
+ // --- INICIO: Lógica Pestaña Análisis de Exámenes ---
200
+ // Event Listener para el botón "Analizar Resultados"
201
+ if (btnAnalyzeLabs) {
202
+ btnAnalyzeLabs.addEventListener('click', async () => {
203
+ const inputText = labInputText.value;
204
+ if (!inputText.trim()) {
205
+ alert("Por favor, pega los resultados del laboratorio en el área de texto.");
206
+ return;
207
+ }
208
+
209
+ // Mostrar indicador de carga y deshabilitar controles
210
+ labLoadingIndicator.style.display = 'flex';
211
+ btnAnalyzeLabs.disabled = true;
212
+ filterAlteredLabsCheckbox.disabled = true;
213
+ labResultsOutput.innerHTML = ''; // Limpiar salida anterior
214
+ lastLabResultText = ''; // Limpiar resultado anterior guardado
215
+
216
+ try {
217
+ // Llamar al módulo para analizar
218
+ const resultText = await analyzeLabResults(inputText);
219
+ lastLabResultText = resultText; // Guardar resultado completo para filtrar después
220
+
221
+ // Obtener estado actual del filtro
222
+ const filterIsActive = filterAlteredLabsCheckbox.checked;
223
+ // Mostrar resultado (filtrado o completo)
224
+ displayLabResults(resultText, labResultsOutput, filterIsActive);
225
+ // Actualizar etiqueta del modelo usado
226
+ updateModelLabels();
227
+
228
+ } catch (error) {
229
+ console.error("Error en análisis de laboratorio:", error);
230
+ labResultsOutput.innerHTML = `<p class="text-red-600">Error al analizar: ${error.message}</p>`;
231
+ alert(`Error al analizar los resultados: ${error.message}`);
232
+ } finally {
233
+ // Ocultar indicador de carga y habilitar controles
234
+ labLoadingIndicator.style.display = 'none';
235
+ btnAnalyzeLabs.disabled = false;
236
+ filterAlteredLabsCheckbox.disabled = false;
237
+ }
238
+ });
239
+ }
240
+
241
+ // Event Listener para el checkbox "Mostrar solo alterados"
242
+ if (filterAlteredLabsCheckbox) {
243
+ filterAlteredLabsCheckbox.addEventListener('change', () => {
244
+ // Si no hay resultado previo guardado, no hacer nada
245
+ if (!lastLabResultText) return;
246
+
247
+ // Obtener estado actual del filtro
248
+ const filterIsActive = filterAlteredLabsCheckbox.checked;
249
+ // Volver a mostrar los resultados (usando el texto completo guardado) con el nuevo estado del filtro
250
+ displayLabResults(lastLabResultText, labResultsOutput, filterIsActive);
251
+ });
252
+ }
253
+
254
+ // Event Listener para el botón "Copiar Resultados" de Laboratorio
255
+ if (btnCopyLabResults) {
256
+ btnCopyLabResults.addEventListener('click', async () => {
257
+ // Copiar el contenido *actualmente visible* en el div de resultados
258
+ const textToCopy = labResultsOutput.textContent;
259
+ if (!textToCopy || textToCopy.startsWith('Error') || textToCopy.includes('No se generaron resultados')) {
260
+ alert('No hay resultados válidos para copiar.');
261
+ return;
262
+ }
263
+ try {
264
+ await copyText(textToCopy);
265
+ console.log('Resultados de laboratorio copiados');
266
+ // Feedback visual rápido (opcional)
267
+ const originalText = btnCopyLabResults.innerHTML;
268
+ btnCopyLabResults.innerHTML = '<i class="fas fa-check mr-2"></i>Copiado';
269
+ setTimeout(() => { btnCopyLabResults.innerHTML = originalText; }, 1500);
270
+ } catch (err) {
271
+ console.error('Error al copiar resultados de laboratorio:', err);
272
+ alert('Error al copiar los resultados.');
273
  }
274
  });
275
  }
276
+ // --- FIN: Lógica Pestaña Análisis de Exámenes ---
277
+
278
+ }); // Fin de window.addEventListener('DOMContentLoaded', ...)