infodocviewdoc 2.0.1 → 2.0.3
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,160 @@
|
|
|
1
|
-
#
|
|
1
|
+
# MFE Document Viewer Integration Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`infodocviewdoc` es una librería Angular para previsualizar documentos en microfrontends SGDEA.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 1) Instalacion del paquete (ultima version)
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm
|
|
8
|
+
npm i infodocviewdoc
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## 2) Dependencias requeridas en el host (package.json)
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Si tu MFE ya existe (con Angular y dependencias base), **solo debes agregar estas nuevas**:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
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';
|
|
39
|
-
|
|
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
|
-
// ...
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
#### 2. Usar en el template
|
|
55
|
-
|
|
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>
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
#### 3. Configurar en el componente TypeScript
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
import { ViewChild } from '@angular/core';
|
|
74
|
-
import { MetadataCrosscuttingComponent, MetadataFormData, MetadataModalFormStructure } from '@infodocnpm/ui-components';
|
|
75
|
-
|
|
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;
|
|
83
|
-
|
|
84
|
-
// Obtener datos actuales del formulario
|
|
85
|
-
getCurrentMetadataData(): MetadataFormData[] {
|
|
86
|
-
if (this.metadataComponent) {
|
|
87
|
-
return this.metadataComponent.getCurrentFormData();
|
|
88
|
-
}
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
|
|
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);
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"infodocviewdoc": "latest",
|
|
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"
|
|
96
24
|
}
|
|
97
25
|
}
|
|
98
26
|
```
|
|
99
27
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
});
|
|
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": "latest",
|
|
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"
|
|
139
59
|
}
|
|
140
60
|
}
|
|
141
61
|
```
|
|
142
62
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
El componente también puede mostrarse en un modal (modo legacy).
|
|
63
|
+
Despues de agregarlas:
|
|
146
64
|
|
|
147
|
-
```
|
|
148
|
-
|
|
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>
|
|
65
|
+
```bash
|
|
66
|
+
npm install
|
|
159
67
|
```
|
|
160
68
|
|
|
161
|
-
|
|
69
|
+
## 3) Configuracion de assets PDF viewer (host)
|
|
162
70
|
|
|
163
|
-
|
|
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'` |
|
|
71
|
+
En `angular.json` del MFE host agrega los assets de `ngx-extended-pdf-viewer`:
|
|
174
72
|
|
|
175
|
-
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"glob": "**/*",
|
|
76
|
+
"input": "node_modules/ngx-extended-pdf-viewer/assets",
|
|
77
|
+
"output": "/assets/"
|
|
78
|
+
}
|
|
79
|
+
```
|
|
176
80
|
|
|
177
|
-
|
|
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) |
|
|
81
|
+
Sin esta configuracion puede aparecer el error 404 de `viewer-*.mjs`.
|
|
181
82
|
|
|
182
|
-
|
|
83
|
+
## 4) Como importar y usar el componente
|
|
183
84
|
|
|
184
|
-
|
|
85
|
+
### Import en componente standalone
|
|
185
86
|
|
|
186
|
-
|
|
87
|
+
```ts
|
|
88
|
+
import { PdfViewerComponent } from 'infodocviewdoc';
|
|
187
89
|
|
|
188
|
-
|
|
189
|
-
|
|
90
|
+
@Component({
|
|
91
|
+
standalone: true,
|
|
92
|
+
imports: [PdfViewerComponent]
|
|
93
|
+
})
|
|
94
|
+
export class PdfPreviewModalComponent {}
|
|
190
95
|
```
|
|
191
96
|
|
|
192
|
-
###
|
|
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
|
-
});
|
|
233
|
-
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
```
|
|
97
|
+
### Uso en template
|
|
238
98
|
|
|
239
|
-
|
|
99
|
+
```html
|
|
100
|
+
<sgdea-document-viewer
|
|
101
|
+
[url]="apiUrl"
|
|
102
|
+
[nameFile]="objectName"
|
|
103
|
+
[nameBucket]="bucketName"
|
|
104
|
+
[nameSpaceBucket]="''"
|
|
105
|
+
[token]="token">
|
|
106
|
+
</sgdea-document-viewer>
|
|
107
|
+
```
|
|
240
108
|
|
|
241
|
-
|
|
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';
|
|
109
|
+
## 5) Inputs del componente
|
|
245
110
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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';
|
|
111
|
+
- `url`: base URL del microservicio de archivos (ej: `https://host-backend`)
|
|
112
|
+
- `nameFile`: ruta/nombre del archivo en bucket (`objectName`)
|
|
113
|
+
- `nameBucket`: nombre del bucket (ej: `attachments`)
|
|
114
|
+
- `nameSpaceBucket`: namespace (si aplica; puede ir vacio)
|
|
115
|
+
- `token`: JWT para `Authorization: Bearer <token>`
|
|
274
116
|
|
|
275
|
-
|
|
117
|
+
## 6) Consideraciones de integracion en MFE
|
|
276
118
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
119
|
+
- El componente prioriza `@Input()`; si no llegan valores por inputs, usa `queryParams` como fallback.
|
|
120
|
+
- En modales, usa contenedor con `height` definido y `overflow` para Excel grandes.
|
|
121
|
+
- Para obtener token en host, puedes usar `localStorage` o tu servicio de autenticacion central.
|
|
122
|
+
- Mantener contrato estable: ruta y forma de datos enviados al visor via inputs.
|
|
281
123
|
|
|
282
|
-
|
|
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
|
-
}
|
|
124
|
+
## 7) Formatos soportados por el visor
|
|
294
125
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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
|
-
```
|
|
126
|
+
- Procesamiento de texto: `.docx`, `.doc`
|
|
127
|
+
- Hojas de calculo: `.xlsx`, `.xls`
|
|
128
|
+
- Presentaciones: `.pptx`, `.ppt`
|
|
129
|
+
- Documentos portatiles: `.pdf`
|
|
130
|
+
- Texto plano: `.txt`
|
|
131
|
+
- Imagenes: `.jpg`, `.png`, `.tiff`, `.gif`
|
|
320
132
|
|
|
321
|
-
##
|
|
133
|
+
## 8) Ejemplo rapido de instalacion local (desarrollo)
|
|
322
134
|
|
|
323
|
-
|
|
135
|
+
Desde el repositorio de la libreria:
|
|
324
136
|
|
|
325
137
|
```bash
|
|
326
138
|
npm run build:lib
|
|
139
|
+
cd dist/ui-components
|
|
140
|
+
npm pack
|
|
327
141
|
```
|
|
328
142
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
### Publicar la Librería
|
|
143
|
+
En el MFE host:
|
|
332
144
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
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
|
-
```
|
|
145
|
+
```bash
|
|
146
|
+
npm install "C:/ruta/a/infodocviewdoc-<version>.tgz"
|
|
147
|
+
```
|
|
344
148
|
|
|
345
|
-
##
|
|
149
|
+
## 9) Public API exportada
|
|
346
150
|
|
|
347
|
-
|
|
151
|
+
`public-api.ts` exporta:
|
|
348
152
|
|
|
349
|
-
|
|
350
|
-
npm test
|
|
351
|
-
```
|
|
153
|
+
- `PdfViewerComponent`
|
|
352
154
|
|
|
353
|
-
|
|
155
|
+
---
|
|
354
156
|
|
|
355
|
-
|
|
157
|
+
Si integras este paquete en otro microfront, valida primero:
|
|
158
|
+
1. dependencias del host,
|
|
159
|
+
2. assets de `ngx-extended-pdf-viewer`,
|
|
160
|
+
3. envio correcto de `url`, `nameFile`, `nameBucket` y `token`.
|