@sotoa-ui/dynamic-form 0.0.7 → 0.0.9

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.
@@ -4,6 +4,7 @@ import { distinctUntilChanged, isObservable, take } from 'rxjs';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { FormBuilder, Validators, ReactiveFormsModule, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
6
6
  import * as _ from 'lodash-es';
7
+ import { isArray } from 'lodash-es';
7
8
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
9
  import { debounceTime } from 'rxjs/operators';
9
10
  import { NgClass, NgTemplateOutlet } from '@angular/common';
@@ -921,23 +922,25 @@ class MatInputFileComponent {
921
922
  constructor() {
922
923
  }
923
924
  ngOnInit() {
924
- if (this.group().get(this.field().name)?.value) {
925
+ const value = this.group().get(this.field().name)?.value;
926
+ if (value) {
925
927
  if (!this.field().multiple) {
926
- this.fichier = this.group().get(this.field().name)?.value;
928
+ this.fichier = { file: value, srcUrl: null };
929
+ this.readFile(this.fichier, value);
927
930
  }
928
931
  else {
929
- this.fileList = this.group().get(this.field().name)?.value;
932
+ if (isArray(value)) {
933
+ this.fileList = value.map((f) => {
934
+ const item = {
935
+ file: f,
936
+ srcUrl: null
937
+ };
938
+ this.readFile(item, f);
939
+ return item;
940
+ });
941
+ }
930
942
  }
931
943
  }
932
- // @ts-ignore
933
- this.group()
934
- .get(this.field().name)
935
- .valueChanges.pipe(takeUntilDestroyed(this.destroyRef))
936
- .subscribe((value1) => {
937
- if (JSON.stringify(value1) !== JSON.stringify(this.fileList)) {
938
- this.fileList = value1;
939
- }
940
- });
941
944
  }
942
945
  writeValue(value) {
943
946
  this.value = value && (!this.field().multiple || value.length > 0) ? value : null;
@@ -954,33 +957,36 @@ class MatInputFileComponent {
954
957
  }
955
958
  onSelectFile(event) {
956
959
  if (event && event.target && event.target.files && event.target.files.length > 0) {
957
- this.fichier = event.target.files[0];
958
- if (!this.field().multiple) {
959
- this.writeValue(this.fichier);
960
- if (this.field().onAddFile) {
961
- this.field().onAddFile(this.fichier ?? null);
960
+ for (let i = 0; i < event.target.files.length; i++) {
961
+ const fichier = { file: event.target.files[i], srcUrl: null };
962
+ this.readFile(fichier, fichier.file);
963
+ if (!this.field().multiple) {
964
+ this.addSimpleFile(fichier);
965
+ }
966
+ else {
967
+ this.addMultipleFile(fichier);
962
968
  }
963
969
  }
964
- else {
965
- this.addFile();
966
- }
967
970
  }
968
971
  }
969
- addFile() {
970
- if (this.fichier) {
972
+ addSimpleFile(file) {
973
+ this.fichier = file;
974
+ this.writeValue(this.fichier?.file);
975
+ if (this.field().onAddFile) {
976
+ this.field().onAddFile(this.fichier?.file ?? null);
977
+ }
978
+ }
979
+ addMultipleFile(file) {
980
+ if (file) {
971
981
  if (!this.fileList) {
972
982
  this.fileList = [];
973
983
  }
974
- this.fileList.push(this.fichier);
984
+ this.fileList.push(file);
975
985
  if (this.field().onAddFile) {
976
- this.field().onAddFile(this.fichier);
977
- }
978
- this.fichier = null;
979
- if (this.fileInput && this.fileInput.nativeElement) {
980
- this.fileInput.nativeElement.value = null;
986
+ this.field().onAddFile(file.file);
981
987
  }
982
988
  }
983
- this.writeValue(this.fileList);
989
+ this.writeValue(this.fileList.map((f) => f.file));
984
990
  }
985
991
  deleteFile(file) {
986
992
  if (!this.field().multiple) {
@@ -989,10 +995,19 @@ class MatInputFileComponent {
989
995
  }
990
996
  else {
991
997
  this.fileList.splice(this.fileList.indexOf(file), 1);
992
- this.writeValue(this.fileList);
998
+ this.writeValue(this.fileList.map((f) => f.file));
993
999
  }
994
1000
  if (this.field().onDeleteFile) {
995
- this.field().onDeleteFile(file);
1001
+ this.field().onDeleteFile(file.file);
1002
+ }
1003
+ }
1004
+ readFile(item, f) {
1005
+ if (f instanceof File && f.type.match('image.*')) {
1006
+ const reader = new FileReader();
1007
+ reader.onload = () => {
1008
+ item.srcUrl = reader.result;
1009
+ };
1010
+ reader.readAsDataURL(f);
996
1011
  }
997
1012
  }
998
1013
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MatInputFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -1002,17 +1017,17 @@ class MatInputFileComponent {
1002
1017
  multi: true,
1003
1018
  useExisting: forwardRef(() => MatInputFileComponent),
1004
1019
  },
1005
- ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"sot-file-wrapper\">\n @if (field().multiple) {\n <label [for]=\"'file-upload-' + field().id\">{{ field().label }}</label>\n <ul>\n @for (item of fileList; track item) {\n <li class=\"file-list-item\">\n <div>\n {{ item.name }}\n </div>\n <div>\n @if (!field().disabled) {\n <button mat-icon-button\n type=\"button\"\n (click)=\"deleteFile(item)\"\n title=\"Supprimer\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </li>\n }\n </ul>\n <div>\n <button matButton type=\"button\" (click)=\"fileInput.click()\" [disabled]=\"field().disabled\">\n Choisir un\n fichier\n </button>\n <input\n #fileInput\n hidden\n type=\"file\"\n [attr.id]=\"'file-upload-' + field().id\"\n name=\"file-upload\"\n (change)=\"onSelectFile($event)\"\n [accept]=\"field().accept ? field().accept : '*/*'\"\n />\n </div>\n } @else {\n <label [for]=\"'file-upload-' + field().id\">{{ field().label }}</label>\n <input\n #fileInput\n hidden\n type=\"file\"\n [attr.id]=\"'file-upload-' + field().id\"\n name=\"file-upload\"\n (change)=\"onSelectFile($event)\"\n [accept]=\"field().accept ? field().accept : '*/*'\"\n />\n <button matButton type=\"button\" (click)=\"fileInput.click()\" [disabled]=\"field().disabled\">\n Choisir un fichier\n </button>\n\n @if (fichier) {\n <div class=\"file-list-item\">\n <div>{{ fichier!.name }}</div>\n @if (!field().disabled) {\n <button type=\"button\" mat-button (click)=\"deleteFile(fichier!)\">Supprimer</button>\n }\n </div>\n }\n }\n</div>\n", styles: [".file-list-item{display:flex;flex-direction:row;gap:1rem;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$1.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: i1$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
1020
+ ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"sot-file-wrapper\">\n <label [ngClass]=\"field()?.labelClassName\" [for]=\"'file-upload-' + field().id\">{{ field().label }}</label>\n <div class=\"sot-file-list\">\n @if (field().multiple) {\n <ul>\n @for (item of fileList; track item) {\n <li class=\"file-list-item\">\n <div>\n <div>\n @if (item.srcUrl) {\n <img [src]=\"item.srcUrl\" [alt]=\"item!.file.name\"/>\n } @else {\n {{ item.file.name }}\n }\n </div>\n </div>\n <div>\n @if (!field().disabled) {\n <button mat-icon-button\n type=\"button\"\n (click)=\"deleteFile(item)\"\n title=\"Supprimer\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </li>\n }\n </ul>\n } @else {\n @if (fichier) {\n <div class=\"file-list-item\">\n <div>\n @if (fichier.srcUrl) {\n <img [src]=\"fichier.srcUrl\" [alt]=\"fichier.file.name\"/>\n } @else {\n {{ fichier.file.name }}\n }\n </div>\n @if (!field().disabled) {\n <button type=\"button\" mat-button (click)=\"deleteFile(fichier!)\">Supprimer</button>\n }\n </div>\n }\n }\n </div>\n <div class=\"sot-file-button\">\n <button matButton type=\"button\" (click)=\"fileInput.click()\" [disabled]=\"field().disabled\">\n Choisir un fichier\n </button>\n <input\n #fileInput\n hidden\n type=\"file\"\n [attr.id]=\"'file-upload-' + field().id\"\n name=\"file-upload\"\n (change)=\"onSelectFile($event)\"\n [accept]=\"field().accept ? field().accept : '*/*'\"\n [multiple]=\"field().multiple\"\n />\n </div>\n</div>\n", styles: [".file-list-item{display:flex;flex-direction:row;gap:1rem;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$1.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: i1$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1006
1021
  }
1007
1022
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MatInputFileComponent, decorators: [{
1008
1023
  type: Component,
1009
- args: [{ selector: 'sot-mat-input-file', standalone: true, imports: [ReactiveFormsModule, MatButtonModule, MatIconModule], providers: [
1024
+ args: [{ selector: 'sot-mat-input-file', standalone: true, imports: [ReactiveFormsModule, MatButtonModule, MatIconModule, NgClass], providers: [
1010
1025
  {
1011
1026
  provide: NG_VALUE_ACCESSOR,
1012
1027
  multi: true,
1013
1028
  useExisting: forwardRef(() => MatInputFileComponent),
1014
1029
  },
1015
- ], template: "<div class=\"sot-file-wrapper\">\n @if (field().multiple) {\n <label [for]=\"'file-upload-' + field().id\">{{ field().label }}</label>\n <ul>\n @for (item of fileList; track item) {\n <li class=\"file-list-item\">\n <div>\n {{ item.name }}\n </div>\n <div>\n @if (!field().disabled) {\n <button mat-icon-button\n type=\"button\"\n (click)=\"deleteFile(item)\"\n title=\"Supprimer\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </li>\n }\n </ul>\n <div>\n <button matButton type=\"button\" (click)=\"fileInput.click()\" [disabled]=\"field().disabled\">\n Choisir un\n fichier\n </button>\n <input\n #fileInput\n hidden\n type=\"file\"\n [attr.id]=\"'file-upload-' + field().id\"\n name=\"file-upload\"\n (change)=\"onSelectFile($event)\"\n [accept]=\"field().accept ? field().accept : '*/*'\"\n />\n </div>\n } @else {\n <label [for]=\"'file-upload-' + field().id\">{{ field().label }}</label>\n <input\n #fileInput\n hidden\n type=\"file\"\n [attr.id]=\"'file-upload-' + field().id\"\n name=\"file-upload\"\n (change)=\"onSelectFile($event)\"\n [accept]=\"field().accept ? field().accept : '*/*'\"\n />\n <button matButton type=\"button\" (click)=\"fileInput.click()\" [disabled]=\"field().disabled\">\n Choisir un fichier\n </button>\n\n @if (fichier) {\n <div class=\"file-list-item\">\n <div>{{ fichier!.name }}</div>\n @if (!field().disabled) {\n <button type=\"button\" mat-button (click)=\"deleteFile(fichier!)\">Supprimer</button>\n }\n </div>\n }\n }\n</div>\n", styles: [".file-list-item{display:flex;flex-direction:row;gap:1rem;align-items:center}\n"] }]
1030
+ ], template: "<div class=\"sot-file-wrapper\">\n <label [ngClass]=\"field()?.labelClassName\" [for]=\"'file-upload-' + field().id\">{{ field().label }}</label>\n <div class=\"sot-file-list\">\n @if (field().multiple) {\n <ul>\n @for (item of fileList; track item) {\n <li class=\"file-list-item\">\n <div>\n <div>\n @if (item.srcUrl) {\n <img [src]=\"item.srcUrl\" [alt]=\"item!.file.name\"/>\n } @else {\n {{ item.file.name }}\n }\n </div>\n </div>\n <div>\n @if (!field().disabled) {\n <button mat-icon-button\n type=\"button\"\n (click)=\"deleteFile(item)\"\n title=\"Supprimer\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </li>\n }\n </ul>\n } @else {\n @if (fichier) {\n <div class=\"file-list-item\">\n <div>\n @if (fichier.srcUrl) {\n <img [src]=\"fichier.srcUrl\" [alt]=\"fichier.file.name\"/>\n } @else {\n {{ fichier.file.name }}\n }\n </div>\n @if (!field().disabled) {\n <button type=\"button\" mat-button (click)=\"deleteFile(fichier!)\">Supprimer</button>\n }\n </div>\n }\n }\n </div>\n <div class=\"sot-file-button\">\n <button matButton type=\"button\" (click)=\"fileInput.click()\" [disabled]=\"field().disabled\">\n Choisir un fichier\n </button>\n <input\n #fileInput\n hidden\n type=\"file\"\n [attr.id]=\"'file-upload-' + field().id\"\n name=\"file-upload\"\n (change)=\"onSelectFile($event)\"\n [accept]=\"field().accept ? field().accept : '*/*'\"\n [multiple]=\"field().multiple\"\n />\n </div>\n</div>\n", styles: [".file-list-item{display:flex;flex-direction:row;gap:1rem;align-items:center}\n"] }]
1016
1031
  }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }], fileInput: [{
1017
1032
  type: ViewChild,
1018
1033
  args: ['fileInput']