wm-menu 1.2.9 → 1.4.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.
Files changed (32) hide show
  1. package/bundles/wm-menu.umd.js +368 -31
  2. package/bundles/wm-menu.umd.js.map +1 -1
  3. package/bundles/wm-menu.umd.min.js +2 -2
  4. package/bundles/wm-menu.umd.min.js.map +1 -1
  5. package/esm2015/lib/wm-menu/asistente-datos/asistente-datos-api.service.js +52 -0
  6. package/esm2015/lib/wm-menu/asistente-datos/asistente-datos.component.js +178 -0
  7. package/esm2015/lib/wm-menu/asistente-datos/reconocimiento-voz.service.js +77 -0
  8. package/esm2015/lib/wm-menu/services/wm-menu-alerta-panico.service.js +4 -21
  9. package/esm2015/lib/wm-menu/services/wm-menu-servicio.service.js +9 -1
  10. package/esm2015/lib/wm-menu/wm-menu.component.js +35 -7
  11. package/esm2015/lib/wm-menu.module.js +9 -2
  12. package/esm2015/wm-menu.js +4 -1
  13. package/esm5/lib/wm-menu/asistente-datos/asistente-datos-api.service.js +53 -0
  14. package/esm5/lib/wm-menu/asistente-datos/asistente-datos.component.js +194 -0
  15. package/esm5/lib/wm-menu/asistente-datos/reconocimiento-voz.service.js +79 -0
  16. package/esm5/lib/wm-menu/services/wm-menu-alerta-panico.service.js +4 -21
  17. package/esm5/lib/wm-menu/services/wm-menu-servicio.service.js +9 -1
  18. package/esm5/lib/wm-menu/wm-menu.component.js +39 -7
  19. package/esm5/lib/wm-menu.module.js +9 -2
  20. package/esm5/wm-menu.js +4 -1
  21. package/fesm2015/wm-menu.js +343 -29
  22. package/fesm2015/wm-menu.js.map +1 -1
  23. package/fesm5/wm-menu.js +366 -29
  24. package/fesm5/wm-menu.js.map +1 -1
  25. package/lib/wm-menu/asistente-datos/asistente-datos-api.service.d.ts +26 -0
  26. package/lib/wm-menu/asistente-datos/asistente-datos.component.d.ts +39 -0
  27. package/lib/wm-menu/asistente-datos/reconocimiento-voz.service.d.ts +7 -0
  28. package/lib/wm-menu/services/wm-menu-servicio.service.d.ts +1 -0
  29. package/lib/wm-menu/wm-menu.component.d.ts +10 -3
  30. package/package.json +1 -1
  31. package/wm-menu.d.ts +3 -0
  32. package/wm-menu.metadata.json +1 -1
package/fesm5/wm-menu.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { __decorate } from 'tslib';
2
- import { ɵɵdefineInjectable, ɵɵinject, Injectable, Input, Component, NgModule } from '@angular/core';
2
+ import { ɵɵdefineInjectable, ɵɵinject, Injectable, Input, Component, EventEmitter, ViewChild, Output, NgModule } from '@angular/core';
3
3
  import { HttpHeaders, HttpParams, HttpClient, HttpClientModule } from '@angular/common/http';
4
4
  import { map, catchError } from 'rxjs/operators';
5
5
  import { throwError } from 'rxjs';
@@ -11,7 +11,10 @@ import { MatSidenavModule } from '@angular/material/sidenav';
11
11
  import { MatListModule } from '@angular/material/list';
12
12
  import { MatButtonModule } from '@angular/material/button';
13
13
  import { MatMenuModule } from '@angular/material/menu';
14
+ import { MatTableModule } from '@angular/material/table';
15
+ import { MatTooltipModule } from '@angular/material/tooltip';
14
16
  import { MatRippleModule } from '@angular/material/core';
17
+ import { FormsModule } from '@angular/forms';
15
18
 
