infodocviewdoc 2.0.2 → 2.0.4

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.
package/README.md CHANGED
@@ -1,355 +1,203 @@
1
- # @infodocnpm/ui-components
1
+ # MFE Document Viewer Integration Guide
2
2
 
3
- Biblioteca de componentes UI para SGDEA (Sistema de Gestión Documental Electrónico de Archivo).
3
+ `infodocviewdoc` es una librería Angular para previsualizar documentos en microfrontends SGDEA.
4
4
 
5
- ## Instalación
5
+ ## 1) Instalacion del paquete (ultima version)
6
6
 
7
7
  ```bash
8
- npm install @infodocnpm/ui-components
8
+ npm i infodocviewdoc
9
9
  ```
10
10
 
11
- ## Documentación Completa
11
+ ## 2) Dependencias requeridas en el host (package.json)
12
12
 
13
- Para la documentación completa de instalación e integración de metadatos, consulta el archivo:
13
+ Si tu MFE ya existe (con Angular y dependencias base), **solo debes agregar estas nuevas**:
14
14
 
15
- **`MANUAL_INSTALACION_METADATOS.md`** en la raíz del repositorio `sgdea-component-library`.
16
-
17
- Este manual contiene:
18
- - Guía paso a paso de instalación
19
- - Configuración de rutas y secciones
20
- - Integración en modo inline (recomendado)
21
- - Ejemplos de código completos
22
- - Validación de campos obligatorios
23
- - Vinculación de metadatos con registros
24
-
25
- ## Componente: Metadata Crosscutting
26
-
27
- Componente para gestionar y mostrar formularios de metadatos de manera inline o en modal.
28
-
29
- **IMPORTANTE:** Consulta el `MANUAL_INSTALACION_METADATOS.md` para ver la documentación completa y actualizada.
30
-
31
- ### Modo Inline (Recomendado)
32
-
33
- El componente puede renderizarse directamente dentro de un formulario sin necesidad de un modal.
34
-
35
- #### 1. Importar el componente
36
-
37
- ```typescript
38
- import { MetadataCrosscuttingComponent } from '@infodocnpm/ui-components';
15
+ ```json
16
+ {
17
+ "dependencies": {
18
+ "infodocviewdoc": "2.0.4",
19
+ "@handsontable/angular": "^16.2.0",
20
+ "handsontable": "^16.2.0",
21
+ "jspdf": "^4.1.0",
22
+ "ngx-extended-pdf-viewer": "^25.6.4",
23
+ "xlsx": "^0.18.5"
24
+ }
25
+ }
26
+ ```
39
27
 
40
- @Component({
41
- selector: 'app-my-component',
42
- standalone: true,
43
- imports: [
44
- MetadataCrosscuttingComponent,
45
- // ... otros imports
46
- ],
47
- // ...
48
- })
49
- export class MyComponent {
50
- // ...
28
+ > En resumen: si comparas contra tu `package.json` anterior, las nuevas para integrar el visor son:
29
+ > - `infodocviewdoc`
30
+ > - `@handsontable/angular`
31
+ > - `handsontable`
32
+ > - `jspdf`
33
+ > - `ngx-extended-pdf-viewer`
34
+ > - `xlsx`
35
+
36
+ ### Ejemplo completo para un MFE nuevo
37
+
38
+ Si creas un microfront desde cero, ademas de Angular/base, tu bloque de `dependencies` debe terminar incluyendo al menos:
39
+
40
+ ```json
41
+ {
42
+ "dependencies": {
43
+ "@angular/animations": "19.2.4",
44
+ "@angular/common": "19.2.4",
45
+ "@angular/core": "19.2.4",
46
+ "@angular/forms": "19.2.4",
47
+ "@angular/platform-browser": "19.2.4",
48
+ "@angular/platform-browser-dynamic": "19.2.4",
49
+ "@angular/router": "19.2.4",
50
+ "rxjs": "~7.8.0",
51
+ "tslib": "2.3.0",
52
+ "zone.js": "~0.15.0",
53
+ "infodocviewdoc": "^2.0.4",
54
+ "@handsontable/angular": "^16.2.0",
55
+ "handsontable": "^16.2.0",
56
+ "jspdf": "^4.1.0",
57
+ "ngx-extended-pdf-viewer": "^25.6.4",
58
+ "xlsx": "^0.18.5"
59
+ }
51
60
  }
