diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.spec.ts index 87af23d93fa..9e67cda109c 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.spec.ts @@ -218,12 +218,10 @@ describe('ArchiveSearchComponent', () => { expect(archiveServiceStub.hasArchiveSearchRole).toHaveBeenCalled(); }); it('should open a modal with TransferAcknowledgmentComponent', () => { - component.accessContractId = 'accessContract'; component.showAcknowledgmentTransferForm(); expect(matDialogSpy.open).toHaveBeenCalledWith(TransferAcknowledgmentComponent, { disableClose: true, data: { - accessContract: 'accessContract', tenantIdentifier: '1', }, }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts index 5fdc6c79115..0d9697301dc 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts @@ -1448,7 +1448,6 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft const dialogRef = this.dialog.open(TransferAcknowledgmentComponent, { disableClose: true, data: { - accessContract: this.accessContractId, tenantIdentifier: this.tenantIdentifier.toString(), }, }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.html index bc9ea98b9b6..56d7e3bdb26 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.html @@ -3,7 +3,7 @@ [title]="'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.TITLE_FIRST_STEP' | translate" > - + @@ -17,19 +17,21 @@

-
+
- - @@ -81,9 +83,7 @@

- + @@ -95,7 +95,32 @@

-
+ @if (isSubmitBtnDisabled) { +
+ +
+ } @else { +
+

+ {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.ACKNOWLEDGMENT_TRANSFER_CONTROL' | translate }} +

+

+ {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.ACKNOWLEDGMENT_TRANSFER_REPLY_CODE' | translate }} + {{ transfertDetails.archiveTransferReply }} +

+

+ @if (transfertDetailsCode === 'OK') { + {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.CONFIRM_SUCCESS_TRANSFER' | translate }} + } + @if (transfertDetailsCode === 'WARNING') { + {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.CONFIRM_SUCCESS_TRANSFER' | translate }} + } + @if (transfertDetailsCode === 'KO') { + {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.CONFIRM_FAILURE_TRANSFER' | translate }} + } +

+
+ }
@@ -129,81 +154,3 @@

- - -
- -
-
- - -
-

- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.ACKNOWLEDGMENT_TRANSFER_CONTROL' | translate }} -

-

- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.ACKNOWLEDGMENT_TRANSFER_REPLY_CODE' | translate }} - {{ transfertDetails.archiveTransferReply }} -

-

- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.CONFIRM_SUCCESS_TRANSFER' | translate }} - - {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.CONFIRM_SUCCESS_TRANSFER' | translate }} - - - {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.CONFIRM_FAILURE_TRANSFER' | translate }} - -

-
-
- - -
-
-
-
- {{ fileName }} - | {{ fileSizeString }} - check_circle -
- {{ message }} - cancel -
- -
-
- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.AUTHORIZED_SIZE' | translate }} - cancel -
-
- -
-
- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.ATR_NOT_VALID' | translate }} - cancel -
-
-
-
- - - -
-
{{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.DRAG_AND_DROP' | translate }}
- -
-
- - {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.BROWSE' | translate }} -
-
-
- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.ACCEPTED_FORMAT' | translate }}

- {{ 'ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.MAX_SIZE' | translate }} -
-
-
-
-
diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.spec.ts index f2248539475..c32661630e6 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.spec.ts @@ -45,6 +45,8 @@ import { ArchiveService } from '../../archive.service'; import { TransferAcknowledgmentComponent } from './transfer-acknowledgment.component'; import { DecimalPipe } from '@angular/common'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { CdkStep } from '@angular/cdk/stepper'; const translations: any = { TEST: 'Mock translate test' }; @@ -84,8 +86,11 @@ describe('TransferAcknowledgmentComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [TransferAcknowledgmentComponent, MockDateTimePipe], + declarations: [MockDateTimePipe], imports: [ + TransferAcknowledgmentComponent, + CdkStep, + NoopAnimationsModule, InjectorModule, LoggerModule.forRoot(), TranslateModule.forRoot({ @@ -118,77 +123,23 @@ describe('TransferAcknowledgmentComponent', () => { expect(component).toBeTruthy(); }); - it('All the parameters must be initialized', () => { - // When - component.initializeParameters(); - - // Then - expect(component.transfertDetailsCode).toBeNull(); - expect(component.isDisabled).toBeFalsy(); - expect(component.hasFileSizeError).toBeFalsy(); - expect(component.isAtrNotValid).toBeFalsy(); - expect(component.transfertDetails).toEqual({}); - expect(component.hasError).toBeFalsy(); - expect(component.message).toBeNull(); - }); - - it('Should return true when the file extension is xml ', () => { - // Given - const fileName = 'ATR_aeeaaaaaaghduohdabkogamdgezb2taaaaaq.xml'; - - // When - const response: boolean = component.checkFileExtension(fileName); - - // Then - expect(response).toBeTruthy(); - }); - - it('Should have an accessContract ', () => { - expect(component.data.accessContract).not.toBeNull(); - }); - - it('Should return false when the file extension is not xml ', () => { - // Given - const fileName = 'SIP-recherche-perf.zip'; - // When - const response: boolean = component.checkFileExtension(fileName); - // Then - expect(response).toBeFalsy(); - }); - - it('Should have a tenant identifier ', () => { - expect(component.data.tenantIdentifier).not.toBeNull(); - }); - - it('Should return true if the extension file is xml ', () => { - const contents = 'text for test'; - const blob = new Blob([contents], { type: 'text/plain' }); - const file = new File([blob], 'fileExample.xml', { type: 'text/plain' }); - expect(component.checkFileExtension(file.name)).toBeTruthy(); - }); - it('should call transferAcknowledgment()', () => { const archiveService = TestBed.inject(ArchiveService); const matDialogRef = TestBed.inject(MatDialogRef); - component.applyTransferAcknowledgment(); - expect(archiveService.transferAcknowledgment).toHaveBeenCalled(); - expect(matDialogRef.close).toHaveBeenCalled(); - }); - - it('should return KO as status()', () => { - // Given - component.transfertDetails = { archiveTransferReply: '\n\t\tKO\n\t' }; - // When - component.goToNextStep(); + const file = new File([''], ''); + component.atrControl.setValue([file]); + component.data.tenantIdentifier = '42'; - // Then - expect(component.transfertDetailsCode).not.toBeNull(); - expect(component.transfertDetailsCode).toEqual('KO'); + component.applyTransferAcknowledgment(); + expect(archiveService.transferAcknowledgment).toHaveBeenCalledWith('42', file); + expect(matDialogRef.close).toHaveBeenCalled(); }); it('should parseXmlToTransferDetails for valid XML', async () => { - const xmlOK = ` + const xmlOK = new File( + [ + ` @@ -202,10 +153,13 @@ describe('TransferAcknowledgmentComponent', () => { Identifier5 -`; +`, + ], + 'ok.xml', + ); - await component.parseXmlToTransferDetails(xmlOK); - expect(component.isAtrNotValid).toBeFalse(); + const errors = await component.atrContentValidator(xmlOK); + expect(errors).toBeFalsy(); expect(component.transfertDetails).toEqual({ messageRequestIdentifier: 'SIP SEDA de test', date: '2024-06-04T12:56:58.824Z', @@ -217,18 +171,21 @@ describe('TransferAcknowledgmentComponent', () => { }); it('should parseXmlToTransferDetails for XML without ArchiveTransferReply', async () => { - const xmlNoArchiveTransferReply = ''; + const xmlNoArchiveTransferReply = new File([''], 'xmlNoArchiveTransferReply.xml'); - await component.parseXmlToTransferDetails(xmlNoArchiveTransferReply); - expect(component.isAtrNotValid).toBeTrue(); + const errors = await component.atrContentValidator(xmlNoArchiveTransferReply); + expect(errors).toBeTruthy(); + expect(errors.fileErrors.atrNotValid).toBeTruthy(); + expect(errors.controlErrors.invalidFiles).toBeTruthy(); }); it('should parseXmlToTransferDetails for invalid XML', async () => { - const xmlBadFormat = 'This is not XML'; + const xmlBadFormat = new File(['This is not XML'], 'xmlBadFormat.xml'); - await component.parseXmlToTransferDetails(xmlBadFormat); - expect(component.hasError).toBeTrue(); - expect(component.message).toBeTruthy(); + const errors = await component.atrContentValidator(xmlBadFormat); + expect(errors).toBeTruthy(); + expect(errors.fileErrors.fileBadFormat).toBeTruthy(); + expect(errors.controlErrors.invalidFiles).toBeTruthy(); }); describe('DOM', () => { @@ -240,24 +197,6 @@ describe('TransferAcknowledgmentComponent', () => { expect(formTitlesHtmlElements[0].textContent).toContain('ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.OPERATION_MESSAGE_IDENTIFIER '); }); - it('should emit handleFileInput function when a file is added ', () => { - // Given - const contents = 'test'; - const blob = new Blob([contents], { type: 'text/plain' }); - const file = new File([blob], 'atrFile.xml', { type: 'text/plain' }); - component.fileToUpload = file; - spyOn(component, 'handleFile'); - const nativeElement = fixture.nativeElement; - const checkBox = nativeElement.querySelector('input[type=file]'); - - // When - checkBox.dispatchEvent(new Event('change')); - fixture.detectChanges(); - - // Then - expect(component.handleFile).toHaveBeenCalled(); - }); - it('should have an input file', () => { const nativeElement = fixture.nativeElement; const elInput = nativeElement.querySelector('input[type=file]'); @@ -270,11 +209,6 @@ describe('TransferAcknowledgmentComponent', () => { expect(matDialogSpyTest.close).toHaveBeenCalled(); }); - it('should have 3 cdk steps', () => { - const elementCdkStep = fixture.nativeElement.querySelectorAll('cdk-step'); - expect(elementCdkStep.length).toBe(3); - }); - it('should call close for all open dialogs', () => { const matDialogSpyTest = TestBed.inject(MatDialogRef); component.onConfirm(); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.ts index 5e6bcc350af..3c27771c34d 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/transfer-acknowledgment/transfer-acknowledgment.component.ts @@ -34,13 +34,27 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import { Component, Inject, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, Inject, OnDestroy, TemplateRef, ViewChild } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import { ApplicationId, BytesPipe, Logger, SnackBarService } from 'vitamui-library'; +import { + ApplicationId, + DialogHeaderComponent, + FileSelectorComponent, + FileValidationErrors, + Logger, + PipesModule, + readFileContent, + SnackBarService, + VitamUICommonModule, + VitamUILibraryModule, +} from 'vitamui-library'; import { ArchiveService } from '../../archive.service'; import { XMLParser } from 'fast-xml-parser'; +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; const FILE_MAX_SIZE = 10737418240; const ATR_EXTENSION = '.xml'; @@ -49,36 +63,34 @@ const ATR_EXTENSION = '.xml'; selector: 'app-transfer-acknowledgment', templateUrl: './transfer-acknowledgment.component.html', styleUrls: ['./transfer-acknowledgment.component.scss'], - standalone: false, + imports: [ + CdkStep, + DialogHeaderComponent, + FileSelectorComponent, + MatDialogActions, + MatDialogContent, + MatProgressSpinner, + PipesModule, + ReactiveFormsModule, + TranslatePipe, + VitamUICommonModule, + VitamUILibraryModule, + ], }) -export class TransferAcknowledgmentComponent implements OnInit, OnDestroy { - stepIndex = 0; - fileSize = 0; - - isAtrNotValid = false; - isDisabled = true; - hasFileSizeError = false; - hasError = false; - isLoadingData = false; +export class TransferAcknowledgmentComponent implements OnDestroy { isSubmitBtnDisabled = false; - fileToUpload: File = null; transfertDetails: any = {}; - message: string; - fileName: string; - fileSizeString: string; - accessContract: string; - tenantIdentifier: string; transfertDetailsCode: string; transferAcknowledgementSubscription: Subscription; + atrControl = new FormControl(undefined, [Validators.required]); + @ViewChild('confirmDeleteTransferAcknowledgmentDialog', { static: true }) confirmDeleteTransferAcknowledgmentDialog: TemplateRef; - @ViewChild('atrXmlFile', { static: false }) atrXmlFile: any; - constructor( public dialog: MatDialog, private dialogRef: MatDialogRef, @@ -86,24 +98,23 @@ export class TransferAcknowledgmentComponent implements OnInit, OnDestroy { public logger: Logger, @Inject(MAT_DIALOG_DATA) public data: { - accessContract: string; tenantIdentifier: string; }, private archiveSearchService: ArchiveService, - private translate: TranslateService, - private bytesPipe: BytesPipe, private snackBarService: SnackBarService, ) {} - async parseXmlToTransferDetails(xmlFileContent: string) { - this.isLoadingData = true; + atrContentValidator = async (file: File): Promise => { + const xmlFileContent = await readFileContent(file); const parser = new XMLParser(); try { const parsedXml: { ArchiveTransferReply: any } = parser.parse(xmlFileContent, true); if (parsedXml.ArchiveTransferReply === undefined || parsedXml.ArchiveTransferReply === null) { - this.isAtrNotValid = true; - this.isLoadingData = false; + return { + fileErrors: { atrNotValid: true }, + controlErrors: { invalidFiles: true }, + }; } else { this.transfertDetails.messageRequestIdentifier = parsedXml.ArchiveTransferReply?.MessageRequestIdentifier; this.transfertDetails.date = parsedXml.ArchiveTransferReply?.Date; @@ -111,22 +122,16 @@ export class TransferAcknowledgmentComponent implements OnInit, OnDestroy { this.transfertDetails.archivalAgency = parsedXml.ArchiveTransferReply.ArchivalAgency?.Identifier; this.transfertDetails.transferringAgency = parsedXml.ArchiveTransferReply.TransferringAgency?.Identifier; this.transfertDetails.archiveTransferReply = parsedXml.ArchiveTransferReply.ReplyCode; - this.isAtrNotValid = false; - this.stepIndex = this.stepIndex + 1; - this.isLoadingData = false; } } catch (error: any) { - this.message = this.translate.instant('ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.FILE_BAD_FORMAT'); - this.hasError = true; - this.isLoadingData = false; this.logger.error('Error with parsing the xml file :', error); + return { + fileErrors: { fileBadFormat: true }, + controlErrors: { invalidFiles: true }, + }; } - } - - ngOnInit(): void { - this.accessContract = this.data.accessContract; - this.tenantIdentifier = this.data.tenantIdentifier; - } + return null; + }; ngOnDestroy(): void { this.transferAcknowledgementSubscription?.unsubscribe(); @@ -150,71 +155,12 @@ export class TransferAcknowledgmentComponent implements OnInit, OnDestroy { this.dialogRef.close(true); } - initializeParameters() { - this.isDisabled = false; - this.hasError = false; - this.hasFileSizeError = false; - this.message = null; - this.isAtrNotValid = false; - this.transfertDetails = {}; - this.transfertDetailsCode = null; - } - - private isFileList(files: FileList | File[]): files is FileList { - return files instanceof FileList; - } - - private initializeFileToUpload(files: FileList | File[]) { - if (files) { - this.fileToUpload = this.isFileList(files) ? files.item(0) : files[0]; - this.fileName = this.fileToUpload.name; - this.fileSize = this.fileToUpload.size; - } - } - - handleFile(files: FileList | File[]) { - this.initializeParameters(); - this.initializeFileToUpload(files); - - this.fileSizeString = this.bytesPipe.transform(this.fileSize); - - if (!this.checkFileExtension(this.fileName)) { - this.message = this.translate.instant('ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.FILE_BAD_FORMAT'); - this.hasError = true; - } else { - if (this.fileSize > FILE_MAX_SIZE) { - this.logger.error(this.translate.instant('ARCHIVE_SEARCH.TRANSFER_ACKNOWLEDGMENT.AUTHORIZED_SIZE')); - this.hasFileSizeError = true; - } - } - } - - addTransferAtrFile() { - this.atrXmlFile.nativeElement.click(); - } - - checkFileExtension(fileName: string): boolean { - return fileName.endsWith(ATR_EXTENSION); - } - - goToNextStep() { - this.stepIndex = this.stepIndex + 1; - this.transfertDetailsCode = this.transfertDetails.archiveTransferReply.replace(/(\r\n|\n|\r)/gm, '').trim(); - } - - // Step 1 : - validateAndParseXmlFile() { - if (this.fileToUpload && !this.hasError && !this.hasFileSizeError) { - this.isLoadingData = true; - this.fileToUpload.text().then((xmlFileContent) => this.parseXmlToTransferDetails(xmlFileContent)); - } - } - // Step 3 : applyTransferAcknowledgment() { this.isSubmitBtnDisabled = true; + const atrFile = this.atrControl.value[0]; this.transferAcknowledgementSubscription = this.archiveSearchService - .transferAcknowledgment(this.tenantIdentifier, this.fileToUpload) + .transferAcknowledgment(this.data.tenantIdentifier, atrFile) .subscribe( (operationId) => { this.dialogRef.close(true); @@ -238,4 +184,7 @@ export class TransferAcknowledgmentComponent implements OnInit, OnDestroy { }, ); } + + protected readonly FILE_MAX_SIZE = FILE_MAX_SIZE; + protected readonly ATR_EXTENSION = ATR_EXTENSION; } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts index 932fa7d7f84..2deed251120 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts @@ -88,7 +88,6 @@ import { SearchCriteriaListComponent } from './archive-search/search-criteria-li import { SearchCriteriaSaverComponent } from './archive-search/search-criteria-saver/search-criteria-saver.component'; import { SimpleCriteriaSearchComponent } from './archive-search/simple-criteria-search/simple-criteria-search.component'; import { TitleAndDescriptionCriteriaSearchComponent } from './archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component'; -import { TransferAcknowledgmentComponent } from './archive-search/transfer-acknowledgment/transfer-acknowledgment.component'; import { ArchiveComponent } from './archive.component'; import { CriteriaSearchComponent } from './criteria-search/criteria-search.component'; import { ClassificationTreeComponent } from './filing-holding-scheme/classification-tree/classification-tree.component'; @@ -162,7 +161,6 @@ import { ConfirmActionModule } from './archive-search/search-criteria-list/confi SimpleCriteriaSearchComponent, StorageRuleSearchComponent, TitleAndDescriptionCriteriaSearchComponent, - TransferAcknowledgmentComponent, TransferRequestModalComponent, UnlockCategoryInheritanceComponent, UnlockRulesInheritanceComponent, diff --git a/ui/ui-frontend/projects/collect/src/assets/i18n/en.json b/ui/ui-frontend/projects/collect/src/assets/i18n/en.json index 3b11e24a281..7b5d4e8c6b9 100644 --- a/ui/ui-frontend/projects/collect/src/assets/i18n/en.json +++ b/ui/ui-frontend/projects/collect/src/assets/i18n/en.json @@ -18,7 +18,6 @@ "ADD_FILE": "Drag and drop", "BROWSE": "or Browse", "ACCEPTED_FORMAT": "Accepted format: csv", - "FILE_BAD_FORMAT": "The uploaded file is not in the correct format", "SUCCESS_MESSAGE": "The metadata update operation was successfully processed", "WAIT_MESSAGE": "The operation is in progress, please do not shut down or refresh your browser", "ACTION_DELETE": "Delete archive unit", diff --git a/ui/ui-frontend/projects/collect/src/assets/i18n/fr.json b/ui/ui-frontend/projects/collect/src/assets/i18n/fr.json index c3c4b9fc08f..a5e496cf37d 100644 --- a/ui/ui-frontend/projects/collect/src/assets/i18n/fr.json +++ b/ui/ui-frontend/projects/collect/src/assets/i18n/fr.json @@ -18,7 +18,6 @@ "ADD_FILE": "Glisser-déposer", "BROWSE": "ou Parcourir", "ACCEPTED_FORMAT": "format accepté : csv", - "FILE_BAD_FORMAT": "Le fichier déposé n'est pas au bon format", "SUCCESS_MESSAGE": "L'opération de mise à jour des métadonnées a bien été traitée", "WAIT_MESSAGE": "L'opération est en cours, merci de ne pas éteindre ou rafraîchir votre navigateur", "ACTION_DELETE": "Supprimer des unités archivistiques", diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.html b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.html index 25d2d94e63c..1d579ab8f5d 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.html +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.html @@ -12,6 +12,11 @@

@if (file.errors && Object.entries(file.errors)?.length) { @for (entry of Object.entries(file.errors); track entry[0]) { - + } } diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.ts index 83645629cf8..5ea5a211112 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/display-file/display-file.component.ts @@ -48,6 +48,7 @@ import { CommonTooltipModule } from '../../common-tooltip/common-tooltip.module' }) export class DisplayFileComponent { @Input() file: DisplayFile; + @Input() errorMessageMap: { [key: string]: string } = {}; @Output() removeFile = new EventEmitter(); protected readonly Object = Object; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.html b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.html index d1c6c31739c..0f9e0f870dd 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.html +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.html @@ -37,7 +37,7 @@ @if (displayFiles.length) {
@for (file of displayFiles; track file) { - + }
} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.ts index 2f63552bd1b..a2a437e2c1d 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/file-selector/file-selector.component.ts @@ -53,7 +53,7 @@ import { I18nPluralPipe, NgTemplateOutlet } from '@angular/common'; import { PipesModule } from '../../pipes/pipes.module'; import { DisplayFile } from './display-file/display-file.interface'; import { CustomFile } from '../../../../lib/models/custom-file'; -import { AbstractControl, FormsModule, NG_VALUE_ACCESSOR, ValidationErrors } from '@angular/forms'; +import { AbstractControl, FormControl, FormsModule, NG_VALUE_ACCESSOR, ValidationErrors } from '@angular/forms'; import { FormErrorsComponent } from '../../../../lib/components/form-errors/form-errors.component'; import { BytesPipe } from '../../pipes'; import { AbstractFormInputDirective } from '../../../../lib/components/abstract-form-input.directive'; @@ -100,6 +100,8 @@ type FileValidatorFunction = (file: File) => Promise; + /** * Allowed extensions. Ex: ['.json', '.rng'] */