npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@infodocnpm/search-select

v0.0.4

Published

Biblioteca de componentes UI para SGDEA (Sistema de Gestión Documental Electrónico de Archivo).

Readme

search-select (npm)

Biblioteca de componentes UI para SGDEA (Sistema de Gestión Documental Electrónico de Archivo).

Versión publicada: 0.0.1. API actual (public-api.ts): consulta el archivo en el repo; en ramas mínimas puede incluir solo button, searchable-select y ui-components placeholder. Los ejemplos de metadatos más abajo aplican si esas rutas existen en tu copia del código.

Instalación

npm install search-select

Documentación Completa

Para la documentación completa de instalación e integración de metadatos, consulta el archivo:

MANUAL_INSTALACION_METADATOS.md en la raíz del repositorio sgdea-component-library.

Este manual contiene:

  • Guía paso a paso de instalación
  • Configuración de rutas y secciones
  • Integración en modo inline (recomendado)
  • Ejemplos de código completos
  • Validación de campos obligatorios
  • Vinculación de metadatos con registros

Componente: Metadata Crosscutting

Componente para gestionar y mostrar formularios de metadatos de manera inline o en modal.

IMPORTANTE: Consulta el MANUAL_INSTALACION_METADATOS.md para ver la documentación completa y actualizada.

Modo Inline (Recomendado)

El componente puede renderizarse directamente dentro de un formulario sin necesidad de un modal.

1. Importar el componente

import { MetadataCrosscuttingComponent } from 'search-select';

@Component({
  selector: 'app-my-component',
  standalone: true,
  imports: [
    MetadataCrosscuttingComponent,
    // ... otros imports
  ],
  // ...
})
export class MyComponent {
  // ...
}

2. Usar en el template

<sgdea-metadata-crosscutting
  #metadataComponent
  [inlineMode]="true"
  [autoLoad]="true"
  [sectionFormId]="sectionFormId"
  [apiUrl]="metadataApiUrl"
  [createApiUrl]="metadataCreateApiUrl"
  [registerId]="null"
  [initialFormData]="initialMetadataData || null"
  (saveModal)="onMetadataSave($event)">
</sgdea-metadata-crosscutting>

3. Configurar en el componente TypeScript

import { ViewChild } from '@angular/core';
import { MetadataCrosscuttingComponent, MetadataFormData, MetadataModalFormStructure } from 'search-select';

export class MyComponent {
  @ViewChild('metadataComponent') metadataComponent?: MetadataCrosscuttingComponent;
  
  sectionFormId = 'your-section-form-id';
  metadataApiUrl = 'https://your-api.com/api/v1/metadata/template/get-all-metadata-for-modal';
  metadataCreateApiUrl = 'https://your-api.com/api/v1/metadata/value-metadata/create';
  initialMetadataData: MetadataFormData[] | null = null;

  // Obtener datos actuales del formulario
  getCurrentMetadataData(): MetadataFormData[] {
    if (this.metadataComponent) {
      return this.metadataComponent.getCurrentFormData();
    }
    return [];
  }

  // Guardar datos (opcional, si quieres guardar localmente)
  onMetadataSave(data: { formData: MetadataFormData[], formStructure: MetadataModalFormStructure | null }): void {
    // Guardar localmente si es necesario
    console.log('Metadata saved:', data);
  }
}

4. Vincular metadatos después de crear un registro