52
61
  ```
53
62
 
54
- #### 2. Usar en el template
63
+ Despues de agregarlas:
55
64
 
56
- ```html
57
- <sgdea-metadata-crosscutting
58
- #metadataComponent
59
- [inlineMode]="true"
60
- [autoLoad]="true"
61
- [sectionFormId]="sectionFormId"
62
- [apiUrl]="metadataApiUrl"
63
- [createApiUrl]="metadataCreateApiUrl"
64
- [registerId]="null"
65
- [initialFormData]="initialMetadataData || null"
66
- (saveModal)="onMetadataSave($event)">
67
- </sgdea-metadata-crosscutting>
65
+ ```bash
66
+ npm install
68
67
  ```
69
68
 
70
- #### 3. Configurar en el componente TypeScript
69
+ ## 3) Configuracion de assets PDF viewer en `angular.json` (host)
71
70
 
72
- ```typescript
73
- import { ViewChild } from '@angular/core';
74
- import { MetadataCrosscuttingComponent, MetadataFormData, MetadataModalFormStructure } from '@infodocnpm/ui-components';
71
+ Los ficheros de PDF.js (`viewer-*.mjs`, workers, `cmaps`, etc.) viven en `node_modules/ngx-extended-pdf-viewer/assets`. El host debe **copiarlos al build** para poder servirlos bajo la ruta base de la aplicacion (normalmente `/assets/`).
75
72
 
76
- export class MyComponent {
77
- @ViewChild('metadataComponent') metadataComponent?: MetadataCrosscuttingComponent;
78
-
79
- sectionFormId = 'your-section-form-id';
80
- metadataApiUrl = 'https://your-api.com/api/v1/metadata/template/get-all-metadata-for-modal';
81
- metadataCreateApiUrl = 'https://your-api.com/api/v1/metadata/value-metadata/create';
82
- initialMetadataData: MetadataFormData[] | null = null;
73
+ ### Donde colocarlo
83
74
 
84
- // Obtener datos actuales del formulario
85
- getCurrentMetadataData(): MetadataFormData[] {
86
- if (this.metadataComponent) {
87
- return this.metadataComponent.getCurrentFormData();
88
- }
89
- return [];
90
- }
75
+ En el proyecto del MFE, dentro del **target que realmente usa `ng build` / `ng serve`** (suele llamarse `esbuild`, `build` o `application`), en `architect.<target>.options.assets` (no solo en el target `test`).
76
+
77
+ Ejemplo con el builder moderno de aplicacion (`@angular-devkit/build-angular:application`):
91
78
 
92
- // Guardar datos (opcional, si quieres guardar localmente)
93
- onMetadataSave(data: { formData: MetadataFormData[], formStructure: MetadataModalFormStructure | null }): void {
94
- // Guardar localmente si es necesario
95
- console.log('Metadata saved:', data);
79
+ ```json
80
+ "architect": {
81
+ "esbuild": {
82
+ "builder": "@angular-devkit/build-angular:application",
83
+ "options": {
84
+ "assets": [
85
+ {
86
+ "glob": "**/*",
87
+ "input": "public"
88
+ },
89
+ {
90
+ "glob": "**/*",
91
+ "input": "node_modules/ngx-extended-pdf-viewer/assets",
92
+ "output": "/assets/"
93
+ }
94
+ ]
95
+ }
96
96
  }
97
97
  }
98
98
  ```
99
99
 
100
- #### 4. Vincular metadatos después de crear un registro
101
-
102
- ```typescript
103
- import { ValueMetadataCreateMapper, ValueMetadataCreateRequestDto } from '@infodocnpm/ui-components';
104
- import { HttpClient } from '@angular/common/http';
105
- import { forkJoin, Observable, of } from 'rxjs';
106
- import { catchError, map } from 'rxjs/operators';
100
+ - Ajusta el primer bloque (`public`, `src/assets`, etc.) segun tu proyecto; lo importante es **anadir** el segundo bloque con `ngx-extended-pdf-viewer/assets`.
101
+ - `output: "/assets/"` hace que los ficheros queden disponibles como `https://<tu-host>/assets/viewer-*.mjs` (y el resto de recursos en el mismo prefijo).
107
102
 
