ngx-dsxlibrary 1.21.98 → 2.21.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.
@@ -884,26 +884,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
884
884
  type: Input
885
885
  }] } });
886
886
 
887
+ /**
888
+ * Servicio centralizado para controlar el estado de carga global.
889
+ *
890
+ * Expone una señal (`spinnerVisible`) que puede consumirse en componentes
891
+ * para mostrar u ocultar un spinner.
892
+ *
893
+ * Uso recomendado:
894
+ * - `show()` / `hide()` para flujos con múltiples operaciones concurrentes.
895
+ * - `showImmediate()` para feedback visual inmediato (sin afectar contador).
896
+ * - `reset()` para recuperar estado en errores inesperados.
897
+ */
887
898
  class SpinnerLoadingService {
888
- // Señal para el estado de visibilidad del spinner
899
+ /**
900
+ * Señal reactiva que indica si el spinner debe mostrarse.
901
+ *
902
+ * Ejemplo:
903
+ * ```ts
904
+ * readonly isLoading = this.spinnerLoadingService.spinnerVisible;
905
+ * ```
906
+ */
889
907
  spinnerVisible = signal(false, ...(ngDevMode ? [{ debugName: "spinnerVisible" }] : /* istanbul ignore next */ []));
890
- // Contador de peticiones/acciones activas
908
+ /**
909
+ * Contador interno de operaciones activas.
910
+ * Permite que el spinner permanezca visible mientras haya procesos en curso.
911
+ */
891
912
  counter = 0;
892
913
  constructor() { }
893
- // Incrementa el contador y muestra el spinner sólo cuando pasa de 0 -> 1
914
+ /**
915
+ * Incrementa el contador de cargas activas.
916
+ *
917
+ * Muestra el spinner solo en la transición de `0 -> 1` para evitar
918
+ * renderizados redundantes cuando hay varias operaciones simultáneas.
919
+ *
920
+ * Cuándo usarlo:
921
+ * - Antes de iniciar una petición HTTP manual.
922
+ * - Antes de ejecutar una acción asíncrona larga.
923
+ */
894
924
  show() {
895
925
  this.counter++;
896
926
  if (this.counter === 1) {
897
927
  this.spinnerVisible.set(true);
898
928
  }
899
929
  }
900
- // Muestra el spinner de forma inmediata sin afectar el contador.
901
- // Útil para feedback al hacer clic en botones, dejando que el interceptor
902
- // controle el inicio/fin real de las peticiones HTTP.
930
+ /**
931
+ * Muestra el spinner de forma inmediata sin modificar el contador.
932
+ *
933
+ * Cuándo usarlo:
934
+ * - Para feedback instantáneo en la UI (por ejemplo, al hacer clic en un botón).
935
+ * - Cuando otro mecanismo (ejemplo: interceptor HTTP) controlará `show()`/`hide()`.
936
+ */
903
937
  showImmediate() {
904
938
  this.spinnerVisible.set(true);
905
939
  }
906
- // Decrementa el contador y oculta el spinner cuando llega a 0
940
+ /**
941
+ * Decrementa el contador de cargas activas.
942
+ *
943
+ * Oculta el spinner únicamente cuando el contador llega a `0`.
944
+ * Si se llama más veces de las debidas, el contador no baja de `0`.
945
+ *
946
+ * Cuándo usarlo:
947
+ * - Al finalizar una operación iniciada con `show()`.
948
+ */
907
949
  hide() {
908
950
  if (this.counter > 0) {
909
951
  this.counter--;
@@ -912,7 +954,12 @@ class SpinnerLoadingService {
912
954
  this.spinnerVisible.set(false);
913
955
  }
914
956
  }
915
- // Por si se desincroniza el estado
957
+ /**
958
+ * Restablece el estado del servicio a su valor inicial.
959
+ *
960
+ * Fuerza `counter = 0` y oculta el spinner.
961
+ * Útil en escenarios de recuperación por error o al reinicializar contexto.
962
+ */
916
963
  reset() {
917
964
  this.counter = 0;
918
965
  this.spinnerVisible.set(false);
@@ -3613,21 +3660,23 @@ class UtilityAddService {
3613
3660
  const fechaMoment = moment(fecha).format('YYYYMMDD');
3614
3661
  return fechaMoment;
3615
3662
  }
3616
- /* OPCIONES PARA FOMULARIOS REACTIVOS */
3617
- /**
3618
- * Crea un FormGroup tipado a partir de una configuración de campos.
3619
- *
3620
- * @param {FormBuilder} fb - Instancia de FormBuilder para crear el FormGroup.
3621
- * @param {FieldConfig<T>} config - Configuración de los campos del formulario.
3622
- * @param {ValidatorFn[]} groupValidators - Validadores adicionales a nivel de grupo.
3623
- * @returns {FormGroup} - El FormGroup creado.
3624
- */
3625
- createTypedForm(fb, config, groupValidators) {
3663
+ createTypedForm(fb, config, groupValidatorsOrOptions, options = { disableUnassignedControls: false }) {
3664
+ const groupValidators = Array.isArray(groupValidatorsOrOptions)
3665
+ ? groupValidatorsOrOptions
3666
+ : undefined;
3667
+ const resolvedOptions = Array.isArray(groupValidatorsOrOptions)
3668
+ ? options
3669
+ : (groupValidatorsOrOptions ?? options);
3626
3670
  const formGroup = {};
3627
3671
  // Crear controles de formulario individuales
3628
3672
  for (const key in config) {
3629
3673
  if (Object.prototype.hasOwnProperty.call(config, key)) {
3630
- const { value, disabled = false, validators = [] } = config[key];
3674
+ const fieldConfig = config[key];
3675
+ const { value, validators = [] } = fieldConfig;
3676
+ const hasAssignedDisabled = Object.prototype.hasOwnProperty.call(fieldConfig, 'disabled');
3677
+ const disabled = hasAssignedDisabled
3678
+ ? Boolean(fieldConfig.disabled)
3679
+ : Boolean(resolvedOptions.disableUnassignedControls);
3631
3680
  formGroup[key] = new FormControl({ value, disabled }, validators);
3632
3681
  }
3633
3682
  }
@@ -3635,41 +3684,14 @@ class UtilityAddService {
3635
3684
  const group = fb.group(formGroup, groupValidators ? { validators: groupValidators } : {});
3636
3685
  return group;
3637
3686
  }
3638
- /**
3639
- * Crea un ReactiveForm tipado con capacidad de suscripción y limpieza.
3640
- *
3641
- * Extiende createTypedForm() agregando un Subject (destroy$) para manejar
3642
- * la suscripción y limpieza automática de observables cuando el componente
3643
- * se destruye.
3644
- *
3645
- * @template T - El tipo genérico del modelo para el formulario.
3646
- * @param fb - Instancia de FormBuilder.
3647
- * @param config - Configuración de los campos del formulario (FieldConfig<T>).
3648
- * @returns ReactiveForm<T> - FormGroup tipado con Subject destroy$ para limpieza.
3649
- *
3650
- * @example
3651
- * ```typescript
3652
- * interface LoginForm {
3653
- * username: string;
3654
- * password: string;
3655
- * }
3656
- *
3657
- * const config: FieldConfig<LoginForm> = {
3658
- * username: { value: '', validators: [Validators.required] },
3659
- * password: { value: '', validators: [Validators.required] }
3660
- * };
3661
- *
3662
- * const form = this.utilityAddService.createReactiveForm(this.fb, config);
3663
- *
3664
- * // Al destruir el componente, limpiar todas las suscripciones
3665
- * ngOnDestroy() {
3666
- * form.destroy$.next();
3667
- * form.destroy$.complete();
3668
- * }
3669
- * ```
3670
- */
3671
- createReactiveForm(fb, config) {
3672
- const form = this.createTypedForm(fb, config);
3687
+ createReactiveForm(fb, config, groupValidatorsOrOptions, options = { disableUnassignedControls: false }) {
3688
+ const groupValidators = Array.isArray(groupValidatorsOrOptions)
3689
+ ? groupValidatorsOrOptions
3690
+ : undefined;
3691
+ const resolvedOptions = Array.isArray(groupValidatorsOrOptions)
3692
+ ? options
3693
+ : (groupValidatorsOrOptions ?? options);
3694
+ const form = this.createTypedForm(fb, config, groupValidators, resolvedOptions);
3673
3695
  form.destroy$ = new Subject();
3674
3696
  return form;
3675
3697
  }