c3-components 0.14.2 → 0.15.1
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/fesm2022/c3-components.mjs +76 -15
- package/fesm2022/c3-components.mjs.map +1 -1
- package/index.d.ts +9 -3
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, signal, viewChild, TemplateRef, inject, ChangeDetectorRef, effect, Component, forwardRef, model, HostListener, Directive, NgModule, Inject, Injector, Injectable, Pipe, output, ViewEncapsulation, Optional, computed, InjectionToken, contentChild, contentChildren,
|
|
2
|
+
import { input, signal, viewChild, TemplateRef, inject, ChangeDetectorRef, effect, Component, forwardRef, model, HostListener, Directive, NgModule, Inject, ViewContainerRef, Injector, Injectable, Pipe, output, ViewEncapsulation, Optional, computed, InjectionToken, contentChild, contentChildren, HostBinding, ElementRef, DestroyRef } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i2 from '@angular/forms';
|
|
@@ -380,14 +380,21 @@ class C3DialogEmbedChildComponent {
|
|
|
380
380
|
this.dialogRef = dialogRef;
|
|
381
381
|
this.data = data;
|
|
382
382
|
this._cdr = _cdr;
|
|
383
|
-
this.target = viewChild
|
|
383
|
+
this.target = viewChild('target', ...(ngDevMode ? [{ debugName: "target", read: ViewContainerRef }] : [{
|
|
384
|
+
read: ViewContainerRef,
|
|
385
|
+
}]));
|
|
384
386
|
// On utilise un signal pour stocker la référence du composant créé
|
|
385
387
|
this.createdComponent = signal(null, ...(ngDevMode ? [{ debugName: "createdComponent" }] : []));
|
|
386
388
|
}
|
|
387
389
|
ngAfterViewInit() {
|
|
388
390
|
// Si on a un composant, on le crée dynamiquement
|
|
389
391
|
if (this.data.component && !this.data.templateRef) {
|
|
390
|
-
const
|
|
392
|
+
const targetRef = this.target();
|
|
393
|
+
if (!targetRef) {
|
|
394
|
+
console.error('ViewContainerRef not found');
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const compRef = targetRef.createComponent(this.data.component);
|
|
391
398
|
this.createdComponent.set(compRef);
|
|
392
399
|
// Injecter les inputs dans le composant
|
|
393
400
|
if (this.data.inputs) {
|
|
@@ -432,7 +439,7 @@ class C3DialogEmbedChildComponent {
|
|
|
432
439
|
}
|
|
433
440
|
}
|
|
434
441
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: C3DialogEmbedChildComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
435
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: C3DialogEmbedChildComponent, isStandalone: false, selector: "C3DialogEmbedChildComponent", viewQueries: [{ propertyName: "target", first: true, predicate: ["target"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
442
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: C3DialogEmbedChildComponent, isStandalone: false, selector: "C3DialogEmbedChildComponent", viewQueries: [{ propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
|
|
436
443
|
<div [class]="'dialog-content-container ' + (data.classContainer || '')">
|
|
437
444
|
@if (data.toolbar) {
|
|
438
445
|
<mat-toolbar [color]="data.toolbar.color || 'default'" class="py-1">
|
|
@@ -445,17 +452,17 @@ class C3DialogEmbedChildComponent {
|
|
|
445
452
|
}
|
|
446
453
|
</mat-toolbar>
|
|
447
454
|
}
|
|
448
|
-
|
|
455
|
+
|
|
449
456
|
<div [class]="'dialog-content ' + (data.classContent || '')">
|
|
450
457
|
<!-- Si templateRef est présent, on l'affiche directement,
|
|
451
458
|
sinon on laisse la place au composant dynamique -->
|
|
452
459
|
@if (data.templateRef) {
|
|
453
460
|
<ng-container *ngTemplateOutlet="data.templateRef"></ng-container>
|
|
454
461
|
} @else {
|
|
455
|
-
<ng-
|
|
462
|
+
<ng-container #target></ng-container>
|
|
456
463
|
}
|
|
457
464
|
</div>
|
|
458
|
-
|
|
465
|
+
|
|
459
466
|
@if (data.actions && data.actions.length > 0) {
|
|
460
467
|
<div [class]="'dialog-actions ' + (data.classActions || '')">
|
|
461
468
|
@for (action of data.actions; track action.label) {
|
|
@@ -490,7 +497,7 @@ class C3DialogEmbedChildComponent {
|
|
|
490
497
|
</div>
|
|
491
498
|
}
|
|
492
499
|
</div>
|
|
493
|
-
|
|
500
|
+
`, isInline: true, styles: [".dialog-content-container{display:flex;flex-direction:column;height:100%;padding:1rem;overflow:auto}.dialog-content-container .dialog-content{display:flex;flex-direction:column;height:100%;overflow:auto;flex-grow:1}.dialog-content-container .mat-toolbar{display:flex;justify-content:space-between;align-items:center;border-radius:.25rem}.dialog-content-container .mat-toolbar span{color:inherit}.dialog-content-container .spacer{flex:1 1 auto;min-width:16px}.dialog-actions{display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: i1$2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }] }); }
|
|
494
501
|
}
|
|
495
502
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: C3DialogEmbedChildComponent, decorators: [{
|
|
496
503
|
type: Component,
|
|
@@ -507,17 +514,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
507
514
|
}
|
|
508
515
|
</mat-toolbar>
|
|
509
516
|
}
|
|
510
|
-
|
|
517
|
+
|
|
511
518
|
<div [class]="'dialog-content ' + (data.classContent || '')">
|
|
512
519
|
<!-- Si templateRef est présent, on l'affiche directement,
|
|
513
520
|
sinon on laisse la place au composant dynamique -->
|
|
514
521
|
@if (data.templateRef) {
|
|
515
522
|
<ng-container *ngTemplateOutlet="data.templateRef"></ng-container>
|
|
516
523
|
} @else {
|
|
517
|
-
<ng-
|
|
524
|
+
<ng-container #target></ng-container>
|
|
518
525
|
}
|
|
519
526
|
</div>
|
|
520
|
-
|
|
527
|
+
|
|
521
528
|
@if (data.actions && data.actions.length > 0) {
|
|
522
529
|
<div [class]="'dialog-actions ' + (data.classActions || '')">
|
|
523
530
|
@for (action of data.actions; track action.label) {
|
|
@@ -552,11 +559,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
552
559
|
</div>
|
|
553
560
|
}
|
|
554
561
|
</div>
|
|
555
|
-
|
|
562
|
+
`, standalone: false, styles: [".dialog-content-container{display:flex;flex-direction:column;height:100%;padding:1rem;overflow:auto}.dialog-content-container .dialog-content{display:flex;flex-direction:column;height:100%;overflow:auto;flex-grow:1}.dialog-content-container .mat-toolbar{display:flex;justify-content:space-between;align-items:center;border-radius:.25rem}.dialog-content-container .mat-toolbar span{color:inherit}.dialog-content-container .spacer{flex:1 1 auto;min-width:16px}.dialog-actions{display:flex;justify-content:flex-end;gap:.5rem}\n"] }]
|
|
556
563
|
}], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
|
|
557
564
|
type: Inject,
|
|
558
565
|
args: [MAT_DIALOG_DATA]
|
|
559
|
-
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { target: [{ type: i0.ViewChild, args: ['target', {
|
|
566
|
+
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { target: [{ type: i0.ViewChild, args: ['target', { ...{
|
|
567
|
+
read: ViewContainerRef,
|
|
568
|
+
}, isSignal: true }] }] } });
|
|
560
569
|
|
|
561
570
|
class C3DialogTemplateComponent {
|
|
562
571
|
constructor() {
|
|
@@ -1243,12 +1252,63 @@ class C3FileViewer {
|
|
|
1243
1252
|
? of(this.locationBlobMap.get(location))
|
|
1244
1253
|
: this.getFile(location).pipe(map((response) => URL.createObjectURL(response)), tap((url) => this.locationBlobMap.set(location, url)))), tap(() => this.onLoaded()));
|
|
1245
1254
|
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Encode une URL de manière sûre pour éviter les problèmes avec les caractères spéciaux
|
|
1257
|
+
* comme +, espaces, etc.
|
|
1258
|
+
* Cette fonction encode correctement les segments du chemin et les paramètres de requête.
|
|
1259
|
+
*/
|
|
1260
|
+
encodeUrl(url) {
|
|
1261
|
+
try {
|
|
1262
|
+
// Si l'URL est relative, on doit encoder manuellement
|
|
1263
|
+
if (!url.includes('://')) {
|
|
1264
|
+
// Pour les URLs relatives, on sépare le chemin et les paramètres de requête
|
|
1265
|
+
const [path, query] = url.split('?');
|
|
1266
|
+
// Encoder chaque segment du chemin (sauf les séparateurs /)
|
|
1267
|
+
const encodedPath = path
|
|
1268
|
+
.split('/')
|
|
1269
|
+
.map((segment) => (segment ? encodeURIComponent(segment) : ''))
|
|
1270
|
+
.join('/');
|
|
1271
|
+
if (query) {
|
|
1272
|
+
// Pour les paramètres de requête, encoder chaque clé et valeur
|
|
1273
|
+
const params = query.split('&');
|
|
1274
|
+
const encodedParams = params.map((param) => {
|
|
1275
|
+
const [key, ...valueParts] = param.split('=');
|
|
1276
|
+
const value = valueParts.join('=');
|
|
1277
|
+
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
1278
|
+
});
|
|
1279
|
+
return `${encodedPath}?${encodedParams.join('&')}`;
|
|
1280
|
+
}
|
|
1281
|
+
return encodedPath;
|
|
1282
|
+
}
|
|
1283
|
+
// Pour les URLs absolues, utiliser le constructeur URL pour parser
|
|
1284
|
+
const urlObj = new URL(url);
|
|
1285
|
+
// Encoder chaque segment du chemin
|
|
1286
|
+
const encodedPath = urlObj.pathname
|
|
1287
|
+
.split('/')
|
|
1288
|
+
.map((segment) => (segment ? encodeURIComponent(segment) : ''))
|
|
1289
|
+
.join('/');
|
|
1290
|
+
// Les searchParams sont déjà gérés correctement par URLSearchParams
|
|
1291
|
+
// mais on doit s'assurer que les valeurs sont encodées
|
|
1292
|
+
const searchParams = new URLSearchParams();
|
|
1293
|
+
urlObj.searchParams.forEach((value, key) => {
|
|
1294
|
+
searchParams.append(key, value);
|
|
1295
|
+
});
|
|
1296
|
+
const encodedSearch = searchParams.toString() ? `?${searchParams.toString()}` : '';
|
|
1297
|
+
return `${urlObj.protocol}//${urlObj.host}${encodedPath}${encodedSearch}${urlObj.hash}`;
|
|
1298
|
+
}
|
|
1299
|
+
catch (e) {
|
|
1300
|
+
// Si le parsing échoue (URL malformée ou relative sans base),
|
|
1301
|
+
// encoder avec encodeURI qui préserve la structure de l'URL
|
|
1302
|
+
return encodeURI(url);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1246
1305
|
getFile(location) {
|
|
1247
1306
|
const client = this.config.customClient || this.client;
|
|
1248
1307
|
if (!client) {
|
|
1249
1308
|
throw new Error('No http client provided. Please provide a custom client or import HttpClientModule');
|
|
1250
1309
|
}
|
|
1251
|
-
|
|
1310
|
+
const encodedLocation = this.encodeUrl(location);
|
|
1311
|
+
return client(encodedLocation, {
|
|
1252
1312
|
responseType: 'blob',
|
|
1253
1313
|
});
|
|
1254
1314
|
}
|
|
@@ -1395,7 +1455,8 @@ class C3FileViewer {
|
|
|
1395
1455
|
}
|
|
1396
1456
|
downloadWithClient(file, client, originalName) {
|
|
1397
1457
|
// Utiliser le client fourni pour récupérer le fichier
|
|
1398
|
-
|
|
1458
|
+
const encodedLocation = this.encodeUrl(file.location);
|
|
1459
|
+
client(encodedLocation, {
|
|
1399
1460
|
responseType: 'blob',
|
|
1400
1461
|
}).subscribe({
|
|
1401
1462
|
next: (blob) => {
|