108
- export class MyComponent {
109
- constructor(private http: HttpClient) {}
110
-
111
- // Después de crear tu registro (ej: préstamo, expediente, etc.)
112
- linkMetadataToRegister(registerId: string): void {
113
- const metadataData = this.metadataComponent?.getCurrentFormData() || [];
114
-
115
- if (metadataData.length === 0) {
116
- return; // No hay datos para vincular
117
- }
103
+ ### Si no configuras estos assets
118
104
 
119
- const apiUrl = 'https://your-api.com/api/v1/metadata/value-metadata/create';
120
- const sectionFormId = this.sectionFormId;
121
-
122
- // Construir el request usando el mapper
123
- const requestPayload: ValueMetadataCreateRequestDto = ValueMetadataCreateMapper.toRequestDto(
124
- metadataData,
125
- sectionFormId,
126
- registerId,
127
- null // formStructure - opcional
128
- );
129
-
130
- // Enviar al backend
131
- this.http.post(apiUrl, requestPayload).subscribe({
132
- next: (response) => {
133
- console.log('Metadata vinculado exitosamente:', response);
134
- },
135
- error: (error) => {
136
- console.error('Error al vincular metadata:', error);
137
- }
138
- });
139
- }
140
- }
141
- ```
105
+ - La libreria puede cargar los mismos recursos desde un **CDN** (jsDelivr) alineado a la version de `ngx-extended-pdf-viewer`: en muchos entornos el PDF **funcionara igual** sin copiar assets.
106
+ - Conviene **mantener** la entrada en `angular.json` si necesitas: **sin acceso a internet**, **CSP** que bloquea dominios externos, o **politica** de no depender de CDN.
142
107
 
143
- ### Modo Modal (Legacy)
108
+ ### Si sirves los assets locales pero con otra ruta
144
109
 
145
- El componente también puede mostrarse en un modal (modo legacy).
110
+ Puedes usar el input opcional `pdfAssetsBaseUrl` en el componente (por ejemplo la URL base donde el host publica los ficheros, sin barra final o normalizada).
146
111
 
147
112
  ```html
148
- <sgdea-metadata-crosscutting
149
- [isVisible]="isModalVisible"
150
- [modalTitle]="'Metadatos del Documento'"
151
- [sectionFormId]="sectionFormId"
152
- [apiUrl]="metadataApiUrl"
153
- [createApiUrl]="metadataCreateApiUrl"
154
- [registerId]="registerId"
155
- [initialFormData]="initialMetadataData"
156
- (closeModal)="closeModal()"
157
- (saveModal)="onMetadataSave($event)">
158
- </sgdea-metadata-crosscutting>
113
+ <sgdea-document-viewer
114
+ [pdfAssetsBaseUrl]="'https://mi-dominio.com/assets'"
115
+ ...
116
+ ></sgdea-document-viewer>
159
117
  ```
160
118
 
161
- ### Propiedades del Componente
119
+ Si no se define `pdfAssetsBaseUrl` y el host **no** sirve `/assets/` con los ficheros del viewer, se usara el **fallback CDN** interno.
162
120
 
163
- | Propiedad | Tipo | Descripción |
164
- |-----------|------|-------------|
165
- | `inlineMode` | `boolean` | Si es `true`, muestra el formulario inline (sin modal). Por defecto: `false` |
166
- | `autoLoad` | `boolean` | Si es `true`, carga automáticamente los metadatos al inicializar. Por defecto: `false` |
167
- | `sectionFormId` | `string \| null` | ID de la sección de formulario de metadatos |
168
- | `apiUrl` | `string \| null` | URL completa del endpoint para obtener la estructura de metadatos |
169
- | `createApiUrl` | `string \| null` | URL completa del endpoint para crear/vincular metadatos |
170
- | `registerId` | `string \| null` | ID del registro al que se vincularán los metadatos (usado en modo modal) |
171
- | `initialFormData` | `MetadataFormData[] \| null` | Datos iniciales para poblar el formulario |
172
- | `isVisible` | `boolean` | Muestra/oculta el modal (solo en modo modal). Por defecto: `false` |
173
- | `modalTitle` | `string` | Título del modal (solo en modo modal). Por defecto: `'Metadatos del Documento'` |
121
+ ### Sintoma tipico si falta todo (host sin assets y sin CDN)
174
122
 
175
- ### Eventos
123
+ Error en red **404** sobre `http(s)://<host>/assets/viewer-*.mjs` y el PDF no se renderiza aunque la descarga del archivo sea **200**.
176
124
 
177
- | Evento | Tipo | Descripción |
178
- |--------|------|-------------|
179
- | `saveModal` | `EventEmitter<{ formData: MetadataFormData[], formStructure: MetadataModalFormStructure \| null }>` | Se emite cuando se guarda el formulario |
180
- | `closeModal` | `EventEmitter<void>` | Se emite cuando se cierra el modal (solo modo modal) |
125
+ ## 4) Como importar y usar el componente
181
126
 
182
- ### Métodos Públicos
127
+ ### Import en componente standalone
183
128
 