import { ValueMetadataCreateMapper, ValueMetadataCreateRequestDto } from 'search-select';
import { HttpClient } from '@angular/common/http';
import { forkJoin, Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

export class MyComponent {
  constructor(private http: HttpClient) {}

  // Después de crear tu registro (ej: préstamo, expediente, etc.)
  linkMetadataToRegister(registerId: string): void {
    const metadataData = this.metadataComponent?.getCurrentFormData() || [];
    
    if (metadataData.length === 0) {
      return; // No hay datos para vincular
    }

    const apiUrl = 'https://your-api.com/api/v1/metadata/value-metadata/create';
    const sectionFormId = this.sectionFormId;

    // Construir el request usando el mapper
    const requestPayload: ValueMetadataCreateRequestDto = ValueMetadataCreateMapper.toRequestDto(
      metadataData,
      sectionFormId,
      registerId,
      null // formStructure - opcional
    );

    // Enviar al backend
    this.http.post(apiUrl, requestPayload).subscribe({
      next: (response) => {
        console.log('Metadata vinculado exitosamente:', response);
      },
      error: (error) => {
        console.error('Error al vincular metadata:', error);
      }
    });
  }
}

Modo Modal (Legacy)

El componente también puede mostrarse en un modal (modo legacy).

<sgdea-metadata-crosscutting
  [isVisible]="isModalVisible"
  [modalTitle]="'Metadatos del Documento'"
  [sectionFormId]="sectionFormId"
  [apiUrl]="metadataApiUrl"
  [createApiUrl]="metadataCreateApiUrl"
  [registerId]="registerId"
  [initialFormData]="initialMetadataData"
  (closeModal)="closeModal()"
  (saveModal)="onMetadataSave($event)">
</sgdea-metadata-crosscutting>

Propiedades del Componente

| Propiedad | Tipo | Descripción | |-----------|------|-------------| | inlineMode | boolean | Si es true, muestra el formulario inline (sin modal). Por defecto: false | | autoLoad | boolean | Si es true, carga automáticamente los metadatos al inicializar. Por defecto: false | | sectionFormId | string \| null | ID de la sección de formulario de metadatos | | apiUrl | string \| null | URL completa del endpoint para obtener la estructura de metadatos | | createApiUrl | string \| null | URL completa del endpoint para crear/vincular metadatos | | registerId | string \| null | ID del registro al que se vincularán los metadatos (usado en modo modal) | | initialFormData | MetadataFormData[] \| null | Datos iniciales para poblar el formulario | | isVisible | boolean | Muestra/oculta el modal (solo en modo modal). Por defecto: false | | modalTitle | string | Título del modal (solo en modo modal). Por defecto: 'Metadatos del Documento' |

Eventos

| Evento | Tipo | Descripción | |--------|------|-------------| | saveModal | EventEmitter<{ formData: MetadataFormData[], formStructure: MetadataModalFormStructure \| null }> | Se emite cuando se guarda el formulario | | closeModal | EventEmitter<void> | Se emite cuando se cierra el modal (solo modo modal) |

Métodos Públicos

getCurrentFormData(): MetadataFormData[]

Obtiene los datos actuales del formulario sin validar ni guardar. Útil para obtener los valores actuales antes de vincular al registro.

const currentData = this.metadataComponent?.getCurrentFormData();

Validación de Campos Obligatorios

Para validar que todos los campos obligatorios estén diligenciados antes de crear un registro:

import { MetadataValidationService, ValidateMissingFieldsResponseDto } from 'search-select';

export class MyComponent {
  constructor(private metadataValidationService: MetadataValidationService) {}

  validateRequiredFields(): boolean {
    const currentData = this.metadataComponent?.getCurrentFormData() || [];
    const sectionFormId = this.sectionFormId;
    
    // Obtener secciones con campos obligatorios
    const apiUrl = 'https://your-api.com/api/v1/metadata/template/get-all-metadata-for-modal';
    
    this.metadataValidationService.validateRequiredFields(apiUrl, [sectionFormId])
      .subscribe({
        next: (response) => {
          if (response.sectionsWithRequiredFields.length > 0) {
            // Hay campos obligatorios, validar que estén diligenciados
            const metadataDataMap = new Map();
            metadataDataMap.set(sectionFormId, {
              formData: currentData,
              formStructure: null // Obtener de la estructura cargada
            });

            const validationResult = this.metadataValidationService.validateMissingRequiredFields(
              response.sectionsWithRequiredFields,
              metadataDataMap
            );

            if (validationResult.hasMissingFields) {
              console.error('Faltan campos obligatorios:', validationResult.missingSections);
              return false;
            }
          }
          return true;
        }
      });

    return false;
  }
}

Ejemplo Completo de Integración

import { Component, ViewChild } from '@angular/core';
import { MetadataCrosscuttingComponent, MetadataFormData, MetadataModalFormStructure, ValueMetadataCreateMapper, ValueMetadataCreateRequestDto } from 'search-select';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-loan-form',
  standalone: true,
  imports: [MetadataCrosscuttingComponent],
  template: `
    <form>
      <!-- Campos del formulario principal -->
      
      <!-- Metadatos inline -->
      <sgdea-metadata-crosscutting
        #metadataComponent
        [inlineMode]="true"
        [autoLoad]="true"
        [sectionFormId]="'DETAIL_SECTION'"
        [apiUrl]="metadataApiUrl"
        [createApiUrl]="metadataCreateApiUrl"
        (saveModal)="onMetadataSave($event)">
      </sgdea-metadata-crosscutting>

      <button (click)="createLoan()">Crear Préstamo</button>
    </form>
  `
})
export class LoanFormComponent {
  @ViewChild('metadataComponent') metadataComponent?: MetadataCrosscuttingComponent;
  
  metadataApiUrl = 'https://api.example.com/api/v1/metadata/template/get-all-metadata-for-modal';
  metadataCreateApiUrl = 'https://api.example.com/api/v1/metadata/value-metadata/create';

  constructor(private http: HttpClient) {}

  onMetadataSave(data: { formData: MetadataFormData[], formStructure: MetadataModalFormStructure | null }): void {
    // Guardar localmente si es necesario
    console.log('Metadata guardado:', data);
  }

  createLoan(): void {
    // 1. Crear el préstamo
    this.http.post('https://api.example.com/api/v1/loans', loanData)
      .subscribe({
        next: (response: any) => {
          const loanId = response.idPrestamo;
          
          // 2. Vincular metadatos al préstamo
          this.linkMetadataToLoan(loanId);
        }
      });
  }

  linkMetadataToLoan(loanId: string): void {
    const metadataData = this.metadataComponent?.getCurrentFormData() || [];
    
    if (metadataData.length === 0) {
      return;
    }

    const requestPayload: ValueMetadataCreateRequestDto = ValueMetadataCreateMapper.toRequestDto(
      metadataData,
      'DETAIL_SECTION',
      loanId,
      null
    );

    this.http.post(this.metadataCreateApiUrl, requestPayload).subscribe({
      next: () => {
        console.log('Metadatos vinculados exitosamente');
      },
      error: (error) => {
        console.error('Error al vincular metadatos:', error);
      }
    });
  }
}

Building

Para construir la librería localmente:

npm run build:lib

Los artefactos de compilación se guardarán en el directorio dist/.

Publicar la Librería

Una vez construida la librería:

  1. Navegar al directorio dist:

    cd dist/ui-components
  2. Ejecutar npm publish para publicar la librería en el registro de npm:

    npm publish

Running unit tests

Para ejecutar las pruebas unitarias:

npm test

Recursos Adicionales

Para más información sobre Angular CLI, visita Angular CLI Overview and Command Reference.