16
19
  var MenuSecundario = /** @class */ (function () {
17
20
  function MenuSecundario() {
@@ -100,6 +103,14 @@ var WmMenuServicioService = /** @class */ (function () {
100
103
  return throwError(error.error);
101
104
  }));
102
105
  };
106
+ // Funciones (permisos) del usuario autenticado, para gatear features del menú como el
107
+ // asistente "Pregúntale a tus datos" (CodigoLogica === 'WebChatConsultaIA').
108
+ WmMenuServicioService.prototype.funcionesObtener = function (url, token) {
109
+ var headers = new HttpHeaders({
110
+ 'Authorization': "Bearer " + token
111
+ });
112
+ return this.http.get(url, { headers: headers }).pipe(map(function (resp) { return resp; }), catchError(function (error) { return throwError(error.error); }));
113
+ };
103
114
  WmMenuServicioService.ctorParameters = function () { return [
104
115
  { type: HttpClient },
105
116
  { type: MatIconRegistry },
@@ -123,28 +134,23 @@ var WmMenuAlertaPanicoService = /** @class */ (function () {
123
134
  this.IdsAlertasPanicoActivas = new Set(); // Almacena los IDs de las alertas ya manejadas
124
135
  this.soundTimeout = null; // Controla el temporizador del sonido
125
136
  this.isRunning = false;
126
- console.log('WmMenuAlertaPanicoService inicializado.');
127
137
  }
128
138
  WmMenuAlertaPanicoService.prototype.iniciarProceso = function (intervalMs, callback, urlObtenerParametro, token, rutaAudio) {
129
139
  var _this = this;
130
- console.log('iniciarProceso llamado con parámetros:', { intervalMs: intervalMs, urlObtenerParametro: urlObtenerParametro, token: token, rutaAudio: rutaAudio });
131
140
  this.rutaAudio = rutaAudio;
132
141
  var iniciarConInteraccion = function () {
133
- console.log('iniciarConInteraccion ejecutado.');
134
142
  _this.wmMenuServicioService
135
143
  .menuApiObtener(urlObtenerParametro, null, token, 'ReporteAlertasPanico')
136
144
  .subscribe(function (resp) {
137
- console.log('Respuesta obtenida de menuApiObtener:', resp);
145
+ // validar si el parametro ReporteAlertasPanico esta encendido
138
146
  if (resp && resp.length > 0 && resp[0].Valor == 1) {
139
147
  if (_this.isRunning) {
140
- console.log('Proceso ya está corriendo.');
141
148
  return;
142
149
  }
150
+ // Inicializar la variable desde localStorage
143
151
  var storedIds = localStorage.getItem('ALERTAS_PANICO_ACTIVAS_WM');
144
152
  _this.IdsAlertasPanicoActivas = storedIds ? new Set(JSON.parse(storedIds)) : new Set();
145
- console.log('IdsAlertasPanicoActivas inicializado:', _this.IdsAlertasPanicoActivas);
146
153
  var ejecutarProceso_1 = function () {
147
- console.log('ejecutarProceso iniciado.');
148
154
  _this.isRunning = true;
149
155
  callback();
150
156
  setTimeout(function () {
@@ -157,49 +163,42 @@ var WmMenuAlertaPanicoService = /** @class */ (function () {
157
163
  });
158
164
  };
159
165
  ['drag', 'click'].forEach(function (evento) {
160
- console.log("Evento " + evento + " registrado para iniciar proceso.");
161
166
  document.addEventListener(evento, function () {
162
167
  iniciarConInteraccion();
163
168
  }, { once: true });
164
169
  });
165
170
  };
166
171
  WmMenuAlertaPanicoService.prototype.stopProcess = function () {
167
- console.log('stopProcess ejecutado.');
168
172
  this.isRunning = false;
169
173
  if (this.subscription) {
170
174
  this.subscription.unsubscribe();
171
175
  }
172
176
  };
173
177
  WmMenuAlertaPanicoService.prototype.ngOnDestroy = function () {
174
- console.log('ngOnDestroy ejecutado.');
175
178
  this.stopSound();
176
179
  this.stopFlashingTitle();
177
180
  };
178
181
  WmMenuAlertaPanicoService.prototype.playSound = function () {
179
182
  var _this = this;
180
- console.log('playSound llamado.');
181
183
  if (this.isPlaying)
182
184
  return; // Evita reproducir si ya está sonando
183
185
  this.isPlaying = true;
184
186
  if (!this.audio) {
185
187
  this.audio = new Audio(this.rutaAudio); // Ruta al archivo de sonido
186
188
  }
187
- console.log("Audio cargado: ", this.audio);
188
189
  this.audio.loop = true; // Reproducir en bucle
189
190
  this.audio.play()
190
191
  .then(function () {
191
- console.log('Sonido reproduciéndose.');
192
192
  // Detener el sonido después de 10 segundos
193
193
  _this.soundTimeout = setTimeout(function () {
194
194
  _this.stopSound();
195
195
  }, 10000); // Detener después de 10 segundos
196
196
  })
197
197
  .catch(function (error) {
198
- console.error('Error al reproducir el sonido:', error);
198
+ console.log('Error al reproducir el sonido:', error);
199
199
  });
200
200
  };
201
201
  WmMenuAlertaPanicoService.prototype.stopSound = function () {
202
- console.log('stopSound llamado.');
203
202
  if (this.audio) {
204
203
  this.audio.pause();
205
204
  this.audio.currentTime = 0; // Reinicia el sonido
@@ -212,7 +211,6 @@ var WmMenuAlertaPanicoService = /** @class */ (function () {
212
211
  };
213
212
  WmMenuAlertaPanicoService.prototype.startFlashingTitle = function () {
214
213
  var _this = this;
215
- console.log('startFlashingTitle llamado.');
216
214
  var toggle = false;
217
215
  // Almacenar el título original si aún no se ha guardado
218
216
  if (!this.originalTitle) {
@@ -227,7 +225,6 @@ var WmMenuAlertaPanicoService = /** @class */ (function () {
227
225
  }
228
226
  };
229
227
  WmMenuAlertaPanicoService.prototype.stopFlashingTitle = function () {
230
- console.log('stopFlashingTitle llamado.');
231
228
  if (this.intervalId) {
232
229
  clearInterval(this.intervalId);
233
230
  this.intervalId = null;
@@ -236,16 +233,13 @@ var WmMenuAlertaPanicoService = /** @class */ (function () {
236
233
  };
237
234
  WmMenuAlertaPanicoService.prototype.revisarAlertasPendientes = function (urlObtenerAlertasPanico, token) {
238
235
  var _this = this;
239
- console.log('revisarAlertasPendientes llamado con parámetros:', { urlObtenerAlertasPanico: urlObtenerAlertasPanico, token: token });
240
236
  var helper = new JwtHelperService();
241
237
  var decodedToken = helper.decodeToken(token);
242
238
  this.wmMenuServicioService
243
239
  .menuApiObtener(urlObtenerAlertasPanico, decodedToken['id_usuario'], token)
244
240
  .subscribe(function (resp) {
245
- console.log('Respuesta obtenida de revisarAlertasPendientes:', resp);
246
241
  if (resp && resp.length > 0) {
247
242
  var alertasIds_1 = resp.map(function (alerta) { return alerta.IdAlertaPanico; });
248
- console.log('IDs de alertas obtenidas:', alertasIds_1);
249
243
  // Eliminar IDs que no están en la respuesta del servicio
250
244
  _this.IdsAlertasPanicoActivas.forEach(function (id) {
251
245
  if (!alertasIds_1.includes(id)) {
@@ -286,18 +280,38 @@ var WmMenuAlertaPanicoService = /** @class */ (function () {
286
280
  }());
287
281
 
288
282
  var WmMenuComponent = /** @class */ (function () {
289
- function WmMenuComponent(wmMenuServicioService, wmMenuAlertaPanicoService) {
283
+ function WmMenuComponent(wmMenuServicioService, alertaPanicoService) {
290
284
  this.wmMenuServicioService = wmMenuServicioService;
291
- this.wmMenuAlertaPanicoService = wmMenuAlertaPanicoService;
292
- this.intervaloPeticionesMs = 60000;
285
+ this.alertaPanicoService = alertaPanicoService;
286
+ this.mostrarAsistente = false;
287
+ this.idiomaAsistente = 'es-CO';
288
+ this.asistenteAbierto = false;
289
+ this.funcionesUsuario = [];
293
290
  this.menuSecundarioSel = new MenuSecundario();
294
291
  this.menuLateralAbierto = false;
295
292
  this.menuIdioma = [];
293
+ this.intervaloPeticionesMs = 60000;
296
294
  }
295
+ Object.defineProperty(WmMenuComponent.prototype, "puedeAsistente", {
296
+ get: function () {
297
+ var forzado = this.mostrarAsistente === true || this.mostrarAsistente === 'true' || this.mostrarAsistente === '1';
298
+ var tienePermiso = this.funcionesUsuario.some(function (f) { return f.CodigoLogica === 'WebChatConsultaIA'; });
299
+ return forzado || tienePermiso;
300
+ },
301
+ enumerable: true,
302
+ configurable: true
303
+ });
297
304
  WmMenuComponent.prototype.ngOnInit = function () {
298
305
  var _this = this;
299
- this.wmMenuAlertaPanicoService.iniciarProceso(this.intervaloPeticionesMs, function () { return _this.wmMenuAlertaPanicoService.revisarAlertasPendientes(_this.urlObtenerAlertasPanico, _this.token); }, this.urlObtenerParametro, this.token, this.rutaAudio);
300
306
  this.cargarMenuCuenta();
307
+ this.alertaPanicoService.iniciarProceso(this.intervaloPeticionesMs, function () { return _this.alertaPanicoService.revisarAlertasPendientes(_this.urlObtenerAlertasPanico, _this.token); }, this.urlObtenerParametro, this.token, this.rutaAudio);
308
+ // Carga las funciones del usuario para gatear el asistente (puedeAsistente / WebChatConsultaIA).
309
+ // Si falla (ej. 401), queda vacía y el asistente no se muestra.
310
+ if (this.urlObtenerFunciones && this.token) {
311
+ this.wmMenuServicioService
312
+ .funcionesObtener(this.urlObtenerFunciones, this.token)
313
+ .subscribe(function (resp) { _this.funcionesUsuario = (resp !== null && resp !== void 0 ? resp : []); }, function () { _this.funcionesUsuario = []; });
314
+ }
301
315
  if (this.urlMenu && this.token) {
302
316
  var helper = new JwtHelperService();
303
317
  var decodedToken = helper.decodeToken(this.token);
@@ -419,30 +433,353 @@ var WmMenuComponent = /** @class */ (function () {
419
433
  __decorate([
420
434
  Input()
421
435
  ], WmMenuComponent.prototype, "urlIdiomas", void 0);
436
+ __decorate([
437
+ Input()
438
+ ], WmMenuComponent.prototype, "urlObtenerFunciones", void 0);
439
+ __decorate([
440
+ Input()
441
+ ], WmMenuComponent.prototype, "mostrarAsistente", void 0);
442
+ __decorate([
443
+ Input()
444
+ ], WmMenuComponent.prototype, "urlAsistenteConsultar", void 0);
445
+ __decorate([
446
+ Input()
447
+ ], WmMenuComponent.prototype, "idiomaAsistente", void 0);
422
448
  WmMenuComponent = __decorate([
423
449
  Component({
424
450
  selector: 'wm-menu',
425
- template: "<div class=\"menu\" [ngStyle]=\"{'background-color': colorFondo, 'color': colorTexto}\">\r\n <div class=\"d-lg-none\">\r\n <button mat-icon-button (click)=\"menuLateralAbierto=!menuLateralAbierto; menuPrincipalSel = null\">\r\n <mat-icon *ngIf=\"!menuLateralAbierto\" class=\"animate__animated animate__fadeInRight animate__faster\">menu\r\n </mat-icon>\r\n <mat-icon *ngIf=\"menuLateralAbierto\" class=\"animate__animated animate__fadeInLeft animate__faster\">close\r\n </mat-icon>\r\n </button>\r\n </div>\r\n <div class=\"d-lg-none logo-menu-principal\">\r\n <img class=\"logo\" src=\"{{logo}}\">\r\n </div>\r\n <div class=\"d-none d-lg-block\">\r\n <img class=\"logo\" src=\"{{logo}}\">\r\n <div *ngFor=\"let menuItem of menuPrincipal; let i=index\" class=\"d-inline-block\">\r\n\r\n <a *ngIf=\"menuItem.url\" mat-button [href]=\"menuItem.url\" (click)=\"clickMenuPrincipal(i)\">\r\n {{menuItem.titulo}}\r\n </a>\r\n <button *ngIf=\"!menuItem.url\" mat-button (click)=\"clickMenuPrincipal(i)\">\r\n {{menuItem.titulo}}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"info-adicional\">\r\n <div class=\"datos border-r mt-1\" *ngIf=\"nombreCliente\">{{nombreCliente}}<mat-icon>people</mat-icon></div>\r\n <div class=\"datos border-r mt-1\" *ngIf=\"nombreUsuario\">{{nombreUsuario}}<mat-icon>person_outline</mat-icon></div>\r\n <div class=\"version\" *ngIf=\"versionWeb\">{{versionWeb}}</div>\r\n <div class=\"content-idioma\" *ngIf=\"urlIdiomas\">\r\n <mat-menu #menuIdiomas=\"matMenu\">\r\n <a mat-menu-item *ngFor=\"let menuItem of menuIdioma.Culturas\" href=\"{{urlCuentaSeguridad}}CambiarIdioma?culture={{menuItem.Name}}&ReturnUrl=/\">\r\n {{menuItem.NativeName}}\r\n </a>\r\n </mat-menu>\r\n <button mat-button [matMenuTriggerFor]=\"menuIdiomas\"><label class=\"mt-1\">{{menuIdioma.Lenguaje}}</label><mat-icon class=\"icon-idioma\">language</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n <div>\r\n <mat-menu #submenu=\"matMenu\">\r\n <a mat-menu-item *ngFor=\"let menuItem of menuSecundarioSel.hijos\" href=\"{{menuItem.url}}\"\r\n [disabled]=\"!menuItem.url\">\r\n <mat-icon *ngIf=\"menuItem.icono\">{{menuItem.icono}}</mat-icon>\r\n {{menuItem.titulo}}\r\n </a>\r\n </mat-menu>\r\n <button *ngFor=\"let menuItem of menuSecundario; let i = index\" mat-icon-button [matMenuTriggerFor]=\"submenu\"\r\n (click)=\"clickMenuSecundario(i)\">\r\n <mat-icon>{{menuItem.icono}}</mat-icon>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"menu-lateral d-lg-none animate__animated animate__fadeInRight animate__faster\" *ngIf=\"menuLateralAbierto\">\r\n <div class=\"row\">\r\n <div *ngFor=\"let menuItem of menuPrincipal; let i=index\" class=\"col-sm-6 col-md-4\">\r\n <a *ngIf=\"menuItem.url\" [href]=\"menuItem.url\" (click)=\"clickMenuPrincipal(i)\">\r\n <div>\r\n <mat-icon svgIcon=\"{{menuItem.icono}}\">{{menuItem.icono}}</mat-icon>\r\n <p>{{menuItem.titulo}}</p>\r\n </div>\r\n </a>\r\n <span *ngIf=\"!menuItem.url\" (click)=\"clickMenuPrincipal(i)\">\r\n <div>\r\n <mat-icon svgIcon=\"{{menuItem.icono}}\">{{menuItem.icono}}</mat-icon>\r\n <p>{{menuItem.titulo}}</p>\r\n </div>\r\n </span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"sub-menu-fondo animate__animated animate__fadeIn animate__faster\" (click)=\"menuPrincipalSel=null\"\r\n *ngIf=\"menuPrincipalSel\"></div>\r\n\r\n<div class=\"sub-menu animate__animated animate__fadeIn animate__faster\" *ngIf=\"menuPrincipalSel\">\r\n <div class=\"container-fluid\">\r\n <div class=\"row\">\r\n <div class=\"col-12 col-lg-5\">\r\n <div class=\"px-3 px-sm-5 pt-5 pb-lg-5 text-center descripcion-menu\">\r\n <mat-icon [ngStyle]=\"{'color': colorFondo}\" svgIcon=\"{{menuPrincipalSel.icono}}\">\r\n {{menuPrincipalSel.icono}}</mat-icon>\r\n <p>{{menuPrincipalSel.titulo}}</p>\r\n <p class=\"text-secondary\">{{menuPrincipalSel.descripcion}}</p>\r\n </div>\r\n </div>\r\n <div class=\"col-12 col-lg-7 my-4\">\r\n <div class=\"px-3 px-md-4 py-2 py-md-2\">\r\n <ul class=\"list-unstyled\">\r\n\r\n <li class=\"mb-3 d-flex\" *ngFor=\"let menuItem of menuPrincipalSel.hijos\">\r\n <mat-icon>{{menuItem.icono}}</mat-icon>\r\n <div class=\"ml-2 flex-fill\">\r\n <a href=\"{{menuItem.url}}\" *ngIf=\"menuItem.url\">\r\n <div class=\"lead mb-2\">{{menuItem.titulo}}</div>\r\n </a>\r\n <div class=\"lead mb-2\" *ngIf=\"!menuItem.url\">{{menuItem.titulo}}</div>\r\n\r\n <a href=\"{{menuSubItem.url}}\" class=\"pl-2 my-2\" *ngFor=\"let menuSubItem of menuItem.hijos\">\r\n <div class=\"text-secondary\">{{menuSubItem.titulo}}</div>\r\n </a>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <button mat-icon-button class=\"close-icon d-lg-none\" (click)=\"menuPrincipalSel=null\">\r\n <mat-icon>arrow_back</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"alerta-almacenamiento\" *ngIf=\"porcentajeUtilizado >= 100\">Su capacidad de almacenamiento ha llegado al {{porcentajeUtilizado}}% , libere espacio o adquiera mayor capacidad</div>",
426
- styles: [".menu{height:46px;display:flex;justify-content:space-between;align-items:center;top:0;left:0;right:0;background-color:#1c98a4;color:#fff;padding:0 4px}.menu .d-lg-block .mat-button{font-weight:400;height:46px;line-height:46px}.menu .logo{display:inline-block;height:40px}.menu .logo-menu-principal{position:absolute;display:block;left:65px}.menu .logo-menu-principal>img{display:block;margin:0 -50%}.menu .info-adicional{color:#fff;display:flex;justify-content:end;font-size:13px;position:absolute;right:47px}.menu .info-adicional .border-r{border-right:1px solid #fff}.menu .info-adicional .version{margin:7px 0 0 7px}.menu .info-adicional div.datos{margin:0 2px 0 5px;height:28px}.menu .info-adicional .mat-icon{vertical-align:middle;font-size:17px;color:#fff;line-height:21px;margin-left:2px}.menu .info-adicional button{padding:0 0 0 15px}.menu .info-adicional .content-idioma{margin:-5px 2px 0 5px;display:block;cursor:pointer}.menu .info-adicional .icon-idioma{font-size:17px!important;vertical-align:text-top!important;color:#fffc}.sub-menu{width:100%;position:absolute;top:46px;z-index:1000;background-color:#fff;display:flex;overflow-y:auto;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.sub-menu .close-icon{position:absolute;left:4px;top:4px}.sub-menu .descripcion-menu .mat-icon{color:#1c98a4;width:100px;height:100px}.sub-menu .descripcion-menu p:first-of-type{font-weight:300;font-size:30px;margin:16px 0}.sub-menu .descripcion-menu p:last-of-type{color:#6c757d}.sub-menu li{float:left;width:50%}.sub-menu li>.mat-icon{color:#444}.sub-menu li:nth-child(even){float:right}.sub-menu li a{transition:.5s;display:block}.sub-menu li a:hover{margin-left:8px}.sub-menu li .lead{line-height:24px;color:#212529;font-size:17px}.sub-menu-fondo{background:#272d3357;position:absolute;top:46px;bottom:0;left:0;right:0;z-index:1000}.menu-lateral{width:100%;position:absolute;top:46px;bottom:0;left:0;right:0;z-index:1000;display:flex;flex-direction:column;overflow-y:auto;background:#f7f7f7;padding:20px}.menu-lateral>div>div>*>div{text-align:center;padding:16px;background-color:#fff;margin:0 0 16px;color:#333;cursor:pointer;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.menu-lateral>div>div>*>div>.mat-icon{width:50px;height:50px}.menu-lateral>div>div>*>div>p{padding:0;margin:8px 0 0}a.mat-menu-item{color:#444!important}.alerta-almacenamiento{background:#ffffec;border-bottom:1px solid #efff00;min-height:39px;line-height:36px;font-size:12px;padding:0 0 0 25px}@media (max-width:767.98px){.sub-menu ul{margin:auto;padding:0 10px}.sub-menu ul li{float:none;width:100%}.sub-menu ul li:nth-child(even){float:none}}@media (max-width:991.98px){.sub-menu{bottom:0}}@media (min-width:600px){.logo-menu-principal{left:50%!important}}* :focus,:active{outline:0!important}"]
451
+ template: "<div class=\"menu\" [ngStyle]=\"{'background-color': colorFondo, 'color': colorTexto}\">\r\n <div class=\"d-lg-none\">\r\n <button mat-icon-button (click)=\"menuLateralAbierto=!menuLateralAbierto; menuPrincipalSel = null\">\r\n <mat-icon *ngIf=\"!menuLateralAbierto\" class=\"animate__animated animate__fadeInRight animate__faster\">menu\r\n </mat-icon>\r\n <mat-icon *ngIf=\"menuLateralAbierto\" class=\"animate__animated animate__fadeInLeft animate__faster\">close\r\n </mat-icon>\r\n </button>\r\n </div>\r\n <div class=\"d-lg-none logo-menu-principal\">\r\n <img class=\"logo\" src=\"{{logo}}\">\r\n </div>\r\n <div class=\"d-none d-lg-block\">\r\n <img class=\"logo\" src=\"{{logo}}\">\r\n <div *ngFor=\"let menuItem of menuPrincipal; let i=index\" class=\"d-inline-block\">\r\n\r\n <a *ngIf=\"menuItem.url\" mat-button [href]=\"menuItem.url\" (click)=\"clickMenuPrincipal(i)\">\r\n {{menuItem.titulo}}\r\n </a>\r\n <button *ngIf=\"!menuItem.url\" mat-button (click)=\"clickMenuPrincipal(i)\">\r\n {{menuItem.titulo}}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"info-adicional\">\r\n <div class=\"datos border-r mt-1 boton-asistente-datos\" *ngIf=\"puedeAsistente\" matTooltip=\"Preg\u00FAntale a tus datos\" (click)=\"asistenteAbierto = !asistenteAbierto\">\r\n <span class=\"icono-asistente-fab\"></span>\r\n </div>\r\n <div class=\"datos border-r mt-1\" *ngIf=\"nombreCliente\">{{nombreCliente}}<mat-icon>people</mat-icon></div>\r\n <div class=\"datos border-r mt-1\" *ngIf=\"nombreUsuario\">{{nombreUsuario}}<mat-icon>person_outline</mat-icon></div>\r\n <div class=\"version\" *ngIf=\"versionWeb\">{{versionWeb}}</div>\r\n <div class=\"content-idioma\" *ngIf=\"urlIdiomas\">\r\n <mat-menu #menuIdiomas=\"matMenu\">\r\n <a mat-menu-item *ngFor=\"let menuItem of menuIdioma.Culturas\" href=\"{{urlCuentaSeguridad}}CambiarIdioma?culture={{menuItem.Name}}&ReturnUrl=/\">\r\n {{menuItem.NativeName}}\r\n </a>\r\n </mat-menu>\r\n <button mat-button [matMenuTriggerFor]=\"menuIdiomas\"><label class=\"mt-1\">{{menuIdioma.Lenguaje}}</label><mat-icon class=\"icon-idioma\">language</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n <div>\r\n <mat-menu #submenu=\"matMenu\">\r\n <a mat-menu-item *ngFor=\"let menuItem of menuSecundarioSel.hijos\" href=\"{{menuItem.url}}\"\r\n [disabled]=\"!menuItem.url\">\r\n <mat-icon *ngIf=\"menuItem.icono\">{{menuItem.icono}}</mat-icon>\r\n {{menuItem.titulo}}\r\n </a>\r\n </mat-menu>\r\n <button *ngFor=\"let menuItem of menuSecundario; let i = index\" mat-icon-button [matMenuTriggerFor]=\"submenu\"\r\n (click)=\"clickMenuSecundario(i)\">\r\n <mat-icon>{{menuItem.icono}}</mat-icon>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"menu-lateral d-lg-none animate__animated animate__fadeInRight animate__faster\" *ngIf=\"menuLateralAbierto\">\r\n <div class=\"row\">\r\n <div *ngFor=\"let menuItem of menuPrincipal; let i=index\" class=\"col-sm-6 col-md-4\">\r\n <a *ngIf=\"menuItem.url\" [href]=\"menuItem.url\" (click)=\"clickMenuPrincipal(i)\">\r\n <div>\r\n <mat-icon svgIcon=\"{{menuItem.icono}}\">{{menuItem.icono}}</mat-icon>\r\n <p>{{menuItem.titulo}}</p>\r\n </div>\r\n </a>\r\n <span *ngIf=\"!menuItem.url\" (click)=\"clickMenuPrincipal(i)\">\r\n <div>\r\n <mat-icon svgIcon=\"{{menuItem.icono}}\">{{menuItem.icono}}</mat-icon>\r\n <p>{{menuItem.titulo}}</p>\r\n </div>\r\n </span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"sub-menu-fondo animate__animated animate__fadeIn animate__faster\" (click)=\"menuPrincipalSel=null\"\r\n *ngIf=\"menuPrincipalSel\"></div>\r\n\r\n<div class=\"sub-menu animate__animated animate__fadeIn animate__faster\" *ngIf=\"menuPrincipalSel\">\r\n <div class=\"container-fluid\">\r\n <div class=\"row\">\r\n <div class=\"col-12 col-lg-5\">\r\n <div class=\"px-3 px-sm-5 pt-5 pb-lg-5 text-center descripcion-menu\">\r\n <mat-icon [ngStyle]=\"{'color': colorFondo}\" svgIcon=\"{{menuPrincipalSel.icono}}\">\r\n {{menuPrincipalSel.icono}}</mat-icon>\r\n <p>{{menuPrincipalSel.titulo}}</p>\r\n <p class=\"text-secondary\">{{menuPrincipalSel.descripcion}}</p>\r\n </div>\r\n </div>\r\n <div class=\"col-12 col-lg-7 my-4\">\r\n <div class=\"px-3 px-md-4 py-2 py-md-2\">\r\n <ul class=\"list-unstyled\">\r\n\r\n <li class=\"mb-3 d-flex\" *ngFor=\"let menuItem of menuPrincipalSel.hijos\">\r\n <mat-icon>{{menuItem.icono}}</mat-icon>\r\n <div class=\"ml-2 flex-fill\">\r\n <a href=\"{{menuItem.url}}\" *ngIf=\"menuItem.url\">\r\n <div class=\"lead mb-2\">{{menuItem.titulo}}</div>\r\n </a>\r\n <div class=\"lead mb-2\" *ngIf=\"!menuItem.url\">{{menuItem.titulo}}</div>\r\n\r\n <a href=\"{{menuSubItem.url}}\" class=\"pl-2 my-2\" *ngFor=\"let menuSubItem of menuItem.hijos\">\r\n <div class=\"text-secondary\">{{menuSubItem.titulo}}</div>\r\n </a>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <button mat-icon-button class=\"close-icon d-lg-none\" (click)=\"menuPrincipalSel=null\">\r\n <mat-icon>arrow_back</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"alerta-almacenamiento\" *ngIf=\"porcentajeUtilizado >= 100\">Su capacidad de almacenamiento ha llegado al {{porcentajeUtilizado}}% , libere espacio o adquiera mayor capacidad</div>\r\n\r\n<!-- Asistente \"Preg\u00FAntale a tus datos\": panel flotante que se abre desde el bot\u00F3n del men\u00FA. -->\r\n<wm-asistente-datos *ngIf=\"puedeAsistente\" [abierto]=\"asistenteAbierto\" [urlConsultar]=\"urlAsistenteConsultar\"\r\n [idioma]=\"idiomaAsistente\" (cerrarChange)=\"asistenteAbierto = false\"></wm-asistente-datos>",
452
+ styles: [".menu{height:46px;display:flex;justify-content:space-between;align-items:center;top:0;left:0;right:0;background-color:#1c98a4;color:#fff;padding:0 4px}.menu .d-lg-block .mat-button{font-weight:400;height:46px;line-height:46px}.menu .logo{display:inline-block;height:40px}.menu .logo-menu-principal{position:absolute;display:block;left:65px}.menu .logo-menu-principal>img{display:block;margin:0 -50%}.menu .info-adicional{color:#fff;display:flex;justify-content:end;font-size:13px;position:absolute;right:47px}.menu .info-adicional .border-r{border-right:1px solid #fff}.menu .info-adicional .version{margin:7px 0 0 7px}.menu .info-adicional div.datos{margin:0 2px 0 5px;height:28px}.menu .info-adicional .boton-asistente-datos{cursor:pointer;padding-right:10px}.menu .info-adicional .mat-icon{vertical-align:middle;font-size:17px;color:#fff;line-height:21px;margin-left:2px}.menu .info-adicional button{padding:0 0 0 15px}.menu .info-adicional .content-idioma{margin:-5px 2px 0 5px;display:block;cursor:pointer}.menu .info-adicional .icon-idioma{font-size:17px!important;vertical-align:text-top!important;color:#fffc}.sub-menu{width:100%;position:absolute;top:46px;z-index:1000;background-color:#fff;display:flex;overflow-y:auto;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.sub-menu .close-icon{position:absolute;left:4px;top:4px}.sub-menu .descripcion-menu .mat-icon{color:#1c98a4;width:100px;height:100px}.sub-menu .descripcion-menu p:first-of-type{font-weight:300;font-size:30px;margin:16px 0}.sub-menu .descripcion-menu p:last-of-type{color:#6c757d}.sub-menu li{float:left;width:50%}.sub-menu li>.mat-icon{color:#444}.sub-menu li:nth-child(even){float:right}.sub-menu li a{transition:.5s;display:block}.sub-menu li a:hover{margin-left:8px}.sub-menu li .lead{line-height:24px;color:#212529;font-size:17px}.sub-menu-fondo{background:#272d3357;position:absolute;top:46px;bottom:0;left:0;right:0;z-index:1000}.menu-lateral{width:100%;position:absolute;top:46px;bottom:0;left:0;right:0;z-index:1000;display:flex;flex-direction:column;overflow-y:auto;background:#f7f7f7;padding:20px}.menu-lateral>div>div>*>div{text-align:center;padding:16px;background-color:#fff;margin:0 0 16px;color:#333;cursor:pointer;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.menu-lateral>div>div>*>div>.mat-icon{width:50px;height:50px}.menu-lateral>div>div>*>div>p{padding:0;margin:8px 0 0}a.mat-menu-item{color:#444!important}.alerta-almacenamiento{background:#ffffec;border-bottom:1px solid #efff00;min-height:39px;line-height:36px;font-size:12px;padding:0 0 0 25px}@media (max-width:767.98px){.sub-menu ul{margin:auto;padding:0 10px}.sub-menu ul li{float:none;width:100%}.sub-menu ul li:nth-child(even){float:none}}@media (max-width:991.98px){.sub-menu{bottom:0}}@media (min-width:600px){.logo-menu-principal{left:50%!important}}* :focus,:active{outline:0!important}.icono-asistente-fab{display:inline-block;width:32px;height:32px;vertical-align:middle;background:url(data:image/png;base64,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) center/contain no-repeat}"]
427
453
  })
428
454
  ], WmMenuComponent);
429
455
  return WmMenuComponent;
430
456
  }());
431
457
 
458
+ // Envoltorio de la Web Speech API (SpeechRecognition) del navegador — dictado de voz a texto,
459
+ // 100% cliente, sin backend. Soportado en Chrome/Edge; SIN soporte en Firefox y de forma
460
+ // inconsistente en Safari (limitación real del navegador, no de esta implementación).
461
+ var ReconocimientoVozService = /** @class */ (function () {
462
+ function ReconocimientoVozService() {
463
+ this.reconocimiento = null;
464
+ }
465
+ ReconocimientoVozService.prototype.estaSoportado = function () {
466
+ return !!(this.obtenerConstructor());
467
+ };
468
+ // onResultado se llama con el texto reconocido hasta el momento (incluye resultados
469
+ // provisionales — interimResults: true — para que el cuadro de texto se vea llenar en vivo).
470
+ // onFin se llama cuando el reconocimiento termina, ya sea porque el navegador detectó una
471
+ // pausa (continuous: false) o porque se llamó a detener().
472
+ ReconocimientoVozService.prototype.iniciar = function (idioma, onResultado, onFin) {
473
+ var _this = this;
474
+ var SpeechRecognitionCtor = this.obtenerConstructor();
475
+ if (!SpeechRecognitionCtor) {
476
+ onFin();
477
+ return;
478
+ }
479
+ this.detener();
480
+ this.reconocimiento = new SpeechRecognitionCtor();
481
+ this.reconocimiento.lang = idioma;
482
+ this.reconocimiento.continuous = false;
483
+ this.reconocimiento.interimResults = true;
484
+ this.reconocimiento.onresult = function (evento) {
485
+ var texto = Array.from(evento.results)
486
+ .map(function (resultado) { return resultado[0].transcript; })
487
+ .join(' ');
488
+ onResultado(texto);
489
+ };
490
+ this.reconocimiento.onerror = function (evento) {
491
+ var _a;
492
+ // Motivos típicos (event.error de SpeechRecognitionErrorEvent): "not-allowed" (permiso de
493
+ // micrófono denegado o sitio sin HTTPS/localhost), "no-speech", "audio-capture" (sin
494
+ // micrófono), "network". Se deja en consola porque no hay backend que lo registre y el
495
+ // navegador no explica el motivo en la UI.
496
+ console.error('Reconocimiento de voz: error -', (_a = evento) === null || _a === void 0 ? void 0 : _a.error);
497
+ _this.reconocimiento = null;
498
+ onFin();
499
+ };
500
+ this.reconocimiento.onend = function () {
501
+ _this.reconocimiento = null;
502
+ onFin();
503
+ };
504
+ try {
505
+ this.reconocimiento.start();
506
+ }
507
+ catch (e) {
508
+ console.error('Reconocimiento de voz: no se pudo iniciar -', e);
509
+ this.reconocimiento = null;
510
+ onFin();
511
+ }
512
+ };
513
+ ReconocimientoVozService.prototype.detener = function () {
514
+ if (this.reconocimiento) {
515
+ this.reconocimiento.onend = null;
516
+ this.reconocimiento.onerror = null;
517
+ this.reconocimiento.stop();
518
+ this.reconocimiento = null;
519
+ }
520
+ };
521
+ ReconocimientoVozService.prototype.obtenerConstructor = function () {
522
+ return window.SpeechRecognition || window.webkitSpeechRecognition || null;
523
+ };
524
+ ReconocimientoVozService.ɵprov = ɵɵdefineInjectable({ factory: function ReconocimientoVozService_Factory() { return new ReconocimientoVozService(); }, token: ReconocimientoVozService, providedIn: "root" });
525
+ ReconocimientoVozService = __decorate([
526
+ Injectable({
527
+ providedIn: 'root',
528
+ })
529
+ ], ReconocimientoVozService);
530
+ return ReconocimientoVozService;
531
+ }());
532
+
533
+ var AsistenteDatosApiService = /** @class */ (function () {
534
+ function AsistenteDatosApiService(http) {
535
+ this.http = http;
536
+ // La fija el componente desde su @Input urlConsultar (reemplaza WmChatConfigService.urlConsultar).
537
+ this.url = '';
538
+ // Mismo origen del JWT que WmSeguridadService.getJWT() en wm-chat: localStorage['WMTKN'],
539
+ // descartado si está vencido. Se replica aquí para que el header Authorization sea idéntico
540
+ // al del chat original sin depender de un servicio de config externo.
541
+ this.TOKEN_KEY = 'WMTKN';
542
+ this.jwtHelper = new JwtHelperService();
543
+ }
544
+ AsistenteDatosApiService.prototype.consultar = function (pregunta, proveedor) {
545
+ var headers = new HttpHeaders({
546
+ Authorization: "Bearer " + this.obtenerJWT(),
547
+ 'Content-Type': 'application/json; charset=utf-8',
548
+ });
549
+ return this.http
550
+ .post(this.url, { Pregunta: pregunta, Proveedor: proveedor }, { headers: headers })
551
+ .pipe(catchError(function (error) {
552
+ return throwError(error.error);
553
+ }));
554
+ };
555
+ AsistenteDatosApiService.prototype.obtenerJWT = function () {
556
+ var jwt = localStorage.getItem(this.TOKEN_KEY);
557
+ if (jwt) {
558
+ try {
559
+ return this.jwtHelper.isTokenExpired(jwt) ? null : jwt;
560
+ }
561
+ catch (_a) { }
562
+ }
563
+ return null;
564
+ };
565
+ AsistenteDatosApiService.ctorParameters = function () { return [
566
+ { type: HttpClient }
567
+ ]; };
568
+ AsistenteDatosApiService.ɵprov = ɵɵdefineInjectable({ factory: function AsistenteDatosApiService_Factory() { return new AsistenteDatosApiService(ɵɵinject(HttpClient)); }, token: AsistenteDatosApiService, providedIn: "root" });
569
+ AsistenteDatosApiService = __decorate([
570
+ Injectable({
571
+ providedIn: 'root',
572
+ })
573
+ ], AsistenteDatosApiService);
574
+ return AsistenteDatosApiService;
575
+ }());
576
+
577
+ var AsistenteDatosComponent = /** @class */ (function () {
578
+ function AsistenteDatosComponent(asistenteDatosApiService, reconocimientoVoz) {
579
+ this.asistenteDatosApiService = asistenteDatosApiService;
580
+ this.reconocimientoVoz = reconocimientoVoz;
581
+ // La apertura/cierre del panel la controla el padre (el menú). El panel solo se renderiza
582
+ // cuando `abierto` es true y avisa, vía `cerrarChange`, cuando el usuario toca la X.
583
+ this.abierto = false;
584
+ // Idioma para el reconocimiento de voz (Web Speech API).
585
+ this.idioma = 'es-CO';
586
+ this.cerrarChange = new EventEmitter();
587
+ this.mensajes = [];
588
+ this.borrador = '';
589
+ // Alterna el alto de la caja del mensaje (compacta ↔ expandida), igual que el "pedir cambios"
590
+ // del asistente de IA del generador de formularios (ver filasBorrador / onClickExpandirBorrador).
591
+ this.borradorExpandido = false;
592
+ this.consultando = false;
593
+ // "Gemini" o "Groq" — mismo selector que el asistente de generación de formularios
594
+ // (ver ProveedorIAServicio en el backend).
595
+ this.proveedorSeleccionado = 'Gemini';
596
+ // Dictado por voz (Web Speech API) — sin soporte en Firefox, inconsistente en Safari.
597
+ this.escuchando = false;
598
+ // Preguntas ya verificadas como respondibles hoy (whitelist + contrato de la IA — ver
599
+ // ChatConsultaWhitelistServicio/ChatConsultaPromptServicio en el backend), mostradas como chips
600
+ // de sugerencia en el estado vacío del chat.
601
+ this.chipsSugeridos = [
602
+ '¿Cuántos formularios se diligenciaron hoy?',
603
+ '¿Cuántos formularios se diligenciaron esta semana?',
604
+ 'Muéstrame los últimos 10 formularios diligenciados',
605
+ ];
606
+ }
607
+ Object.defineProperty(AsistenteDatosComponent.prototype, "urlConsultar", {
608
+ // URL del POST de consulta. Se refleja en el api service (propiedad `url`), que es donde se usa.
609
+ set: function (valor) {
610
+ if (valor) {
611
+ this.asistenteDatosApiService.url = valor;
612
+ }
613
+ },
614
+ enumerable: true,
615
+ configurable: true
616
+ });
617
+ // El padre abre/cierra el panel; aquí solo se avisa que el usuario pidió cerrarlo (botón X).
618
+ AsistenteDatosComponent.prototype.cerrar = function () {
619
+ this.cerrarChange.emit();
620
+ };
621
+ Object.defineProperty(AsistenteDatosComponent.prototype, "filasBorrador", {
622
+ // Caja del mensaje compacta (1 fila, como era el chat originalmente) ↔ expandida (6 filas).
623
+ // El botón de expandir es el mismo patrón del "pedir cambios" del generador.
624
+ get: function () {
625
+ return this.borradorExpandido ? 6 : 1;
626
+ },
627
+ enumerable: true,
628
+ configurable: true
629
+ });
630
+ AsistenteDatosComponent.prototype.onClickExpandirBorrador = function () {
631
+ this.borradorExpandido = !this.borradorExpandido;
632
+ };
633
+ Object.defineProperty(AsistenteDatosComponent.prototype, "micDisponible", {
634
+ get: function () {
635
+ return this.reconocimientoVoz.estaSoportado();
636
+ },
637
+ enumerable: true,
638
+ configurable: true
639
+ });
640
+ AsistenteDatosComponent.prototype.onClickMicrofono = function () {
641
+ var _this = this;
642
+ if (this.escuchando) {
643
+ this.reconocimientoVoz.detener();
644
+ this.escuchando = false;
645
+ return;
646
+ }
647
+ if (!this.reconocimientoVoz.estaSoportado()) {
648
+ return;
649
+ }
650
+ // El resultado del reconocimiento no incluye lo que ya estaba escrito — se guarda antes de
651
+ // empezar y se antepone en cada actualización (que llega con la transcripción COMPLETA de
652
+ // esta sesión de escucha, no un incremento) para no perder lo que ya había en el campo.
653
+ var textoPrevio = this.borrador.trim();
654
+ this.escuchando = true;
655
+ this.reconocimientoVoz.iniciar(this.idioma, function (texto) { return (_this.borrador = textoPrevio ? textoPrevio + " " + texto : texto); }, function () { return (_this.escuchando = false); });
656
+ };
657
+ AsistenteDatosComponent.prototype.onClickEnviar = function (textoPreset) {
658
+ var _this = this;
659
+ var pregunta = ((textoPreset !== null && textoPreset !== void 0 ? textoPreset : this.borrador)).trim();
660
+ if (!pregunta || this.consultando) {
661
+ return;
662
+ }
663
+ this.mensajes.push({ deUsuario: true, texto: pregunta });
664
+ this.borrador = '';
665
+ // Sin url de consulta no se hace la petición: el usuario ve el mismo error genérico que
666
+ // cuando la API falla.
667
+ if (!this.asistenteDatosApiService.url) {
668
+ this.mensajes.push({
669
+ deUsuario: false,
670
+ texto: 'No se pudo procesar la consulta.',
671
+ esError: true,
672
+ });
673
+ this.scrollAlFinal();
674
+ return;
675
+ }
676
+ this.consultando = true;
677
+ this.scrollAlFinal();
678
+ this.asistenteDatosApiService.consultar(pregunta, this.proveedorSeleccionado).subscribe({
679
+ // El tipo (RespuestaAsistenteDatos) se infiere del Observable: importar la interfaz
680
+ // dejaba un import a un símbolo inexistente en el JS de la librería (aviso de rollup).
681
+ next: function (respuesta) {
682
+ var _a;
683
+ _this.consultando = false;
684
+ _this.mensajes.push({
685
+ deUsuario: false,
686
+ descripcion: respuesta.Descripcion,
687
+ resultado: (_a = respuesta.Resultado, (_a !== null && _a !== void 0 ? _a : [])),
688
+ proveedor: respuesta.Proveedor,
689
+ });
690
+ _this.scrollAlFinal();
691
+ },
692
+ error: function (error) {
693
+ var _a;
694
+ _this.consultando = false;
695
+ _this.mensajes.push({
696
+ deUsuario: false,
697
+ texto: ((_a = error) === null || _a === void 0 ? void 0 : _a.Mensaje) || 'No se pudo procesar la consulta.',
698
+ esError: true,
699
+ });
700
+ _this.scrollAlFinal();
701
+ },
702
+ });
703
+ };
704
+ // El nuevo mensaje recién se refleja en el DOM después del siguiente ciclo de detección de
705
+ // cambios — por eso el scrollTop se ajusta en un setTimeout(0), no inmediatamente después del
706
+ // push, para que scrollHeight ya incluya el mensaje agregado.
707
+ AsistenteDatosComponent.prototype.scrollAlFinal = function () {
708
+ var _this = this;
709
+ setTimeout(function () {
710
+ var _a;
711
+ var elemento = (_a = _this.mensajesContainer) === null || _a === void 0 ? void 0 : _a.nativeElement;
712
+ if (elemento) {
713
+ elemento.scrollTop = elemento.scrollHeight;
714
+ }
715
+ });
716
+ };
717
+ AsistenteDatosComponent.prototype.columnasDe = function (resultado) {
718
+ return resultado.length ? Object.keys(resultado[0]) : [];
719
+ };
720
+ // El backend devuelve un conteo (ChatConsultaIAServicio.EjecutarConteo) como una sola fila con
721
+ // una sola columna llamada literalmente "Resultado" — se muestra como número grande en vez de
722
+ // como tabla de una celda.
723
+ AsistenteDatosComponent.prototype.esConteo = function (resultado) {
724
+ var _a;
725
+ return ((_a = resultado) === null || _a === void 0 ? void 0 : _a.length) === 1 && Object.keys(resultado[0]).length === 1 && 'Resultado' in resultado[0];
726
+ };
727
+ // Listado con una sola columna (ej. una lista de nombres/ids) — se muestra como texto simple
728
+ // en vez de una tabla de una sola columna repetida.
729
+ AsistenteDatosComponent.prototype.esListaSimple = function (resultado) {
730
+ var _a;
731
+ return ((_a = resultado) === null || _a === void 0 ? void 0 : _a.length) > 0 && !this.esConteo(resultado) && this.columnasDe(resultado).length === 1;
732
+ };
733
+ AsistenteDatosComponent.prototype.textoListaSimple = function (resultado) {
734
+ var columna = this.columnasDe(resultado)[0];
735
+ return resultado.map(function (fila) { return fila[columna]; }).join(', ');
736
+ };
737
+ AsistenteDatosComponent.ctorParameters = function () { return [
738
+ { type: AsistenteDatosApiService },
739
+ { type: ReconocimientoVozService }
740
+ ]; };
741
+ __decorate([
742
+ ViewChild('mensajesContainer')
743
+ ], AsistenteDatosComponent.prototype, "mensajesContainer", void 0);
744
+ __decorate([
745
+ Input()
746
+ ], AsistenteDatosComponent.prototype, "abierto", void 0);
747
+ __decorate([
748
+ Input()
749
+ ], AsistenteDatosComponent.prototype, "urlConsultar", null);
750
+ __decorate([
751
+ Input()
752
+ ], AsistenteDatosComponent.prototype, "idioma", void 0);
753
+ __decorate([
754
+ Output()
755
+ ], AsistenteDatosComponent.prototype, "cerrarChange", void 0);
756
+ AsistenteDatosComponent = __decorate([
757
+ Component({
758
+ selector: 'wm-asistente-datos',
759
+ template: "<!-- Panel (abierto) -->\r\n<div class=\"chat-ia-panel\" *ngIf=\"abierto\">\r\n <div class=\"chat-ia-header\">\r\n <div class=\"chat-ia-header-info\">\r\n <div class=\"chat-ia-header-icono\">\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\">\r\n <path d=\"M4 5h16v10H9l-4 4V15H4z\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"chat-ia-titulo\">Preg\u00FAntale a tus Datos</div>\r\n <div class=\"chat-ia-subtitulo\">Consulta tus reportes en lenguaje natural</div>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-cerrar\" (click)=\"cerrar()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" stroke=\"#fff\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\">\r\n <path d=\"M6 6l12 12M18 6L6 18\"></path>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-mensajes\" #mensajesContainer>\r\n <div class=\"chat-ia-bienvenida-texto\">Hola, soy tu asistente de datos de Snap Forms. Preg\u00FAntame lo que quieras saber sobre tu operaci\u00F3n.</div>\r\n\r\n <div class=\"chat-ia-mensaje\" *ngFor=\"let mensaje of mensajes\" [class.chat-ia-mensaje-usuario]=\"mensaje.deUsuario\">\r\n <div class=\"chat-ia-burbuja\" [class.chat-ia-burbuja-error]=\"mensaje.esError\">\r\n <span *ngIf=\"mensaje.texto\">{{ mensaje.texto }}</span>\r\n\r\n <ng-container *ngIf=\"mensaje.resultado\">\r\n <div class=\"chat-ia-descripcion\" *ngIf=\"mensaje.descripcion\">{{ mensaje.descripcion }}</div>\r\n\r\n <div class=\"chat-ia-sin-resultados\" *ngIf=\"mensaje.resultado.length === 0\">La consulta no encontr\u00F3 resultados.</div>\r\n\r\n <div class=\"chat-ia-stat\" *ngIf=\"esConteo(mensaje.resultado)\">\r\n <div class=\"chat-ia-stat-valor\">{{ mensaje.resultado[0].Resultado | number }}</div>\r\n </div>\r\n\r\n <div class=\"chat-ia-lista-simple\" *ngIf=\"esListaSimple(mensaje.resultado)\">{{ textoListaSimple(mensaje.resultado) }}</div>\r\n\r\n <div class=\"chat-ia-tabla-resultado\" *ngIf=\"mensaje.resultado.length > 0 && !esConteo(mensaje.resultado) && !esListaSimple(mensaje.resultado)\">\r\n <table mat-table [dataSource]=\"mensaje.resultado\">\r\n <ng-container *ngFor=\"let columna of columnasDe(mensaje.resultado)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(mensaje.resultado)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(mensaje.resultado);\"></tr>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-pensando\" *ngIf=\"consultando\">\r\n <span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chips-chat-ia\">\r\n <span class=\"chip-chat-ia\" *ngFor=\"let chip of chipsSugeridos\"\r\n (click)=\"onClickEnviar(chip)\">{{ chip }}</span>\r\n </div>\r\n\r\n <div class=\"chat-ia-entrada\">\r\n <div class=\"chat-ia-caja-entrada\">\r\n <mat-icon class=\"chat-ia-expandir\" (click)=\"onClickExpandirBorrador()\">{{ borradorExpandido ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>\r\n <textarea [rows]=\"filasBorrador\" [(ngModel)]=\"borrador\" (keydown.enter)=\"$event.preventDefault(); onClickEnviar()\"\r\n [class.chat-ia-textarea-expandido]=\"borradorExpandido\"\r\n placeholder=\"Escribe tu pregunta...\"></textarea>\r\n <div class=\"chat-ia-pie-entrada\">\r\n <button class=\"chat-ia-selector-modelo\" [matMenuTriggerFor]=\"menuModeloChatIA\" type=\"button\">\r\n <span *ngIf=\"proveedorSeleccionado === 'Gemini'\">Gemini</span>\r\n <span *ngIf=\"proveedorSeleccionado === 'Groq'\">Groq</span>\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-microfono\" [class.chat-ia-microfono-activo]=\"escuchando\" *ngIf=\"micDisponible\"\r\n (click)=\"onClickMicrofono()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-enviar\" [disabled]=\"!borrador.trim() || consultando\" (click)=\"onClickEnviar()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 19V6\"></path>\r\n <path d=\"M5 13l7-7 7 7\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<mat-menu #menuModeloChatIA=\"matMenu\" class=\"menu-modelo-chat-ia\">\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Gemini'\"\r\n (click)=\"proveedorSeleccionado = 'Gemini'\">\r\n <span>Gemini</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Gemini'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Groq'\"\r\n (click)=\"proveedorSeleccionado = 'Groq'\">\r\n <span>Groq</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Groq'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n</mat-menu>\r\n",
760
+ styles: [":host{position:fixed;right:32px;bottom:32px;z-index:1000;font-family:Roboto,sans-serif}.chat-ia-panel{width:450px;height:650px;max-width:calc(100vw - 48px);max-height:calc(100vh - 96px);background:#fff;border-radius:18px;box-shadow:0 24px 60px rgba(20,25,30,.28);display:flex;flex-direction:column;overflow:hidden}.chat-ia-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:16px 18px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.chat-ia-header-info{display:flex;align-items:center;gap:10px;min-width:0}.chat-ia-header-icono{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;flex:none}.chat-ia-titulo{color:#fff;font-size:14px;font-weight:500}.chat-ia-subtitulo{color:rgba(255,255,255,.75);font-size:11px;margin-top:1px}.chat-ia-cerrar{width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:.85;flex:none}.chat-ia-cerrar:hover{opacity:1}.chat-ia-mensajes{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:12px;padding:16px;background:#fbfafc}.chat-ia-mensaje{display:flex}.chat-ia-mensaje .chat-ia-burbuja{max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chat-ia-mensaje .chat-ia-burbuja-error{background:#fdecea;color:#7a1f14}.chat-ia-mensaje.chat-ia-mensaje-usuario{justify-content:flex-end}.chat-ia-mensaje.chat-ia-mensaje-usuario .chat-ia-burbuja{background:#7c5ce0;color:#fff;border-radius:14px 14px 3px}.chat-ia-bienvenida-texto{align-self:flex-start;max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chips-chat-ia{flex:none;display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 10px}.chip-chat-ia{border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:14px;padding:5px 10px;font-size:11px;cursor:pointer}.chip-chat-ia:hover{background:#e7ddfa}.chat-ia-descripcion{font-size:13px;line-height:1.5;margin-bottom:6px}.chat-ia-sin-resultados{color:#5a5a5a;font-style:italic}.chat-ia-stat{margin-top:4px}.chat-ia-stat-valor{font-size:30px;font-weight:600;color:#5f42bd;line-height:1.15;font-variant-numeric:proportional-nums}.chat-ia-lista-simple,.chat-ia-tabla-resultado{margin-top:4px;background:#fff;border-radius:10px;padding:8px 10px}.chat-ia-lista-simple{font-size:13px;line-height:1.5}.chat-ia-tabla-resultado{overflow-x:auto;max-width:100%;padding:4px 10px}.chat-ia-tabla-resultado table{font-size:12px;background:0 0}.chat-ia-tabla-resultado th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 14px 5px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-tabla-resultado td.mat-cell{padding:7px 14px 0 0;white-space:nowrap;font-variant-numeric:tabular-nums}.chat-ia-pensando{align-self:flex-start;background:#f2eefb;padding:12px 16px;border-radius:14px 14px 14px 3px;display:flex;gap:5px;flex-shrink:0}.chat-ia-dot{width:6px;height:6px;border-radius:50%;background:#9a93ae;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}.chat-ia-dot:nth-child(2){-webkit-animation-delay:.15s;animation-delay:.15s}.chat-ia-dot:nth-child(3){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}@keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}.chat-ia-entrada{padding:10px 14px 14px;border-top:1px solid #e9f2ee;flex-shrink:0}.chat-ia-caja-entrada{position:relative;background:#f2f7f5;border:1px solid #e6efea;border-radius:18px;padding:10px 12px 8px}.chat-ia-caja-entrada textarea{border:none;outline:0;background:0 0;width:100%;font:inherit;font-size:13.5px;color:#26313a;resize:none;line-height:1.45;max-height:110px;overflow-y:auto;display:block;padding:0 28px 0 0}.chat-ia-caja-entrada textarea.chat-ia-textarea-expandido{max-height:160px}.chat-ia-caja-entrada textarea::-webkit-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-moz-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea:-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::placeholder{color:#9a93ae}.chat-ia-expandir{position:absolute;top:8px;right:10px;font-size:17px;height:17px;width:17px;color:#9a9a9a;cursor:pointer}.chat-ia-pie-entrada{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:8px}.chat-ia-selector-modelo{display:inline-flex;align-items:center;gap:4px;border:none;background:0 0;color:#4e5d57;border-radius:14px;padding:5px 9px;font-size:11.5px;font-weight:600;cursor:pointer}.chat-ia-enviar{width:32px;height:32px;border-radius:50%;border:none;background:#7c5ce0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-enviar:disabled{background:#dce6e1;color:#a9bab3;cursor:default}.chat-ia-microfono{width:28px;height:28px;border-radius:50%;border:none;background:0 0;color:#6b6478;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-microfono:hover{background:#f2eefb}.chat-ia-microfono.chat-ia-microfono-activo{color:#fff;background:#e05a5a;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}::ng-deep .mat-menu-panel.menu-modelo-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;height:auto;line-height:normal;padding:7px 10px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item.opcion-activa{background:#f2f7f5}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item .chat-ia-check{color:#7c5ce0}"]
761
+ })
762
+ ], AsistenteDatosComponent);
763
+ return AsistenteDatosComponent;
764
+ }());
765
+
432
766
  var WmMenuModule = /** @class */ (function () {
433
767
  function WmMenuModule() {
434
768
  }
435
769
  WmMenuModule = __decorate([
436
770
  NgModule({
437
- declarations: [WmMenuComponent],
771
+ declarations: [WmMenuComponent, AsistenteDatosComponent],
438
772
  imports: [
439
773
  BrowserModule,
774
+ FormsModule,
440
775
  MatToolbarModule,
441
776
  MatSidenavModule,
442
777
  MatListModule,
443
778
  MatButtonModule,
444
779
  MatIconModule,
445
780
  MatMenuModule,
781
+ MatTableModule,
782
+ MatTooltipModule,
446
783
  MatRippleModule,
447
784
  HttpClientModule,
448
785
  JwtModule
@@ -461,5 +798,5 @@ var WmMenuModule = /** @class */ (function () {
461
798
  * Generated bundle index. Do not edit.
462
799
  */
463
800
 
464
- export { WmMenuAlertaPanicoService, WmMenuComponent, WmMenuModule, WmMenuServicioService };
801
+ export { WmMenuAlertaPanicoService, WmMenuComponent, WmMenuModule, WmMenuServicioService, AsistenteDatosComponent as ɵa, AsistenteDatosApiService as ɵb, ReconocimientoVozService as ɵc };
465
802
  //# sourceMappingURL=wm-menu.js.map