184
- #### `getCurrentFormData(): MetadataFormData[]`
129
+ ```ts
130
+ import { PdfViewerComponent } from 'infodocviewdoc';
185
131
 
186
- Obtiene los datos actuales del formulario sin validar ni guardar. Útil para obtener los valores actuales antes de vincular al registro.
187
-
188
- ```typescript
189
- const currentData = this.metadataComponent?.getCurrentFormData();
132
+ @Component({
133
+ standalone: true,
134
+ imports: [PdfViewerComponent]
135
+ })
136
+ export class PdfPreviewModalComponent {}
190
137
  ```
191
138
 
192
- ### Validación de Campos Obligatorios
193
-
194
- Para validar que todos los campos obligatorios estén diligenciados antes de crear un registro:
195
-
196
- ```typescript
197
- import { MetadataValidationService, ValidateMissingFieldsResponseDto } from '@infodocnpm/ui-components';
198
-
199
- export class MyComponent {
200
- constructor(private metadataValidationService: MetadataValidationService) {}
201
-
202
- validateRequiredFields(): boolean {
203
- const currentData = this.metadataComponent?.getCurrentFormData() || [];
204
- const sectionFormId = this.sectionFormId;
205
-
206
- // Obtener secciones con campos obligatorios
207
- const apiUrl = 'https://your-api.com/api/v1/metadata/template/get-all-metadata-for-modal';
208
-
209
- this.metadataValidationService.validateRequiredFields(apiUrl, [sectionFormId])
210
- .subscribe({
211
- next: (response) => {
212
- if (response.sectionsWithRequiredFields.length > 0) {
213
- // Hay campos obligatorios, validar que estén diligenciados
214
- const metadataDataMap = new Map();
215
- metadataDataMap.set(sectionFormId, {
216
- formData: currentData,
217
- formStructure: null // Obtener de la estructura cargada
218
- });
219
-
220
- const validationResult = this.metadataValidationService.validateMissingRequiredFields(
221
- response.sectionsWithRequiredFields,
222
- metadataDataMap
223
- );
224
-
225
- if (validationResult.hasMissingFields) {
226
- console.error('Faltan campos obligatorios:', validationResult.missingSections);
227
- return false;
228
- }
229
- }
230
- return true;
231
- }
232
- });
139
+ ### Uso en template
233
140
 
234
- return false;
235
- }
236
- }
141
+ ```html
142
+ <sgdea-document-viewer
143
+ [url]="apiUrl"
144
+ [nameFile]="objectName"
145
+ [nameBucket]="bucketName"
146
+ [nameSpaceBucket]="''"
147
+ [token]="token">
148
+ </sgdea-document-viewer>
237
149
  ```
238
150
 
239
- ### Ejemplo Completo de Integración
151
+ ## 5) Inputs del componente
240
152
 
241
- ```typescript
242
- import { Component, ViewChild } from '@angular/core';
243
- import { MetadataCrosscuttingComponent, MetadataFormData, MetadataModalFormStructure, ValueMetadataCreateMapper, ValueMetadataCreateRequestDto } from '@infodocnpm/ui-components';
244
- import { HttpClient } from '@angular/common/http';
153
+ - `url`: base URL del microservicio de archivos (ej: `https://host-backend`)
154
+ - `nameFile`: ruta/nombre del archivo en bucket (`objectName`)
155
+ - `nameBucket`: nombre del bucket (ej: `attachments`)
156
+ - `nameSpaceBucket`: namespace (si aplica; puede ir vacio)
157
+ - `token`: JWT para `Authorization: Bearer <token>`
158
+ - `pdfAssetsBaseUrl` (opcional): URL base donde el host publica los assets de `ngx-extended-pdf-viewer` (p. ej. `https://mi-app.com/assets`). Si no se define, se usa CDN o, si estan copiados en el build, la ruta por defecto del viewer.
245
159
 
