@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-selectDocumentació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:libLos artefactos de compilación se guardarán en el directorio dist/.
Publicar la Librería
Una vez construida la librería:
Navegar al directorio
dist:cd dist/ui-componentsEjecutar
npm publishpara publicar la librería en el registro de npm:npm publish
Running unit tests
Para ejecutar las pruebas unitarias:
npm testRecursos Adicionales
Para más información sobre Angular CLI, visita Angular CLI Overview and Command Reference.
