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
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('rxjs/operators'), require('rxjs'), require('@angular/platform-browser'), require('@angular/material/icon'), require('@auth0/angular-jwt'), require('@angular/material/toolbar'), require('@angular/material/sidenav'), require('@angular/material/list'), require('@angular/material/button'), require('@angular/material/menu'), require('@angular/material/core')) :
3
- typeof define === 'function' && define.amd ? define('wm-menu', ['exports', '@angular/core', '@angular/common/http', 'rxjs/operators', 'rxjs', '@angular/platform-browser', '@angular/material/icon', '@auth0/angular-jwt', '@angular/material/toolbar', '@angular/material/sidenav', '@angular/material/list', '@angular/material/button', '@angular/material/menu', '@angular/material/core'], factory) :
4
- (global = global || self, factory(global['wm-menu'] = {}, global.ng.core, global.ng.common.http, global.rxjs.operators, global.rxjs, global.ng.platformBrowser, global.ng.material.icon, global.angularJwt, global.ng.material.toolbar, global.ng.material.sidenav, global.ng.material.list, global.ng.material.button, global.ng.material.menu, global.ng.material.core));
5
- }(this, (function (exports, core, http, operators, rxjs, platformBrowser, icon, angularJwt, toolbar, sidenav, list, button, menu, core$1) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('rxjs/operators'), require('rxjs'), require('@angular/platform-browser'), require('@angular/material/icon'), require('@auth0/angular-jwt'), require('@angular/material/toolbar'), require('@angular/material/sidenav'), require('@angular/material/list'), require('@angular/material/button'), require('@angular/material/menu'), require('@angular/material/table'), require('@angular/material/tooltip'), require('@angular/material/core'), require('@angular/forms')) :
3
+ typeof define === 'function' && define.amd ? define('wm-menu', ['exports', '@angular/core', '@angular/common/http', 'rxjs/operators', 'rxjs', '@angular/platform-browser', '@angular/material/icon', '@auth0/angular-jwt', '@angular/material/toolbar', '@angular/material/sidenav', '@angular/material/list', '@angular/material/button', '@angular/material/menu', '@angular/material/table', '@angular/material/tooltip', '@angular/material/core', '@angular/forms'], factory) :
4
+ (global = global || self, factory(global['wm-menu'] = {}, global.ng.core, global.ng.common.http, global.rxjs.operators, global.rxjs, global.ng.platformBrowser, global.ng.material.icon, global.angularJwt, global.ng.material.toolbar, global.ng.material.sidenav, global.ng.material.list, global.ng.material.button, global.ng.material.menu, global.ng.material.table, global.ng.material.tooltip, global.ng.material.core, global.ng.forms));
5
+ }(this, (function (exports, core, http, operators, rxjs, platformBrowser, icon, angularJwt, toolbar, sidenav, list, button, menu, table, tooltip, core$1, forms) { 'use strict';
6
6
 
7
7
  /*! *****************************************************************************
8
8
  Copyright (c) Microsoft Corporation.
@@ -310,6 +310,14 @@
310
310
  return rxjs.throwError(error.error);
311
311
  }));
312
312
  };
313
+ // Funciones (permisos) del usuario autenticado, para gatear features del menú como el
314
+ // asistente "Pregúntale a tus datos" (CodigoLogica === 'WebChatConsultaIA').
315
+ WmMenuServicioService.prototype.funcionesObtener = function (url, token) {
316
+ var headers = new http.HttpHeaders({
317
+ 'Authorization': "Bearer " + token
318
+ });
319
+ return this.http.get(url, { headers: headers }).pipe(operators.map(function (resp) { return resp; }), operators.catchError(function (error) { return rxjs.throwError(error.error); }));
320
+ };
313
321
  WmMenuServicioService.ctorParameters = function () { return [
314
322
  { type: http.HttpClient },
315
323
  { type: icon.MatIconRegistry },
@@ -333,28 +341,23 @@
333
341
  this.IdsAlertasPanicoActivas = new Set(); // Almacena los IDs de las alertas ya manejadas
334
342
  this.soundTimeout = null; // Controla el temporizador del sonido
335
343
  this.isRunning = false;
336
- console.log('WmMenuAlertaPanicoService inicializado.');
337
344
  }
338
345
  WmMenuAlertaPanicoService.prototype.iniciarProceso = function (intervalMs, callback, urlObtenerParametro, token, rutaAudio) {
339
346
  var _this = this;
340
- console.log('iniciarProceso llamado con parámetros:', { intervalMs: intervalMs, urlObtenerParametro: urlObtenerParametro, token: token, rutaAudio: rutaAudio });
341
347
  this.rutaAudio = rutaAudio;
342
348
  var iniciarConInteraccion = function () {
343
- console.log('iniciarConInteraccion ejecutado.');
344
349
  _this.wmMenuServicioService
345
350
  .menuApiObtener(urlObtenerParametro, null, token, 'ReporteAlertasPanico')
346
351
  .subscribe(function (resp) {
347
- console.log('Respuesta obtenida de menuApiObtener:', resp);
352
+ // validar si el parametro ReporteAlertasPanico esta encendido
348
353
  if (resp && resp.length > 0 && resp[0].Valor == 1) {
349
354
  if (_this.isRunning) {
350
- console.log('Proceso ya está corriendo.');
351
355
  return;
352
356
  }
357
+ // Inicializar la variable desde localStorage
353
358
  var storedIds = localStorage.getItem('ALERTAS_PANICO_ACTIVAS_WM');
354
359
  _this.IdsAlertasPanicoActivas = storedIds ? new Set(JSON.parse(storedIds)) : new Set();
355
- console.log('IdsAlertasPanicoActivas inicializado:', _this.IdsAlertasPanicoActivas);
356
360
  var ejecutarProceso_1 = function () {
357
- console.log('ejecutarProceso iniciado.');
358
361
  _this.isRunning = true;
359
362
  callback();
360
363
  setTimeout(function () {
@@ -367,49 +370,42 @@
367
370
  });
368
371
  };
369
372
  ['drag', 'click'].forEach(function (evento) {
370
- console.log("Evento " + evento + " registrado para iniciar proceso.");
371
373
  document.addEventListener(evento, function () {
372
374
  iniciarConInteraccion();
373
375
  }, { once: true });
374
376
  });
375
377
  };
376
378
  WmMenuAlertaPanicoService.prototype.stopProcess = function () {
377
- console.log('stopProcess ejecutado.');
378
379
  this.isRunning = false;
379
380
  if (this.subscription) {
380
381
  this.subscription.unsubscribe();
381
382
  }
382
383
  };
383
384
  WmMenuAlertaPanicoService.prototype.ngOnDestroy = function () {
384
- console.log('ngOnDestroy ejecutado.');
385
385
  this.stopSound();
386
386
  this.stopFlashingTitle();
387
387
  };
388
388
  WmMenuAlertaPanicoService.prototype.playSound = function () {
389
389
  var _this = this;
390
- console.log('playSound llamado.');
391
390
  if (this.isPlaying)
392
391
  return; // Evita reproducir si ya está sonando
393
392
  this.isPlaying = true;
394
393
  if (!this.audio) {
395
394
  this.audio = new Audio(this.rutaAudio); // Ruta al archivo de sonido
396
395
  }
397
- console.log("Audio cargado: ", this.audio);
398
396
  this.audio.loop = true; // Reproducir en bucle
399
397
  this.audio.play()
400
398
  .then(function () {
401
- console.log('Sonido reproduciéndose.');
402
399
  // Detener el sonido después de 10 segundos
403
400
  _this.soundTimeout = setTimeout(function () {
404
401
  _this.stopSound();
405
402
  }, 10000); // Detener después de 10 segundos
406
403
  })
407
404
  .catch(function (error) {
408
- console.error('Error al reproducir el sonido:', error);
405
+ console.log('Error al reproducir el sonido:', error);
409
406
  });
410
407
  };
411
408
  WmMenuAlertaPanicoService.prototype.stopSound = function () {
412
- console.log('stopSound llamado.');
413
409
  if (this.audio) {
414
410
  this.audio.pause();
415
411
  this.audio.currentTime = 0; // Reinicia el sonido
@@ -422,7 +418,6 @@
422
418
  };
423
419
  WmMenuAlertaPanicoService.prototype.startFlashingTitle = function () {
424
420
  var _this = this;
425
- console.log('startFlashingTitle llamado.');
426
421
  var toggle = false;
427
422
  // Almacenar el título original si aún no se ha guardado
428
423
  if (!this.originalTitle) {
@@ -437,7 +432,6 @@
437
432
  }
438
433
  };
439
434
  WmMenuAlertaPanicoService.prototype.stopFlashingTitle = function () {
440
- console.log('stopFlashingTitle llamado.');
441
435
  if (this.intervalId) {
442
436
  clearInterval(this.intervalId);
443
437
  this.intervalId = null;
@@ -446,16 +440,13 @@
446
440
  };
447
441
  WmMenuAlertaPanicoService.prototype.revisarAlertasPendientes = function (urlObtenerAlertasPanico, token) {
448
442
  var _this = this;
449
- console.log('revisarAlertasPendientes llamado con parámetros:', { urlObtenerAlertasPanico: urlObtenerAlertasPanico, token: token });
450
443
  var helper = new angularJwt.JwtHelperService();
451
444
  var decodedToken = helper.decodeToken(token);
452
445
  this.wmMenuServicioService
453
446
  .menuApiObtener(urlObtenerAlertasPanico, decodedToken['id_usuario'], token)
454
447
  .subscribe(function (resp) {
455
- console.log('Respuesta obtenida de revisarAlertasPendientes:', resp);
456
448
  if (resp && resp.length > 0) {
457
449
  var alertasIds_1 = resp.map(function (alerta) { return alerta.IdAlertaPanico; });
458
- console.log('IDs de alertas obtenidas:', alertasIds_1);
459
450
  // Eliminar IDs que no están en la respuesta del servicio
460
451
  _this.IdsAlertasPanicoActivas.forEach(function (id) {
461
452
  if (!alertasIds_1.includes(id)) {
@@ -496,18 +487,38 @@
496
487
  }());
497
488
 
498
489
  var WmMenuComponent = /** @class */ (function () {
499
- function WmMenuComponent(wmMenuServicioService, wmMenuAlertaPanicoService) {
490
+ function WmMenuComponent(wmMenuServicioService, alertaPanicoService) {
500
491
  this.wmMenuServicioService = wmMenuServicioService;
501
- this.wmMenuAlertaPanicoService = wmMenuAlertaPanicoService;
502
- this.intervaloPeticionesMs = 60000;
492
+ this.alertaPanicoService = alertaPanicoService;
493
+ this.mostrarAsistente = false;
494
+ this.idiomaAsistente = 'es-CO';
495
+ this.asistenteAbierto = false;
496
+ this.funcionesUsuario = [];
503
497
  this.menuSecundarioSel = new MenuSecundario();
504
498
  this.menuLateralAbierto = false;
505
499
  this.menuIdioma = [];
500
+ this.intervaloPeticionesMs = 60000;
506
501
  }
502
+ Object.defineProperty(WmMenuComponent.prototype, "puedeAsistente", {
503
+ get: function () {
504
+ var forzado = this.mostrarAsistente === true || this.mostrarAsistente === 'true' || this.mostrarAsistente === '1';
505
+ var tienePermiso = this.funcionesUsuario.some(function (f) { return f.CodigoLogica === 'WebChatConsultaIA'; });
506
+ return forzado || tienePermiso;
507
+ },
508
+ enumerable: true,
509
+ configurable: true
510
+ });
507
511
  WmMenuComponent.prototype.ngOnInit = function () {
508
512
  var _this = this;
509
- this.wmMenuAlertaPanicoService.iniciarProceso(this.intervaloPeticionesMs, function () { return _this.wmMenuAlertaPanicoService.revisarAlertasPendientes(_this.urlObtenerAlertasPanico, _this.token); }, this.urlObtenerParametro, this.token, this.rutaAudio);
510
513
  this.cargarMenuCuenta();
514
+ this.alertaPanicoService.iniciarProceso(this.intervaloPeticionesMs, function () { return _this.alertaPanicoService.revisarAlertasPendientes(_this.urlObtenerAlertasPanico, _this.token); }, this.urlObtenerParametro, this.token, this.rutaAudio);
515
+ // Carga las funciones del usuario para gatear el asistente (puedeAsistente / WebChatConsultaIA).
516
+ // Si falla (ej. 401), queda vacía y el asistente no se muestra.
517
+ if (this.urlObtenerFunciones && this.token) {
518
+ this.wmMenuServicioService
519
+ .funcionesObtener(this.urlObtenerFunciones, this.token)
520
+ .subscribe(function (resp) { _this.funcionesUsuario = (resp !== null && resp !== void 0 ? resp : []); }, function () { _this.funcionesUsuario = []; });
521
+ }
511
522
  if (this.urlMenu && this.token) {
512
523
  var helper = new angularJwt.JwtHelperService();
513
524
  var decodedToken = helper.decodeToken(this.token);
@@ -629,30 +640,353 @@
629
640
  __decorate([
630
641
  core.Input()
631
642
  ], WmMenuComponent.prototype, "urlIdiomas", void 0);
643
+ __decorate([
644
+ core.Input()
645
+ ], WmMenuComponent.prototype, "urlObtenerFunciones", void 0);
646
+ __decorate([
647
+ core.Input()
648
+ ], WmMenuComponent.prototype, "mostrarAsistente", void 0);
649
+ __decorate([
650
+ core.Input()
651
+ ], WmMenuComponent.prototype, "urlAsistenteConsultar", void 0);
652
+ __decorate([
653
+ core.Input()
654
+ ], WmMenuComponent.prototype, "idiomaAsistente", void 0);
632
655
  WmMenuComponent = __decorate([
633
656
  core.Component({
634
657
  selector: 'wm-menu',
635
- 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>",
636
- 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}"]
658
+ 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>",
659
+ 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}"]
637
660
  })
638
661
  ], WmMenuComponent);
639
662
  return WmMenuComponent;
640
663
  }());
641
664
 
665
+ // Envoltorio de la Web Speech API (SpeechRecognition) del navegador — dictado de voz a texto,
666
+ // 100% cliente, sin backend. Soportado en Chrome/Edge; SIN soporte en Firefox y de forma
667
+ // inconsistente en Safari (limitación real del navegador, no de esta implementación).
668
+ var ReconocimientoVozService = /** @class */ (function () {
669
+ function ReconocimientoVozService() {
670
+ this.reconocimiento = null;
671
+ }
672
+ ReconocimientoVozService.prototype.estaSoportado = function () {
673
+ return !!(this.obtenerConstructor());
674
+ };
675
+ // onResultado se llama con el texto reconocido hasta el momento (incluye resultados
676
+ // provisionales — interimResults: true — para que el cuadro de texto se vea llenar en vivo).
677
+ // onFin se llama cuando el reconocimiento termina, ya sea porque el navegador detectó una
678
+ // pausa (continuous: false) o porque se llamó a detener().
679
+ ReconocimientoVozService.prototype.iniciar = function (idioma, onResultado, onFin) {
680
+ var _this = this;
681
+ var SpeechRecognitionCtor = this.obtenerConstructor();
682
+ if (!SpeechRecognitionCtor) {
683
+ onFin();
684
+ return;
685
+ }
686
+ this.detener();
687
+ this.reconocimiento = new SpeechRecognitionCtor();
688
+ this.reconocimiento.lang = idioma;
689
+ this.reconocimiento.continuous = false;
690
+ this.reconocimiento.interimResults = true;
691
+ this.reconocimiento.onresult = function (evento) {
692
+ var texto = Array.from(evento.results)
693
+ .map(function (resultado) { return resultado[0].transcript; })
694
+ .join(' ');
695
+ onResultado(texto);
696
+ };
697
+ this.reconocimiento.onerror = function (evento) {
698
+ var _a;
699
+ // Motivos típicos (event.error de SpeechRecognitionErrorEvent): "not-allowed" (permiso de
700
+ // micrófono denegado o sitio sin HTTPS/localhost), "no-speech", "audio-capture" (sin
701
+ // micrófono), "network". Se deja en consola porque no hay backend que lo registre y el
702
+ // navegador no explica el motivo en la UI.
703
+ console.error('Reconocimiento de voz: error -', (_a = evento) === null || _a === void 0 ? void 0 : _a.error);
704
+ _this.reconocimiento = null;
705
+ onFin();
706
+ };
707
+ this.reconocimiento.onend = function () {
708
+ _this.reconocimiento = null;
709
+ onFin();
710
+ };
711
+ try {
712
+ this.reconocimiento.start();
713
+ }
714
+ catch (e) {
715
+ console.error('Reconocimiento de voz: no se pudo iniciar -', e);
716
+ this.reconocimiento = null;
717
+ onFin();
718
+ }
719
+ };
720
+ ReconocimientoVozService.prototype.detener = function () {
721
+ if (this.reconocimiento) {
722
+ this.reconocimiento.onend = null;
723
+ this.reconocimiento.onerror = null;
724
+ this.reconocimiento.stop();
725
+ this.reconocimiento = null;
726
+ }
727
+ };
728
+ ReconocimientoVozService.prototype.obtenerConstructor = function () {
729
+ return window.SpeechRecognition || window.webkitSpeechRecognition || null;
730
+ };
731
+ ReconocimientoVozService.ɵprov = core.ɵɵdefineInjectable({ factory: function ReconocimientoVozService_Factory() { return new ReconocimientoVozService(); }, token: ReconocimientoVozService, providedIn: "root" });
732
+ ReconocimientoVozService = __decorate([
733
+ core.Injectable({
734
+ providedIn: 'root',
735
+ })
736
+ ], ReconocimientoVozService);
737
+ return ReconocimientoVozService;
738
+ }());
739
+
740
+ var AsistenteDatosApiService = /** @class */ (function () {
741
+ function AsistenteDatosApiService(http) {
742
+ this.http = http;
743
+ // La fija el componente desde su @Input urlConsultar (reemplaza WmChatConfigService.urlConsultar).
744
+ this.url = '';
745
+ // Mismo origen del JWT que WmSeguridadService.getJWT() en wm-chat: localStorage['WMTKN'],
746
+ // descartado si está vencido. Se replica aquí para que el header Authorization sea idéntico
747
+ // al del chat original sin depender de un servicio de config externo.
748
+ this.TOKEN_KEY = 'WMTKN';
749
+ this.jwtHelper = new angularJwt.JwtHelperService();
750
+ }
751
+ AsistenteDatosApiService.prototype.consultar = function (pregunta, proveedor) {
752
+ var headers = new http.HttpHeaders({
753
+ Authorization: "Bearer " + this.obtenerJWT(),
754
+ 'Content-Type': 'application/json; charset=utf-8',
755
+ });
756
+ return this.http
757
+ .post(this.url, { Pregunta: pregunta, Proveedor: proveedor }, { headers: headers })
758
+ .pipe(operators.catchError(function (error) {
759
+ return rxjs.throwError(error.error);
760
+ }));
761
+ };
762
+ AsistenteDatosApiService.prototype.obtenerJWT = function () {
763
+ var jwt = localStorage.getItem(this.TOKEN_KEY);
764
+ if (jwt) {
765
+ try {
766
+ return this.jwtHelper.isTokenExpired(jwt) ? null : jwt;
767
+ }
768
+ catch (_a) { }
769
+ }
770
+ return null;
771
+ };
772
+ AsistenteDatosApiService.ctorParameters = function () { return [
773
+ { type: http.HttpClient }
774
+ ]; };
775
+ AsistenteDatosApiService.ɵprov = core.ɵɵdefineInjectable({ factory: function AsistenteDatosApiService_Factory() { return new AsistenteDatosApiService(core.ɵɵinject(http.HttpClient)); }, token: AsistenteDatosApiService, providedIn: "root" });
776
+ AsistenteDatosApiService = __decorate([
777
+ core.Injectable({
778
+ providedIn: 'root',
779
+ })
780
+ ], AsistenteDatosApiService);
781
+ return AsistenteDatosApiService;
782
+ }());
783
+
784
+ var AsistenteDatosComponent = /** @class */ (function () {
785
+ function AsistenteDatosComponent(asistenteDatosApiService, reconocimientoVoz) {
786
+ this.asistenteDatosApiService = asistenteDatosApiService;
787
+ this.reconocimientoVoz = reconocimientoVoz;
788
+ // La apertura/cierre del panel la controla el padre (el menú). El panel solo se renderiza
789
+ // cuando `abierto` es true y avisa, vía `cerrarChange`, cuando el usuario toca la X.
790
+ this.abierto = false;
791
+ // Idioma para el reconocimiento de voz (Web Speech API).
792
+ this.idioma = 'es-CO';
793
+ this.cerrarChange = new core.EventEmitter();
794
+ this.mensajes = [];
795
+ this.borrador = '';
796
+ // Alterna el alto de la caja del mensaje (compacta ↔ expandida), igual que el "pedir cambios"
797
+ // del asistente de IA del generador de formularios (ver filasBorrador / onClickExpandirBorrador).
798
+ this.borradorExpandido = false;
799
+ this.consultando = false;
800
+ // "Gemini" o "Groq" — mismo selector que el asistente de generación de formularios
801
+ // (ver ProveedorIAServicio en el backend).
802
+ this.proveedorSeleccionado = 'Gemini';
803
+ // Dictado por voz (Web Speech API) — sin soporte en Firefox, inconsistente en Safari.
804
+ this.escuchando = false;
805
+ // Preguntas ya verificadas como respondibles hoy (whitelist + contrato de la IA — ver
806
+ // ChatConsultaWhitelistServicio/ChatConsultaPromptServicio en el backend), mostradas como chips
807
+ // de sugerencia en el estado vacío del chat.
808
+ this.chipsSugeridos = [
809
+ '¿Cuántos formularios se diligenciaron hoy?',
810
+ '¿Cuántos formularios se diligenciaron esta semana?',
811
+ 'Muéstrame los últimos 10 formularios diligenciados',
812
+ ];
813
+ }
814
+ Object.defineProperty(AsistenteDatosComponent.prototype, "urlConsultar", {
815
+ // URL del POST de consulta. Se refleja en el api service (propiedad `url`), que es donde se usa.
816
+ set: function (valor) {
817
+ if (valor) {
818
+ this.asistenteDatosApiService.url = valor;
819
+ }
820
+ },
821
+ enumerable: true,
822
+ configurable: true
823
+ });
824
+ // El padre abre/cierra el panel; aquí solo se avisa que el usuario pidió cerrarlo (botón X).
825
+ AsistenteDatosComponent.prototype.cerrar = function () {
826
+ this.cerrarChange.emit();
827
+ };
828
+ Object.defineProperty(AsistenteDatosComponent.prototype, "filasBorrador", {
829
+ // Caja del mensaje compacta (1 fila, como era el chat originalmente) ↔ expandida (6 filas).
830
+ // El botón de expandir es el mismo patrón del "pedir cambios" del generador.
831
+ get: function () {
832
+ return this.borradorExpandido ? 6 : 1;
833
+ },
834
+ enumerable: true,
835
+ configurable: true
836
+ });
837
+ AsistenteDatosComponent.prototype.onClickExpandirBorrador = function () {
838
+ this.borradorExpandido = !this.borradorExpandido;
839
+ };
840
+ Object.defineProperty(AsistenteDatosComponent.prototype, "micDisponible", {
841
+ get: function () {
842
+ return this.reconocimientoVoz.estaSoportado();
843
+ },
844
+ enumerable: true,
845
+ configurable: true
846
+ });
847
+ AsistenteDatosComponent.prototype.onClickMicrofono = function () {
848
+ var _this = this;
849
+ if (this.escuchando) {
850
+ this.reconocimientoVoz.detener();
851
+ this.escuchando = false;
852
+ return;
853
+ }
854
+ if (!this.reconocimientoVoz.estaSoportado()) {
855
+ return;
856
+ }
857
+ // El resultado del reconocimiento no incluye lo que ya estaba escrito — se guarda antes de
858
+ // empezar y se antepone en cada actualización (que llega con la transcripción COMPLETA de
859
+ // esta sesión de escucha, no un incremento) para no perder lo que ya había en el campo.
860
+ var textoPrevio = this.borrador.trim();
861
+ this.escuchando = true;
862
+ this.reconocimientoVoz.iniciar(this.idioma, function (texto) { return (_this.borrador = textoPrevio ? textoPrevio + " " + texto : texto); }, function () { return (_this.escuchando = false); });
863
+ };
864
+ AsistenteDatosComponent.prototype.onClickEnviar = function (textoPreset) {
865
+ var _this = this;
866
+ var pregunta = ((textoPreset !== null && textoPreset !== void 0 ? textoPreset : this.borrador)).trim();
867
+ if (!pregunta || this.consultando) {
868
+ return;
869
+ }
870
+ this.mensajes.push({ deUsuario: true, texto: pregunta });
871
+ this.borrador = '';
872
+ // Sin url de consulta no se hace la petición: el usuario ve el mismo error genérico que
873
+ // cuando la API falla.
874
+ if (!this.asistenteDatosApiService.url) {
875
+ this.mensajes.push({
876
+ deUsuario: false,
877
+ texto: 'No se pudo procesar la consulta.',
878
+ esError: true,
879
+ });
880
+ this.scrollAlFinal();
881
+ return;
882
+ }
883
+ this.consultando = true;
884
+ this.scrollAlFinal();
885
+ this.asistenteDatosApiService.consultar(pregunta, this.proveedorSeleccionado).subscribe({
886
+ // El tipo (RespuestaAsistenteDatos) se infiere del Observable: importar la interfaz
887
+ // dejaba un import a un símbolo inexistente en el JS de la librería (aviso de rollup).
888
+ next: function (respuesta) {
889
+ var _a;
890
+ _this.consultando = false;
891
+ _this.mensajes.push({
892
+ deUsuario: false,
893
+ descripcion: respuesta.Descripcion,
894
+ resultado: (_a = respuesta.Resultado, (_a !== null && _a !== void 0 ? _a : [])),
895
+ proveedor: respuesta.Proveedor,
896
+ });
897
+ _this.scrollAlFinal();
898
+ },
899
+ error: function (error) {
900
+ var _a;
901
+ _this.consultando = false;
902
+ _this.mensajes.push({
903
+ deUsuario: false,
904
+ texto: ((_a = error) === null || _a === void 0 ? void 0 : _a.Mensaje) || 'No se pudo procesar la consulta.',
905
+ esError: true,
906
+ });
907
+ _this.scrollAlFinal();
908
+ },
909
+ });
910
+ };
911
+ // El nuevo mensaje recién se refleja en el DOM después del siguiente ciclo de detección de
912
+ // cambios — por eso el scrollTop se ajusta en un setTimeout(0), no inmediatamente después del
913
+ // push, para que scrollHeight ya incluya el mensaje agregado.
914
+ AsistenteDatosComponent.prototype.scrollAlFinal = function () {
915
+ var _this = this;
916
+ setTimeout(function () {
917
+ var _a;
918
+ var elemento = (_a = _this.mensajesContainer) === null || _a === void 0 ? void 0 : _a.nativeElement;
919
+ if (elemento) {
920
+ elemento.scrollTop = elemento.scrollHeight;
921
+ }
922
+ });
923
+ };
924
+ AsistenteDatosComponent.prototype.columnasDe = function (resultado) {
925
+ return resultado.length ? Object.keys(resultado[0]) : [];
926
+ };
927
+ // El backend devuelve un conteo (ChatConsultaIAServicio.EjecutarConteo) como una sola fila con
928
+ // una sola columna llamada literalmente "Resultado" — se muestra como número grande en vez de
929
+ // como tabla de una celda.
930
+ AsistenteDatosComponent.prototype.esConteo = function (resultado) {
931
+ var _a;
932
+ return ((_a = resultado) === null || _a === void 0 ? void 0 : _a.length) === 1 && Object.keys(resultado[0]).length === 1 && 'Resultado' in resultado[0];
933
+ };
934
+ // Listado con una sola columna (ej. una lista de nombres/ids) — se muestra como texto simple
935
+ // en vez de una tabla de una sola columna repetida.
936
+ AsistenteDatosComponent.prototype.esListaSimple = function (resultado) {
937
+ var _a;
938
+ return ((_a = resultado) === null || _a === void 0 ? void 0 : _a.length) > 0 && !this.esConteo(resultado) && this.columnasDe(resultado).length === 1;
939
+ };
940
+ AsistenteDatosComponent.prototype.textoListaSimple = function (resultado) {
941
+ var columna = this.columnasDe(resultado)[0];
942
+ return resultado.map(function (fila) { return fila[columna]; }).join(', ');
943
+ };
944
+ AsistenteDatosComponent.ctorParameters = function () { return [
945
+ { type: AsistenteDatosApiService },
946
+ { type: ReconocimientoVozService }
947
+ ]; };
948
+ __decorate([
949
+ core.ViewChild('mensajesContainer')
950
+ ], AsistenteDatosComponent.prototype, "mensajesContainer", void 0);
951
+ __decorate([
952
+ core.Input()
953
+ ], AsistenteDatosComponent.prototype, "abierto", void 0);
954
+ __decorate([
955
+ core.Input()
956
+ ], AsistenteDatosComponent.prototype, "urlConsultar", null);
957
+ __decorate([
958
+ core.Input()
959
+ ], AsistenteDatosComponent.prototype, "idioma", void 0);
960
+ __decorate([
961
+ core.Output()
962
+ ], AsistenteDatosComponent.prototype, "cerrarChange", void 0);
963
+ AsistenteDatosComponent = __decorate([
964
+ core.Component({
965
+ selector: 'wm-asistente-datos',
966
+ 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",
967
+ 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}"]
968
+ })
969
+ ], AsistenteDatosComponent);
970
+ return AsistenteDatosComponent;
971
+ }());
972
+
642
973
  var WmMenuModule = /** @class */ (function () {
643
974
  function WmMenuModule() {
644
975
  }
645
976
  WmMenuModule = __decorate([
646
977
  core.NgModule({
647
- declarations: [WmMenuComponent],
978
+ declarations: [WmMenuComponent, AsistenteDatosComponent],
648
979
  imports: [
649
980
  platformBrowser.BrowserModule,
981
+ forms.FormsModule,
650
982
  toolbar.MatToolbarModule,
651
983
  sidenav.MatSidenavModule,
652
984
  list.MatListModule,
653
985
  button.MatButtonModule,
654
986
  icon.MatIconModule,
655
987
  menu.MatMenuModule,
988
+ table.MatTableModule,
989
+ tooltip.MatTooltipModule,
656
990
  core$1.MatRippleModule,
657
991
  http.HttpClientModule,
658
992
  angularJwt.JwtModule
@@ -667,6 +1001,9 @@
667
1001
  exports.WmMenuComponent = WmMenuComponent;
668
1002
  exports.WmMenuModule = WmMenuModule;
669
1003
  exports.WmMenuServicioService = WmMenuServicioService;
1004
+ exports.ɵa = AsistenteDatosComponent;
1005
+ exports.ɵb = AsistenteDatosApiService;
1006
+ exports.ɵc = ReconocimientoVozService;
670
1007
 
671
1008
  Object.defineProperty(exports, '__esModule', { value: true });
672
1009