@sapenlinea/shared-services

v0.0.2

Published

Librería compartida con servicios comunes para proyectos Angular de Sconnect

Downloads

9

Readme

📚 Shared Services

Librería que centraliza los servicios y catálogos comunes entre los distintos microfrontends
(devices, administration, documents, etc.) para evitar duplicación y mantener consistencia.


🚀 Funcionalidad

  • Carga y cacheo de catálogos: ciudades, países, departamentos, tipos de documento.
  • Exposición de datos en arrays y mapas por id/nombre.
  • Generación de opciones para selects ({ value, label }).
  • Observable dataLoaded$ para reaccionar cuando la data esté disponible.
  • Métodos de búsqueda por nombre (getCityByName, getCountryByName, etc.).

📖 Servicios incluidos

  • CityService → Ciudades
  • CountryService → Países
  • DepartamentService → Departamentos
  • DocumentsTypeService → Tipos de documento
  • SharedDataService → Punto central para manejar todos los catálogos y exponer utilidades

🛠️ Uso básico

1. Cargar datos compartidos

import { inject } from '@angular/core';
import { SharedDataService } from '@sconnectnpm/shared-services';

export class MiComponente {
  private sharedData = inject(SharedDataService);

  ngOnInit() {
    this.sharedData.loadSharedServicesData();

    this.sharedData.dataLoaded$.subscribe((loaded) => {
      if (loaded) {
        console.log(this.sharedData.getCitiesArray());
      }
    });
  }
}

2. Obtener opciones para selects

const cityOptions = this.sharedData.getOptions('city');
const deptOptions = this.sharedData.getOptions('department');

Resultado típico:

[
  { value: 1, label: 'Bogotá' },
  { value: 2, label: 'Medellín' }
]

3. Obtener opciones para varios campos a la vez

const fieldOptions = this.sharedData.getOptionsForFields({
  loc_city: 'city',
  infpl_department: 'department',
  own_doc_type: 'documentType',
  inf_license_country: 'country',
});

📋 Ejemplo en formSectionsDevice

Puedes definir tus formSections con options vacíos y luego llenarlos dinámicamente desde SharedDataService:

{
  key: 'department',
  label: 'Departamento',
  type: 'select',
  placeholder: 'Selecciona el departamento',
  required: false,
  col: 6,
  options: [] // se llenará con sharedData.getOptions('department')
},
{
  key: 'municipality',
  label: 'Municipio',
  type: 'select',
  placeholder: 'Selecciona el municipio',
  required: false,
  col: 6,
  options: [] // se llenará con sharedData.getOptions('city')
}

Y en tu componente:

this.sharedData.dataLoaded$.subscribe((loaded) => {
  if (loaded) {
    const fieldOptions = this.sharedData.getOptionsForFields({
      department: 'department',
      municipality: 'city'
    });

    this.updateFieldOptions('department', fieldOptions['department']);
    this.updateFieldOptions('municipality', fieldOptions['municipality']);
  }
});

✅ Beneficios

  • Centralización → una sola fuente de verdad para catálogos.
  • Reutilización → usado en todos los microfrontends sin duplicar código.
  • Flexibilidad → obtener arrays, mapas o directamente opciones para formularios.
  • Sincronización → eventos reactivos para actualizar la UI al cargar datos.

📚 API Completa

Métodos principales

loadSharedServicesData(): void

Carga todos los catálogos compartidos (solo se ejecuta una vez).

dataLoaded$: Observable<boolean>

Observable que emite true cuando todos los datos están cargados.

isDataLoaded(): boolean

Retorna true si los datos ya fueron cargados.

Obtener datos como arrays

getCitiesArray(): any[]
getCountriesArray(): any[]
getDepartmentsArray(): any[]
getDocumentTypesArray(): any[]
getAllAsArrays(): { countries, departments, cities, documentTypes }

Búsqueda por nombre

getCityByName(name: string): any
getCountryByName(name: string): any
getDepartmentByName(name: string): any
getDocumentTypeByName(name: string): any

Generación de opciones

getOptions(field: 'city' | 'country' | 'department' | 'documentType', placeholder?: string): Array<{value, label}>

getOptionsForFields(
  fieldMap: { [key: string]: 'city' | 'country' | 'department' | 'documentType' },
  placeholder?: string
): { [key: string]: any[] }

🎯 Casos de uso

Cargar datos al iniciar la aplicación

// app.component.ts
export class AppComponent {
  private sharedData = inject(SharedDataService);

  ngOnInit() {
    this.sharedData.loadSharedServicesData();
  }
}

Usar en formularios reactivos

export class FormComponent {
  private sharedData = inject(SharedDataService);
  cityOptions: any[] = [];
  countryOptions: any[] = [];

  ngOnInit() {
    this.sharedData.dataLoaded$
      .pipe(filter(loaded => loaded))
      .subscribe(() => {
        this.cityOptions = this.sharedData.getOptions('city');
        this.countryOptions = this.sharedData.getOptions('country');
      });
  }
}

Buscar por nombre

const bogota = this.sharedData.getCityByName('Bogotá');
console.log(bogota); // { id: 1, name: 'Bogotá', ... }

🔧 Estructura interna

El servicio utiliza Map para almacenamiento eficiente:

private maps = {
  cities: new Map<number, any>(),           // búsqueda por ID
  citiesByName: new Map<string, any>(),     // búsqueda por nombre
  countries: new Map<number, any>(),
  countriesByName: new Map<string, any>(),
  departments: new Map<number, any>(),
  departmentsByName: new Map<string, any>(),
  documentTypes: new Map<number, any>(),
  documentTypesByName: new Map<string, any>(),
};

📝 Notas

  • Los datos se cargan una sola vez por sesión.
  • Si intentas cargar nuevamente con loadSharedServicesData(), se ignora la petición.
  • Todos los servicios hijos (CityService, CountryService, etc.) deben implementar métodos load() y getXxx() que retornen observables.