246
- @Component({
247
- selector: 'app-loan-form',
248
- standalone: true,
249
- imports: [MetadataCrosscuttingComponent],
250
- template: `
251
- <form>
252
- <!-- Campos del formulario principal -->
253
-
254
- <!-- Metadatos inline -->
255
- <sgdea-metadata-crosscutting
256
- #metadataComponent
257
- [inlineMode]="true"
258
- [autoLoad]="true"
259
- [sectionFormId]="'DETAIL_SECTION'"
260
- [apiUrl]="metadataApiUrl"
261
- [createApiUrl]="metadataCreateApiUrl"
262
- (saveModal)="onMetadataSave($event)">
263
- </sgdea-metadata-crosscutting>
264
-
265
- <button (click)="createLoan()">Crear Préstamo</button>
266
- </form>
267
- `
268
- })
269
- export class LoanFormComponent {
270
- @ViewChild('metadataComponent') metadataComponent?: MetadataCrosscuttingComponent;
271
-
272
- metadataApiUrl = 'https://api.example.com/api/v1/metadata/template/get-all-metadata-for-modal';
273
- metadataCreateApiUrl = 'https://api.example.com/api/v1/metadata/value-metadata/create';
160
+ ## 6) Consideraciones de integracion en MFE
274
161
 
275
- constructor(private http: HttpClient) {}
162
+ - El componente prioriza `@Input()`; si no llegan valores por inputs, usa `queryParams` como fallback.
163
+ - En modales, usa contenedor con `height` definido y `overflow` para Excel grandes.
164
+ - Para obtener token en host, puedes usar `localStorage` o tu servicio de autenticacion central.
165
+ - Mantener contrato estable: ruta y forma de datos enviados al visor via inputs.
276
166
 
277
- onMetadataSave(data: { formData: MetadataFormData[], formStructure: MetadataModalFormStructure | null }): void {
278
- // Guardar localmente si es necesario
279
- console.log('Metadata guardado:', data);
280
- }
167
+ ## 7) Formatos soportados por el visor
281
168
 
282
- createLoan(): void {
283
- // 1. Crear el préstamo
284
- this.http.post('https://api.example.com/api/v1/loans', loanData)
285
- .subscribe({
286
- next: (response: any) => {
287
- const loanId = response.idPrestamo;
288
-
289
- // 2. Vincular metadatos al préstamo
290
- this.linkMetadataToLoan(loanId);
291
- }
292
- });
293
- }
169
+ - Procesamiento de texto: `.docx`, `.doc`
170
+ - Hojas de calculo: `.xlsx`, `.xls`
171
+ - Presentaciones: `.pptx`, `.ppt`
172
+ - Documentos portatiles: `.pdf`
173
+ - Texto plano: `.txt`
174
+ - Imagenes: `.jpg`, `.png`, `.tiff`, `.gif`
294
175
 
295
- linkMetadataToLoan(loanId: string): void {
296
- const metadataData = this.metadataComponent?.getCurrentFormData() || [];
297
-
298
- if (metadataData.length === 0) {
299
- return;
300
- }
176
+ ## 8) Ejemplo rapido de instalacion local (desarrollo)
301
177
 
302
- const requestPayload: ValueMetadataCreateRequestDto = ValueMetadataCreateMapper.toRequestDto(
303
- metadataData,
304
- 'DETAIL_SECTION',
305
- loanId,
306
- null
307
- );
308
-
309
- this.http.post(this.metadataCreateApiUrl, requestPayload).subscribe({
310
- next: () => {
311
- console.log('Metadatos vinculados exitosamente');
312
- },
313
- error: (error) => {
314
- console.error('Error al vincular metadatos:', error);
315
- }
316
- });
317
- }
318
- }
319
- ```
320
-
321
- ## Building
322
-
323
- Para construir la librería localmente:
178
+ Desde el repositorio de la libreria:
324
179
 
325
180
  ```bash
326
181
  npm run build:lib
182
+ cd dist/ui-components
183
+ npm pack
327
184
  ```
328
185
 
329
- Los artefactos de compilación se guardarán en el directorio `dist/`.
330
-
331
- ### Publicar la Librería
186
+ En el MFE host:
332
187
 
333
- Una vez construida la librería:
334
-
335
- 1. Navegar al directorio `dist`:
336
- ```bash
337
- cd dist/ui-components
338
- ```
339
-
340
- 2. Ejecutar `npm publish` para publicar la librería en el registro de npm:
341
- ```bash
342
- npm publish
343
- ```
188
+ ```bash
189
+ npm install "C:/ruta/a/infodocviewdoc-<version>.tgz"
190
+ ```
344
191
 
345
- ## Running unit tests
192
+ ## 9) Public API exportada
346
193
 
347
- Para ejecutar las pruebas unitarias:
194
+ `public-api.ts` exporta:
348
195
 
349
- ```bash
350
- npm test
351
- ```
196
+ - `PdfViewerComponent`
352
197
 
353
- ## Recursos Adicionales
198
+ ---
354
199
 
355
- Para más información sobre Angular CLI, visita [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli).
200
+ Si integras este paquete en otro microfront, valida primero:
201
+ 1. dependencias del host,
202
+ 2. assets de `ngx-extended-pdf-viewer` en `angular.json` del target de build (recomendado) o, si no, que el entorno permita el fallback CDN / `pdfAssetsBaseUrl`,
203
+ 3. envio correcto de `url`, `nameFile`, `nameBucket` y `token`.