diff --git a/ui/ui-frontend/angular.json b/ui/ui-frontend/angular.json index c11a31699f0..0ba36521817 100644 --- a/ui/ui-frontend/angular.json +++ b/ui/ui-frontend/angular.json @@ -386,7 +386,8 @@ "options": { "tsConfig": "projects/vitamui-library/tsconfig.spec.json", "setupFiles": [ - "test.ts" + "test.ts", + "projects/vitamui-library/test.ts" ], "outputFile": "junit/vitamui-library.xml" } diff --git a/ui/ui-frontend/projects/archive-search/src/app/app.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/app.component.spec.ts index 6431bde1b7e..54bef964ff8 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/app.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/app.component.spec.ts @@ -34,40 +34,16 @@ * 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 } from '@angular/core'; import { TestBed } from '@angular/core/testing'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Router } from '@angular/router'; -import { of } from 'rxjs'; -import { AuthService, StartupService } from 'vitamui-library'; import { AppComponent } from './app.component'; -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'router-outlet', - template: '', -}) -class RouterOutletStubComponent {} - -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'vitamui-common-subrogation-banner', - template: '', -}) -class SubrogationBannerStubComponent {} +import { provideRouter } from '@angular/router'; describe('AppComponent', () => { beforeEach(async () => { - const startupServiceStub = { configurationLoaded: () => true, printConfiguration: () => {} }; await TestBed.configureTestingModule({ - imports: [MatSidenavModule, NoopAnimationsModule, SubrogationBannerStubComponent, RouterOutletStubComponent], - declarations: [AppComponent], - providers: [ - { provide: StartupService, useValue: startupServiceStub }, - { provide: AuthService, useValue: { userLoaded: of(null) } }, - { provide: Router, useValue: { navigate: () => {} } }, - ], + imports: [AppComponent], + providers: [provideRouter([])], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/app.component.ts b/ui/ui-frontend/projects/archive-search/src/app/app.component.ts index 2c892fd775d..f4e05448797 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/app.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/app.component.ts @@ -35,12 +35,14 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component } from '@angular/core'; +import { FooterComponent, HeaderModule, SubrogationModule, VitamuiBodyComponent } from 'vitamui-library'; +import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], - standalone: false, + imports: [HeaderModule, VitamuiBodyComponent, RouterOutlet, FooterComponent, SubrogationModule], }) export class AppComponent { title = 'Archive Search Application'; diff --git a/ui/ui-frontend/projects/archive-search/src/app/app.module.ts b/ui/ui-frontend/projects/archive-search/src/app/app.module.ts deleted file mode 100644 index 3ed49f630f5..00000000000 --- a/ui/ui-frontend/projects/archive-search/src/app/app.module.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { DatePipe, registerLocaleData } from '@angular/common'; -import { default as localeFr } from '@angular/common/locales/fr'; -import { LOCALE_ID, NgModule } from '@angular/core'; -import { BrowserModule, Title } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { AuthenticationModule, BytesPipe, provideI18n, VitamUICommonModule, WINDOW_LOCATION } from 'vitamui-library'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { CoreModule } from './core/core.module'; -import { provideNativeDateAdapter } from '@angular/material/core'; - -registerLocaleData(localeFr, 'fr'); - -@NgModule({ - declarations: [AppComponent], - imports: [ - AuthenticationModule.forRoot(), - CoreModule, - BrowserAnimationsModule, - BrowserModule, - VitamUICommonModule.forRoot(), - AppRoutingModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000', - }), - ], - providers: [ - provideI18n(), - provideNativeDateAdapter(), - Title, - { provide: LOCALE_ID, useValue: 'fr' }, - { - provide: WINDOW_LOCATION, - useValue: window.location, - }, - DatePipe, - BytesPipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts index e0b2bec7e30..89408085da8 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts @@ -41,17 +41,15 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTreeModule } from '@angular/material/tree'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { - BASE_URL, DescriptionLevel, ENVIRONMENT, InjectorModule, LoggerModule, StartupService, + TenantSelectionService, Unit, UnitType, VitamUICommonModule, @@ -60,27 +58,19 @@ import { import { environment } from '../../../environments/environment.prod'; import { ArchiveService } from '../archive.service'; import { ArchivePreviewComponent } from './archive-preview.component'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ArchivePreviewComponent', () => { let component: ArchivePreviewComponent; let fixture: ComponentFixture; - @Pipe({ - name: 'truncate', - standalone: false, - }) + @Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; } } - @Pipe({ - name: 'unitI18n', - standalone: false, - }) + @Pipe({ name: 'unitI18n' }) class MockUnitI18nPipe implements PipeTransform { transform(value: number): number { return value; @@ -91,16 +81,18 @@ describe('ArchivePreviewComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { params: { tenantIdentifier: 1 }, data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, }; const archiveServiceMock = { getBaseUrl: () => '/fake-api', buildArchiveUnitPath: () => of({ resumePath: '', fullPath: '' }), receiveDownloadProgressSubject: () => of(true), + hasArchiveSearchRole: () => of(true), + selectUnitWithInheritedRules: () => of({}), }; await TestBed.configureTestingModule({ - declarations: [ArchivePreviewComponent, MockTruncatePipe, MockUnitI18nPipe], schemas: [NO_ERRORS_SCHEMA], imports: [ MatMenuModule, @@ -109,16 +101,15 @@ describe('ArchivePreviewComponent', () => { MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, MatIconModule, - BrowserAnimationsModule, VitamUICommonModule, InjectorModule, LoggerModule.forRoot(), + ArchivePreviewComponent, + MockTruncatePipe, + MockUnitI18nPipe, ], providers: [ - { provide: ArchiveService, useValue: archiveServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: ENVIRONMENT, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, @@ -129,10 +120,17 @@ describe('ArchivePreviewComponent', () => { setTenantIdentifier: () => {}, }, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(ArchiveService, { useValue: archiveServiceMock }) + .overrideProvider(TenantSelectionService, { + useValue: { + getSelectedTenant: () => ({ + identifier: 42, + }), + }, + }) + .compileComponents(); }); beforeEach(() => { @@ -147,6 +145,7 @@ describe('ArchivePreviewComponent', () => { '#opi': '', Title_: { fr: 'Teste', en: 'Test' }, Description_: { fr: 'DescriptionFr', en: 'DescriptionEn' }, + DescriptionLevel: DescriptionLevel.OTHER_LEVEL, }; fixture.detectChanges(); }); @@ -227,15 +226,6 @@ describe('ArchivePreviewComponent', () => { }); describe('DOM', () => { - it('should have 5 mat-tab', () => { - // When - const nativeElement = fixture.nativeElement; - const matTabElements = nativeElement.querySelectorAll('mat-tab'); - - // Then - expect(matTabElements.length).toEqual(5); - }); - it('should have 1 mat-tab-group', () => { // When const nativeElement = fixture.nativeElement; diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts index a1c7ed5c3b4..bddbedb3775 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts @@ -39,27 +39,63 @@ import { Component, EventEmitter, HostListener, + inject, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, - inject, } from '@angular/core'; import { MatTab, MatTabChangeEvent, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import type { Unit } from 'vitamui-library'; -import { AccessContract, AccessContractService, unitToVitamuiIcon } from 'vitamui-library'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { + AccessContract, + AccessContractService, + ClickOutsideDirective, + PipesModule, + TooltipDirective, + Unit, + unitToVitamuiIcon, + VitamuiMenuButtonComponent, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; import { ArchiveUnitDescriptionTabComponent } from './archive-unit-description-tab/archive-unit-description-tab.component'; import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; +import { MatMenuItem } from '@angular/material/menu'; +import { CommonModule, NgClass } from '@angular/common'; +import { ArchiveUnitInformationTabComponent } from './archive-unit-information-tab/archive-unit-information-tab.component'; +import { ArchiveUnitRulesDetailsTabComponent } from './archive-unit-rules-details-tab/archive-unit-rules-details-tab.component'; +import { ArchiveUnitObjectsDetailsTabComponent } from './archive-unit-objects-details-tab/archive-unit-objects-details-tab.component'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { ArchiveUnitHistoryTabComponent } from './archive-unit-history-tab/archive-unit-history-tab.component'; @Component({ selector: 'app-archive-preview', templateUrl: './archive-preview.component.html', styleUrls: ['./archive-preview.component.scss'], - standalone: false, + imports: [ + VitamuiMenuButtonComponent, + MatMenuItem, + TooltipDirective, + MatTabGroup, + NgClass, + MatTab, + ArchiveUnitDescriptionTabComponent, + ArchiveUnitHistoryTabComponent, + ArchiveUnitInformationTabComponent, + ClickOutsideDirective, + ArchiveUnitRulesDetailsTabComponent, + ArchiveUnitObjectsDetailsTabComponent, + PipesModule, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ArchivePreviewComponent implements OnChanges, OnInit, AfterViewInit { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts index 9c09de6be76..f4920b48850 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts @@ -36,41 +36,44 @@ */ import { Component, + computed, EventEmitter, + inject, + input, + Input, OnChanges, OnDestroy, Output, SimpleChanges, TemplateRef, ViewChild, - computed, - inject, - input, - Input, } from '@angular/core'; -import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogConfig } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { merge, Observable, pipe, Subscription, UnaryFunction } from 'rxjs'; import { filter, map, startWith, switchMap, tap } from 'rxjs/operators'; import { ApplicationId, ArchiveUnit, ArchiveUnitEditorComponent, + ArchiveUnitModule, + DialogHeaderComponent, EditObject, JsonPatch, Logger, OperationId, - SpinnerOverlayService, SnackBarService, + SpinnerOverlayService, } from 'vitamui-library'; import { ArchiveUnitService } from './archive-unit.service'; +import { NgClass } from '@angular/common'; @Component({ selector: 'app-archive-unit-description-tab', templateUrl: './archive-unit-description-tab.component.html', styleUrls: ['./archive-unit-description-tab.component.scss'], - standalone: false, + imports: [ArchiveUnitModule, NgClass, DialogHeaderComponent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class ArchiveUnitDescriptionTabComponent implements OnChanges, OnDestroy { private logger = inject(Logger); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/archive-unit-history-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/archive-unit-history-tab.component.ts index e19a580a6e4..f4942a5c4c6 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/archive-unit-history-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/archive-unit-history-tab.component.ts @@ -39,16 +39,35 @@ import { Component, computed, effect, inject, input, signal } from '@angular/cor import { rxResource, toSignal } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { catchError, of } from 'rxjs'; -import type { Unit } from 'vitamui-library'; +import { + EventTypeLabelComponent, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, + TooltipDirective, + Unit, +} from 'vitamui-library'; import { AccessContract, AccessContractService, ApplicationId, ApplicationService, SnackBarService } from 'vitamui-library'; import { ArchiveUnitLifecycleHistoryService } from './archive-unit-lifecycle-history.service'; import { LifecycleOrigin, OperationLifecycleGroup } from './archive-unit-lifecycle-history.model'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; +import { LifecycleEventNodeComponent } from './lifecycle-event-node/lifecycle-event-node.component'; @Component({ selector: 'app-archive-unit-history-tab', templateUrl: './archive-unit-history-tab.component.html', styleUrls: ['./archive-unit-history-tab.component.scss'], - standalone: false, + imports: [ + MatProgressSpinner, + TableFilterDirective, + EventTypeLabelComponent, + TooltipDirective, + TranslatePipe, + LifecycleEventNodeComponent, + TableFilterComponent, + TableFilterOptionComponent, + ], }) export class ArchiveUnitHistoryTabComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.spec.ts index 1e52a12d695..8907cf6b88b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.spec.ts @@ -34,31 +34,11 @@ * 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 { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { LifecycleEventNodeComponent } from './lifecycle-event-node.component'; import { ConsolidatedLifecycleEvent } from '../archive-unit-lifecycle-history.model'; -@Pipe({ - name: 'dateTime', - standalone: false, -}) -class DateTimeStubPipe implements PipeTransform { - transform(value: string = ''): string { - return value; - } -} - -@Pipe({ - name: 'translate', - standalone: false, -}) -class TranslateStubPipe implements PipeTransform { - transform(value: string = ''): string { - return value; - } -} - function event(partial: Partial): ConsolidatedLifecycleEvent { return { evId: 'ev1', @@ -85,7 +65,7 @@ describe('LifecycleEventNodeComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [LifecycleEventNodeComponent, DateTimeStubPipe, TranslateStubPipe], + imports: [LifecycleEventNodeComponent], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.ts index 3d7f4ea0250..bf40d6d89ea 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-history-tab/lifecycle-event-node/lifecycle-event-node.component.ts @@ -36,12 +36,14 @@ */ import { Component, computed, input, signal } from '@angular/core'; import type { ConsolidatedLifecycleEvent } from '../archive-unit-lifecycle-history.model'; +import { EventTypeLabelComponent, DateTimePipe } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-lifecycle-event-node', templateUrl: './lifecycle-event-node.component.html', styleUrls: ['./lifecycle-event-node.component.scss'], - standalone: false, + imports: [EventTypeLabelComponent, DateTimePipe, TranslatePipe], }) export class LifecycleEventNodeComponent { event = input(); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.spec.ts index d4a5850b956..e78341c537e 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.spec.ts @@ -46,14 +46,12 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTreeModule } from '@angular/material/tree'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { environment } from 'projects/archive-search/src/environments/environment'; import { of } from 'rxjs'; import { AccessContract, AccessContractService, ApiUnitObject, - BASE_URL, DataComponent, DescriptionLevel, ENVIRONMENT, @@ -73,20 +71,14 @@ describe('ArchiveUnitInformationTabComponent', () => { let component: ArchiveUnitInformationTabComponent; let fixture: ComponentFixture; - @Pipe({ - name: 'unitI18n', - standalone: false, - }) + @Pipe({ name: 'unitI18n' }) class UnitI18nStubPipe implements PipeTransform { transform(value: any, _attribute: string): string { return value?.Title ?? ''; } } - @Pipe({ - name: 'dateTime', - standalone: false, - }) + @Pipe({ name: 'dateTime' }) class DateTimeStubPipe implements PipeTransform { transform(value: string = ''): string { return value; @@ -100,6 +92,7 @@ describe('ArchiveUnitInformationTabComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, }; const archiveServiceMock = { @@ -136,17 +129,17 @@ describe('ArchiveUnitInformationTabComponent', () => { MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, MatIconModule, BrowserAnimationsModule, DataComponent, PipesModule, + ArchiveUnitInformationTabComponent, + UnitI18nStubPipe, + DateTimeStubPipe, ], - declarations: [ArchiveUnitInformationTabComponent, UnitI18nStubPipe, DateTimeStubPipe], providers: [ FormBuilder, { provide: ArchiveService, useValue: archiveServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: ENVIRONMENT, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts index 11e3716dafb..b8accb274c7 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts @@ -34,18 +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, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; -import type { Unit, VersionWithQualifierDto } from 'vitamui-library'; -import { AccessContract, AccessContractService, ObjectQualifierType } from 'vitamui-library'; +import { + AccessContract, + AccessContractService, + DataComponent, + ObjectQualifierType, + PipesModule, + Unit, + VersionWithQualifierDto, +} from 'vitamui-library'; import { ArchiveService } from '../../archive.service'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; +import { AsyncPipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-archive-unit-information-tab', templateUrl: './archive-unit-information-tab.component.html', styleUrls: ['./archive-unit-information-tab.component.css'], - standalone: false, + imports: [DataComponent, AsyncPipe, PipesModule, TranslatePipe], }) export class ArchiveUnitInformationTabComponent implements OnInit, OnChanges, OnDestroy { private archiveService = inject(ArchiveService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.spec.ts index 47860c9f7e4..809cc09556c 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.spec.ts @@ -51,9 +51,10 @@ import { import { ArchiveService } from '../../archive.service'; import { ArchiveUnitObjectsDetailsTabComponent } from './archive-unit-objects-details-tab.component'; import { vi } from 'vitest'; +import { ActivatedRoute } from '@angular/router'; + const createSpyObj = (methods: string[]): any => Object.fromEntries(methods.map((m) => [m, vi.fn()])); const anything = () => expect.anything(); -import { ActivatedRoute } from '@angular/router'; describe('ArchiveUnitObjectsDetailsTabComponent', () => { let component: ArchiveUnitObjectsDetailsTabComponent; @@ -87,8 +88,7 @@ describe('ArchiveUnitObjectsDetailsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [ArchiveUnitObjectsDetailsTabComponent], + imports: [ArchiveUnitObjectsDetailsTabComponent], providers: [ { provide: ArchiveService, useValue: archiveServiceSpy }, { provide: TenantSelectionService, useValue: tenantSelectionServiceSpy }, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.ts index 6b76114a827..17235901dbe 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-objects-details-tab/archive-unit-objects-details-tab.component.ts @@ -36,25 +36,31 @@ */ import { Clipboard } from '@angular/cdk/clipboard'; import { HttpHeaders } from '@angular/common/http'; -import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, inject } from '@angular/core'; -import type { Unit, VersionWithQualifierDto } from 'vitamui-library'; +import { Component, inject, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; import { AccessContract, AccessContractService, + ArchiveUnitModule, DescriptionLevel, + PipesModule, qualifiersToVersionsWithQualifier, TenantSelectionService, + TooltipDirective, + Unit, + VersionWithQualifierDto, VitamuiHttpHeaders, } from 'vitamui-library'; import { ArchiveService } from '../../archive.service'; import { Subscription } from 'rxjs'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; +import { NgClass } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-archive-unit-objects-details-tab', templateUrl: './archive-unit-objects-details-tab.component.html', styleUrls: ['./archive-unit-objects-details-tab.component.scss'], - standalone: false, + imports: [ArchiveUnitModule, NgClass, TooltipDirective, PipesModule, TranslatePipe], }) export class ArchiveUnitObjectsDetailsTabComponent implements OnChanges, OnInit, OnDestroy { private archiveService = inject(ArchiveService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts index 0ede209f72c..e4d901d2e16 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts @@ -34,15 +34,13 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { environment } from 'projects/archive-search/src/environments/environment'; import { of } from 'rxjs'; -import { BASE_URL, InjectorModule, Unit, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, Unit, WINDOW_LOCATION } from 'vitamui-library'; import { ArchiveService } from '../../archive.service'; import { ArchiveUnitRulesDetailsTabComponent } from './archive-unit-rules-details-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ArchiveUnitRulesDetailsTabComponent', () => { let component: ArchiveUnitRulesDetailsTabComponent; @@ -70,16 +68,12 @@ describe('ArchiveUnitRulesDetailsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitRulesDetailsTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [InjectorModule], + imports: [InjectorModule, ArchiveUnitRulesDetailsTabComponent], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: environment, useValue: environment }, { provide: ArchiveService, useValue: archiveServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -124,23 +118,4 @@ describe('ArchiveUnitRulesDetailsTabComponent', () => { // Then expect(archiveServiceMock.selectUnitWithInheritedRules).toHaveBeenCalled(); }); - - describe('DOM', () => { - it('should have 8 rows ', () => { - // When - const nativeElement = fixture.nativeElement; - const elementRow = nativeElement.querySelectorAll('.row'); - - // Then - expect(elementRow.length).toBe(8); - }); - it('should have 7 columns ', () => { - // When - const nativeElement = fixture.nativeElement; - const elementColumn = nativeElement.querySelectorAll('.col'); - - // Then - expect(elementColumn.length).toBe(7); - }); - }); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts index 5649b0f665c..1d717794d74 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts @@ -34,12 +34,12 @@ * 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, Input, OnChanges, OnDestroy, SimpleChanges, inject } from '@angular/core'; +import { Component, inject, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; -import type { SearchCriteriaEltDto, Unit } from 'vitamui-library'; -import { CriteriaDataType, CriteriaOperator, SearchCriteriaTypeEnum } from 'vitamui-library'; +import { CriteriaDataType, CriteriaOperator, SearchCriteriaEltDto, SearchCriteriaTypeEnum, Unit } from 'vitamui-library'; import { ArchiveService } from '../../archive.service'; +import { ArchiveUnitRulesInformationsTabComponent } from './archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component'; const PAGE_SIZE = 10; const CURRENT_PAGE = 0; @@ -48,7 +48,7 @@ const CURRENT_PAGE = 0; selector: 'app-archive-unit-rules-details-tab', templateUrl: './archive-unit-rules-details-tab.component.html', styleUrls: ['./archive-unit-rules-details-tab.component.css'], - standalone: false, + imports: [ArchiveUnitRulesInformationsTabComponent], }) export class ArchiveUnitRulesDetailsTabComponent implements OnChanges, OnDestroy { private archiveSearchService = inject(ArchiveService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts index 6c7845b0b23..9e35ba62616 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts @@ -34,13 +34,10 @@ * 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 { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { Directive, Input, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { - BASE_URL, InheritedPropertyDto, InjectorModule, LoggerModule, @@ -75,10 +72,7 @@ describe('ArchiveUnitRulesInformationsTabComponent', () => { @Input() vitamuiCommonCollapse: any; } - @Pipe({ - name: 'dateTime', - standalone: false, - }) + @Pipe({ name: 'dateTime' }) class DateTimeStubPipe implements PipeTransform { transform(value: string = ''): string { return value; @@ -121,22 +115,17 @@ describe('ArchiveUnitRulesInformationsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitRulesInformationsTabComponent, DateTimeStubPipe], imports: [ CollapseStubDirective, CollapseTriggerForStubDirective, BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, VitamUICommonTestModule, + ArchiveUnitRulesInformationsTabComponent, + DateTimeStubPipe, ], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - provideI18n(), - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideI18n()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts index 7daea522529..1295d14204b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts @@ -34,16 +34,16 @@ * 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, Input, OnChanges, SimpleChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import type { InheritedPropertyDto, RuleActionDetails, Unit, UnitRuleDto } from 'vitamui-library'; -import { Logger } from 'vitamui-library'; +import { Component, inject, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { InheritedPropertyDto, Logger, PipesModule, RuleActionDetails, Unit, UnitRuleDto } from 'vitamui-library'; +import { NgClass } from '@angular/common'; @Component({ selector: 'app-archive-unit-rules-informations-tab', templateUrl: './archive-unit-rules-informations-tab.component.html', styleUrls: ['./archive-unit-rules-informations-tab.component.css'], - standalone: false, + imports: [NgClass, PipesModule, TranslatePipe], }) export class ArchiveUnitRulesInformationsTabComponent implements OnChanges { private translateService = inject(TranslateService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.spec.ts index c15faac90b1..5781c3ff5c8 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.spec.ts @@ -34,25 +34,15 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { environment } from 'projects/archive-search/src/environments/environment'; import { of } from 'rxjs'; -import { - BASE_URL, - ConfirmDialogService, - InjectorModule, - LoggerModule, - StartupService, - UsageVersionEnum, - WINDOW_LOCATION, -} from 'vitamui-library'; +import { ConfirmDialogService, InjectorModule, LoggerModule, StartupService, UsageVersionEnum, WINDOW_LOCATION } from 'vitamui-library'; import { ArchiveApiService } from '../../../../core/api/archive-api.service'; import { DipRequestCreateComponent } from './dip-request-create.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('DipRequestCreateComponent', () => { let component: DipRequestCreateComponent; @@ -87,8 +77,7 @@ describe('DipRequestCreateComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [DipRequestCreateComponent], - imports: [InjectorModule, MatButtonToggleModule, LoggerModule.forRoot()], + imports: [InjectorModule, MatButtonToggleModule, LoggerModule.forRoot(), DipRequestCreateComponent], providers: [ FormBuilder, { provide: MatDialogRef, useValue: matDialogRefSpy }, @@ -103,14 +92,11 @@ describe('DipRequestCreateComponent', () => { selectedItemCountKnown: true, }, }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: environment, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ConfirmDialogService, useValue: confirmDialogServiceMock }, { provide: ArchiveApiService, useValue: archiveServiceMock }, { provide: StartupService, useValue: startupServiceStub }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.ts index b94020b7334..d0355e13596 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/dip-request-create/dip-request-create.component.ts @@ -34,21 +34,28 @@ * 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, OnDestroy, OnInit, ResourceRef, inject } from '@angular/core'; -import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, inject, OnDestroy, OnInit, ResourceRef } from '@angular/core'; +import { FormArray, FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { finalize, Subscription } from 'rxjs'; import * as uuid from 'uuid'; import { AgencyService, ApplicationId, ConfirmDialogService, + DialogHeaderComponent, + InputComponent, Logger, + NextStepComponent, ObjectQualifierTypeList, ObjectQualifierTypeType, + PreviousStepComponent, SearchCriteriaEltDto, + SelectComponent, + SlideToggleComponent, SnackBarService, + StepperComponent, UsageVersionEnum, VitamuiSelectOptions, } from 'vitamui-library'; @@ -56,12 +63,32 @@ import { ArchiveService } from '../../../archive.service'; import { ExportDIPRequestDto, QualifierVersion } from '../../../models/dip.interface'; import { distinctUntilChanged, map } from 'rxjs/operators'; import { rxResource } from '@angular/core/rxjs-interop'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { MatRadioButton, MatRadioGroup } from '@angular/material/radio'; @Component({ selector: 'app-dip-request-create', templateUrl: './dip-request-create.component.html', styleUrls: ['./dip-request-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + StepperComponent, + CdkStep, + ReactiveFormsModule, + MatDialogContent, + InputComponent, + SelectComponent, + MatDialogActions, + NextStepComponent, + MatButtonToggleGroup, + MatButtonToggle, + MatRadioGroup, + MatRadioButton, + SlideToggleComponent, + PreviousStepComponent, + TranslatePipe, + ], }) export class DipRequestCreateComponent implements OnInit, OnDestroy { private translate = inject(TranslateService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.html index 5dc5062c04b..e956a87cc8b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.html @@ -43,7 +43,7 @@ - @if (isLoading) { + @if (isLoading()) {
diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.spec.ts index 8370de803c1..e12205d4bd1 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.spec.ts @@ -34,18 +34,14 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { UpdateUnitManagementRuleService } from 'projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service'; import { ManagementRulesValidatorService } from 'projects/archive-search/src/app/archive/validators/management-rules-validator.service'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { Observable, of } from 'rxjs'; import { - BASE_URL, CriteriaDataType, CriteriaOperator, InjectorModule, @@ -58,17 +54,9 @@ import { import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ActionsRules, ManagementRules, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { AddManagementRulesComponent } from './add-management-rules.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -215,11 +203,9 @@ describe('AddManagementRulesComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AddManagementRulesComponent], - imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, RouterTestingModule], + imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, AddManagementRulesComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, @@ -227,8 +213,6 @@ describe('AddManagementRulesComponent', () => { { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: ManagementRulesValidatorService, useValue: managementRulesValidatorServiceMock }, { provide: UpdateUnitManagementRuleService, useValue: updateUnitManagementRuleServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -266,7 +250,7 @@ describe('AddManagementRulesComponent', () => { describe('DOM', () => { it('should have 1 title ', () => { - const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('label'); + const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('div.align-items-stretch > label'); expect(formTitlesHtmlElements).toBeTruthy(); expect(formTitlesHtmlElements.length).toBe(1); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.ts index 4691a5ffdca..c548f27df26 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-management-rules/add-management-rules.component.ts @@ -34,23 +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, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, signal, TemplateRef, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { cloneDeep } from 'lodash-es'; import { merge, Observable, Subscription } from 'rxjs'; -import { debounceTime, filter, map } from 'rxjs/operators'; +import { debounceTime, filter, finalize, map } from 'rxjs/operators'; import { CriteriaDataType, CriteriaOperator, + DatepickerComponent, + DialogHeaderComponent, diff, + InputComponent, ManagementRuleValidators, Rule, RuleService, SearchCriteriaDto, SearchCriteriaEltDto, VitamTenantConfigService, + SelectComponent, VitamuiSelectOptions, } from 'vitamui-library'; import { ManagementRulesSharedDataService } from '../../../../../../core/management-rules-shared-data.service'; @@ -59,6 +63,9 @@ import { UpdateUnitManagementRuleService } from '../../../../../common-services/ import { ArchiveSearchConstsEnum } from '../../../../../models/archive-search-consts-enum'; import { ManagementRules, RuleAction, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { ManagementRulesValidatorService } from '../../../../../validators/management-rules-validator.service'; +import { MatMiniFabButton } from '@angular/material/button'; +import { NgStyle } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; const MANAGEMENT_RULE_IDENTIFIER = 'MANAGEMENT_RULE_IDENTIFIER'; const MANAGEMENT_RULE_START_DATE = 'MANAGEMENT_RULE_START_DATE'; @@ -68,7 +75,19 @@ const ORIGIN_HAS_AT_LEAST_ONE = 'ORIGIN_HAS_AT_LEAST_ONE'; selector: 'app-add-management-rules', templateUrl: './add-management-rules.component.html', styleUrls: ['./add-management-rules.component.css'], - standalone: false, + imports: [ + ReactiveFormsModule, + SelectComponent, + DatepickerComponent, + MatMiniFabButton, + NgStyle, + InputComponent, + MatProgressSpinner, + DialogHeaderComponent, + MatDialogActions, + MatDialogClose, + TranslatePipe, + ], }) export class AddManagementRulesComponent implements OnDestroy, OnInit { private managementRulesSharedDataService = inject(ManagementRulesSharedDataService); @@ -116,8 +135,8 @@ export class AddManagementRulesComponent implements OnDestroy, OnInit { getRuleSuscription: Subscription; searchArchiveUnitsByCriteriaSubscription: Subscription; - isLoading = false; - isWarningLoading = false; + isLoading = signal(false); + isWarningLoading = signal(false); isDisabled = true; managementRules: ManagementRules[] = []; managementRulesSubscription: Subscription; @@ -197,7 +216,7 @@ export class AddManagementRulesComponent implements OnDestroy, OnInit { } addRuleToQuery() { - this.isLoading = true; + this.isLoading.set(true); this.initDSLQuery(); const onlyManagementRules: SearchCriteriaEltDto = { @@ -222,25 +241,30 @@ export class AddManagementRulesComponent implements OnDestroy, OnInit { if (this.hasExactCount) { this.searchArchiveUnitsByCriteriaSubscription = this.archiveService .getTotalTrackHitsByCriteria(this.criteriaSearchDSLQuery.criteriaList) - .subscribe((resultsNumber) => { - this.itemsWithSameRule = resultsNumber; - this.itemsToUpdate = this.selectedItem - resultsNumber; - this.isLoading = false; + .pipe(finalize(() => this.isLoading.set(false))) + .subscribe({ + next: (resultsNumber) => { + this.itemsWithSameRule = resultsNumber; + this.itemsToUpdate = this.selectedItem - resultsNumber; + }, + error: () => this.isLoading.set(false), }); } else { this.searchArchiveUnitsByCriteriaSubscription = this.archiveService .searchArchiveUnitsByCriteria(this.criteriaSearchDSLQuery) - .subscribe((data) => { - this.itemsWithSameRule = data.totalResults; + .pipe(finalize(() => this.isLoading.set(false))) + .subscribe({ + next: (data) => { + this.itemsWithSameRule = data.totalResults; - this.itemsToUpdate = - data.totalResults === this.vitamConfigurationService.tenantConfig()?.resultThreshold - ? this.resultNumberToShow - : this.selectedItem === this.vitamConfigurationService.tenantConfig()?.resultThreshold + this.itemsToUpdate = + data.totalResults === this.vitamConfigurationService.tenantConfig()?.resultThreshold ? this.resultNumberToShow - : this.selectedItem - data.totalResults; - - this.isLoading = false; + : this.selectedItem === this.vitamConfigurationService.tenantConfig()?.resultThreshold + ? this.resultNumberToShow + : this.selectedItem - data.totalResults; + }, + error: () => this.isLoading.set(false), }); } if (this.ruleDetailsForm.get('startDate').value) { @@ -249,7 +273,7 @@ export class AddManagementRulesComponent implements OnDestroy, OnInit { } addRuleAndStartDateToQuery() { - this.isWarningLoading = true; + this.isWarningLoading.set(true); this.initDSLQuery(); if (this.ruleDetailsForm.get('startDate').value) { const criteriaWithId: SearchCriteriaEltDto = { @@ -283,18 +307,26 @@ export class AddManagementRulesComponent implements OnDestroy, OnInit { this.criteriaSearchDSLQuery.criteriaList.push(onlyManagementRules); if (this.hasExactCount) { - this.archiveService.getTotalTrackHitsByCriteria(this.criteriaSearchDSLQuery.criteriaList).subscribe((resultsNumber) => { - this.itemsWithSameRuleAndDate = resultsNumber; - this.isWarningLoading = false; - }); + this.archiveService + .getTotalTrackHitsByCriteria(this.criteriaSearchDSLQuery.criteriaList) + .pipe(finalize(() => this.isWarningLoading.set(false))) + .subscribe({ + next: (resultsNumber) => (this.itemsWithSameRuleAndDate = resultsNumber), + error: () => this.isWarningLoading.set(false), + }); } else { - this.archiveService.searchArchiveUnitsByCriteria(this.criteriaSearchDSLQuery).subscribe((data) => { - this.itemsWithSameRuleAndDate = - data.totalResults === this.vitamConfigurationService.tenantConfig()?.resultThreshold - ? this.resultNumberToShow - : data.totalResults; - }); - this.isWarningLoading = false; + this.archiveService + .searchArchiveUnitsByCriteria(this.criteriaSearchDSLQuery) + .pipe(finalize(() => this.isWarningLoading.set(false))) + .subscribe({ + next: (data) => { + this.itemsWithSameRuleAndDate = + data.totalResults === this.vitamConfigurationService.tenantConfig()?.resultThreshold + ? this.resultNumberToShow + : data.totalResults; + }, + error: () => this.isWarningLoading.set(false), + }); } } } @@ -362,7 +394,7 @@ export class AddManagementRulesComponent implements OnDestroy, OnInit { submit() { this.isDisabled = true; this.showText = true; - this.isLoading = !this.isLoading; + this.isLoading.set(true); const rule: RuleAction = { rule: this.ruleDetailsForm.get('rule').value, startDate: this.ruleDetailsForm.get('startDate').value, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.spec.ts index 26b2e0445b0..62d101ed457 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.spec.ts @@ -34,29 +34,18 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; -import { Observable, of } from 'rxjs'; -import { BASE_URL, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { of } from 'rxjs'; +import { InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { RuleTypeEnum } from '../../../../../models/rule-type-enum'; import { ActionsRules, ManagementRules, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { AddUpdatePropertyComponent } from './add-update-property.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -135,18 +124,14 @@ describe('AddUpdatePropertyComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AddUpdatePropertyComponent], - imports: [InjectorModule, LoggerModule.forRoot(), RouterTestingModule], + imports: [InjectorModule, LoggerModule.forRoot(), AddUpdatePropertyComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -524,7 +509,7 @@ describe('AddUpdatePropertyComponent', () => { describe('DOM', () => { it('should have 1 title ', () => { - const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('label'); + const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('div.align-items-stretch > label'); expect(formTitlesHtmlElements).toBeTruthy(); expect(formTitlesHtmlElements.length).toBe(1); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.ts index a5b7212966f..63c14cd1683 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/add-update-property/add-update-property.component.ts @@ -34,19 +34,22 @@ * 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, Input, OnDestroy, OnInit, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, inject, Input, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; import { ManagementRulesSharedDataService } from '../../../../../../core/management-rules-shared-data.service'; import { RuleTypeEnum } from '../../../../../models/rule-type-enum'; import { ActionsRules, ManagementRules, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; +import { DialogHeaderComponent, SelectComponent } from 'vitamui-library'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-add-update-property', templateUrl: './add-update-property.component.html', styleUrls: ['./add-update-property.component.css'], - standalone: false, + imports: [SelectComponent, ReactiveFormsModule, FormsModule, DialogHeaderComponent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class AddUpdatePropertyComponent implements OnInit, OnDestroy { private managementRulesSharedDataService = inject(ManagementRulesSharedDataService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.spec.ts index ad23f7614e5..3e2145edaa2 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.spec.ts @@ -34,39 +34,20 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; -import { Observable, of } from 'rxjs'; -import { - BASE_URL, - InjectorModule, - LoggerModule, - SearchCriteriaDto, - WINDOW_LOCATION, - TenantSelectionService, - Tenant, -} from 'vitamui-library'; +import { of } from 'rxjs'; +import { InjectorModule, LoggerModule, SearchCriteriaDto, Tenant, TenantSelectionService, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { UpdateUnitManagementRuleService } from '../../../../common-services/update-unit-management-rule.service'; import { RuleTypeEnum } from '../../../../models/rule-type-enum'; import { ActionsRules, ManagementRules, RuleCategoryAction } from '../../../../models/ruleAction.interface'; import { ArchiveUnitRulesComponent } from './archive-unit-rules.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -205,11 +186,9 @@ describe('ArchiveUnitRulesComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitRulesComponent], - imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule], + imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), ArchiveUnitRulesComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, @@ -217,8 +196,6 @@ describe('ArchiveUnitRulesComponent', () => { { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: UpdateUnitManagementRuleService, useValue: updateUnitManagementRuleServiceMock }, { provide: TenantSelectionService, useValue: tenantSelectionServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.ts index 5c89084ce91..d28c42c1c4f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/archive-unit-rules.component.ts @@ -34,17 +34,36 @@ * 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, Input, OnDestroy, inject } from '@angular/core'; +import { Component, inject, Input, OnDestroy } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { ManagementRulesSharedDataService } from '../../../../../core/management-rules-shared-data.service'; import { ActionsRules, ManagementRules, RuleAction, RuleActionsEnum, RuleCategoryAction } from '../../../../models/ruleAction.interface'; import { Rule } from 'vitamui-library'; +import { AddManagementRulesComponent } from './add-management-rules/add-management-rules.component'; +import { DeleteUnitRulesComponent } from './delete-unit-rules/delete-unit-rules.component'; +import { AddUpdatePropertyComponent } from './add-update-property/add-update-property.component'; +import { UpdateUnitRulesComponent } from './update-unit-rules/update-unit-rules.component'; +import { BlockCategoryInheritanceComponent } from './block-category-inheritance/block-category-inheritance.component'; +import { UnlockCategoryInheritanceComponent } from './unlock-category-inheritance/unlock-category-inheritance.component'; +import { BlockRulesInheritanceComponent } from './block-rules-inheritance/block-rules-inheritance.component'; +import { UnlockRulesInheritanceComponent } from './unlock-rules-inheritance/unlock-rules-inheritance.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-archive-unit-rules', templateUrl: './archive-unit-rules.component.html', styleUrls: ['./archive-unit-rules.component.css'], - standalone: false, + imports: [ + AddManagementRulesComponent, + DeleteUnitRulesComponent, + AddUpdatePropertyComponent, + UpdateUnitRulesComponent, + BlockCategoryInheritanceComponent, + UnlockCategoryInheritanceComponent, + BlockRulesInheritanceComponent, + UnlockRulesInheritanceComponent, + TranslatePipe, + ], }) export class ArchiveUnitRulesComponent implements OnDestroy { private managementRulesSharedDataService = inject(ManagementRulesSharedDataService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.spec.ts index 5cd9eb624df..5a497657b00 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.spec.ts @@ -34,30 +34,19 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; -import { Observable, of } from 'rxjs'; -import { BASE_URL, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { of } from 'rxjs'; +import { InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { RuleTypeEnum } from '../../../../../models/rule-type-enum'; import { ActionsRules, ManagementRules, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { BlockCategoryInheritanceComponent } from './block-category-inheritance.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -134,18 +123,14 @@ describe('BlockCategoryInheritanceComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [BlockCategoryInheritanceComponent], - imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, RouterTestingModule], + imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, BlockCategoryInheritanceComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.ts index bbe9d376614..3758967682f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-category-inheritance/block-category-inheritance.component.ts @@ -34,18 +34,20 @@ * 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, Input, OnDestroy, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, inject, Input, OnDestroy, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; import { ActionsRules, ManagementRules, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; +import { DialogHeaderComponent } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-block-category-inheritance', templateUrl: './block-category-inheritance.component.html', styleUrls: ['./block-category-inheritance.component.css'], - standalone: false, + imports: [DialogHeaderComponent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class BlockCategoryInheritanceComponent implements OnDestroy { private managementRulesSharedDataService = inject(ManagementRulesSharedDataService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.spec.ts index 475a0421259..5fecf2875cf 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.spec.ts @@ -34,30 +34,19 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { ManagementRulesValidatorService } from 'projects/archive-search/src/app/archive/validators/management-rules-validator.service'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { Observable, of } from 'rxjs'; -import { BASE_URL, InjectorModule, LoggerModule, Rule, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, LoggerModule, Rule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ActionsRules, ManagementRules, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { BlockRulesInheritanceComponent } from './block-rules-inheritance.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -156,19 +145,15 @@ describe('BlockRulesInheritanceComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [BlockRulesInheritanceComponent], - imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, RouterTestingModule], + imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, BlockRulesInheritanceComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: ManagementRulesValidatorService, useValue: managementRulesValidatorServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -197,7 +182,7 @@ describe('BlockRulesInheritanceComponent', () => { describe('DOM', () => { it('should have 1 title ', () => { - const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('label'); + const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('form > div > label'); expect(formTitlesHtmlElements).toBeTruthy(); expect(formTitlesHtmlElements.length).toBe(1); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.ts index 1ccd6d9dce1..1cd17f13fee 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/block-rules-inheritance/block-rules-inheritance.component.ts @@ -34,22 +34,32 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { merge, Observable, Subscription } from 'rxjs'; import { debounceTime, filter, map } from 'rxjs/operators'; -import { diff, ManagementRuleValidators, Rule, RuleService, SearchCriteriaDto, VitamuiSelectOptions } from 'vitamui-library'; +import { + DialogHeaderComponent, + diff, + ManagementRuleValidators, + Rule, + RuleService, + SearchCriteriaDto, + SelectComponent, + VitamuiSelectOptions, +} from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../../../../models/archive-search-consts-enum'; import { ManagementRules, RuleAction, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { ManagementRulesValidatorService } from '../../../../../validators/management-rules-validator.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-block-rules-inheritance', templateUrl: './block-rules-inheritance.component.html', styleUrls: ['./block-rules-inheritance.component.css'], - standalone: false, + imports: [ReactiveFormsModule, SelectComponent, DialogHeaderComponent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class BlockRulesInheritanceComponent implements OnDestroy, OnInit { private managementRulesValidatorService = inject(ManagementRulesValidatorService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.spec.ts index a59118b677a..f586d57ba09 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.spec.ts @@ -34,18 +34,14 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { UpdateUnitManagementRuleService } from 'projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service'; import { ManagementRulesValidatorService } from 'projects/archive-search/src/app/archive/validators/management-rules-validator.service'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { Observable, of } from 'rxjs'; import { - BASE_URL, CriteriaDataType, CriteriaOperator, InjectorModule, @@ -58,17 +54,9 @@ import { import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ActionsRules, ManagementRules, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { DeleteUnitRulesComponent } from './delete-unit-rules.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -215,11 +203,9 @@ describe('DeleteUnitRulesComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [DeleteUnitRulesComponent], - imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, RouterTestingModule], + imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, DeleteUnitRulesComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, @@ -227,8 +213,6 @@ describe('DeleteUnitRulesComponent', () => { { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: ManagementRulesValidatorService, useValue: managementRulesValidatorServiceMock }, { provide: UpdateUnitManagementRuleService, useValue: updateUnitManagementRuleServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -266,7 +250,7 @@ describe('DeleteUnitRulesComponent', () => { describe('DOM', () => { it('should have 1 title ', () => { - const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('label'); + const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('form > div > label'); expect(formTitlesHtmlElements).toBeTruthy(); expect(formTitlesHtmlElements.length).toBe(1); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.ts index 0410a2f5fff..f6cb6ea802b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/delete-unit-rules/delete-unit-rules.component.ts @@ -34,31 +34,34 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { cloneDeep } from 'lodash-es'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; -import { merge, Subscription, Observable } from 'rxjs'; +import { merge, Observable, Subscription } from 'rxjs'; import { debounceTime, filter, map } from 'rxjs/operators'; import { CriteriaDataType, CriteriaOperator, + DialogHeaderComponent, + diff, ManagementRuleValidators, Rule, RuleService, SearchCriteriaDto, SearchCriteriaEltDto, - VitamuiSelectOptions, - diff, + SelectComponent, VitamTenantConfigService, + VitamuiSelectOptions, } from 'vitamui-library'; import { ArchiveService } from '../../../../../archive.service'; import { UpdateUnitManagementRuleService } from '../../../../../common-services/update-unit-management-rule.service'; import { ArchiveSearchConstsEnum } from '../../../../../models/archive-search-consts-enum'; import { ManagementRules, RuleAction, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { ManagementRulesValidatorService } from '../../../../../validators/management-rules-validator.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; const MANAGEMENT_RULE_IDENTIFIER = 'MANAGEMENT_RULE_IDENTIFIER'; const ORIGIN_HAS_AT_LEAST_ONE = 'ORIGIN_HAS_AT_LEAST_ONE'; @@ -67,7 +70,15 @@ const ORIGIN_HAS_AT_LEAST_ONE = 'ORIGIN_HAS_AT_LEAST_ONE'; selector: 'app-delete-unit-rules', templateUrl: './delete-unit-rules.component.html', styleUrls: ['./delete-unit-rules.component.css'], - standalone: false, + imports: [ + ReactiveFormsModule, + SelectComponent, + MatProgressSpinner, + DialogHeaderComponent, + MatDialogActions, + MatDialogClose, + TranslatePipe, + ], }) export class DeleteUnitRulesComponent implements OnDestroy, OnInit { private managementRulesValidatorService = inject(ManagementRulesValidatorService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.spec.ts index 457731d6e35..71c27c0f556 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.spec.ts @@ -34,31 +34,20 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; +import { MatDialog } from '@angular/material/dialog'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; -import { Observable, of } from 'rxjs'; -import { BASE_URL, InjectorModule, LoggerModule, PagedResult, SearchCriteriaDto, WINDOW_LOCATION } from 'vitamui-library'; +import { of } from 'rxjs'; +import { InjectorModule, LoggerModule, PagedResult, SearchCriteriaDto, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { UpdateUnitManagementRuleService } from '../../../../../common-services/update-unit-management-rule.service'; import { RuleTypeEnum } from '../../../../../models/rule-type-enum'; import { ActionsRules, ManagementRules, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { UnlockCategoryInheritanceComponent } from './unlock-category-inheritance.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -222,12 +211,6 @@ describe('UnlockCategoryInheritanceComponent', () => { let component: UnlockCategoryInheritanceComponent; let fixture: ComponentFixture; - const matDialogRefSpy = { - open: vi.fn().mockName('MatDialogRef.open'), - close: vi.fn().mockName('MatDialogRef.close'), - }; - matDialogRefSpy.open.mockReturnValue({ afterClosed: () => of(true) }); - const matDialogSpy = { open: vi.fn().mockName('MatDialog.open'), close: vi.fn().mockName('MatDialog.close'), @@ -256,21 +239,16 @@ describe('UnlockCategoryInheritanceComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [UnlockCategoryInheritanceComponent], - imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule], + imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), UnlockCategoryInheritanceComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: MatDialogRef, useValue: matDialogRefSpy }, - { provide: MatDialog, useValue: matDialogSpy }, - { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: UpdateUnitManagementRuleService, useValue: updateUnitManagementRuleServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(MatDialog, { useValue: matDialogSpy }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.ts index 28bfd61c1c8..64d3989f097 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-category-inheritance/unlock-category-inheritance.component.ts @@ -34,17 +34,25 @@ * 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, Input, OnDestroy, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, inject, Input, OnDestroy, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogModule } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { cloneDeep } from 'lodash-es'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; -import { CriteriaDataType, CriteriaOperator, SearchCriteriaDto, SearchCriteriaEltDto, VitamTenantConfigService } from 'vitamui-library'; +import { + CriteriaDataType, + CriteriaOperator, + DialogHeaderComponent, + SearchCriteriaDto, + SearchCriteriaEltDto, + VitamTenantConfigService, +} from 'vitamui-library'; import { ArchiveService } from '../../../../../archive.service'; import { UpdateUnitManagementRuleService } from '../../../../../common-services/update-unit-management-rule.service'; import { ActionsRules, ManagementRules, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; const ORIGIN_HAS_AT_LEAST_ONE = 'ORIGIN_HAS_AT_LEAST_ONE'; const MANAGEMENT_RULE_INHERITED_CRITERIA = 'MANAGEMENT_RULE_INHERITED_CRITERIA'; @@ -52,7 +60,7 @@ const MANAGEMENT_RULE_INHERITED_CRITERIA = 'MANAGEMENT_RULE_INHERITED_CRITERIA'; selector: 'app-unlock-category-inheritance', templateUrl: './unlock-category-inheritance.component.html', styleUrls: ['./unlock-category-inheritance.component.css'], - standalone: false, + imports: [MatProgressSpinner, DialogHeaderComponent, MatDialogModule, MatDialogActions, MatDialogClose, TranslatePipe], }) export class UnlockCategoryInheritanceComponent implements OnDestroy { private managementRulesSharedDataService = inject(ManagementRulesSharedDataService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.spec.ts index 7141bc28afb..ed6cdd6359e 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.spec.ts @@ -34,18 +34,13 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { UpdateUnitManagementRuleService } from 'projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service'; import { ManagementRulesValidatorService } from 'projects/archive-search/src/app/archive/validators/management-rules-validator.service'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; import { Observable, of } from 'rxjs'; import { - BASE_URL, CriteriaDataType, CriteriaOperator, InjectorModule, @@ -58,17 +53,9 @@ import { import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ActionsRules, ManagementRules, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { UnlockRulesInheritanceComponent } from './unlock-rules-inheritance.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; const accessContract = 'AccessContract'; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const ruleCategoryAction: RuleCategoryAction = { rules: [], finalAction: 'keep', @@ -156,18 +143,6 @@ const searchCriteriaDto: SearchCriteriaDto = { trackTotalHits: true, }; -const matDialogRefSpy = { - open: vi.fn().mockName('MatDialogRef.open'), - close: vi.fn().mockName('MatDialogRef.close'), -}; -matDialogRefSpy.open.mockReturnValue({ afterClosed: () => of(true) }); - -const matDialogSpy = { - open: vi.fn().mockName('MatDialog.open'), - close: vi.fn().mockName('MatDialog.close'), -}; -matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); - const managementRulesSharedDataServiceMock = { getCriteriaSearchDSLQuery: () => of(searchCriteriaDto), getManagementRules: () => of(managementRules), @@ -215,20 +190,13 @@ describe('UnlockRulesInheritanceComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [UnlockRulesInheritanceComponent], - imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, RouterTestingModule], + imports: [InjectorModule, LoggerModule.forRoot(), VitamUICommonTestModule, UnlockRulesInheritanceComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: MatDialogRef, useValue: matDialogRefSpy }, - { provide: MatDialog, useValue: matDialogSpy }, - { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: ManagementRulesValidatorService, useValue: managementRulesValidatorServiceMock }, { provide: UpdateUnitManagementRuleService, useValue: updateUnitManagementRuleServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -266,7 +234,7 @@ describe('UnlockRulesInheritanceComponent', () => { describe('DOM', () => { it('should have 1 title ', () => { - const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('label'); + const formTitlesHtmlElements = fixture.nativeElement.querySelectorAll('form > div > label'); expect(formTitlesHtmlElements).toBeTruthy(); expect(formTitlesHtmlElements.length).toBe(1); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.ts index 437c443acb9..9cc2e88a3bb 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/unlock-rules-inheritance/unlock-rules-inheritance.component.ts @@ -34,10 +34,10 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { cloneDeep } from 'lodash-es'; import { UpdateUnitManagementRuleService } from 'projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service'; import { ManagementRulesSharedDataService } from 'projects/archive-search/src/app/core/management-rules-shared-data.service'; @@ -46,19 +46,22 @@ import { debounceTime, filter, map } from 'rxjs/operators'; import { CriteriaDataType, CriteriaOperator, + DialogHeaderComponent, diff, ManagementRuleValidators, Rule, RuleService, SearchCriteriaDto, SearchCriteriaEltDto, - VitamuiSelectOptions, + SelectComponent, VitamTenantConfigService, + VitamuiSelectOptions, } from 'vitamui-library'; import { ArchiveService } from '../../../../../archive.service'; import { ArchiveSearchConstsEnum } from '../../../../../models/archive-search-consts-enum'; import { ManagementRules, RuleAction, RuleActionsEnum, RuleCategoryAction } from '../../../../../models/ruleAction.interface'; import { ManagementRulesValidatorService } from '../../../../../validators/management-rules-validator.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; const ORIGIN_HAS_AT_LEAST_ONE = 'ORIGIN_HAS_AT_LEAST_ONE'; const APPRAISAL_PREVENT_RULE_IDENTIFIER = 'APPRAISAL_PREVENT_RULE_IDENTIFIER'; @@ -68,7 +71,15 @@ const APPRAISAL_RULE_INHERITED_CRITERIA = 'APPRAISAL_RULE_INHERITED_CRITERIA'; selector: 'app-unlock-rules-inheritance', templateUrl: './unlock-rules-inheritance.component.html', styleUrls: ['./unlock-rules-inheritance.component.css'], - standalone: false, + imports: [ + ReactiveFormsModule, + SelectComponent, + MatProgressSpinner, + DialogHeaderComponent, + MatDialogActions, + MatDialogClose, + TranslatePipe, + ], }) export class UnlockRulesInheritanceComponent implements OnDestroy, OnInit { private managementRulesValidatorService = inject(ManagementRulesValidatorService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/update-unit-rules/update-unit-rules.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/update-unit-rules/update-unit-rules.component.html index d9c2324ac7c..acd5e3e7e5e 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/update-unit-rules/update-unit-rules.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/archive-unit-rules/update-unit-rules/update-unit-rules.component.html @@ -6,7 +6,7 @@ @@ -25,9 +25,9 @@ @@ -48,7 +48,7 @@ outputType="Date" format="dd/MM/yyyy" class="w-100" - [disabled]="isStartDateDisabled" + [disabled]="isStartDateDisabled()" >
- - @@ -30,7 +34,7 @@
{{ 'ARCHIVE_SEARCH.TITLE_SEARCH' | translate }}
- @for (criteriaKey of searchCriteriaKeys; track criteriaKey) { + @for (criteriaKey of searchCriteriaKeys(); track criteriaKey) { @if (searchCriterias.get(criteriaKey); as criteriaVal) { {{ 'ARCHIVE_SEARCH.TITLE_SEARCH' | translate }}
} - @if (!pendingComputeFacets && submitted && rulesFacetsComputed && showingFacets) { + @if (!pendingComputeFacets && submitted() && rulesFacetsComputed && showingFacets) {
{{ 'ARCHIVE_SEARCH.TITLE_SEARCH' | translate }} [holdRuleFacets]="archiveSearchResultFacets?.holdRuleFacets" [classificationRuleFacets]="archiveSearchResultFacets?.classificationRuleFacets" [tenantIdentifier]="tenantIdentifier" - [totalResults]="totalResults" + [totalResults]="totalResults()" [defaultFacetTabIndex]="defaultFacetTabIndex" >
} - @if (!pending) { + @if (!pending()) {
- @if (!showCriteriaPanel) { + @if (!showCriteriaPanel()) { {{ 'ARCHIVE_SEARCH.SHOW_SEARCH_CRITERIA' | translate }} } - @if (!pendingComputeFacets && !showingFacets && submitted) { + @if (!pendingComputeFacets && !showingFacets && submitted()) { {{ 'ARCHIVE_SEARCH.COMPUTE_RULES_FACETS' | translate }} }
} -
+
@@ -210,51 +214,52 @@
{{ 'ARCHIVE_SEARCH.TITLE_SEARCH' | translate }}
- @if (showCriteriaPanel) { + @if (showCriteriaPanel()) { }
-@if (submitted) { +@if (submitted()) {
- - - - - @if ((configService.config$ | async)?.REASSIGNMENT_ENABLED) { @@ -420,15 +425,15 @@
{{ 'ARCHIVE_SEARCH.TITLE_SEARCH' | translate }}
> 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 3f82ec0dcc5..83d74e0c08a 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 @@ -36,7 +36,6 @@ import type { Mock } from 'vitest'; * knowledge of the CeCILL-C license and that you accept its terms. */ import { Location } from '@angular/common'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; @@ -45,12 +44,9 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTreeModule } from '@angular/material/tree'; import { ActivatedRoute, Params, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { environment } from 'projects/archive-search/src/environments/environment'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; import { - BASE_URL, InjectorModule, LoggerModule, PagedResult, @@ -76,17 +72,9 @@ import { UpdateUnitManagementRuleService } from '../common-services/update-unit- import { ArchiveSearchComponent } from './archive-search.component'; import { TransferAcknowledgmentComponent } from './transfer-acknowledgment/transfer-acknowledgment.component'; import { SimpleCriteriaSearchComponent } from './simple-criteria-search/simple-criteria-search.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { NodeData } from '../models/nodedata.interface'; -const arrayWithExactContents = (arr: T[]) => expect.arrayContaining(arr as any); - -const translations: any = { TEST: 'Mock translate test' }; -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} +const arrayWithExactContents = (arr: T[]) => expect.arrayContaining(arr as any); describe('ArchiveSearchComponent', () => { let component: ArchiveSearchComponent; @@ -191,7 +179,6 @@ describe('ArchiveSearchComponent', () => { vi.spyOn(archiveServiceStub, 'searchArchiveUnitsByCriteria'); await TestBed.configureTestingModule({ - declarations: [ArchiveSearchComponent, SimpleCriteriaSearchComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ InjectorModule, @@ -200,34 +187,30 @@ describe('ArchiveSearchComponent', () => { MatProgressSpinnerModule, MatSidenavModule, MatTreeModule, - RouterTestingModule, + ArchiveSearchComponent, + SimpleCriteriaSearchComponent, ], providers: [ ArchiveSearchHelperService, ArchiveSharedDataService, - { provide: ActivatedRoute, useValue: computeActivatedRoute(queryParams) }, - { provide: ArchiveService, useValue: archiveServiceStub }, - { provide: SecurityService, useValue: securityServiceStub }, - { provide: ArchiveUnitDipService, useValue: archiveUnitDipServiceMock }, - { provide: ArchiveUnitEliminationService, useValue: archiveUnitEliminationServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ComputeInheritedRulesService, useValue: computeInheritedRulesServiceMock }, - { provide: Location, useValue: locationSpy }, - { provide: MatDialog, useValue: matDialogSpy }, - { provide: Router, useValue: routerSpy }, - { provide: SchemaService, useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } }, - { provide: SearchCriteriaService, useValue: searchCriteriaServiceMock }, - { provide: UpdateUnitManagementRuleService, useValue: updateUnitManagementRuleServiceMock }, - { provide: environment, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, - { - provide: VitamTenantConfigService, - useValue: tenantConfigServiceMock, - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), + { provide: environment, useValue: environment }, ], - }).compileComponents(); + }) + .overrideProvider(MatDialog, { useValue: matDialogSpy }) + .overrideProvider(Router, { useValue: routerSpy }) + .overrideProvider(Location, { useValue: locationSpy }) + .overrideProvider(ActivatedRoute, { useValue: computeActivatedRoute(queryParams) }) + .overrideProvider(SearchCriteriaService, { useValue: searchCriteriaServiceMock }) + .overrideProvider(ArchiveService, { useValue: archiveServiceStub }) + .overrideProvider(SecurityService, { useValue: securityServiceStub }) + .overrideProvider(ArchiveUnitDipService, { useValue: archiveUnitDipServiceMock }) + .overrideProvider(ArchiveUnitEliminationService, { useValue: archiveUnitEliminationServiceMock }) + .overrideProvider(UpdateUnitManagementRuleService, { useValue: updateUnitManagementRuleServiceMock }) + .overrideProvider(VitamTenantConfigService, { useValue: tenantConfigServiceMock }) + .overrideProvider(ComputeInheritedRulesService, { useValue: computeInheritedRulesServiceMock }) + .overrideProvider(SchemaService, { useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } }) + .compileComponents(); fixture = TestBed.createComponent(ArchiveSearchComponent); component = fixture.componentInstance; @@ -251,7 +234,7 @@ describe('ArchiveSearchComponent', () => { it('should be false', () => { component.showHidePanel(false); - expect(component.showCriteriaPanel).toBeFalsy(); + expect(component.showCriteriaPanel()).toBeFalsy(); }); it('should call hasArchiveSearchRole', () => { @@ -284,7 +267,7 @@ describe('ArchiveSearchComponent', () => { }); describe('DOM', () => { - it('should have 5 rows ', () => { + it('should have 5 rows on init (no search yet, criteria panel expanded)', () => { // When const nativeElement = fixture.nativeElement; const elementRow = nativeElement.querySelectorAll('.row'); @@ -301,10 +284,6 @@ describe('ArchiveSearchComponent', () => { // Then expect(elementRow.length).toBe(1); }); - it('should have 2 buttons ', () => { - const elementBtn = fixture.nativeElement.querySelectorAll('button[type=button]'); - expect(elementBtn.length).toBe(2); - }); }); describe('checkChildrenBoxChange', () => { @@ -427,26 +406,26 @@ describe('ArchiveSearchComponent', () => { }); }); - it('should trigger a search with criteria matching the queryParams in the URL on page access', async () => { - vi.useFakeTimers(); + it('should not trigger a search on portal landing (no query params on arrival)', async () => { + await setupTest({}); - await setupTest({ opi: '1234' }); + // Leave time for any asynchronous auto-submit to run. + await new Promise((resolve) => setTimeout(resolve, 500)); - // flush ready().then() promise chain - await fixture.whenStable(); + const currentCalls = vi.mocked(archiveServiceStub.searchArchiveUnitsByCriteria as Mock).mock.calls; + expect(currentCalls.length).toBe(0); + }); - // flush the setTimeout(() => this.submit(true)) inside ngAfterViewInit - vi.runAllTimers(); + it('should trigger a search with criteria matching the queryParams in the URL on reload / deep link', async () => { + await setupTest({ opi: '1234' }); - // let Angular process the submit() call - await fixture.whenStable(); + await vi.waitFor(() => { + const currentCalls = vi.mocked(archiveServiceStub.searchArchiveUnitsByCriteria as Mock).mock.calls; + expect(currentCalls.length).toBeGreaterThan(0); + }); const calls = vi.mocked(archiveServiceStub.searchArchiveUnitsByCriteria as Mock).mock.calls; - vi.useRealTimers(); - - expect(calls.length).toBeGreaterThan(0); - const matchingCall = calls .map((call) => call[0]) .find((criteria) => 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 82b36087394..60679c1d8bf 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 @@ -36,25 +36,24 @@ */ import { HttpErrorResponse } from '@angular/common/http'; import { - AfterContentChecked, AfterViewInit, - ChangeDetectorRef, Component, EventEmitter, + inject, OnChanges, OnDestroy, OnInit, Output, + signal, SimpleChanges, TemplateRef, ViewChild, - inject, } from '@angular/core'; -import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogConfig, MatDialogContent } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { merge, Observable, Subject, Subscription } from 'rxjs'; -import { debounceTime, filter, map } from 'rxjs/operators'; +import { debounceTime, filter, map, take } from 'rxjs/operators'; import { ACCESS_RULE, AccessContract, @@ -68,20 +67,27 @@ import { ARCHIVE_UNIT_WITH_OBJECTS, ARCHIVE_UNIT_WITHOUT_OBJECTS, ArchiveSearchResultFacets, + ArchiveUnitModule, ConfigService, CriteriaDataType, CriteriaOperator, CriteriaSearchCriteria, CriteriaValue, + DialogHeaderComponent, Direction, DISSEMINATION_RULE, FilingHoldingSchemeNode, + HasRoleDirective, + InfiniteScrollDirective, Logger, MANAGEMENT_RULE_SHARED_DATA_SERVICE, + ManagementRuleSearchComponent, NODES, + OrderByButtonComponent, ORIGIN_WAITING_RECALCULATE, ORPHANS_NODE_ID, PagedResult, + PipesModule, QueryParamsService, ReclassificationDialogComponent, REUSE_RULE, @@ -102,12 +108,15 @@ import { STORAGE_RULE, TermsFacet, toManagementRuleType, + TooltipDirective, Unit, UnitType, VALID_COMPUTED_INHERITED_RULES_FACET, + VitamTenantConfigService, + VitamuiMenuButtonComponent, VitamuiRoles, + VitamuiSupHeaderComponent, WAITING_RECALCULATE, - VitamTenantConfigService, } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; import { ManagementRulesSharedDataService } from '../../core/management-rules-shared-data.service'; @@ -122,10 +131,31 @@ import { ActionsRules } from '../models/ruleAction.interface'; import { SearchCriteriaSaverComponent } from './search-criteria-saver/search-criteria-saver.component'; import { TransferAcknowledgmentComponent } from './transfer-acknowledgment/transfer-acknowledgment.component'; import { PuaUpdateDialogComponent, PuaUpdateDialogComponentData } from './pua-update-dialog/pua-update-dialog.component'; -import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox'; import { ReassignmentDialogService } from './additional-actions-search/originating-agency-reassignment-dialog/reassignment-dialog.service'; import { PreservationDialogService } from './additional-actions-search/preservation-dialog/preservation-dialog.service'; import { ReassignmentMode } from '../models/reassign-request.interface'; +import { TitleAndDescriptionCriteriaSearchComponent } from './title-and-description-criteria-search/title-and-description-criteria-search.component'; +import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; +import { CriteriaSearchComponent } from '../criteria-search/criteria-search.component'; +import { SearchCriteriaListComponent } from './search-criteria-list/search-criteria-list.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { AsyncPipe, CommonModule, NgClass, NgTemplateOutlet } from '@angular/common'; +import { ArchiveSearchRulesFacetsComponent } from './archive-search-rules-facets/archive-search-rules-facets.component'; +import { MatTab, MatTabGroup, MatTabLabel } from '@angular/material/tabs'; +import { SimpleCriteriaSearchComponent } from './simple-criteria-search/simple-criteria-search.component'; +import { + MatCell, + MatCellDef, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, + MatHeaderRow, + MatHeaderRowDef, + MatRow, + MatRowDef, + MatTable, +} from '@angular/material/table'; const PAGE_SIZE = 10; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -138,15 +168,57 @@ const NON_TREE_UNIT_TYPES = [ARCHIVE_UNIT_FILING_UNIT, ARCHIVE_UNIT_WITH_OBJECTS selector: 'app-archive-search', templateUrl: './archive-search.component.html', styleUrls: ['./archive-search.component.scss'], - standalone: false, providers: [ { provide: MANAGEMENT_RULE_SHARED_DATA_SERVICE, useExisting: ArchiveSharedDataService, }, ], + imports: [ + TitleAndDescriptionCriteriaSearchComponent, + VitamuiMenuButtonComponent, + MatMenuItem, + CriteriaSearchComponent, + MatMenuTrigger, + MatMenu, + SearchCriteriaListComponent, + MatProgressSpinner, + NgClass, + ArchiveSearchRulesFacetsComponent, + MatTabGroup, + MatTab, + SimpleCriteriaSearchComponent, + MatTabLabel, + ManagementRuleSearchComponent, + VitamuiSupHeaderComponent, + ArchiveUnitModule, + TooltipDirective, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + NgTemplateOutlet, + MatCellDef, + MatCell, + MatCheckbox, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow, + DialogHeaderComponent, + MatDialogActions, + MatDialogClose, + MatDialogContent, + OrderByButtonComponent, + AsyncPipe, + PipesModule, + TranslatePipe, + CommonModule, + HasRoleDirective, + InfiniteScrollDirective, + ], }) -export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, AfterContentChecked, AfterViewInit { +export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit { archiveService = inject(ArchiveService); private archiveFacetsService = inject(ArchiveFacetsService); private translateService = inject(TranslateService); @@ -162,7 +234,6 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft private computeInheritedRulesService = inject(ComputeInheritedRulesService); private archiveUnitDipService = inject(ArchiveUnitDipService); private accessContractService = inject(AccessContractService); - private cdr = inject(ChangeDetectorRef); private queryParamsService = inject(QueryParamsService); private searchCriteriaService = inject(SearchCriteriaService); private ruleService = inject(RuleService); @@ -182,8 +253,8 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft direction = Direction.ASCENDANT; accessContractId: string; - accessContractAllowUpdating: boolean; - accessContractUpdatingRestrictedDesc: boolean; + accessContractAllowUpdating = signal(false); + accessContractUpdatingRestrictedDesc = signal(false); @Output() archiveUnitClick = new EventEmitter(); tenantIdentifier: number; @@ -196,28 +267,37 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft isAllChecked: boolean; hasResults = false; - hasReassignmentRole = false; - hasDipExportRole = false; - hasTransferRequestRole = false; - hasUpdateManagementRuleRole = false; - hasEliminationAnalysisOrActionRole = false; - hasComputedInheritedRulesRole = false; - hasReclassificationRole = false; - hasPreservationRole = false; + hasReassignmentRole = signal(false); + hasDipExportRole = signal(false); + hasTransferRequestRole = signal(false); + hasUpdateManagementRuleRole = signal(false); + hasEliminationAnalysisOrActionRole = signal(false); + hasComputedInheritedRulesRole = signal(false); + hasReclassificationRole = signal(false); + hasPreservationRole = signal(false); waitingToGetFixedCount = false; showDuaEndDate = false; - pending = false; + pending = signal(false); pendingComputeFacets = false; - submitted = false; + submitted = signal(false); pendingGetFixedCount = false; submitedGetFixedCount = false; included = false; canLoadMore = false; - showCriteriaPanel = true; + // Starts visible: no search runs on portal landing, the user starts it explicitly. + // submit() collapses the panel once a search is launched. + showCriteriaPanel = signal(true); + /** + * True when the page is opened with query params already present (reload or deep link + * with search criteria): the search runs automatically once criteria are ready. + * False on portal landing (bare URL): default criteria are prefilled without searching. + * Captured from the arrival snapshot in ngOnInit, before default params are injected. + */ + private shouldAutoSearchOnInit = false; defaultFacetTabIndex = 1; currentPage = 0; pageNumbers = 0; - totalResults = 0; + totalResults = signal(0); selectedItemCount = 0; selectedHoldingUnitItemCount = 0; itemNotSelected = 0; @@ -232,7 +312,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft searchCriteriaHistory: SearchCriteriaHistory[] = []; criteriaSearchList: SearchCriteriaEltDto[] = []; listOfUACriteriaSearch: SearchCriteriaEltDto[] = []; - searchCriteriaKeys: string[]; + searchCriteriaKeys = signal([]); additionalSearchCriteriaCategories: SearchCriteriaCategory[]; subscriptions: Subscription = new Subscription(); @@ -246,7 +326,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft archiveUnitAllunitup: string[]; hasAccessContractManagementPermissionsMessage = ''; bulkOperationsThreshold = -1; - hasTransferAcknowledgmentRole = false; + hasTransferAcknowledgmentRole = signal(false); selectedArchive$: Observable; rulesToExport$: Observable; @@ -448,8 +528,8 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.accessContractService.currentAccessContract$.subscribe((ac: AccessContract) => { this.accessContractId = ac.identifier; - this.accessContractAllowUpdating = ac.writingPermission; - this.accessContractUpdatingRestrictedDesc = ac.writingRestrictedDesc; + this.accessContractAllowUpdating.set(ac.writingPermission); + this.accessContractUpdatingRestrictedDesc.set(ac.writingRestrictedDesc); }); this.additionalSearchCriteriaCategoryIndex = 0; this.additionalSearchCriteriaCategories = []; @@ -459,7 +539,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft }); this.hasAccessContractManagementPermissionsMessage = this.translateService.instant('UNIT_UPDATE.NO_PERMISSION'); this.searchCriterias = new Map(); - this.searchCriteriaKeys = []; + this.searchCriteriaKeys.set([]); if (!this.route.snapshot.queryParamMap.keys.length) { this.queryParamsService @@ -469,6 +549,12 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft .navigate({ replaceUrl: true }); } + // Snapshot taken on arrival, before the default params are injected above: + // - portal landing (bare URL): prefill defaults, do NOT search; + // - reload or deep link with criteria: the search runs automatically (see ngAfterViewInit). + // Selecting criteria later never triggers a search by itself (submit stays explicit). + this.shouldAutoSearchOnInit = this.route.snapshot.queryParamMap.keys.length > 0; + const searchCriteriaChange = merge(this.orderChange, this.filterChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); searchCriteriaChange.subscribe(() => { this.submit(true); @@ -491,9 +577,28 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft .pipe(map((rules) => rules.sort((a, b) => a.ruleId.localeCompare(b.ruleId)))); } + // No automatic search on portal landing (see shouldAutoSearchOnInit set in ngOnInit). + // On reload / deep link with criteria, the search runs automatically once the + // searchCriteriaService is ready (i.e.: schema retrieved, URL criteria applied). + // Reactive subscription (not snapshot): the default query params may be added by an async + // navigation, so the snapshot may still be empty here. take(1) guarantees a single submit: + // selecting criteria afterwards never triggers a search by itself. + // A schema failure must not block the initial search either. ngAfterViewInit() { - // Trigger the search if we land on the page with query params, but only after searchCriteriaService is ready (i.e.: schema has been retrieved) in order to trigger search only after criteria have been set from the URL query params - if (this.route.snapshot.queryParamMap.keys.length) this.searchCriteriaService.ready().then(() => setTimeout(() => this.submit(true))); + if (!this.shouldAutoSearchOnInit) return; + this.searchCriteriaService + .ready() + .catch((): void => undefined) + .then(() => { + this.subscriptions.add( + this.route.queryParamMap + .pipe( + filter((params) => params.keys.length > 0), + take(1), + ) + .subscribe(() => setTimeout(() => this.submit(true))), + ); + }); } ngOnChanges(changes: SimpleChanges): void { @@ -502,10 +607,6 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } } - ngAfterContentChecked(): void { - this.cdr.detectChanges(); - } - toManagementRuleType = toManagementRuleType; toUpdateOn(category: SearchCriteriaCategory) { @@ -521,13 +622,13 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } showHidePanel(show: boolean) { - this.showCriteriaPanel = show; + this.showCriteriaPanel.set(show); } showStoredSearchCriteria(event: SearchCriteriaHistory) { if (this.searchCriterias.size > 0) { this.searchCriterias = new Map(); - this.searchCriteriaKeys = []; + this.searchCriteriaKeys.set([]); this.included = false; } this.clearCriteria(); @@ -551,10 +652,12 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } removeCriteria(keyElt: string, valueElt: CriteriaValue, emit: boolean) { - this.archiveHelperService.removeCriteria(keyElt, valueElt, emit, this.searchCriteriaKeys, this.searchCriterias, this.nbQueryCriteria); + this.archiveHelperService.removeCriteria(keyElt, valueElt, emit, this.searchCriteriaKeys(), this.searchCriterias, this.nbQueryCriteria); + // The helper mutates the keys array in place: publish a new reference so zoneless change detection re-renders the chips. + this.searchCriteriaKeys.set([...this.searchCriteriaKeys()]); if (this.searchCriterias && this.searchCriterias.size === 0) { - this.submitted = false; - this.showCriteriaPanel = true; + this.submitted.set(false); + this.showCriteriaPanel.set(true); this.archiveUnits = []; this.archiveSharedDataService.emitNodeTarget(null); } @@ -655,7 +758,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft pageNumber: 0, size: 1, sortingCriteria, - trackTotalHits: this.totalResults >= 10000, + trackTotalHits: this.totalResults() >= 10000, computeMgtRulesFacets: true, facets: facets, }; @@ -681,7 +784,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.pendingComputeFacets = true; this.showingFacets = false; } - this.pending = true; + this.pending.set(true); let facets: TermsFacet[] = []; facets.push(ALL_DESCENDANTS_FACET); if (includeFacets) { @@ -711,16 +814,16 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.archiveSearchResultFacets.nodesFacets = this.archiveFacetsService.extractNodesFacetsResults(pagedResult.facets); this.archiveSharedDataService.emitFacets(this.archiveSearchResultFacets.nodesFacets); this.hasResults = true; - this.totalResults = pagedResult.totalResults; - this.archiveSharedDataService.emitTotalResults(this.totalResults); + this.totalResults.set(pagedResult.totalResults); + this.archiveSharedDataService.emitTotalResults(this.totalResults()); } else if (pagedResult.results) { this.hasResults = true; this.archiveUnits = [...this.archiveUnits, ...pagedResult.results]; } this.pageNumbers = pagedResult.pageNumbers; - this.waitingToGetFixedCount = this.totalResults === this.vitamConfigurationService.tenantConfig()?.resultThreshold; + this.waitingToGetFixedCount = this.totalResults() === this.vitamConfigurationService.tenantConfig()?.resultThreshold; if (this.isAllChecked) { - this.selectedItemCount = this.totalResults - this.itemNotSelected; + this.selectedItemCount = this.totalResults() - this.itemNotSelected; } this.canLoadMore = this.currentPage < this.pageNumbers - 1; this.archiveHelperService.updateCriteriaStatus( @@ -728,12 +831,12 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft SearchCriteriaStatusEnum.IN_PROGRESS, SearchCriteriaStatusEnum.INCLUDED, ); - this.pending = false; + this.pending.set(false); this.included = true; }, (error: HttpErrorResponse) => { this.canLoadMore = false; - this.pending = false; + this.pending.set(false); if (includeFacets) { this.pendingComputeFacets = false; this.archiveSharedDataService.emitFacets([]); @@ -750,7 +853,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } onArchiveUnitCountChange(resultCount: number) { - this.totalResults = resultCount; + this.totalResults.set(resultCount); this.archiveSharedDataService.emitTotalResults(resultCount); } @@ -895,9 +998,10 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.nodeArray, nodeId.value, this.searchCriterias, - this.searchCriteriaKeys, + this.searchCriteriaKeys(), this.nbQueryCriteria, ); + this.searchCriteriaKeys.set([...this.searchCriteriaKeys()]); }); this.nodeArray = null; this.archiveSharedDataService.emitToggle(true); @@ -905,14 +1009,14 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } loadMore() { - if (this.pending) { + if (this.pending()) { return; } this.canLoadMore = this.currentPage < this.pageNumbers - 1; if (!this.canLoadMore) { return; } - this.submitted = true; + this.submitted.set(true); this.currentPage = this.currentPage + 1; if (!this.hasSearchCriteria()) { return; @@ -935,7 +1039,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.submitedGetFixedCount = true; const exactCountResults: number = await this.archiveService.getTotalTrackHitsByCriteria(this.criteriaSearchList).toPromise(); if (exactCountResults !== -1) { - this.totalResults = exactCountResults; + this.totalResults.set(exactCountResults); this.waitingToGetFixedCount = false; this.managementRulesSharedDataService.emitHasExactCount(true); this.launchComputingManagementRulesFacets(); @@ -986,7 +1090,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } clearCriteria() { - const searchCriteriaKeysCloned = Object.assign([], this.searchCriteriaKeys); + const searchCriteriaKeysCloned = Object.assign([], this.searchCriteriaKeys()); searchCriteriaKeysCloned.forEach((criteriaKey) => { if (this.searchCriterias.has(criteriaKey)) { const criteria = this.searchCriterias.get(criteriaKey); @@ -1000,11 +1104,11 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.removeCriteriaCategory(category); }); this.searchCriterias = new Map(); - this.searchCriteriaKeys = []; + this.searchCriteriaKeys.set([]); this.included = false; this.nbQueryCriteria = 0; this.pageNumbers = 0; - this.totalResults = 0; + this.totalResults.set(0); this.selectedItemCount = 0; this.isAllChecked = false; this.isIndeterminate = false; @@ -1021,7 +1125,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft const { checked } = event; this.isAllChecked = checked; - this.selectedItemCount = checked ? this.totalResults : 0; + this.selectedItemCount = checked ? this.totalResults() : 0; this.selectedHoldingUnitItemCount = 0; if (!checked) { this.isIndeterminate = false; @@ -1057,7 +1161,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } this.listOfUACriteriaSearch = []; this.selectedItemCount++; - if (this.selectedItemCount === this.totalResults) { + if (this.selectedItemCount === this.totalResults()) { this.isIndeterminate = false; } if (this.isAllChecked) { @@ -1079,9 +1183,9 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft } private initializeSelectionParams() { - this.pending = true; - this.submitted = true; - this.showCriteriaPanel = false; + this.pending.set(true); + this.submitted.set(true); + this.showCriteriaPanel.set(false); this.currentPage = 0; this.archiveUnits = []; this.criteriaSearchList = []; @@ -1096,28 +1200,28 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.archiveService.hasArchiveSearchRole(role, tenantIdentifier).subscribe((result) => { switch (role) { case VitamuiRoles.ROLE_EXPORT_DIP: - this.hasDipExportRole = result; + this.hasDipExportRole.set(result); break; case VitamuiRoles.ROLE_TRANSFER_REQUEST: - this.hasTransferRequestRole = result; + this.hasTransferRequestRole.set(result); break; case VitamuiRoles.ROLE_ELIMINATION: - this.hasEliminationAnalysisOrActionRole = result; + this.hasEliminationAnalysisOrActionRole.set(result); break; case VitamuiRoles.ROLE_ARCHIVE_SEARCH_UPDATE_ARCHIVE_UNIT: - this.hasUpdateManagementRuleRole = result; + this.hasUpdateManagementRuleRole.set(result); break; case VitamuiRoles.ROLE_COMPUTED_INHERITED_RULES: - this.hasComputedInheritedRulesRole = result; + this.hasComputedInheritedRulesRole.set(result); break; case VitamuiRoles.ROLE_RECLASSIFICATION: - this.hasReclassificationRole = result; + this.hasReclassificationRole.set(result); break; case VitamuiRoles.ROLE_LAUNCH_PRESERVATION: - this.hasPreservationRole = result; + this.hasPreservationRole.set(result); break; case VitamuiRoles.ROLE_TRANSFER_ACKNOWLEDGMENT: - this.hasTransferAcknowledgmentRole = result; + this.hasTransferAcknowledgmentRole.set(result); break; default: break; @@ -1195,9 +1299,9 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.submitedGetFixedCount = true; const exactCountResults: number = await this.archiveService.getTotalTrackHitsByCriteria(this.criteriaSearchList).toPromise(); if (exactCountResults !== -1) { - this.totalResults = exactCountResults; + this.totalResults.set(exactCountResults); if (this.isAllChecked) { - this.selectedItemCount = this.totalResults - this.itemNotSelected; + this.selectedItemCount = this.totalResults() - this.itemNotSelected; } this.waitingToGetFixedCount = false; this.managementRulesSharedDataService.emitHasExactCount(true); @@ -1249,7 +1353,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft private hasRole(role: string): void { const appId = 'ARCHIVE_SEARCH_MANAGEMENT_APP'; this.securityService.hasRole$(appId, role, this.tenantIdentifier).subscribe((result) => { - return (this.hasReassignmentRole = result); + return this.hasReassignmentRole.set(result); }); } @@ -1497,7 +1601,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft ) { this.archiveHelperService.addCriteria( this.searchCriterias, - this.searchCriteriaKeys, + this.searchCriteriaKeys(), this.nbQueryCriteria, keyElt, valueElt, @@ -1509,6 +1613,8 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft dataType, emit, ); + // The helper mutates the keys array in place: publish a new reference so zoneless change detection re-renders the chips. + this.searchCriteriaKeys.set([...this.searchCriteriaKeys()]); } trackBy(_: number, unit: Unit) { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.component.ts index 6665b30bcd7..05cd052314f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.component.ts @@ -72,12 +72,16 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input } from '@angular/core'; +import { CommonConfirmDialogComponent, PipesModule } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; +import { MatDialogModule } from '@angular/material/dialog'; // FIXME: should be factorized in vitamui-library ConfirmActionComponent @Component({ selector: 'vitamui-confirm-action', templateUrl: './confirm-action.component.html', - standalone: false, + imports: [PipesModule, TranslatePipe, CommonConfirmDialogComponent, CommonModule, MatDialogModule], }) export class ConfirmActionComponent { // delete or changeTab diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.module.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.module.ts deleted file mode 100644 index 4d5b5a20e19..00000000000 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/confirm-action/confirm-action.module.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { ConfirmDialogModule, VitamUICommonModule } from 'vitamui-library'; -import { ConfirmActionComponent } from './confirm-action.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [ConfirmActionComponent], - imports: [CommonModule, MatDialogModule, ConfirmDialogModule, VitamUICommonModule, TranslatePipe], - exports: [ConfirmActionComponent], -}) -export class ConfirmActionModule {} diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.html index a9eeb19e292..791d06f8ea0 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.html @@ -1,5 +1,5 @@
- @for (criteria of searchCriteriaHistory; track criteria) { + @for (criteria of searchCriteriaHistory(); track criteria) { } - @if (pending) { + @if (pending()) {
diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.spec.ts index 47249a8f921..ac68c3462bf 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.spec.ts @@ -39,9 +39,7 @@ import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; import { CriteriaDataType, CriteriaOperator, @@ -56,24 +54,13 @@ import { ArchiveSharedDataService } from '../../../core/archive-shared-data.serv import { SearchCriteriaListComponent } from './search-criteria-list.component'; import { SearchCriteriaListService } from './search-criteria-list.service'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; } } -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('SearchCriteriaListComponent', () => { let component: SearchCriteriaListComponent; let fixture: ComponentFixture; @@ -95,8 +82,7 @@ describe('SearchCriteriaListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [InjectorModule, LoggerModule.forRoot(), RouterTestingModule], - declarations: [SearchCriteriaListComponent, MockTruncatePipe], + imports: [InjectorModule, LoggerModule.forRoot(), SearchCriteriaListComponent, MockTruncatePipe], providers: [ ArchiveSharedDataService, DatePipe, @@ -105,7 +91,11 @@ describe('SearchCriteriaListComponent', () => { { provide: SearchCriteriaListService, useValue: SearchCriteriaListServiceStub }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, + }, }, { provide: environment, useValue: environment }, { provide: SnackBarService, useValue: {} }, @@ -194,7 +184,7 @@ describe('SearchCriteriaListComponent', () => { }, ]; - component.searchCriteriaHistory = searchCriteriaHistory$; + component.searchCriteriaHistory.set(searchCriteriaHistory$); }); it('should call getSearchCriteriaHistory of SearchCriteriaListService', () => { @@ -205,14 +195,14 @@ describe('SearchCriteriaListComponent', () => { component.getSearchCriteriaHistory(); // Then - expect(component.pending).toBeFalsy(); + expect(component.pending()).toBeFalsy(); expect(SearchCriteriaListServiceStub.getSearchCriteriaHistory).toHaveBeenCalled(); }); it('should delete searchCriteria', () => { component.clearElement(searchCriteriaHistory$[0].id); - expect(component.searchCriteriaHistory.length).toEqual(1); - expect(component.searchCriteriaHistory[0].name).toEqual('Second Save'); + expect(component.searchCriteriaHistory().length).toEqual(1); + expect(component.searchCriteriaHistory()[0].name).toEqual('Second Save'); }); }); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.ts index 6f45e316fcc..3f5e3c7d01d 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.component.ts @@ -34,21 +34,23 @@ * 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, EventEmitter, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, OnDestroy, OnInit, Output, signal } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Subject, Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; -import { Direction, SearchCriteriaHistory, SnackBarService } from 'vitamui-library'; +import { Direction, PipesModule, SearchCriteriaHistory, SnackBarService, TooltipDirective } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; import { ConfirmActionComponent } from './confirm-action/confirm-action.component'; import { SearchCriteriaListService } from './search-criteria-list.service'; +import { MatMenuItem } from '@angular/material/menu'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; @Component({ selector: 'app-search-criteria-list', templateUrl: './search-criteria-list.component.html', styleUrls: ['./search-criteria-list.component.css'], - standalone: false, + imports: [MatMenuItem, TooltipDirective, MatProgressSpinner, PipesModule, TranslatePipe], }) export class SearchCriteriaListComponent implements OnInit, OnDestroy { private searchCriteriaListService = inject(SearchCriteriaListService); @@ -60,7 +62,7 @@ export class SearchCriteriaListComponent implements OnInit, OnDestroy { @Output() storedSearchCriteriaHistory = new EventEmitter(); - searchCriteriaHistory: SearchCriteriaHistory[]; + searchCriteriaHistory = signal([]); private readonly orderChange = new Subject(); direction: Direction = Direction.ASCENDANT; @@ -68,15 +70,16 @@ export class SearchCriteriaListComponent implements OnInit, OnDestroy { subscriptionSearchCriteriaHistory: Subscription; keyPressSubscription: Subscription; - pending = false; + pending = signal(false); ngOnInit() { this.subscriptionSearchCriteriaHistoryShared = this.archiveSharedDataService .getSearchCriteriaHistoryShared() .subscribe((searchCriteriaHistoryResults) => { if (searchCriteriaHistoryResults) { - this.searchCriteriaHistory.push(searchCriteriaHistoryResults); - this.archiveSharedDataService.sort(Direction.ASCENDANT, this.searchCriteriaHistory); + const next = [...this.searchCriteriaHistory(), searchCriteriaHistoryResults]; + this.archiveSharedDataService.sort(Direction.ASCENDANT, next); + this.searchCriteriaHistory.set(next); } }); this.getSearchCriteriaHistory(); @@ -93,12 +96,12 @@ export class SearchCriteriaListComponent implements OnInit, OnDestroy { } getSearchCriteriaHistory() { - this.pending = true; + this.pending.set(true); this.subscriptionSearchCriteriaHistory = this.searchCriteriaListService.getSearchCriteriaHistory().subscribe((data) => { - this.searchCriteriaHistory = data; - this.archiveSharedDataService.sort(Direction.ASCENDANT, this.searchCriteriaHistory); + this.archiveSharedDataService.sort(Direction.ASCENDANT, data); + this.searchCriteriaHistory.set(data); this.archiveSharedDataService.emitAllSearchCriteriaHistory(data); - this.pending = false; + this.pending.set(false); }); } @@ -124,10 +127,6 @@ export class SearchCriteriaListComponent implements OnInit, OnDestroy { } clearElement(id: string) { - for (let i = 0; i < this.searchCriteriaHistory.length; i++) { - if (this.searchCriteriaHistory[i].id === id) { - this.searchCriteriaHistory.splice(i, 1); - } - } + this.searchCriteriaHistory.set(this.searchCriteriaHistory().filter((criteria) => criteria.id !== id)); } } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.service.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.service.spec.ts index ec353a4cb42..bc54f2318b6 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.service.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-list/search-criteria-list.service.spec.ts @@ -34,14 +34,11 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { InjectorModule } from 'vitamui-library'; import { ArchiveApiService } from '../../../core/api/archive-api.service'; import { SearchCriteriaListService } from './search-criteria-list.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('SearchCriteriaListService', () => { let service: SearchCriteriaListService; @@ -71,14 +68,12 @@ describe('SearchCriteriaListService', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [InjectorModule, RouterTestingModule], + imports: [InjectorModule], providers: [ { provide: ArchiveApiService, useValue: archiveApiServiceMock, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }); service = TestBed.inject(SearchCriteriaListService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.spec.ts index c6c52ef6ce4..4449d22bda2 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.spec.ts @@ -41,9 +41,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; import { CriteriaDataType, CriteriaOperator, @@ -59,24 +57,13 @@ import { ArchiveSharedDataService } from '../../../core/archive-shared-data.serv import { SearchCriteriaSaverComponent } from './search-criteria-saver.component'; import { SearchCriteriaSaverService } from './search-criteria-saver.service'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; } } -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('SearchCriteriaSaverComponent', () => { let component: SearchCriteriaSaverComponent; let fixture: ComponentFixture; @@ -99,8 +86,7 @@ describe('SearchCriteriaSaverComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [InjectorModule, LoggerModule.forRoot(), RouterTestingModule], - declarations: [SearchCriteriaSaverComponent, MockTruncatePipe], + imports: [InjectorModule, LoggerModule.forRoot(), SearchCriteriaSaverComponent, MockTruncatePipe], providers: [ FormBuilder, ArchiveSharedDataService, @@ -111,7 +97,11 @@ describe('SearchCriteriaSaverComponent', () => { { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, + }, }, { provide: environment, useValue: environment }, { provide: SnackBarService, useValue: {} }, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.ts index 3060f21b690..d3097114d96 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.component.ts @@ -35,19 +35,24 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { DatePipe } from '@angular/common'; -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslatePipe } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; import { + ChipComponent, ConfirmDialogService, CriteriaSearchCriteria, Direction, + ElementsComponent, + InputComponent, + ORIGIN_WAITING_RECALCULATE, + PipesModule, SearchCriteriaHistory, SearchCriteriaTypeEnum, SnackBarService, - ORIGIN_WAITING_RECALCULATE, + TooltipDirective, WAITING_RECALCULATE, } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; @@ -58,7 +63,7 @@ import { SearchCriteriaSaverService } from './search-criteria-saver.service'; templateUrl: './search-criteria-saver.component.html', styleUrls: ['./search-criteria-saver.component.css'], providers: [TranslatePipe], - standalone: false, + imports: [ChipComponent, TooltipDirective, ReactiveFormsModule, InputComponent, ElementsComponent, PipesModule, TranslatePipe], }) export class SearchCriteriaSaverComponent implements OnInit, OnDestroy { data = inject(MAT_DIALOG_DATA); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.service.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.service.spec.ts index e52b2f6e398..4c00acc0df1 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.service.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/search-criteria-saver/search-criteria-saver.service.spec.ts @@ -37,7 +37,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { Type } from '@angular/core'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, SearchCriteriaHistory } from 'vitamui-library'; +import { SearchCriteriaHistory } from 'vitamui-library'; import { SearchCriteriaSaverService } from './search-criteria-saver.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -49,14 +49,7 @@ describe('SearchCriteriaSaverService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }); httpTestingController = TestBed.inject(HttpTestingController as Type); service = TestBed.inject(SearchCriteriaSaverService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.html index d17d471a277..dc5ec3bbf9b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.html @@ -1,13 +1,14 @@
- @if (titleSearchTypes) { - @if (titleSearchTypes?.length) { + @if (titleSearchTypes()) { + @if (titleSearchTypes()?.length) { } @else { @@ -54,7 +55,7 @@ [multiple]="true" [enableSelectAll]="false" formControlName="agencies" - [options]="selectOptions.agency" + [options]="selectOptions().agency" [placeholder]="'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.SP' | translate" [searchBarPlaceHolder]="'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.SP_PLACEHOLDER' | translate" class="w-100" @@ -64,7 +65,7 @@ [multiple]="true" [enableSelectAll]="false" formControlName="archiveUnitProfiles" - [options]="selectOptions.archiveUnitProfile" + [options]="selectOptions().archiveUnitProfile" [placeholder]="'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.AUP' | translate" [searchBarPlaceHolder]="'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.AUP_PLACEHOLDER' | translate" class="w-100" @@ -123,13 +124,13 @@

{{ 'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.OTHER_FIELDS' | translate }}

- @if (otherCriteriaOptions) { + @if (otherCriteriaOptions()) {
@for (otherCriteria of otherCriteriaList.value; track otherCriteria.ApiPath) { - @if (['Title'].includes(otherCriteria.ApiPath) && titleSearchTypes?.length) { + @if (['Title'].includes(otherCriteria.ApiPath) && titleSearchTypes()?.length) { } @else if (['TEXT', 'KEYWORD', 'BOOLEAN', 'LONG'].includes(otherCriteria.Type)) { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.spec.ts index 76e4acd6783..635bbb69da1 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.spec.ts @@ -34,14 +34,12 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { BehaviorSubject, of } from 'rxjs'; import { AgenciesModule, - BASE_URL, InjectorModule, ItemNode, LoggerModule, @@ -55,7 +53,6 @@ import { ManagementRulesSharedDataService } from '../../../core/management-rules import { SimpleCriteriaSearchComponent } from './simple-criteria-search.component'; import { ArchiveService } from '../../archive.service'; import { ActivatedRoute } from '@angular/router'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('SimpleCriteriaSearchComponent', () => { let component: SimpleCriteriaSearchComponent; @@ -92,8 +89,7 @@ describe('SimpleCriteriaSearchComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [SimpleCriteriaSearchComponent], - imports: [InjectorModule, AgenciesModule, LoggerModule.forRoot()], + imports: [InjectorModule, AgenciesModule, LoggerModule.forRoot(), SimpleCriteriaSearchComponent], providers: [ FormBuilder, { provide: ArchiveService, useValue: archiveServiceStub }, @@ -101,7 +97,6 @@ describe('SimpleCriteriaSearchComponent', () => { { provide: MatDialog, useValue: matDialogSpy }, { provide: ManagementRulesSharedDataService, useValue: managementRulesSharedDataServiceMock }, { provide: SchemaService, useValue: schemaServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, SnackBarService, { provide: ActivatedRoute, @@ -109,8 +104,6 @@ describe('SimpleCriteriaSearchComponent', () => { queryParamMap: of(), }, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts index 43093fca298..7122a7075f1 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts @@ -34,10 +34,10 @@ * 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, OnInit, ChangeDetectorRef, inject } from '@angular/core'; -import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, inject, OnInit, signal } from '@angular/core'; +import { AbstractControl, FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { AgencyService, ArchiveUnitProfilesService, @@ -45,6 +45,9 @@ import { CriteriaDataType, CriteriaOperator, CriteriaValue, + DatepickerComponent, + EditableInputComponent, + FormFieldValueWrapperComponent, ItemNode, Option, SchemaElement, @@ -54,6 +57,9 @@ import { SearchCriteriaService, SearchCriteriaTypeEnum, SearchType, + SearchWithTypeSelectorComponent, + SelectComponent, + SelectWithTreeComponent, VitamuiSelectOptions, } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; @@ -63,7 +69,14 @@ import { combineLatest } from 'rxjs'; import { ArchiveSearchConstsEnum } from '../../models/archive-search-consts-enum'; import { ActivatedRoute, Params } from '@angular/router'; import { ArchiveSearchHelperService } from '../../common-services/archive-search-helper.service'; -import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox'; +import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule, NgTemplateOutlet } from '@angular/common'; +import { MatInputModule } from '@angular/material/input'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; const FINAL_ACTION_TYPE = 'FINAL_ACTION_TYPE'; const ARCHIVE_UNIT_FILING_UNIT = 'ARCHIVE_UNIT_FILING_UNIT'; @@ -84,7 +97,28 @@ const COMPLEX_INPUTS = ['otherCriteriaList']; selector: 'app-simple-criteria-search', templateUrl: './simple-criteria-search.component.html', styleUrls: ['./simple-criteria-search.component.css'], - standalone: false, + imports: [ + ReactiveFormsModule, + FormFieldValueWrapperComponent, + SearchWithTypeSelectorComponent, + MatProgressSpinner, + SelectComponent, + DatepickerComponent, + MatCheckbox, + NgTemplateOutlet, + SelectWithTreeComponent, + TranslatePipe, + CommonModule, + EditableInputComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class SimpleCriteriaSearchComponent implements OnInit { dialog = inject(MatDialog); @@ -98,7 +132,6 @@ export class SimpleCriteriaSearchComponent implements OnInit { private schemaService = inject(SchemaService); private agencyService = inject(AgencyService); private archiveUnitProfilesService = inject(ArchiveUnitProfilesService); - private cdr = inject(ChangeDetectorRef); form: FormGroup; criteriaSearchListToSave: SearchCriteriaEltDto[] = []; @@ -110,17 +143,17 @@ export class SimpleCriteriaSearchComponent implements OnInit { [ARCHIVE_UNIT_WITHOUT_OBJECTS, false], ]); - otherCriteriaOptions: ItemNode[]; + otherCriteriaOptions = signal[]>(undefined); getOtherCriteriaDisplayValue = (element: SchemaElement) => `${element.Origin === 'EXTERNAL' ? 'EXT-' : ''}${element.ShortName} - ${element.FieldName}`; - titleSearchTypes: SearchType[]; - titleSelectedType?: SearchType; + titleSearchTypes = signal(undefined); + titleSelectedType = signal(undefined); - selectOptions = { + selectOptions = signal({ agency: { options: [] as Option[] }, archiveUnitProfile: { options: [] as Option[] }, - } satisfies { [key: string]: VitamuiSelectOptions }; + } satisfies { [key: string]: VitamuiSelectOptions }); constructor() { const otherCriteriaListControl = this.formBuilder.control([]); @@ -160,7 +193,9 @@ export class SimpleCriteriaSearchComponent implements OnInit { }), ), ) - .subscribe((options) => (this.selectOptions.agency = options)); + .subscribe((options) => { + this.selectOptions.update((selectOptions) => ({ ...selectOptions, agency: options })); + }); this.archiveUnitProfilesService .getAll() @@ -174,18 +209,21 @@ export class SimpleCriteriaSearchComponent implements OnInit { }), ), ) - .subscribe((options) => (this.selectOptions.archiveUnitProfile = options)); + .subscribe((options) => { + this.selectOptions.update((selectOptions) => ({ ...selectOptions, archiveUnitProfile: options })); + }); const descriptiveSchemaTree$ = this.schemaService.getDescriptiveSchemaTree().pipe(share()); - descriptiveSchemaTree$.subscribe((schema) => (this.otherCriteriaOptions = schema)); + descriptiveSchemaTree$.subscribe((schema) => { + this.otherCriteriaOptions.set(schema); + }); const titleSearchTypes$ = descriptiveSchemaTree$.pipe( map((schema) => this.searchTypes(schema, 'Title')), share(), ); titleSearchTypes$.subscribe((titleSearchTypes) => { - this.titleSearchTypes = titleSearchTypes; - this.cdr.detectChanges(); // Force la détection de changements + this.titleSearchTypes.set(titleSearchTypes); }); const otherCriteriaControl = this.form.controls['otherCriteria'] as FormGroup; @@ -205,12 +243,13 @@ export class SimpleCriteriaSearchComponent implements OnInit { combineLatest([titleKeys$, titleSearchTypes$]).subscribe(([titleKeys, titleSearchTypes]) => { const hasTitleSearchCriteria = !!titleKeys?.length; const type = hasTitleSearchCriteria ? titleKeys[0].split('.')[1] || '' : null; - this.titleSearchTypes = titleSearchTypes.map((item) => ({ - ...item, - disabled: hasTitleSearchCriteria && item.value !== type, - })); - if (hasTitleSearchCriteria) this.titleSelectedType = this.titleSearchTypes.find((item) => item.value === type); - this.cdr.detectChanges(); // Force la détection de changements + this.titleSearchTypes.set( + titleSearchTypes.map((item) => ({ + ...item, + disabled: hasTitleSearchCriteria && item.value !== type, + })), + ); + if (hasTitleSearchCriteria) this.titleSelectedType.set(this.titleSearchTypes().find((item) => item.value === type)); }); // Sync archive unit types with criteria @@ -309,7 +348,7 @@ export class SimpleCriteriaSearchComponent implements OnInit { getCriteriaName(criteria: SchemaElement) { const path = criteria.Path.split('.').slice(0, -1); const parent = path.reduce((acc, p) => acc.children.find((o) => o.item.FieldName === p), { - children: this.otherCriteriaOptions, + children: this.otherCriteriaOptions(), } as ItemNode); return `${criteria.ShortName}${parent?.item ? ` (${parent.item.ShortName})` : ''}`; } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.spec.ts index 64a918cbb6c..b4a751cc56e 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.spec.ts @@ -56,13 +56,12 @@ describe('TitleAndDescriptionCriteriaSearchComponent', () => { }; matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - declarations: [TitleAndDescriptionCriteriaSearchComponent], providers: [ FormBuilder, { provide: MatDialog, useValue: matDialogSpy }, { provide: ArchiveSharedDataService, useValue: archiveExchangeDataServiceMock }, ], - imports: [InjectorModule], + imports: [InjectorModule, TitleAndDescriptionCriteriaSearchComponent], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.ts index 45951597646..cd9ec200d79 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/title-and-description-criteria-search/title-and-description-criteria-search.component.ts @@ -35,20 +35,41 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { merge } from 'rxjs'; import { debounceTime, filter, map } from 'rxjs/operators'; -import { CriteriaDataType, CriteriaOperator, CriteriaValue, diff, SearchCriteriaTypeEnum } from 'vitamui-library'; +import { CriteriaDataType, CriteriaOperator, CriteriaValue, diff, EditableInputComponent, SearchCriteriaTypeEnum } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; import { ArchiveSearchConstsEnum } from '../../models/archive-search-consts-enum'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const TITLE_OR_DESCRIPTION = 'TITLE_OR_DESCRIPTION'; @Component({ selector: 'app-title-and-description-criteria-search', templateUrl: './title-and-description-criteria-search.component.html', - standalone: false, + imports: [ + ReactiveFormsModule, + TranslatePipe, + CommonModule, + EditableInputComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class TitleAndDescriptionCriteriaSearchComponent { private formBuilder = inject(FormBuilder); 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 450382aa5d5..f74a968beae 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 @@ -34,23 +34,17 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { of } from 'rxjs'; -import { BASE_URL, BytesPipe, InjectorModule, LoggerModule, StartupService, WINDOW_LOCATION } from 'vitamui-library'; +import { BytesPipe, InjectorModule, LoggerModule, StartupService, WINDOW_LOCATION } from 'vitamui-library'; 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'; -@Pipe({ - name: 'dateTime', - standalone: false, -}) +@Pipe({ name: 'dateTime' }) export class MockDateTimePipe implements PipeTransform { transform(value: string = ''): any { return value; @@ -90,10 +84,8 @@ describe('TransferAcknowledgmentComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [MockDateTimePipe], - imports: [TransferAcknowledgmentComponent, CdkStep, NoopAnimationsModule, InjectorModule, LoggerModule.forRoot()], + imports: [TransferAcknowledgmentComponent, CdkStep, InjectorModule, LoggerModule.forRoot(), MockDateTimePipe], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, @@ -102,8 +94,6 @@ describe('TransferAcknowledgmentComponent', () => { { provide: ArchiveService, useValue: archiveSearchServiceStub }, DecimalPipe, BytesPipe, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.html index 29e472c7d3c..207e4020c36 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.html @@ -1,5 +1,5 @@ - @if (foundAccessContract) { + @if (foundAccessContract()) { @@ -29,7 +29,7 @@
{{ 'APPLICATION.ARCHIVE_SEARCH_MANAGEMENT_APP.NAME' | translate }}
- @if (foundAccessContract) { + @if (foundAccessContract()) {
@if (!show) { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.spec.ts index 32ec6f0dc35..3179bd67d1f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.spec.ts @@ -34,7 +34,6 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; @@ -42,13 +41,10 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatDialog } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { AccessContract, - BASE_URL, InjectorModule, LoggerModule, SearchBarComponent, @@ -60,7 +56,6 @@ import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { environment } from '../../environments/environment'; import { ArchiveApiService } from '../core/api/archive-api.service'; import { ArchiveComponent } from './archive.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ArchiveComponent', () => { let component: ArchiveComponent; @@ -108,20 +103,16 @@ describe('ArchiveComponent', () => { }; matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - declarations: [ArchiveComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ MatDatepickerModule, MatMenuModule, MatSidenavModule, InjectorModule, - RouterTestingModule, VitamUICommonTestModule, - BrowserAnimationsModule, LoggerModule.forRoot(), - RouterTestingModule, - NoopAnimationsModule, SearchBarComponent, + ArchiveComponent, ], providers: [ FormBuilder, @@ -129,16 +120,17 @@ describe('ArchiveComponent', () => { { provide: ArchiveApiService, useValue: archiveServiceMock }, { provide: SecurityService, useValue: securityServiceMock }, { provide: WINDOW_LOCATION, useValue: window.location }, - { - provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }) }, - }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: environment, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(ActivatedRoute, { + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, + }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.ts index 63ecf1817d2..8f65fdf4492 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.component.ts @@ -34,7 +34,7 @@ * 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, OnInit, inject } from '@angular/core'; +import { Component, inject, OnInit, signal } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { @@ -42,24 +42,45 @@ import { Collection, ExternalParameters, ExternalParametersService, - GlobalEventService, + ResizeSidebarDirective, SchemaService, SidenavPage, SnackBarService, + TooltipDirective, Unit, + VitamuiTitleBreadcrumbComponent, } from 'vitamui-library'; import { ArchiveSharedDataService } from '../core/archive-shared-data.service'; import { ManagementRulesSharedDataService } from '../core/management-rules-shared-data.service'; import { ArchiveService } from './archive.service'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { FilingHoldingSchemeComponent } from './filing-holding-scheme/filing-holding-scheme.component'; +import { CommonModule, NgClass } from '@angular/common'; +import { ArchivePreviewComponent } from './archive-preview/archive-preview.component'; +import { ArchiveSearchComponent } from './archive-search/archive-search.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-archive', templateUrl: './archive.component.html', styleUrls: ['./archive.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + FilingHoldingSchemeComponent, + NgClass, + ArchivePreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + TooltipDirective, + ArchiveSearchComponent, + TranslatePipe, + CommonModule, + ResizeSidebarDirective, + ], }) export class ArchiveComponent extends SidenavPage implements OnInit { - private route: ActivatedRoute; + private route = inject(ActivatedRoute); private router = inject(Router); dialog = inject(MatDialog); private archiveSharedDataService = inject(ArchiveSharedDataService); @@ -72,17 +93,15 @@ export class ArchiveComponent extends SidenavPage implements OnInit { show = true; tenantIdentifier: string; - foundAccessContract = false; + // Signal (et non booléen) : la notification via ChangeDetectionScheduler planifie un tick + // même si la zone ne notifie pas la fin des callbacks HTTP. + foundAccessContract = signal(false); bulkOperationsThreshold: number; isLPExtended = false; hasUpdateDescriptiveUnitMetadataRole = false; constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - this.route = route; + super(); this.schemaService.getSchema(Collection.ARCHIVE_UNIT); } @@ -111,7 +130,7 @@ export class ArchiveComponent extends SidenavPage implements OnInit { fetchUserExternalParameters() { this.accessContractService.currentAccessContractId$.subscribe((accessContractId) => { if (accessContractId && accessContractId.length > 0) { - this.foundAccessContract = true; + this.foundAccessContract.set(true); this.managementRulesSharedDataService.emitAccessContract(accessContractId); } else { this.snackBarService.open({ 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 014f3f1e130..a9dc0209345 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 @@ -91,7 +91,7 @@ import { ClassificationTreeComponent } from './filing-holding-scheme/classificat import { FilingHoldingSchemeComponent } from './filing-holding-scheme/filing-holding-scheme.component'; import { LeavesTreeComponent } from './filing-holding-scheme/leaves-tree/leaves-tree.component'; import { MatTableModule } from '@angular/material/table'; -import { ConfirmActionModule } from './archive-search/search-criteria-list/confirm-action/confirm-action.module'; + import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ @@ -116,14 +116,11 @@ import { TranslatePipe } from '@ngx-translate/core'; MatTabsModule, MatTreeModule, ReactiveFormsModule, - ConfirmActionModule, VitamUICommonModule, VitamUILibraryModule, MatTableModule, TranslatePipe, DiscussionIconComponent, - ], - declarations: [ AddManagementRulesComponent, AddUpdatePropertyComponent, ArchiveComponent, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.spec.ts index 5f7df9aa461..df147276199 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.spec.ts @@ -37,9 +37,7 @@ import { TestBed } from '@angular/core/testing'; import { ArchiveService } from './archive.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { BASE_URL, LoggerModule, Unit } from 'vitamui-library'; +import { LoggerModule, Unit } from 'vitamui-library'; import { ArchiveApiService } from '../core/api/archive-api.service'; import { vi } from 'vitest'; import { of } from 'rxjs'; @@ -53,12 +51,7 @@ describe('ArchiveService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - { provide: ArchiveApiService, useValue: archiveApiService }, - ], + providers: [{ provide: ArchiveApiService, useValue: archiveApiService }], }); service = TestBed.inject(ArchiveService); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-facets.service.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-facets.service.spec.ts index 03a261500f0..f97af347019 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-facets.service.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-facets.service.spec.ts @@ -34,9 +34,8 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { ResultFacet, ResultFacetList, LoggerModule, BASE_URL } from 'vitamui-library'; +import { LoggerModule, ResultFacet, ResultFacetList } from 'vitamui-library'; import { ArchiveFacetsService } from './archive-facets.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -130,12 +129,7 @@ describe('ArchiveFacetsService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - ArchiveFacetsService, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), ArchiveFacetsService], }); archiveFacetsService = TestBed.inject(ArchiveFacetsService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-unit-elimination.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-unit-elimination.service.ts index 15ac185cf47..d18c5ab5b7e 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-unit-elimination.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-unit-elimination.service.ts @@ -38,7 +38,7 @@ import { inject, Injectable, TemplateRef } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { filter } from 'rxjs/operators'; -import { ApplicationId, VitamTenantConfigService, SearchCriteriaEltDto, SnackBarService } from 'vitamui-library'; +import { ApplicationId, SearchCriteriaEltDto, SnackBarService, VitamTenantConfigService } from 'vitamui-library'; import { ArchiveSearchComponent } from '../archive-search/archive-search.component'; import { ArchiveService } from '../archive.service'; diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service.ts index 921d970ea58..39f15cef010 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service.ts @@ -34,7 +34,7 @@ * 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 { Injectable, TemplateRef, inject } from '@angular/core'; +import { inject, Injectable, TemplateRef } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.spec.ts index 939f21403c3..884eb21ae16 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.spec.ts @@ -34,14 +34,11 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { environment } from 'projects/archive-search/src/environments/environment'; import { - BASE_URL, InjectorModule, LoggerModule, SearchCriteriaTypeEnum, @@ -50,7 +47,6 @@ import { } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { CriteriaSearchComponent } from './criteria-search.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('CriteriaSearchComponent', () => { let component: CriteriaSearchComponent; @@ -58,23 +54,12 @@ describe('CriteriaSearchComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [CriteriaSearchComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [ - InjectorModule, - RouterTestingModule, - VitamUICommonTestModule, - BrowserAnimationsModule, - LoggerModule.forRoot(), - RouterTestingModule, - ], + imports: [InjectorModule, VitamUICommonTestModule, BrowserAnimationsModule, LoggerModule.forRoot(), CriteriaSearchComponent], providers: [ TranslateWithOptionalTypeSuffixPipe, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: environment, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.ts index 55bcb282ad0..295b817e32f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/criteria-search/criteria-search.component.ts @@ -34,22 +34,28 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import type { CriteriaSearchCriteria, CriteriaValue, SearchCriteriaValue } from 'vitamui-library'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; import { + CriteriaSearchCriteria, + CriteriaValue, ORIGIN_WAITING_RECALCULATE, + PipesModule, QueryParamsService, SearchCriteriaTypeEnum, + SearchCriteriaValue, + TooltipDirective, TranslateWithOptionalTypeSuffixPipe, WAITING_RECALCULATE, } from 'vitamui-library'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { NgClass } from '@angular/common'; + @Component({ selector: 'app-criteria-search', templateUrl: './criteria-search.component.html', styleUrls: ['./criteria-search.component.scss'], - standalone: false, providers: [TranslateWithOptionalTypeSuffixPipe], + imports: [TooltipDirective, NgClass, PipesModule, TranslatePipe], }) export class CriteriaSearchComponent { private queryParamsService = inject(QueryParamsService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.ts index 0a4b671bf13..8fdaf50bd3c 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.ts @@ -36,14 +36,34 @@ */ import { NestedTreeControl } from '@angular/cdk/tree'; import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { MatTreeNestedDataSource } from '@angular/material/tree'; -import { FilingHoldingSchemeNode, nodeHasChildren, nodeHasMatch, nodeToVitamuiIcon } from 'vitamui-library'; +import { + MatNestedTreeNode, + MatTree, + MatTreeNestedDataSource, + MatTreeNode, + MatTreeNodeDef, + MatTreeNodeOutlet, +} from '@angular/material/tree'; +import { FilingHoldingSchemeNode, nodeHasChildren, nodeHasMatch, nodeToVitamuiIcon, VitamuiTreeNodeComponent } from 'vitamui-library'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { DecimalPipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-classification-tree', templateUrl: './classification-tree.component.html', styleUrls: ['./classification-tree.component.scss'], - standalone: false, + imports: [ + MatProgressSpinner, + MatTree, + MatTreeNodeDef, + MatTreeNode, + VitamuiTreeNodeComponent, + MatNestedTreeNode, + MatTreeNodeOutlet, + DecimalPipe, + TranslatePipe, + ], }) export class ClassificationTreeComponent { @Input() loadingHolding: boolean; diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.html index 465708f1aee..20c19d39e90 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.html @@ -1,10 +1,10 @@
-@if (hasMatchesInSearch) { +@if (hasMatchesInSearch()) {
} -@if (hasMatchesInSearch) { +@if (hasMatchesInSearch()) {
{ MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, + FilingHoldingSchemeComponent, ], - declarations: [FilingHoldingSchemeComponent], providers: [ { provide: ArchiveService, useValue: archiveServiceStub }, { provide: ArchiveApiService, useValue: archiveServiceMock }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, + }, }, { provide: environment, useValue: environment }, ], diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts index 7fed6f0672e..ae7b8c7cd65 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { NestedTreeControl } from '@angular/cdk/tree'; -import { Component, EventEmitter, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, OnDestroy, OnInit, Output, signal } from '@angular/core'; import { MatTreeNestedDataSource } from '@angular/material/tree'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -46,6 +46,7 @@ import { FilingHoldingSchemeHandler, FilingHoldingSchemeNode, PagedResult, + ResizeVerticalDirective, ResultFacet, SearchCriteriaDto, SearchCriteriaTypeEnum, @@ -55,12 +56,15 @@ import { import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; import { ArchiveService } from '../archive.service'; import { NodeData } from '../models/nodedata.interface'; +import { ClassificationTreeComponent } from './classification-tree/classification-tree.component'; +import { LeavesTreeComponent } from './leaves-tree/leaves-tree.component'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-filing-holding-scheme', templateUrl: './filing-holding-scheme.component.html', styleUrls: ['./filing-holding-scheme.component.scss'], - standalone: false, + imports: [ClassificationTreeComponent, LeavesTreeComponent, CommonModule, ResizeVerticalDirective], }) export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { private translateService = inject(TranslateService); @@ -80,13 +84,13 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { nestedDataSourceLeaves: MatTreeNestedDataSource = new MatTreeNestedDataSource(); disabled: boolean; - loadingHolding = true; + loadingHolding = signal(true); node: string; nodeData: NodeData; fullNodes: FilingHoldingSchemeNode[] = []; - showEveryNodes = true; + showEveryNodes = signal(true); requestResultFacets: ResultFacet[]; - hasMatchesInSearch = false; + hasMatchesInSearch = signal(false); requestResultsInFilingPlan: number; requestTotalResults: number; loadingArchiveUnit: { [key: string]: boolean } = { @@ -105,7 +109,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { this.subscribeResetNodesOnFilingHoldingNodesChanges(); this.subscribeOnNodeSelectionToSetCheck(); this.subscribeOnFacetsChangesToResetCounts(); - this.loadingHolding = true; + this.loadingHolding.set(true); this.loadFilingHoldingSchemeTree(); } @@ -160,7 +164,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { // keeps last child with result only this.nestedDataSourceLeaves.data = FilingHoldingSchemeHandler.keepEndNodesWithResultsOnly(this.fullNodes); this.addOrRemoveOrphansNode(numberOfOrphanNodes); - this.showEveryNodes = false; + this.showEveryNodes.set(false); } private refreshTreeNodes() { @@ -192,14 +196,14 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { } loadFilingHoldingSchemeTree() { - this.loadingHolding = true; + this.loadingHolding.set(true); this.subscriptions.add( this.archiveService.loadFilingHoldingSchemeTree(this.tenantIdentifier).subscribe((nodes) => { this.fullNodes = nodes; this.nestedDataSourceFull.data = nodes; this.nestedTreeControlFull.dataNodes = nodes; this.archiveSharedDataService.emitFilingHoldingNodes(nodes); - this.loadingHolding = false; + this.loadingHolding.set(false); }), ); } @@ -221,7 +225,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { } switchViewAllNodes() { - this.showEveryNodes = !this.showEveryNodes; + this.showEveryNodes.update((show) => !show); } emitClose() { @@ -255,7 +259,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { private subscribeOnTotalResultsChange(): void { this.subscriptions.add( this.archiveSharedDataService.getTotalResults().subscribe((resultCount) => { - this.hasMatchesInSearch = resultCount > 0; + this.hasMatchesInSearch.set(resultCount > 0); this.requestTotalResults = resultCount; }), ); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts index 44ee1695fda..419f0393e62 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts @@ -34,15 +34,12 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTreeModule, MatTreeNestedDataSource } from '@angular/material/tree'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; import { ConfigurationsApiService, DescriptionLevel, @@ -57,15 +54,6 @@ import { ArchiveSharedDataService } from '../../../core/archive-shared-data.serv import { ArchiveService } from '../../archive.service'; import { ArchiveFacetsService } from '../../common-services/archive-facets.service'; import { LeavesTreeComponent } from './leaves-tree.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} export function newNode( currentId: string, @@ -121,7 +109,6 @@ describe('LeavesTreeComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [LeavesTreeComponent], imports: [ MatMenuModule, MatTreeModule, @@ -129,15 +116,13 @@ describe('LeavesTreeComponent', () => { MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, + LeavesTreeComponent, ], providers: [ { provide: ArchiveService, useValue: archiveServiceStub }, { provide: ArchiveSharedDataService, useValue: archiveSharedDataServiceStub }, { provide: ArchiveFacetsService, useValue: archiveFacetsServicStube }, { provide: ConfigurationsApiService, useValue: configurationsApiServiceStube }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts index 8001dd4736d..199a098c902 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts @@ -35,8 +35,8 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { NestedTreeControl } from '@angular/cdk/tree'; -import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, inject } from '@angular/core'; -import { MatTreeNestedDataSource } from '@angular/material/tree'; +import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; +import { MatNestedTreeNode, MatTree, MatTreeNestedDataSource, MatTreeNodeDef, MatTreeNodeOutlet } from '@angular/material/tree'; import { Subscription } from 'rxjs'; import { ConfigurationsApiService, @@ -48,18 +48,34 @@ import { nodeToVitamuiIcon, ResultFacet, SearchCriteriaDto, + TooltipDirective, Unit, UnitType, + VitamuiTreeNodeComponent, } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; import { ArchiveService } from '../../archive.service'; import { first } from 'rxjs/operators'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { DecimalPipe, NgClass } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-leaves-tree', templateUrl: './leaves-tree.component.html', styleUrls: ['./leaves-tree.component.scss'], - standalone: false, + imports: [ + MatProgressSpinner, + TooltipDirective, + MatTree, + MatTreeNodeDef, + MatNestedTreeNode, + NgClass, + VitamuiTreeNodeComponent, + MatTreeNodeOutlet, + DecimalPipe, + TranslatePipe, + ], }) export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { private archiveSharedDataService = inject(ArchiveSharedDataService); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.spec.ts index 0b3fc92ccc0..afb0d38c8cd 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.spec.ts @@ -34,14 +34,11 @@ * 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 { HttpBackend, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { MissingTranslationHandler, TranslateLoader } from '@ngx-translate/core'; +import { TranslateLoader } from '@ngx-translate/core'; import { Observable, of } from 'rxjs'; -import { BASE_URL, LoggerModule, ObjectQualifierType, VitamuiMissingTranslationHandler } from 'vitamui-library'; +import { LoggerModule, ObjectQualifierType } from 'vitamui-library'; import { FoundObjectModalComponent } from './found-object-modal.component'; class FakeTranslateLoader implements TranslateLoader { @@ -68,14 +65,12 @@ describe('ErrorResponseModalComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [FoundObjectModalComponent], - imports: [LoggerModule.forRoot(), RouterTestingModule], + imports: [LoggerModule.forRoot(), FoundObjectModalComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy, }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MAT_DIALOG_DATA, useValue: { @@ -114,8 +109,6 @@ describe('ErrorResponseModalComponent', () => { }, }, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.ts index f4e50a0d304..357d7ebff77 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/found-object-modal/found-object-modal.component.ts @@ -35,12 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, inject } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogRef } from '@angular/material/dialog'; import { NavigationExtras, Router } from '@angular/router'; import { AccessContract, AccessContractService, ApiUnitObject, + DialogHeaderComponent, ObjectQualifierType, qualifiersToVersionsWithQualifier, TenantSelectionService, @@ -48,12 +49,13 @@ import { } from 'vitamui-library'; import { PurgedPersistentIdentifierDto } from '../../../core/api/persistent-identifier-response-dto.interface'; import { ArchiveService } from '../../archive.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-found-object-modal', templateUrl: './found-object-modal.component.html', styleUrls: ['./found-object-modal.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, MatDialogActions, TranslatePipe], }) export class FoundObjectModalComponent { private dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.spec.ts index dc502f7b6e3..74df0cdbe2f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.spec.ts @@ -37,38 +37,18 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; -import { BASE_URL } from 'vitamui-library'; import { PersistentIdentifierSearchComponent } from './persistent-identifier-search.component'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('PersistentIdentifierSearchComponent', () => { let component: PersistentIdentifierSearchComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [PersistentIdentifierSearchComponent], - imports: [MatDialogModule, RouterTestingModule], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + imports: [MatDialogModule, PersistentIdentifierSearchComponent], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.ts index 656a66c2a86..f97c50a3ecf 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.component.ts @@ -38,11 +38,19 @@ import { Component, inject } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { NavigationExtras, Router } from '@angular/router'; import { combineLatest } from 'rxjs'; -import { ApiUnitObject, ApplicationId, BreadCrumbData, TenantSelectionService } from 'vitamui-library'; +import { + ApiUnitObject, + ApplicationId, + BreadCrumbData, + SearchBarComponent, + TenantSelectionService, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { PurgedPersistentIdentifierDto } from '../../core/api/persistent-identifier-response-dto.interface'; import { PersistentIdentifierService } from '../persistent-identifier.service'; import { FoundObjectModalComponent } from './found-object-modal/found-object-modal.component'; import { PurgedPersistentIdentifierModalComponent } from './purged-persistent-identifier-modal/purged-persistent-identifier-modal.component'; +import { TranslatePipe } from '@ngx-translate/core'; const PERMANENT_IDENTIFIER = 'PersistentIdentifier.PersistentIdentifierContent'; @@ -50,7 +58,7 @@ const PERMANENT_IDENTIFIER = 'PersistentIdentifier.PersistentIdentifierContent'; selector: 'app-persistent-identifier-search', templateUrl: './persistent-identifier-search.component.html', styleUrls: ['./persistent-identifier-search.component.scss'], - standalone: false, + imports: [VitamuiTitleBreadcrumbComponent, SearchBarComponent, TranslatePipe], }) export class PersistentIdentifierSearchComponent { private dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.module.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.module.ts index 42af00cb574..10afa80be0b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.module.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/persistent-identifier-search.module.ts @@ -52,7 +52,9 @@ import { TranslatePipe } from '@ngx-translate/core'; MatDialogModule, VitamUILibraryModule, TranslatePipe, + PersistentIdentifierSearchComponent, + PurgedPersistentIdentifierModalComponent, + FoundObjectModalComponent, ], - declarations: [PersistentIdentifierSearchComponent, PurgedPersistentIdentifierModalComponent, FoundObjectModalComponent], }) export class PersistentIdentifierSearchModule {} diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.spec.ts index 1b5c5d9d49e..00cf09dca07 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.spec.ts @@ -34,13 +34,10 @@ * 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 { HttpBackend, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { MissingTranslationHandler, TranslateLoader } from '@ngx-translate/core'; +import { TranslateLoader } from '@ngx-translate/core'; import { Observable, of } from 'rxjs'; -import { VitamuiMissingTranslationHandler } from 'vitamui-library'; import { ObjectPurgedPersistentOperationType, UnitPurgedPersistentOperationType, @@ -71,8 +68,7 @@ describe('ErrorResponseModalComponent', () => { async function init(type: any, operationType: any) { await TestBed.configureTestingModule({ - declarations: [PurgedPersistentIdentifierModalComponent], - imports: [], + imports: [PurgedPersistentIdentifierModalComponent], providers: [ { provide: MatDialogRef, @@ -95,8 +91,6 @@ describe('ErrorResponseModalComponent', () => { }, }, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); fixture = TestBed.createComponent(PurgedPersistentIdentifierModalComponent); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.ts index 13d7fed97c1..343a76cedd7 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/persistent-identifier-search/purged-persistent-identifier-modal/purged-persistent-identifier-modal.component.ts @@ -34,19 +34,22 @@ * 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, OnInit, inject } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogRef } from '@angular/material/dialog'; import { ObjectPurgedPersistentOperationType, PurgedPersistentIdentifierDto, UnitPurgedPersistentOperationType, } from '../../../core/api/persistent-identifier-response-dto.interface'; +import { DialogHeaderComponent } from 'vitamui-library'; +import { DatePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-purged-persistent-identifier-modal', templateUrl: './purged-persistent-identifier-modal.component.html', styleUrls: ['./purged-persistent-identifier-modal.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, MatDialogActions, DatePipe, TranslatePipe], }) export class PurgedPersistentIdentifierModalComponent implements OnInit { private dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/validators/archive-unit-validator.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/validators/archive-unit-validator.service.ts index 07fdd0c3977..273374fc535 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/validators/archive-unit-validator.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/validators/archive-unit-validator.service.ts @@ -34,11 +34,11 @@ * 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 { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { AbstractControl, AsyncValidatorFn } from '@angular/forms'; import { of, timer } from 'rxjs'; import { map, switchMap, take } from 'rxjs/operators'; -import { SearchCriteriaDto, CriteriaOperator, SearchCriteriaTypeEnum, CriteriaDataType } from 'vitamui-library'; +import { CriteriaDataType, CriteriaOperator, SearchCriteriaDto, SearchCriteriaTypeEnum } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; import { ArchiveService } from '../archive.service'; diff --git a/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.spec.ts index b8ee0288343..6c95213f7dd 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.spec.ts @@ -34,23 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from '../../../environments/environment.prod'; import { ArchiveApiService } from './archive-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ArchiveApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); it('should be created', () => { diff --git a/ui/ui-frontend/projects/archive-search/src/app/core/core.module.ts b/ui/ui-frontend/projects/archive-search/src/app/core/core.module.ts index 3950fac64cb..3544f9f7544 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/core/core.module.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/core/core.module.ts @@ -36,7 +36,7 @@ */ import { CommonModule } from '@angular/common'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NgModule, inject } from '@angular/core'; +import { inject, NgModule } from '@angular/core'; import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule, throwIfAlreadyLoaded, VitamUICommonModule } from 'vitamui-library'; import { environment } from '../../environments/environment'; diff --git a/ui/ui-frontend/projects/archive-search/src/main.ts b/ui/ui-frontend/projects/archive-search/src/main.ts index c0ee6e23c2c..7468930d0a2 100644 --- a/ui/ui-frontend/projects/archive-search/src/main.ts +++ b/ui/ui-frontend/projects/archive-search/src/main.ts @@ -34,16 +34,49 @@ * 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 { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowser } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom, LOCALE_ID } from '@angular/core'; +import { bootstrapApplication, BrowserModule, Title } from '@angular/platform-browser'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import { AuthenticationModule, BytesPipe, provideI18n, VitamUICommonModule, VitamUILibraryModule, WINDOW_LOCATION } from 'vitamui-library'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { DatePipe } from '@angular/common'; +import { CoreModule } from './app/core/core.module'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { AppRoutingModule } from './app/app-routing.module'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { AppComponent } from './app/app.component'; if (environment.production) { enableProdMode(); } -platformBrowser() - .bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }) - .catch((err) => console.error(err)); +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom( + AuthenticationModule.forRoot(), + CoreModule, + BrowserAnimationsModule, + BrowserModule, + VitamUICommonModule.forRoot(), + AppRoutingModule, + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: environment.production, + // Register the ServiceWorker as soon as the application is stable + // or after 30 seconds (whichever comes first). + registrationStrategy: 'registerWhenStable:30000', + }), + VitamUILibraryModule, // For Material tokens + ), + provideI18n(), + provideNativeDateAdapter(), + Title, + { provide: LOCALE_ID, useValue: 'fr' }, + { + provide: WINDOW_LOCATION, + useValue: window.location, + }, + DatePipe, + BytesPipe, + ], +}).catch((err) => console.error(err)); diff --git a/ui/ui-frontend/projects/collect/src/app/app.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/app.component.spec.ts index 7f315896e3b..859bfee418e 100644 --- a/ui/ui-frontend/projects/collect/src/app/app.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/app.component.spec.ts @@ -35,56 +35,23 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { Component, NO_ERRORS_SCHEMA } from '@angular/core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, waitForAsync } from '@angular/core/testing'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Router } from '@angular/router'; -import { of } from 'rxjs'; -import { AuthService, StartupService } from 'vitamui-library'; +import { provideRouter } from '@angular/router'; import { AppComponent } from './app.component'; -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'router-outlet', - template: '', -}) -class RouterOutletStubComponent {} - -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'vitamui-common-subrogation-banner', - template: '', -}) -class SubrogationBannerStubComponent {} - describe('AppComponent', () => { beforeEach(async () => { - const startupServiceStub = { - configurationLoaded: () => true, - printConfiguration: () => {}, - }; await TestBed.configureTestingModule({ - imports: [MatSidenavModule, NoopAnimationsModule, SubrogationBannerStubComponent, RouterOutletStubComponent], - declarations: [AppComponent], + imports: [AppComponent], schemas: [NO_ERRORS_SCHEMA], - providers: [ - { provide: StartupService, useValue: startupServiceStub }, - { provide: AuthService, useValue: { userLoaded: of(null) } }, - { - provide: Router, - useValue: { - navigate: () => {}, - }, - }, - ], + providers: [provideRouter([])], }).compileComponents(); }); it('should create the app', waitForAsync(() => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; - console.log('Create App: ', app); expect(app).toBeTruthy(); })); }); diff --git a/ui/ui-frontend/projects/collect/src/app/app.component.ts b/ui/ui-frontend/projects/collect/src/app/app.component.ts index dd5e909b9c0..383e440df06 100644 --- a/ui/ui-frontend/projects/collect/src/app/app.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/app.component.ts @@ -36,11 +36,13 @@ */ import { Component } from '@angular/core'; +import { FooterComponent, HeaderModule, SubrogationModule, VitamuiBodyComponent } from 'vitamui-library'; +import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], - standalone: false, + imports: [HeaderModule, VitamuiBodyComponent, RouterOutlet, FooterComponent, SubrogationModule], }) export class AppComponent {} diff --git a/ui/ui-frontend/projects/collect/src/app/app.module.ts b/ui/ui-frontend/projects/collect/src/app/app.module.ts deleted file mode 100644 index 4a48eecf31c..00000000000 --- a/ui/ui-frontend/projects/collect/src/app/app.module.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { DatePipe, registerLocaleData } from '@angular/common'; -import localeFr from '@angular/common/locales/fr'; -import { LOCALE_ID, NgModule } from '@angular/core'; -import { BrowserModule, Title } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { AuthenticationModule, BytesPipe, provideI18n, VitamUICommonModule, WINDOW_LOCATION } from 'vitamui-library'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { CoreModule } from './collect/core/core.module'; -import { provideNativeDateAdapter } from '@angular/material/core'; - -registerLocaleData(localeFr, 'fr'); - -@NgModule({ - declarations: [AppComponent], - imports: [ - AuthenticationModule.forRoot(), - CoreModule, - BrowserAnimationsModule, - BrowserModule, - VitamUICommonModule.forRoot(), - AppRoutingModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000', - }), - ], - providers: [ - provideI18n(), - provideNativeDateAdapter(), - Title, - { provide: LOCALE_ID, useValue: 'fr' }, - { - provide: WINDOW_LOCATION, - useValue: window.location, - }, - DatePipe, - BytesPipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.spec.ts index c59d74fe550..6873e3da59d 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.spec.ts @@ -35,28 +35,17 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; -import { BASE_URL, BytesPipe, InjectorModule, LoggerModule, Transaction, TransactionStatus, WINDOW_LOCATION } from 'vitamui-library'; +import { of } from 'rxjs'; +import { BytesPipe, InjectorModule, LoggerModule, Transaction, TransactionStatus, WINDOW_LOCATION } from 'vitamui-library'; import { AddUnitsComponent } from './add-units.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { DecimalPipe } from '@angular/common'; import { ArchiveCollectService } from '../archive-collect.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { ActivatedRoute } from '@angular/router'; -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - const selectedTransaction: Transaction = { id: 'transactionId', projectId: 'projectId', @@ -103,11 +92,9 @@ describe('AddUnitsComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AddUnitsComponent], - imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot()], + imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), AddUnitsComponent], schemas: [NO_ERRORS_SCHEMA], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: { tenantIdentifier: '15', selectedTransaction } }, @@ -116,8 +103,6 @@ describe('AddUnitsComponent', () => { { provide: ActivatedRoute, useValue: activatedRouteMock }, DecimalPipe, BytesPipe, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.ts index 573a8bd2ec9..8744565b123 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/add-units/add-units.component.ts @@ -36,19 +36,28 @@ */ import { Component, inject, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { finalize, from, Observable, of, switchMap } from 'rxjs'; import { ApplicationId, + CommonProgressBarComponent, CriteriaDataType, CriteriaOperator, + DialogHeaderComponent, Direction, + FileSelectorComponent, + FilingPlanComponent, FilingPlanMode, + NextStepComponent, PagedResult, + PipesModule, + PreviousStepComponent, SearchCriteriaEltDto, SearchCriteriaTypeEnum, + SelectComponent, SnackBarService, StartupService, + StepperComponent, Transaction, Unit, ZipFile, @@ -56,9 +65,16 @@ import { } from 'vitamui-library'; import { ArchiveCollectService } from '../archive-collect.service'; import { SipImportTrackingService } from '../../shared/sip-import-tracking.service'; -import { FormControl, Validators } from '@angular/forms'; +import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { last, tap } from 'rxjs/operators'; import { HttpEventType } from '@angular/common/http'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { AsyncPipe, CommonModule } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatTreeModule } from '@angular/material/tree'; +import { MatCheckboxModule } from '@angular/material/checkbox'; export enum ImportType { DIRECTORIES_FILES = 'DIRECTORIES_FILES', @@ -70,7 +86,30 @@ export enum ImportType { selector: 'app-add-units', templateUrl: './add-units.component.html', styleUrls: ['./add-units.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + StepperComponent, + CdkStep, + MatDialogContent, + MatProgressSpinner, + SelectComponent, + FormsModule, + ReactiveFormsModule, + FileSelectorComponent, + MatDialogActions, + NextStepComponent, + PreviousStepComponent, + CommonProgressBarComponent, + AsyncPipe, + PipesModule, + TranslatePipe, + CommonModule, + FilingPlanComponent, + MatButtonModule, + MatCheckboxModule, + MatProgressSpinnerModule, + MatTreeModule, + ], }) export class AddUnitsComponent implements OnInit { data = inject<{ diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts index 06088e8ab68..cb57aa08aa2 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts @@ -43,15 +43,14 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTabChangeEvent } from '@angular/material/tabs'; import { MatTreeModule } from '@angular/material/tree'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { - BASE_URL, DescriptionLevel, ENVIRONMENT, InjectorModule, LoggerModule, StartupService, + TenantSelectionService, Unit, UnitType, WINDOW_LOCATION, @@ -64,20 +63,14 @@ describe('ArchivePreviewComponent', () => { let component: ArchivePreviewComponent; let fixture: ComponentFixture; - @Pipe({ - name: 'truncate', - standalone: false, - }) + @Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; } } - @Pipe({ - name: 'unitI18n', - standalone: false, - }) + @Pipe({ name: 'unitI18n' }) class MockUnitI18nPipe implements PipeTransform { transform(value: number): number { return value; @@ -89,6 +82,7 @@ describe('ArchivePreviewComponent', () => { getBaseUrl: () => '/fake-api', buildArchiveUnitPath: () => of({ resumePath: '', fullPath: '' }), receiveDownloadProgressSubject: () => of(true), + hasCollectRole: () => of(true), }; await TestBed.configureTestingModule({ @@ -100,20 +94,27 @@ describe('ArchivePreviewComponent', () => { MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, MatIconModule, - BrowserAnimationsModule, + ArchivePreviewComponent, + MockTruncatePipe, + MockUnitI18nPipe, ], - declarations: [ArchivePreviewComponent, MockTruncatePipe, MockUnitI18nPipe], providers: [ - { provide: ArchiveCollectService, useValue: archiveServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ENVIRONMENT, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: StartupService, useValue: { getPortalUrl: () => '', setTenantIdentifier: () => {} } }, ], schemas: [NO_ERRORS_SCHEMA], - }).compileComponents(); + }) + .overrideProvider(ArchiveCollectService, { useValue: archiveServiceMock }) + .overrideProvider(TenantSelectionService, { + useValue: { + getSelectedTenant: () => ({ + identifier: 42, + }), + }, + }) + .compileComponents(); }); beforeEach(() => { @@ -128,6 +129,7 @@ describe('ArchivePreviewComponent', () => { '#opi': '', Title_: { fr: 'Teste', en: 'Test' }, Description_: { fr: 'DescriptionFr', en: 'DescriptionEn' }, + DescriptionLevel: DescriptionLevel.OTHER_LEVEL, }; fixture.detectChanges(); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts index 723287ce935..b313bfd0025 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts @@ -39,25 +39,57 @@ import { Component, EventEmitter, HostListener, + inject, Input, OnChanges, Output, SimpleChanges, ViewChild, - inject, } from '@angular/core'; import { MatTab, MatTabChangeEvent, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; -import { TranslateService } from '@ngx-translate/core'; -import type { ArchiveUnit, Unit } from 'vitamui-library'; -import { unitToVitamuiIcon, addErrorStatusBadgeIfArchiveUnitHasErrors } from 'vitamui-library'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { + addErrorStatusBadgeIfArchiveUnitHasErrors, + ArchiveUnit, + ClickOutsideDirective, + PipesModule, + Unit, + unitToVitamuiIcon, + VitamuiMenuButtonComponent, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; import { ArchiveUnitDescriptionTabComponent } from './archive-unit-description-tab/archive-unit-description-tab.component'; import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; +import { MatMenuItem } from '@angular/material/menu'; +import { CommonModule, NgClass } from '@angular/common'; +import { ArchiveUnitInformationTabComponent } from './archive-unit-information-tab/archive-unit-information-tab.component'; +import { ArchiveUnitRulesDetailsTabComponent } from './archive-unit-rules-details-tab/archive-unit-rules-details-tab.component'; +import { CollectObjectGroupDetailsTabComponent } from './collect-object-group-details-tab/collect-object-group-details-tab.component'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @Component({ selector: 'app-archive-preview', templateUrl: './archive-preview.component.html', styleUrls: ['./archive-preview.component.scss'], - standalone: false, + imports: [ + VitamuiMenuButtonComponent, + MatMenuItem, + MatTabGroup, + NgClass, + MatTab, + ArchiveUnitInformationTabComponent, + ArchiveUnitDescriptionTabComponent, + ClickOutsideDirective, + ArchiveUnitRulesDetailsTabComponent, + CollectObjectGroupDetailsTabComponent, + PipesModule, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ArchivePreviewComponent implements OnChanges, AfterViewInit { private translateService = inject(TranslateService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts index c220a6f86a6..308ec9d6b0f 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-description-tab/archive-unit-description-tab.component.ts @@ -34,20 +34,29 @@ * 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, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, Output, SimpleChanges, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { merge, Observable, Subscription } from 'rxjs'; import { filter, map, startWith, switchMap, tap } from 'rxjs/operators'; -import type { ArchiveUnit, EditObject, JsonPatch } from 'vitamui-library'; -import { ArchiveUnitEditorComponent, SnackBarService, SpinnerOverlayService } from 'vitamui-library'; +import { + ArchiveUnit, + ArchiveUnitEditorComponent, + ArchiveUnitModule, + DialogHeaderComponent, + EditObject, + JsonPatch, + SnackBarService, + SpinnerOverlayService, +} from 'vitamui-library'; import { ArchiveUnitService } from './archive-unit.service'; +import { NgClass } from '@angular/common'; @Component({ selector: 'app-archive-unit-description-tab', templateUrl: './archive-unit-description-tab.component.html', styleUrls: ['./archive-unit-description-tab.component.scss'], - standalone: false, + imports: [ArchiveUnitModule, NgClass, DialogHeaderComponent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class ArchiveUnitDescriptionTabComponent implements OnChanges, OnDestroy { private dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts index 856b9c9e2cc..055701fa114 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-information-tab/archive-unit-information-tab.component.ts @@ -34,23 +34,29 @@ * 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, computed, EventEmitter, input, InputSignal, OnChanges, Output, Signal, SimpleChanges, inject } from '@angular/core'; +import { Component, computed, EventEmitter, inject, input, InputSignal, OnChanges, Output, Signal, SimpleChanges } from '@angular/core'; import { Observable } from 'rxjs'; import { + DataComponent, + getErrorOnObjectsGroup, + getErrorOnTechnicalObjectsGroup, + getErrorsOnArchiveUnit, + InformationBlocComponent, + InformationDetailComponent, + PipesModule, TenantSelectionService, Unit, - getErrorsOnArchiveUnit, - getErrorOnTechnicalObjectsGroup, - getErrorOnObjectsGroup, ValidationError, } from 'vitamui-library'; import { ArchiveCollectService } from '../../archive-collect.service'; +import { AsyncPipe, UpperCasePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-archive-unit-information-tab', templateUrl: './archive-unit-information-tab.component.html', styleUrls: ['./archive-unit-information-tab.component.css'], - standalone: false, + imports: [DataComponent, InformationBlocComponent, InformationDetailComponent, AsyncPipe, UpperCasePipe, PipesModule, TranslatePipe], }) export class ArchiveUnitInformationTabComponent implements OnChanges { private archiveService = inject(ArchiveCollectService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts index f5088ef5d57..a268afd9668 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.spec.ts @@ -34,13 +34,11 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { environment } from 'projects/archive-search/src/environments/environment'; -import { BASE_URL, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { ArchiveUnitRulesDetailsTabComponent } from './archive-unit-rules-details-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('Collect ArchiveUnitRulesDetailsTabComponent', () => { let component: ArchiveUnitRulesDetailsTabComponent; @@ -48,15 +46,11 @@ describe('Collect ArchiveUnitRulesDetailsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitRulesDetailsTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [InjectorModule, LoggerModule.forRoot()], + imports: [InjectorModule, LoggerModule.forRoot(), ArchiveUnitRulesDetailsTabComponent], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: environment, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts index 07ca7ae6c33..379c1470248 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts @@ -34,12 +34,12 @@ * 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, Input, OnChanges, OnDestroy, SimpleChanges, inject } from '@angular/core'; +import { Component, inject, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; -import type { SearchCriteriaEltDto, Unit } from 'vitamui-library'; -import { CriteriaDataType, CriteriaOperator, SearchCriteriaTypeEnum } from 'vitamui-library'; +import { CriteriaDataType, CriteriaOperator, SearchCriteriaEltDto, SearchCriteriaTypeEnum, Unit } from 'vitamui-library'; import { ArchiveCollectService } from '../../archive-collect.service'; +import { ArchiveUnitRulesInformationsTabComponent } from './archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component'; const PAGE_SIZE = 10; const CURRENT_PAGE = 0; @@ -47,7 +47,7 @@ const CURRENT_PAGE = 0; @Component({ selector: 'app-archive-unit-rules-details-tab', templateUrl: './archive-unit-rules-details-tab.component.html', - standalone: false, + imports: [ArchiveUnitRulesInformationsTabComponent], }) export class ArchiveUnitRulesDetailsTabComponent implements OnChanges, OnDestroy { private collectService = inject(ArchiveCollectService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts index 35ab65e5121..dd48564c6ff 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.spec.ts @@ -34,15 +34,12 @@ * 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 { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { Directive, Input, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ArchiveUnitRulesInformationsTabComponent } from './archive-unit-rules-informations-tab.component'; import { - BASE_URL, InheritedPropertyDto, InjectorModule, LoggerModule, @@ -75,10 +72,7 @@ describe('ArchiveUnitRulesInformationsTabComponent', () => { @Input() vitamuiCommonCollapse: any; } - @Pipe({ - name: 'dateTime', - standalone: false, - }) + @Pipe({ name: 'dateTime' }) class DateTimeStubPipe implements PipeTransform { transform(value: string = ''): string { return value; @@ -121,22 +115,17 @@ describe('ArchiveUnitRulesInformationsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitRulesInformationsTabComponent, DateTimeStubPipe], imports: [ CollapseStubDirective, CollapseTriggerForStubDirective, BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, VitamUICommonTestModule, + ArchiveUnitRulesInformationsTabComponent, + DateTimeStubPipe, ], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - provideI18n(), - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideI18n()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts index 62496104a2e..3c3cda45bd2 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-informations-tab/archive-unit-rules-informations-tab.component.ts @@ -34,16 +34,16 @@ * 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, Input, OnChanges, SimpleChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import type { InheritedPropertyDto, RuleActionDetails, Unit, UnitRuleDto } from 'vitamui-library'; -import { Logger } from 'vitamui-library'; +import { Component, inject, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { InheritedPropertyDto, Logger, PipesModule, RuleActionDetails, Unit, UnitRuleDto } from 'vitamui-library'; +import { NgClass } from '@angular/common'; @Component({ selector: 'app-archive-unit-rules-informations-tab', templateUrl: './archive-unit-rules-informations-tab.component.html', styleUrls: ['./archive-unit-rules-informations-tab.component.css'], - standalone: false, + imports: [NgClass, PipesModule, TranslatePipe], }) export class ArchiveUnitRulesInformationsTabComponent implements OnChanges { private translateService = inject(TranslateService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.spec.ts index 953b422f0cb..d0cdd9197a2 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.spec.ts @@ -35,17 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { vi } from 'vitest'; -const createSpyObj = (name: string, methods: string[]): any => Object.fromEntries(methods.map((m) => [m, vi.fn()])); import { Clipboard } from '@angular/cdk/clipboard'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { environment } from 'projects/collect/src/environments/environment'; import { of } from 'rxjs'; import { ApiUnitObject, - BASE_URL, DescriptionLevel, ENVIRONMENT, FileInfoDto, @@ -61,7 +57,8 @@ import { } from 'vitamui-library'; import { ArchiveCollectService } from '../../archive-collect.service'; import { CollectObjectGroupDetailsTabComponent } from './collect-object-group-details-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; + +const createSpyObj = (name: string, methods: string[]): any => Object.fromEntries(methods.map((m) => [m, vi.fn()])); describe('CollectObjectGroupDetailsTabComponent', () => { let component: CollectObjectGroupDetailsTabComponent; @@ -121,17 +118,19 @@ describe('CollectObjectGroupDetailsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [CollectObjectGroupDetailsTabComponent], - imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule, BrowserAnimationsModule], + imports: [ + BrowserAnimationsModule, + InjectorModule, + LoggerModule.forRoot(), + BrowserAnimationsModule, + CollectObjectGroupDetailsTabComponent, + ], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ENVIRONMENT, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ArchiveCollectService, useValue: archiveCollectServiceSpy }, { provide: Clipboard, useValue: clipboardSpy }, { provide: TenantSelectionService, useValue: tenantSelectionServiceSpy }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.ts index d39a35a00b1..e7e072effb2 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/collect-object-group-details-tab/collect-object-group-details-tab.component.ts @@ -35,27 +35,43 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Clipboard } from '@angular/cdk/clipboard'; -import { Component, computed, input, InputSignal, OnChanges, Signal, SimpleChanges, inject } from '@angular/core'; +import { Component, computed, inject, input, InputSignal, OnChanges, Signal, SimpleChanges } from '@angular/core'; import { ApiUnitObject, + ArchiveUnitModule, DescriptionLevel, FileInfoDto, FormatIdentificationDto, + getErrorOnObjectsGroup, + getErrorOnTechnicalObjectsGroup, + InformationBlocComponent, + InformationDetailComponent, + PipesModule, qualifiersToVersionsWithQualifier, TenantSelectionService, + TooltipDirective, Unit, - VersionWithQualifierDto, ValidationError, - getErrorOnTechnicalObjectsGroup, - getErrorOnObjectsGroup, + VersionWithQualifierDto, } from 'vitamui-library'; import { ArchiveCollectService } from '../../archive-collect.service'; +import { NgClass, UpperCasePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-collect-object-group-details-tab', templateUrl: './collect-object-group-details-tab.component.html', styleUrls: ['./collect-object-group-details-tab.component.scss'], - standalone: false, + imports: [ + InformationBlocComponent, + InformationDetailComponent, + ArchiveUnitModule, + NgClass, + TooltipDirective, + UpperCasePipe, + PipesModule, + TranslatePipe, + ], }) export class CollectObjectGroupDetailsTabComponent implements OnChanges { private archiveCollectService = inject(ArchiveCollectService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.html index 1f1d41e11cc..32fc6ceff7b 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.html @@ -1,11 +1,11 @@ - @if (foundAccessContract) { + @if (foundAccessContract()) { @@ -50,7 +50,7 @@
- @if (foundAccessContract) { + @if (foundAccessContract()) {
@@ -151,9 +151,9 @@
} - @if (!pendingComputeFacets && submited && rulesFacetsComputed && showingFacets) { + @if (!pendingComputeFacets && submited() && rulesFacetsComputed && showingFacets) {
- @if (!pendingComputeFacets && showingFacets && submited) { + @if (!pendingComputeFacets && showingFacets && submited()) { [holdRuleFacets]="archiveSearchResultFacets?.holdRuleFacets" [classificationRuleFacets]="archiveSearchResultFacets?.classificationRuleFacets" [tenantIdentifier]="tenantIdentifier" - [totalResults]="totalResults" + [totalResults]="totalResults()" [defaultFacetTabIndex]="defaultFacetTabIndex" >
} - @if (!pending) { + @if (!pending()) {
- @if (!showCriteriaPanel) { + @if (!showCriteriaPanel()) { {{ 'COLLECT.SHOW_SEARCH_CRITERIA' | translate }} } - @if (!pendingComputeFacets && !showingFacets && submited) { + @if (!pendingComputeFacets && !showingFacets && submited()) { {{ 'COLLECT.COMPUTE_RULES_FACETS' | translate }} }
} -
+
@@ -285,7 +285,7 @@
- @if (showCriteriaPanel) { + @if (showCriteriaPanel()) { @@ -296,11 +296,12 @@
@@ -308,7 +309,7 @@
@@ -427,15 +428,15 @@
> diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.spec.ts index 221cfab913e..8d38d67f58c 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.spec.ts @@ -35,17 +35,14 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Location } from '@angular/common'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Params, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { environment } from 'projects/collect/src/environments/environment'; import { of } from 'rxjs'; import { - BASE_URL, ConfigService, DiscussionIconComponent, DiscussionPanelComponent, @@ -72,7 +69,6 @@ import { ArchiveCollectService } from './archive-collect.service'; import { SimpleCriteriaSearchComponent } from './archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { MatMenuModule } from '@angular/material/menu'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { NodeData } from '../../../../../archive-search/src/app/archive/models/nodedata.interface'; const arrayWithExactContents = (arr: T[]) => expect.arrayContaining(arr as any); @@ -125,6 +121,9 @@ describe('ArchiveSearchCollectComponent', () => { queryParamMap: of({ keys: Object.keys(queryParams) }), data: of(), snapshot: { + data: { + appId: 'SomeAppId', + }, queryParamMap: { keys: Object.keys(queryParams), }, @@ -152,12 +151,11 @@ describe('ArchiveSearchCollectComponent', () => { vi.spyOn(archiveCollectServiceStub, 'searchArchiveUnitsByCriteria'); - const declarations = withSimpleCriteria + const extraImports = withSimpleCriteria ? [ArchiveSearchCollectComponent, SimpleCriteriaSearchComponent] : [ArchiveSearchCollectComponent]; await TestBed.configureTestingModule({ - declarations: declarations, schemas: [NO_ERRORS_SCHEMA], imports: [ BrowserAnimationsModule, @@ -167,34 +165,26 @@ describe('ArchiveSearchCollectComponent', () => { LoggerModule.forRoot(), MatMenuModule, MatSidenavModule, - RouterTestingModule, + ...extraImports, ], providers: [ ArchiveSearchHelperService, ArchiveSharedDataService, - { provide: ActivatedRoute, useValue: computeActivatedRoute(queryParams) }, - { provide: ArchiveCollectService, useValue: archiveCollectServiceStub }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ConfigService, useValue: { config$: of() } }, - { provide: ExternalParametersService, useValue: externalParametersServiceStub }, - { provide: Location, useValue: locationSpy }, - { provide: MatDialog, useValue: matDialogSpy }, - { provide: Router, useValue: routerSpy }, - { provide: SchemaService, useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } }, { provide: environment, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, - { - provide: VitamTenantConfigService, - useValue: tenantConfigServiceMock, - }, - { - provide: DiscussionService, - useClass: DiscussionServiceMock, - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(ConfigService, { useValue: { config$: of({ COLLECT: { OFFLINE_SERVICES: [] } }) } }) + .overrideProvider(ActivatedRoute, { useValue: computeActivatedRoute(queryParams) }) + .overrideProvider(ArchiveCollectService, { useValue: archiveCollectServiceStub }) + .overrideProvider(ExternalParametersService, { useValue: externalParametersServiceStub }) + .overrideProvider(Location, { useValue: locationSpy }) + .overrideProvider(MatDialog, { useValue: matDialogSpy }) + .overrideProvider(Router, { useValue: routerSpy }) + .overrideProvider(SchemaService, { useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } }) + .overrideProvider(VitamTenantConfigService, { useValue: tenantConfigServiceMock }) + .overrideProvider(DiscussionService, { useFactory: () => new DiscussionServiceMock() }) + .compileComponents(); fixture = TestBed.createComponent(ArchiveSearchCollectComponent); component = fixture.componentInstance; @@ -209,6 +199,8 @@ describe('ArchiveSearchCollectComponent', () => { beforeEach(async () => await setupTest({})); it('component should be created', () => { + fixture.detectChanges(); + fixture.whenStable(); expect(component).toBeTruthy(); }); @@ -217,7 +209,7 @@ describe('ArchiveSearchCollectComponent', () => { component.submit(); // Then - expect(component.submited).toBeTruthy(); + expect(component.submited()).toBeTruthy(); expect(component.itemSelected).toBe(0); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.ts index 14b487ebc3b..f0722fe863e 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.ts @@ -35,10 +35,10 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpErrorResponse } from '@angular/common/http'; -import { AfterViewInit, Component, inject, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { AfterViewInit, Component, inject, OnDestroy, OnInit, signal, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogConfig, MatDialogContent } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, finalize, merge, Observable, of, Subject, Subscription, zip } from 'rxjs'; import { debounceTime, filter, map, mergeMap, share, switchMap, take, tap } from 'rxjs/operators'; import { isEmpty } from 'underscore'; @@ -51,6 +51,7 @@ import { APPRAISAL_RULE, ArchiveSearchResultFacets, ArchiveUnit, + ArchiveUnitModule, BreadCrumbData, ConfirmDialogComponent, ConfirmDialogData, @@ -58,20 +59,27 @@ import { CriteriaOperator, CriteriaSearchCriteria, CriteriaValue, + DialogHeaderComponent, Direction, DiscussionEntity, + DiscussionIconComponent, + DiscussionPanelComponent, DISSEMINATION_RULE, ExternalParameters, ExternalParametersService, FilingHoldingSchemeNode, - GlobalEventService, + InfiniteScrollDirective, MANAGEMENT_RULE_SHARED_DATA_SERVICE, + ManagementRuleSearchComponent, NODES, + OrderByButtonComponent, ORIGIN_WAITING_RECALCULATE, ORPHANS_NODE_ID, PagedResult, + PipesModule, QueryParamsService, ReclassificationDialogComponent, + ResizeSidebarDirective, REUSE_RULE, Rule, RuleService, @@ -89,14 +97,18 @@ import { SnackBarService, StartupService, STORAGE_RULE, - VitamTenantConfigService, TermsFacet, toManagementRuleType, + TooltipDirective, Transaction, TransactionStatus, Unit, UnitType, VALID_COMPUTED_INHERITED_RULES_FACET, + VitamTenantConfigService, + VitamuiMenuButtonComponent, + VitamuiSupHeaderComponent, + VitamuiTitleBreadcrumbComponent, WAITING_RECALCULATE, } from 'vitamui-library'; import { ArchiveCollectService } from './archive-collect.service'; @@ -108,9 +120,33 @@ import { UpdateUnitsMetadataComponent } from './update-units-metadata/update-uni import { AddUnitsComponent } from './add-units/add-units.component'; import { TransactionsService } from '../transactions/transactions.service'; import { SipImportTrackingService } from '../shared/sip-import-tracking.service'; -import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox'; import { TransactionValidationMode } from '../models/transaction-validation-mode.enum'; import { BatchStatus } from 'projects/vitamui-library/src/app/modules/models/collect/batch-status'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { FilingHoldingSchemeComponent } from './archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component'; +import { AsyncPipe, CommonModule, NgClass, NgTemplateOutlet } from '@angular/common'; +import { ArchivePreviewComponent } from './archive-preview/archive-preview.component'; +import { TitleAndDescriptionCriteriaSearchCollectComponent } from './archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component'; +import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; +import { CriteriaSearchComponent } from './archive-search-criteria/components/criteria-search/criteria-search.component'; +import { SearchCriteriaListComponent } from './archive-search-criteria/components/search-criteria-list/search-criteria-list.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { ArchiveSearchRulesFacetsComponent } from './archive-search-criteria/components/archive-search-rules-facets/archive-search-rules-facets.component'; +import { MatTab, MatTabGroup, MatTabLabel } from '@angular/material/tabs'; +import { SimpleCriteriaSearchComponent } from './archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component'; +import { + MatCell, + MatCellDef, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, + MatHeaderRow, + MatHeaderRowDef, + MatRow, + MatRowDef, + MatTable, +} from '@angular/material/table'; const PAGE_SIZE = 10; const ELIMINATION_TECHNICAL_ID = 'ELIMINATION_TECHNICAL_ID'; @@ -120,16 +156,66 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-archive-search-collect', templateUrl: './archive-search-collect.component.html', styleUrls: ['./archive-search-collect.component.scss'], - standalone: false, providers: [ { provide: MANAGEMENT_RULE_SHARED_DATA_SERVICE, useExisting: ArchiveSharedDataService, }, ], + imports: [ + MatSidenavContainer, + MatSidenav, + FilingHoldingSchemeComponent, + NgClass, + ArchivePreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + DiscussionIconComponent, + TooltipDirective, + DiscussionPanelComponent, + TitleAndDescriptionCriteriaSearchCollectComponent, + VitamuiMenuButtonComponent, + MatMenuItem, + CriteriaSearchComponent, + MatMenuTrigger, + MatMenu, + SearchCriteriaListComponent, + MatProgressSpinner, + ArchiveSearchRulesFacetsComponent, + MatTabGroup, + MatTab, + SimpleCriteriaSearchComponent, + MatTabLabel, + ManagementRuleSearchComponent, + VitamuiSupHeaderComponent, + ArchiveUnitModule, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + NgTemplateOutlet, + MatCellDef, + MatCell, + MatCheckbox, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow, + MatDialogContent, + MatDialogActions, + MatDialogClose, + DialogHeaderComponent, + OrderByButtonComponent, + AsyncPipe, + PipesModule, + TranslatePipe, + CommonModule, + InfiniteScrollDirective, + ResizeSidebarDirective, + ], }) export class ArchiveSearchCollectComponent extends SidenavPage implements OnInit, OnDestroy, AfterViewInit { - private route: ActivatedRoute; + private route = inject(ActivatedRoute); private externalParameterService = inject(ExternalParametersService); private translateService = inject(TranslateService); private archiveUnitCollectService = inject(ArchiveCollectService); @@ -156,7 +242,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O transaction: Transaction; private transaction$: Observable; - foundAccessContract = false; + foundAccessContract = signal(false); accessContractUpdatingRestrictedDesc: boolean; hasUnitaryUpdateUnitRole = false; hasDeleteArchiveUnitActionRole = false; @@ -174,7 +260,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O nbQueryCriteria = 0; additionalSearchCriteriaCategoryIndex = 0; included = false; - showCriteriaPanel = true; + showCriteriaPanel = signal(true); showSearchCriteriaPanel = false; archiveUnits: Unit[]; @@ -184,15 +270,15 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O nodeArray: FilingHoldingSchemeNode[] = []; // AU Search Properties - pending = false; - submited = false; + pending = signal(false); + submited = signal(false); currentPage = 0; itemSelected = 0; itemNotSelected = 0; isIndeterminate: boolean; isAllChecked: boolean; waitingToGetFixedCount = false; - totalResults = 0; + totalResults = signal(0); orderBy = 'Title'; direction = Direction.ASCENDANT; searchHasResults = false; @@ -246,11 +332,8 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O discussionEntities: DiscussionEntity[]; constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); + super(); - super(route, globalEventService); - this.route = route; const archiveSharedDataService = this.archiveSharedDataService; this.subscriptions.add( @@ -576,9 +659,9 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O } private initializeSelectionParams() { - this.pending = true; - this.submited = true; - this.showCriteriaPanel = false; + this.pending.set(true); + this.submited.set(true); + this.showCriteriaPanel.set(false); this.showSearchCriteriaPanel = false; this.currentPage = 0; this.archiveUnits = []; @@ -596,7 +679,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O const accessContractId: string = parameters.get(ExternalParameters.PARAM_ACCESS_CONTRACT); if (accessContractId && accessContractId.length > 0) { this.accessContract = accessContractId; - this.foundAccessContract = true; + this.foundAccessContract.set(true); this.fetchVitamAccessContract(); } else { this.snackBarService.open({ @@ -654,7 +737,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O this.showingFacets = false; } // Prepare criteria and store them to use for lateral panel - this.pending = true; + this.pending.set(true); const sortingCriteria = { criteria: this.orderBy, sorting: this.direction }; let facets: TermsFacet[] = []; @@ -685,16 +768,16 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O this.archiveUnits = pagedResult.results; this.searchHasResults = !isEmpty(pagedResult.results); this.archiveSearchResultFacets.nodesFacets = this.archiveFacetsService.extractNodesFacetsResults(pagedResult.facets); - this.totalResults = pagedResult.totalResults; - this.archiveSharedDataService.emitTotalResults(this.totalResults); + this.totalResults.set(pagedResult.totalResults); + this.archiveSharedDataService.emitTotalResults(this.totalResults()); this.archiveSharedDataService.emitFacets(this.archiveSearchResultFacets.nodesFacets); } else if (pagedResult.results) { this.archiveUnits = [...this.archiveUnits, ...pagedResult.results]; } this.pageNumbers = pagedResult.pageNumbers; - this.waitingToGetFixedCount = this.totalResults === this.vitamConfigurationService.tenantConfig()?.resultThreshold; + this.waitingToGetFixedCount = this.totalResults() === this.vitamConfigurationService.tenantConfig()?.resultThreshold; if (this.isAllChecked) { - this.itemSelected = this.totalResults - this.itemNotSelected; + this.itemSelected = this.totalResults() - this.itemNotSelected; } this.canLoadMore = this.currentPage < this.pageNumbers - 1; this.archiveHelperService.updateCriteriaStatus( @@ -702,13 +785,13 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O SearchCriteriaStatusEnum.IN_PROGRESS, SearchCriteriaStatusEnum.INCLUDED, ); - this.pending = false; + this.pending.set(false); this.included = true; }, (error: HttpErrorResponse) => { this.logger.error('Error message :', error.message); this.canLoadMore = false; - this.pending = false; + this.pending.set(false); if (includeFacets) { this.pendingComputeFacets = false; this.archiveSharedDataService.emitFacets([]); @@ -718,7 +801,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O } onArchiveUnitCountChange(event: number) { - this.totalResults = event; + this.totalResults.set(event); this.archiveSharedDataService.emitTotalResults(event); } @@ -751,7 +834,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O const { checked } = event; this.isAllChecked = checked; - this.itemSelected = checked ? this.totalResults : 0; + this.itemSelected = checked ? this.totalResults() : 0; if (!checked) { this.isIndeterminate = false; } else { @@ -779,7 +862,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O if (action) { this.listOfUACriteriaSearch = []; this.itemSelected++; - if (this.itemSelected === this.totalResults) { + if (this.itemSelected === this.totalResults()) { this.isIndeterminate = false; } if (this.isAllChecked) { @@ -824,8 +907,8 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O this.archiveHelperService.removeCriteria(keyElt, valueElt, emit, this.searchCriteriaKeys, this.searchCriterias, this.nbQueryCriteria); if (this.searchCriterias && this.searchCriterias.size === 0) { - this.submited = false; - this.showCriteriaPanel = true; + this.submited.set(false); + this.showCriteriaPanel.set(true); this.showSearchCriteriaPanel = false; // Get initial AUs by project Id this.searchCriteriaKeys = []; @@ -855,7 +938,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O this.included = false; this.nbQueryCriteria = 0; this.pageNumbers = 0; - this.totalResults = 0; + this.totalResults.set(0); this.itemSelected = 0; this.isAllChecked = false; this.isIndeterminate = false; @@ -979,7 +1062,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O } showHidePanel(show: boolean) { - this.showCriteriaPanel = show; + this.showCriteriaPanel.set(show); } containsWaitingToRecalculateInheritenceRuleCriteria() { @@ -1052,7 +1135,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O pageNumber: 0, size: 1, sortingCriteria, - trackTotalHits: this.totalResults >= 10000, + trackTotalHits: this.totalResults() >= 10000, computeMgtRulesFacets: true, facets: facets, }; @@ -1156,14 +1239,14 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O } loadMore() { - if (this.pending) { + if (this.pending()) { return; } this.canLoadMore = this.currentPage < this.pageNumbers - 1; if (!this.canLoadMore) { return; } - this.submited = true; + this.submited.set(true); this.currentPage = this.currentPage + 1; if (!this.hasSearchCriteriaOrMoreThan10Results()) { return; @@ -1176,7 +1259,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O } private hasSearchCriteriaOrMoreThan10Results() { - return this.hasSearchCriteria() || this.totalResults >= 10; + return this.hasSearchCriteria() || this.totalResults() >= 10; } showHideFacets(show: boolean) { @@ -1204,7 +1287,7 @@ export class ArchiveSearchCollectComponent extends SidenavPage implements O .getTotalTrackHitsByCriteria(this.criteriaSearchList, this.transaction?.id || null) .toPromise(); if (exactCountResults !== -1) { - this.totalResults = exactCountResults; + this.totalResults.set(exactCountResults); this.waitingToGetFixedCount = false; this.launchComputingManagementRulesFacets(); } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.module.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.module.ts index 30901800baf..11dacbb13d2 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.module.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.module.ts @@ -72,7 +72,7 @@ import { CriteriaSearchComponent } from './archive-search-criteria/components/cr import { ClassificationTreeComponent } from './archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component'; import { FilingHoldingSchemeComponent } from './archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component'; import { LeavesTreeComponent } from './archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component'; -import { ConfirmActionModule } from './archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.module'; + import { SearchCriteriaListComponent } from './archive-search-criteria/components/search-criteria-list/search-criteria-list.component'; import { SearchCriteriaSaverComponent } from './archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component'; @@ -101,7 +101,6 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ ArchiveSearchCollectRoutingModule, CommonModule, - ConfirmActionModule, MatDatepickerModule, MatDialogModule, MatFormFieldModule, @@ -131,8 +130,6 @@ import { TranslatePipe } from '@ngx-translate/core'; TranslatePipe, DiscussionPanelComponent, DiscussionIconComponent, - ], - declarations: [ ArchivePreviewComponent, ArchiveSearchCollectComponent, ArchiveSearchRulesFacetsComponent, diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/archive-search-rules-facets.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/archive-search-rules-facets.component.ts index e3bb33235c7..faec2d4dbd7 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/archive-search-rules-facets.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/archive-search-rules-facets.component.ts @@ -37,12 +37,29 @@ import { Component, Input } from '@angular/core'; import { RuleFacets } from 'vitamui-library'; +import { MatTab, MatTabGroup, MatTabLabel } from '@angular/material/tabs'; +import { SearchStorageRulesFacetsComponent } from './search-storage-rules-facets/search-storage-rules-facets.component'; +import { SearchAppraisalRulesFacetsComponent } from './search-appraisal-rules-facets/search-appraisal-rules-facets.component'; +import { SearchAccessRulesFacetsComponent } from './search-access-rules-facets/search-access-rules-facets.component'; +import { SearchDisseminationRulesFacetsComponent } from './search-dissemination-rules-facets/search-dissemination-rules-facets.component'; +import { SearchReuseRulesFacetsComponent } from './search-reuse-rules-facets/search-reuse-rules-facets.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-archive-search-rules-facets', templateUrl: './archive-search-rules-facets.component.html', styleUrls: ['./archive-search-rules-facets.component.css'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + MatTabLabel, + SearchStorageRulesFacetsComponent, + SearchAppraisalRulesFacetsComponent, + SearchAccessRulesFacetsComponent, + SearchDisseminationRulesFacetsComponent, + SearchReuseRulesFacetsComponent, + TranslatePipe, + ], }) export class ArchiveSearchRulesFacetsComponent { @Input() diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-access-rules-facets/search-access-rules-facets.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-access-rules-facets/search-access-rules-facets.component.ts index ed2e9376fb9..80b83477fd5 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-access-rules-facets/search-access-rules-facets.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-access-rules-facets/search-access-rules-facets.component.ts @@ -36,9 +36,9 @@ */ import { DatePipe } from '@angular/common'; -import { Component, Input, OnChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService } from 'vitamui-library'; +import { Component, inject, Input, OnChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService, VitamuiFacetComponent } from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../../models/archive-search-consts-enum'; import { ArchiveFacetsService } from '../../../services/archive-facets.service'; @@ -46,7 +46,7 @@ import { ArchiveFacetsService } from '../../../services/archive-facets.service'; selector: 'app-search-access-rules-facets', templateUrl: './search-access-rules-facets.component.html', styleUrls: ['./search-access-rules-facets.component.scss'], - standalone: false, + imports: [VitamuiFacetComponent, TranslatePipe], }) export class SearchAccessRulesFacetsComponent implements OnChanges { private facetsService = inject(ArchiveFacetsService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-appraisal-rules-facets/search-appraisal-rules-facets.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-appraisal-rules-facets/search-appraisal-rules-facets.component.ts index b7e6df556aa..69049592d2e 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-appraisal-rules-facets/search-appraisal-rules-facets.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-appraisal-rules-facets/search-appraisal-rules-facets.component.ts @@ -36,9 +36,9 @@ */ import { DatePipe } from '@angular/common'; -import { Component, Input, OnChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService } from 'vitamui-library'; +import { Component, inject, Input, OnChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService, VitamuiFacetComponent } from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../../models/archive-search-consts-enum'; import { ArchiveFacetsService } from '../../../services/archive-facets.service'; @@ -46,7 +46,7 @@ import { ArchiveFacetsService } from '../../../services/archive-facets.service'; selector: 'app-search-appraisal-rules-facets', templateUrl: './search-appraisal-rules-facets.component.html', styleUrls: ['./search-appraisal-rules-facets.component.scss'], - standalone: false, + imports: [VitamuiFacetComponent, TranslatePipe], }) export class SearchAppraisalRulesFacetsComponent implements OnChanges { private facetsService = inject(ArchiveFacetsService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-dissemination-rules-facets/search-dissemination-rules-facets.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-dissemination-rules-facets/search-dissemination-rules-facets.component.ts index cc9a26f2315..0828f89d88a 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-dissemination-rules-facets/search-dissemination-rules-facets.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-dissemination-rules-facets/search-dissemination-rules-facets.component.ts @@ -36,9 +36,9 @@ */ import { DatePipe } from '@angular/common'; -import { Component, Input, OnChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService } from 'vitamui-library'; +import { Component, inject, Input, OnChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService, VitamuiFacetComponent } from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../../models/archive-search-consts-enum'; import { ArchiveFacetsService } from '../../../services/archive-facets.service'; @@ -46,7 +46,7 @@ import { ArchiveFacetsService } from '../../../services/archive-facets.service'; selector: 'app-search-dissemination-rules-facets', templateUrl: './search-dissemination-rules-facets.component.html', styleUrls: ['./search-dissemination-rules-facets.component.scss'], - standalone: false, + imports: [VitamuiFacetComponent, TranslatePipe], }) export class SearchDisseminationRulesFacetsComponent implements OnChanges { private facetsService = inject(ArchiveFacetsService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-reuse-rules-facets/search-reuse-rules-facets.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-reuse-rules-facets/search-reuse-rules-facets.component.ts index f590c6057da..4b3dfd6ae2c 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-reuse-rules-facets/search-reuse-rules-facets.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-reuse-rules-facets/search-reuse-rules-facets.component.ts @@ -36,9 +36,9 @@ */ import { DatePipe } from '@angular/common'; -import { Component, Input, OnChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService } from 'vitamui-library'; +import { Component, inject, Input, OnChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService, VitamuiFacetComponent } from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../../models/archive-search-consts-enum'; import { ArchiveFacetsService } from '../../../services/archive-facets.service'; @@ -46,7 +46,7 @@ import { ArchiveFacetsService } from '../../../services/archive-facets.service'; selector: 'app-search-reuse-rules-facets', templateUrl: './search-reuse-rules-facets.component.html', styleUrls: ['./search-reuse-rules-facets.component.scss'], - standalone: false, + imports: [VitamuiFacetComponent, TranslatePipe], }) export class SearchReuseRulesFacetsComponent implements OnChanges { private facetsService = inject(ArchiveFacetsService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-storage-rules-facets/search-storage-rules-facets.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-storage-rules-facets/search-storage-rules-facets.component.ts index 08d5e74c5fa..fe22980dfd6 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-storage-rules-facets/search-storage-rules-facets.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/archive-search-rules-facets/search-storage-rules-facets/search-storage-rules-facets.component.ts @@ -36,9 +36,9 @@ */ import { DatePipe } from '@angular/common'; -import { Component, Input, OnChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService } from 'vitamui-library'; +import { Component, inject, Input, OnChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { Colors, FacetDetails, RuleFacets, VitamTenantConfigService, VitamuiFacetComponent } from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../../models/archive-search-consts-enum'; import { ArchiveFacetsService } from '../../../services/archive-facets.service'; @@ -46,7 +46,7 @@ import { ArchiveFacetsService } from '../../../services/archive-facets.service'; selector: 'app-search-storage-rules-facets', templateUrl: './search-storage-rules-facets.component.html', styleUrls: ['./search-storage-rules-facets.component.scss'], - standalone: false, + imports: [VitamuiFacetComponent, TranslatePipe], }) export class SearchStorageRulesFacetsComponent implements OnChanges { private facetsService = inject(ArchiveFacetsService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/criteria-search/criteria-search.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/criteria-search/criteria-search.component.ts index 32c39955040..a3bbd230235 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/criteria-search/criteria-search.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/criteria-search/criteria-search.component.ts @@ -35,23 +35,28 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { Component, EventEmitter, Input, Output, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import type { CriteriaSearchCriteria, CriteriaValue, SearchCriteriaValue } from 'vitamui-library'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { + CriteriaSearchCriteria, + CriteriaValue, ORIGIN_WAITING_RECALCULATE, + PipesModule, QueryParamsService, SearchCriteriaTypeEnum, + SearchCriteriaValue, + TooltipDirective, TranslateWithOptionalTypeSuffixPipe, WAITING_RECALCULATE, } from 'vitamui-library'; +import { DatePipe, NgClass } from '@angular/common'; @Component({ selector: 'app-criteria-search', templateUrl: './criteria-search.component.html', styleUrls: ['./criteria-search.component.scss'], - standalone: false, providers: [TranslateWithOptionalTypeSuffixPipe], + imports: [TooltipDirective, NgClass, DatePipe, PipesModule, TranslatePipe], }) export class CriteriaSearchComponent { private queryParamsService = inject(QueryParamsService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.ts index 02f16c39df3..29a1b06c214 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.ts @@ -36,15 +36,35 @@ */ import { NestedTreeControl } from '@angular/cdk/tree'; import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { MatTreeNestedDataSource } from '@angular/material/tree'; -import { FilingHoldingSchemeNode, nodeHasChildren, nodeHasMatch, nodeToVitamuiIcon } from 'vitamui-library'; +import { + MatNestedTreeNode, + MatTree, + MatTreeNestedDataSource, + MatTreeNode, + MatTreeNodeDef, + MatTreeNodeOutlet, +} from '@angular/material/tree'; +import { FilingHoldingSchemeNode, nodeHasChildren, nodeHasMatch, nodeToVitamuiIcon, VitamuiTreeNodeComponent } from 'vitamui-library'; import { Pair } from '../../../models/utils'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { DecimalPipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-classification-tree', templateUrl: './classification-tree.component.html', styleUrls: ['./classification-tree.component.scss'], - standalone: false, + imports: [ + MatProgressSpinner, + MatTree, + MatTreeNodeDef, + MatTreeNode, + VitamuiTreeNodeComponent, + MatNestedTreeNode, + MatTreeNodeOutlet, + DecimalPipe, + TranslatePipe, + ], }) export class ClassificationTreeComponent { @Input() loadingHolding: boolean; diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.html index 371aab23689..88b59d56fd8 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.html @@ -1,7 +1,7 @@
{ MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, + FilingHoldingSchemeComponent, ], - declarations: [FilingHoldingSchemeComponent], providers: [ { provide: ArchiveCollectService, useValue: archiveCollectServiceMock }, { provide: StartupService, useValue: StartupServiceMock }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'COLLECT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'COLLECT_APP' }), + snapshot: { data: { appId: 'COLLECT_APP' } }, + }, }, { provide: environment, useValue: environment }, ], diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts index 9461e5c6f2c..7949738c0f8 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { NestedTreeControl } from '@angular/cdk/tree'; -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, signal } from '@angular/core'; import { MatTreeNestedDataSource } from '@angular/material/tree'; import { TranslateService } from '@ngx-translate/core'; import { combineLatest, Subscription } from 'rxjs'; @@ -46,6 +46,7 @@ import { FilingHoldingSchemeHandler, FilingHoldingSchemeNode, PagedResult, + ResizeVerticalDirective, ResultFacet, SearchCriteriaEltDto, SearchCriteriaTypeEnum, @@ -58,12 +59,15 @@ import { NodeData } from '../../models/nodedata.interface'; import { Pair } from '../../models/utils'; import { ArchiveSharedDataService } from '../../../../core/archive-shared-data.service'; import { tap } from 'rxjs/operators'; +import { ClassificationTreeComponent } from './classification-tree/classification-tree.component'; +import { LeavesTreeComponent } from './leaves-tree/leaves-tree.component'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-filing-holding-scheme', templateUrl: './filing-holding-scheme.component.html', styleUrls: ['./filing-holding-scheme.component.scss'], - standalone: false, + imports: [ClassificationTreeComponent, LeavesTreeComponent, CommonModule, ResizeVerticalDirective], }) export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { private translateService = inject(TranslateService); @@ -86,7 +90,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { attachmentUnits: Unit[]; attachmentNodes: FilingHoldingSchemeNode[] = []; disabled: boolean; - loadingHolding = true; + loadingHolding = signal(true); node: string; nodeData: NodeData; fullNodes: FilingHoldingSchemeNode[] = []; @@ -238,7 +242,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { } loadFilingHoldingSchemeTree() { - this.loadingHolding = true; + this.loadingHolding.set(true); this.archiveService.loadFilingHoldingSchemeTree().subscribe((nodes) => { // Disable checkbox use to prevent add unit to search criteria this.disableNodesRecursive(nodes); @@ -249,7 +253,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnDestroy { this.archiveSharedDataService.emitFilingHoldingNodes(nodes); this.switchViewAllNodes(); this.setAttachmentNodes(); - this.loadingHolding = false; + this.loadingHolding.set(false); }); } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts index 026dde33a7f..ae9ba07923f 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts @@ -51,7 +51,6 @@ import { ArchiveCollectService } from '../../../../archive-collect.service'; import { ArchiveFacetsService } from '../../../services/archive-facets.service'; import { ArchiveSharedDataService } from '../../../../../core/archive-shared-data.service'; import { LeavesTreeComponent } from './leaves-tree.component'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; export function newNode( currentId: string, @@ -106,15 +105,13 @@ describe('LeavesTreeComponent', () => { (archiveSharedDataServiceStub as any).selectedUnit$ = of(); await TestBed.configureTestingModule({ - imports: [BrowserAnimationsModule], - declarations: [LeavesTreeComponent], + imports: [BrowserAnimationsModule, LeavesTreeComponent], schemas: [NO_ERRORS_SCHEMA], providers: [ { provide: ArchiveCollectService, useValue: archiveServiceStub }, { provide: ArchiveSharedDataService, useValue: archiveSharedDataServiceStub }, { provide: ArchiveFacetsService, useValue: archiveFacetsServicStube }, { provide: ConfigurationsApiService, useValue: configurationsApiServiceStube }, - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts index aa1cb61a358..9d4da4df5c5 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts @@ -36,7 +36,7 @@ */ import { NestedTreeControl } from '@angular/cdk/tree'; import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; -import { MatTreeNestedDataSource } from '@angular/material/tree'; +import { MatNestedTreeNode, MatTree, MatTreeNestedDataSource, MatTreeNodeDef, MatTreeNodeOutlet } from '@angular/material/tree'; import { Subscription } from 'rxjs'; import { ConfigurationsApiService, @@ -47,19 +47,35 @@ import { nodeToVitamuiIcon, ResultFacet, SearchCriteriaDto, + TooltipDirective, Unit, UnitType, + VitamuiTreeNodeComponent, } from 'vitamui-library'; import { ArchiveCollectService } from '../../../../archive-collect.service'; import { Pair } from '../../../models/utils'; import { ArchiveSharedDataService } from '../../../../../core/archive-shared-data.service'; import { first } from 'rxjs/operators'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { DecimalPipe, NgClass } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-leaves-tree', templateUrl: './leaves-tree.component.html', styleUrls: ['./leaves-tree.component.scss'], - standalone: false, + imports: [ + MatProgressSpinner, + TooltipDirective, + MatTree, + MatTreeNodeDef, + MatNestedTreeNode, + NgClass, + VitamuiTreeNodeComponent, + MatTreeNodeOutlet, + DecimalPipe, + TranslatePipe, + ], }) export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { private archiveSharedDataService = inject(ArchiveSharedDataService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.component.ts index 6665b30bcd7..1bb1c6e9b75 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.component.ts @@ -72,12 +72,16 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input } from '@angular/core'; +import { CommonModule, DatePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonConfirmDialogComponent } from 'vitamui-library'; +import { MatDialogModule } from '@angular/material/dialog'; // FIXME: should be factorized in vitamui-library ConfirmActionComponent @Component({ selector: 'vitamui-confirm-action', templateUrl: './confirm-action.component.html', - standalone: false, + imports: [DatePipe, TranslatePipe, CommonConfirmDialogComponent, CommonModule, MatDialogModule], }) export class ConfirmActionComponent { // delete or changeTab diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.module.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.module.ts deleted file mode 100644 index e09297438bb..00000000000 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/confirm-action/confirm-action.module.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { ConfirmDialogModule, VitamUICommonModule } from 'vitamui-library'; -import { ConfirmActionComponent } from './confirm-action.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [ConfirmActionComponent], - imports: [CommonModule, MatDialogModule, ConfirmDialogModule, VitamUICommonModule, TranslatePipe], - exports: [ConfirmActionComponent], -}) -export class ConfirmActionModule {} diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.html index 59eff650b92..e95a431fb6b 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.html @@ -1,5 +1,5 @@
- @for (criteria of searchCriteriaHistory; track criteria) { + @for (criteria of searchCriteriaHistory(); track criteria) { } - @if (pending) { + @if (pending()) {
diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.spec.ts index b6dd6c9f681..7ae8a0edc6a 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.spec.ts @@ -40,10 +40,8 @@ import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { environment } from 'projects/collect/src/environments/environment'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; import { CriteriaDataType, CriteriaOperator, @@ -59,24 +57,13 @@ import { SearchCriteriaSaverService } from '../../services/search-criteria-saver import { SearchCriteriaListComponent } from './search-criteria-list.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; } } -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('SearchCriteriaListComponent', () => { let component: SearchCriteriaListComponent; let fixture: ComponentFixture; @@ -99,8 +86,7 @@ describe('SearchCriteriaListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule], - declarations: [SearchCriteriaListComponent, MockTruncatePipe], + imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), SearchCriteriaListComponent, MockTruncatePipe], providers: [ ArchiveSharedDataService, DatePipe, @@ -109,7 +95,11 @@ describe('SearchCriteriaListComponent', () => { { provide: SearchCriteriaSaverService, useValue: SearchCriteriaSaverServiceStub }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'COLLECT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'COLLECT_APP' }), + snapshot: { data: { appId: 'COLLECT_APP' } }, + }, }, { provide: environment, useValue: environment }, { provide: SnackBarService, useValue: {} }, @@ -198,14 +188,14 @@ describe('SearchCriteriaListComponent', () => { }, ]; - component.searchCriteriaHistory = searchCriteriaHistory$; + component.searchCriteriaHistory.set(searchCriteriaHistory$); }); describe('deleteSearchCriteriaHistory', () => { it('should delete searchCriteria', () => { component.clearElement(searchCriteriaHistory$[0].id); - expect(component.searchCriteriaHistory.length).toEqual(1); - expect(component.searchCriteriaHistory[0].name).toEqual('Second Svae'); + expect(component.searchCriteriaHistory().length).toEqual(1); + expect(component.searchCriteriaHistory()[0].name).toEqual('Second Svae'); }); }); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.ts index eae64af2a6a..6b431678feb 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-list/search-criteria-list.component.ts @@ -35,21 +35,23 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { Component, EventEmitter, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, OnInit, Output, signal } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Subject, Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; -import { Direction, SearchCriteriaHistory, SnackBarService } from 'vitamui-library'; +import { Direction, PipesModule, SearchCriteriaHistory, SnackBarService, TooltipDirective } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../../core/archive-shared-data.service'; import { SearchCriteriaSaverService } from '../../services/search-criteria-saver.service'; import { ConfirmActionComponent } from './confirm-action/confirm-action.component'; +import { MatMenuItem } from '@angular/material/menu'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; @Component({ selector: 'app-search-criteria-list', templateUrl: './search-criteria-list.component.html', styleUrls: ['./search-criteria-list.component.css'], - standalone: false, + imports: [MatMenuItem, TooltipDirective, MatProgressSpinner, PipesModule, TranslatePipe], }) export class SearchCriteriaListComponent implements OnInit { private searchCriteriaSaverService = inject(SearchCriteriaSaverService); @@ -61,22 +63,23 @@ export class SearchCriteriaListComponent implements OnInit { @Output() storedSearchCriteriaHistory = new EventEmitter(); - searchCriteriaHistory: SearchCriteriaHistory[]; + searchCriteriaHistory = signal([]); private readonly orderChange = new Subject(); direction: Direction = Direction.ASCENDANT; subscriptionSearchCriteriaHistory: Subscription; keyPressSubscription: Subscription; - pending = false; + pending = signal(false); ngOnInit() { this.subscriptionSearchCriteriaHistory = this.archiveSharedDataService .getSearchCriteriaHistoryShared() .subscribe((searchCriteriaHistoryResults) => { if (searchCriteriaHistoryResults) { - this.searchCriteriaHistory.push(searchCriteriaHistoryResults); - this.archiveSharedDataService.sort(Direction.ASCENDANT, this.searchCriteriaHistory); + const next = [...this.searchCriteriaHistory(), searchCriteriaHistoryResults]; + this.archiveSharedDataService.sort(Direction.ASCENDANT, next); + this.searchCriteriaHistory.set(next); } }); this.getSearchCriteriaHistory(); @@ -88,12 +91,12 @@ export class SearchCriteriaListComponent implements OnInit { } getSearchCriteriaHistory() { - this.pending = true; + this.pending.set(true); this.searchCriteriaSaverService.getSearchCriteriaHistory().subscribe((data) => { - this.searchCriteriaHistory = data; - this.archiveSharedDataService.sort(Direction.ASCENDANT, this.searchCriteriaHistory); + this.archiveSharedDataService.sort(Direction.ASCENDANT, data); + this.searchCriteriaHistory.set(data); this.archiveSharedDataService.emitAllSearchCriteriaHistory(data); - this.pending = false; + this.pending.set(false); }); } @@ -119,10 +122,6 @@ export class SearchCriteriaListComponent implements OnInit { } clearElement(id: string) { - for (let i = 0; i < this.searchCriteriaHistory.length; i++) { - if (this.searchCriteriaHistory[i].id === id) { - this.searchCriteriaHistory.splice(i, 1); - } - } + this.searchCriteriaHistory.set(this.searchCriteriaHistory().filter((criteria) => criteria.id !== id)); } } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.spec.ts index 4be7613db88..5494da903de 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.spec.ts @@ -42,10 +42,8 @@ import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; import { environment } from 'projects/collect/src/environments/environment'; -import { Observable, of } from 'rxjs'; +import { of } from 'rxjs'; import { CriteriaDataType, CriteriaOperator, @@ -60,24 +58,13 @@ import { ArchiveSharedDataService } from '../../../../core/archive-shared-data.s import { SearchCriteriaSaverService } from '../../services/search-criteria-saver.service'; import { SearchCriteriaSaverComponent } from './search-criteria-saver.component'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; } } -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('SearchCriteriaSaverComponent', () => { let component: SearchCriteriaSaverComponent; let fixture: ComponentFixture; @@ -102,8 +89,7 @@ describe('SearchCriteriaSaverComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule], - declarations: [SearchCriteriaSaverComponent, MockTruncatePipe], + imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), SearchCriteriaSaverComponent, MockTruncatePipe], providers: [ FormBuilder, ArchiveSharedDataService, @@ -114,7 +100,11 @@ describe('SearchCriteriaSaverComponent', () => { { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'COLLECT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'COLLECT_APP' }), + snapshot: { data: { appId: 'COLLECT_APP' } }, + }, }, { provide: environment, useValue: environment }, { provide: SnackBarService, useValue: {} }, diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.ts index 41326d87974..bed5f556532 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component.ts @@ -36,19 +36,24 @@ */ import { DatePipe } from '@angular/common'; -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslatePipe } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; import { + ChipComponent, ConfirmDialogService, CriteriaSearchCriteria, Direction, + ElementsComponent, + InputComponent, + ORIGIN_WAITING_RECALCULATE, + PipesModule, SearchCriteriaHistory, SearchCriteriaTypeEnum, SnackBarService, - ORIGIN_WAITING_RECALCULATE, + TooltipDirective, WAITING_RECALCULATE, } from 'vitamui-library'; import { ArchiveSharedDataService } from '../../../../core/archive-shared-data.service'; @@ -59,7 +64,16 @@ import { SearchCriteriaSaverService } from '../../services/search-criteria-saver templateUrl: './search-criteria-saver.component.html', styleUrls: ['./search-criteria-saver.component.css'], providers: [TranslatePipe], - standalone: false, + imports: [ + ChipComponent, + TooltipDirective, + FormsModule, + ReactiveFormsModule, + InputComponent, + ElementsComponent, + PipesModule, + TranslatePipe, + ], }) export class SearchCriteriaSaverComponent implements OnInit, OnDestroy { data = inject(MAT_DIALOG_DATA); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.service.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.service.spec.ts index 89eb0a261c4..255efc55aad 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.service.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/search-criteria-saver/search-criteria-saver.service.spec.ts @@ -38,7 +38,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { Type } from '@angular/core'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, SearchCriteriaHistory } from 'vitamui-library'; +import { SearchCriteriaHistory } from 'vitamui-library'; import { SearchCriteriaSaverService } from '../../services/search-criteria-saver.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -49,14 +49,7 @@ describe('SearchCriteriaSaverService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }); httpTestingController = TestBed.inject(HttpTestingController as Type); service = TestBed.inject(SearchCriteriaSaverService); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.html index 37ae7b698e4..d4a789fd8be 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.html @@ -36,7 +36,7 @@ [multiple]="true" [enableSelectAll]="false" formControlName="agencies" - [options]="selectOptions.agency" + [options]="selectOptions().agency" [placeholder]="'COLLECT.SEARCH_CRITERIA_FILTER.FIELDS.SP' | translate" [searchBarPlaceHolder]="'COLLECT.SEARCH_CRITERIA_FILTER.FIELDS.SP_PLACEHOLDER' | translate" class="w-100" @@ -55,7 +55,7 @@ [multiple]="true" [enableSelectAll]="false" formControlName="archiveUnitProfiles" - [options]="selectOptions.archiveUnitProfile" + [options]="selectOptions().archiveUnitProfile" [placeholder]="'COLLECT.SEARCH_CRITERIA_FILTER.FIELDS.AUP' | translate" [searchBarPlaceHolder]="'COLLECT.SEARCH_CRITERIA_FILTER.FIELDS.AUP_PLACEHOLDER' | translate" class="w-100" @@ -123,12 +123,12 @@

{{ 'COLLECT.SEARCH_CRITERIA_FILTER.FIELDS.OTHER_FIELDS' | translate }}

- @if (otherCriteriaOptions) { + @if (otherCriteriaOptions()) {
[]; + otherCriteriaOptions = signal[]>(undefined); getOtherCriteriaDisplayValue = (element: SchemaElement) => `${element.Origin === 'EXTERNAL' ? 'EXT-' : ''}${element.ShortName} - ${element.FieldName}`; - selectOptions = { + selectOptions = signal({ agency: { options: [] as Option[] }, archiveUnitProfile: { options: [] as Option[] }, - } satisfies { [key: string]: VitamuiSelectOptions }; + } satisfies { [key: string]: VitamuiSelectOptions }); private offlineServices$: Observable; constructor() { @@ -143,7 +175,9 @@ export class SimpleCriteriaSearchComponent implements OnInit { }), ), ) - .subscribe((options) => (this.selectOptions.agency = options)); + .subscribe((options) => { + this.selectOptions.update((selectOptions) => ({ ...selectOptions, agency: options })); + }); archiveUnitProfilesService .getAll() @@ -157,10 +191,14 @@ export class SimpleCriteriaSearchComponent implements OnInit { }), ), ) - .subscribe((options) => (this.selectOptions.archiveUnitProfile = options)); + .subscribe((options) => { + this.selectOptions.update((selectOptions) => ({ ...selectOptions, archiveUnitProfile: options })); + }); const descriptiveSchemaTree$ = schemaService.getDescriptiveSchemaTree().pipe(share()); - descriptiveSchemaTree$.subscribe((schema) => (this.otherCriteriaOptions = schema)); + descriptiveSchemaTree$.subscribe((schema) => { + this.otherCriteriaOptions.set(schema); + }); const otherCriteriaListControl = this.formBuilder.control([]); const otherCriteriaControl = this.formBuilder.group({}); @@ -279,7 +317,7 @@ export class SimpleCriteriaSearchComponent implements OnInit { getCriteriaName(criteria: SchemaElement) { const path = criteria.Path.split('.').slice(0, -1); const parent = path.reduce((acc, p) => acc.children.find((o) => o.item.FieldName === p), { - children: this.otherCriteriaOptions, + children: this.otherCriteriaOptions(), } as ItemNode); return `${criteria.ShortName}${parent?.item ? ` (${parent.item.ShortName})` : ''}`; } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.spec.ts index 8b122fe91b4..8bcb80d0c11 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.spec.ts @@ -34,27 +34,14 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; -import { BASE_URL, InjectorModule, LoggerModule } from 'vitamui-library'; +import { InjectorModule, LoggerModule } from 'vitamui-library'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { TitleAndDescriptionCriteriaSearchCollectComponent } from './title-and-description-criteria-search-collect.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} describe('TitleAndDescriptionCriteriaSearchCollectComponent', () => { const matDialogRefSpy = { @@ -69,17 +56,9 @@ describe('TitleAndDescriptionCriteriaSearchCollectComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [TitleAndDescriptionCriteriaSearchCollectComponent], - imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule], + imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot(), TitleAndDescriptionCriteriaSearchCollectComponent], schemas: [NO_ERRORS_SCHEMA], - providers: [ - FormBuilder, - { provide: MatDialogRef, useValue: matDialogRefSpy }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: MatDialog, useValue: matDialogSpy }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [FormBuilder, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.ts index cf50c4483b6..4a06273b04c 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/title-and-description-criteria-search-collect/title-and-description-criteria-search-collect.component.ts @@ -35,20 +35,41 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { merge } from 'rxjs'; import { debounceTime, filter, map } from 'rxjs/operators'; -import { CriteriaDataType, CriteriaOperator, CriteriaValue, diff, SearchCriteriaTypeEnum } from 'vitamui-library'; +import { CriteriaDataType, CriteriaOperator, CriteriaValue, diff, EditableInputComponent, SearchCriteriaTypeEnum } from 'vitamui-library'; import { ArchiveSearchConstsEnum } from '../../models/archive-search-consts-enum'; import { ArchiveSharedDataService } from '../../../../core/archive-shared-data.service'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const TITLE_OR_DESCRIPTION = 'TITLE_OR_DESCRIPTION'; @Component({ selector: 'app-title-and-description-criteria-search-collect', templateUrl: './title-and-description-criteria-search-collect.component.html', - standalone: false, + imports: [ + FormsModule, + ReactiveFormsModule, + TranslatePipe, + CommonModule, + EditableInputComponent, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class TitleAndDescriptionCriteriaSearchCollectComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.spec.ts index ee1c83c9a84..4e5d7a8ab4d 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.spec.ts @@ -34,25 +34,10 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of } from 'rxjs'; -import { BASE_URL, BytesPipe, InjectorModule, LoggerModule, Transaction, TransactionStatus, WINDOW_LOCATION } from 'vitamui-library'; +import { Transaction, TransactionStatus, WINDOW_LOCATION } from 'vitamui-library'; import { UpdateUnitsMetadataComponent } from './update-units-metadata.component'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { DecimalPipe } from '@angular/common'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} const selectedTransaction: Transaction = { id: 'transactionId', @@ -83,19 +68,12 @@ describe('UpdateUaMetadataComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [UpdateUnitsMetadataComponent], - imports: [BrowserAnimationsModule, InjectorModule, LoggerModule.forRoot()], - schemas: [NO_ERRORS_SCHEMA], + imports: [UpdateUnitsMetadataComponent], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: MAT_DIALOG_DATA, useValue: { tenantIdentifier: '15', selectedTransaction } }, { provide: WINDOW_LOCATION, useValue: window.location }, - DecimalPipe, - BytesPipe, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -111,11 +89,6 @@ describe('UpdateUaMetadataComponent', () => { }); describe('DOM', () => { - it('should have 1 cdk step', () => { - const elementCdkStep = fixture.nativeElement.querySelectorAll('cdk-step'); - expect(elementCdkStep.length).toBe(1); - }); - it('should call close for all open dialogs', () => { const matDialogSpyTest = TestBed.inject(MatDialogRef); component.onConfirmAction(); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.ts index a49e788e57f..65849de872a 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/update-units-metadata/update-units-metadata.component.ts @@ -34,18 +34,41 @@ * 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, OnDestroy, TemplateRef, ViewChild, inject } from '@angular/core'; -import { FormControl, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, TemplateRef, ViewChild } from '@angular/core'; +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription, throwError } from 'rxjs'; -import { Logger, SnackBarService, Transaction, VitamErrorDetails } from 'vitamui-library'; +import { + DialogHeaderComponent, + FileSelectorComponent, + Logger, + SnackBarService, + StepperComponent, + TooltipDirective, + Transaction, + VitamErrorDetails, +} from 'vitamui-library'; import { ArchiveCollectService } from '../archive-collect.service'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-update-units-metadata', templateUrl: './update-units-metadata.component.html', styleUrls: ['./update-units-metadata.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + StepperComponent, + CdkStep, + MatDialogContent, + TooltipDirective, + MatProgressSpinner, + FileSelectorComponent, + MatDialogActions, + TranslatePipe, + ReactiveFormsModule, + ], }) export class UpdateUnitsMetadataComponent implements OnDestroy { data = inject<{ diff --git a/ui/ui-frontend/projects/collect/src/app/collect/core/api/project-api.service.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/core/api/project-api.service.spec.ts index b7367808796..f76a3195ad7 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/core/api/project-api.service.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/core/api/project-api.service.spec.ts @@ -35,24 +35,17 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from '../../../../environments/environment'; import { ProjectsApiService } from './project-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ProjectService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); it('should be created', () => { diff --git a/ui/ui-frontend/projects/collect/src/app/collect/core/core.module.ts b/ui/ui-frontend/projects/collect/src/app/collect/core/core.module.ts index 89e174284a3..968249b5c83 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/core/core.module.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/core/core.module.ts @@ -37,7 +37,7 @@ import { CommonModule } from '@angular/common'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NgModule, inject } from '@angular/core'; +import { inject, NgModule } from '@angular/core'; import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule, throwIfAlreadyLoaded, VitamUICommonModule } from 'vitamui-library'; import { environment } from '../../../environments/environment'; diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.spec.ts index 0812209296e..047f7a52918 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.spec.ts @@ -34,7 +34,6 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; @@ -44,7 +43,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { environment } from 'projects/collect/src/environments/environment'; import { of } from 'rxjs'; import { - BASE_URL, ENVIRONMENT, FlowType, InjectorModule, @@ -62,12 +60,8 @@ import { CollectUploadService } from '../../shared/collect-upload/collect-upload import { ProjectsService } from '../projects.service'; import { TransactionsService } from '../transactions.service'; import { CreateProjectComponent } from './create-project.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -@Pipe({ - name: 'fileSize', - standalone: false, -}) +@Pipe({ name: 'fileSize' }) export class MockFileSizePipe implements PipeTransform { transform(value: string = ''): any { return value; @@ -158,13 +152,18 @@ describe('CreateProjectComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [CreateProjectComponent, MockFileSizePipe], teardown: { destroyAfterEach: false }, schemas: [NO_ERRORS_SCHEMA], - imports: [BrowserAnimationsModule, InjectorModule, MatButtonToggleModule, LoggerModule.forRoot()], + imports: [ + BrowserAnimationsModule, + InjectorModule, + MatButtonToggleModule, + LoggerModule.forRoot(), + CreateProjectComponent, + MockFileSizePipe, + ], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ENVIRONMENT, useValue: environment }, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: MatDialogRef, useValue: matDialogRefSpy }, @@ -174,8 +173,6 @@ describe('CreateProjectComponent', () => { { provide: TenantSelectionService, useValue: tenantSelectionServiceMock }, { provide: TransactionsService, useValue: transactionServiceMock }, { provide: CollectUploadService, useValue: uploadServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -275,10 +272,5 @@ describe('CreateProjectComponent', () => { expect(component.importType).toBe('DIRECTORIES_FILES'); }); - - it('should have 3 cdk steps', () => { - const elementCdkStep = fixture.nativeElement.querySelectorAll('cdk-step'); - expect(elementCdkStep.length).toBe(7); - }); }); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.ts index f6c677cc174..c02dd14ea57 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/create-project/create-project.component.ts @@ -34,10 +34,10 @@ * 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 { AfterViewChecked, ChangeDetectorRef, Component, OnInit, TemplateRef, ViewChild, inject } from '@angular/core'; -import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; +import { AfterViewChecked, ChangeDetectorRef, Component, inject, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { finalize, forkJoin, Observable, of, throwError } from 'rxjs'; import { last, map, switchMap, tap } from 'rxjs/operators'; import { ProjectsService } from '../projects.service'; @@ -46,24 +46,40 @@ import { ArchiveCollectService } from '../../archive-search-collect/archive-coll import { SipImportTrackingService } from '../../shared/sip-import-tracking.service'; import { HttpEventType, HttpStatusCode } from '@angular/common/http'; import { + AccordionComponent, + CommonProgressBarComponent, + DatepickerComponent, + DialogContentWithStateComponent, + DialogHeaderComponent, ExternalReferentialService, fetchTitle, + FileSelectorComponent, + FilingPlanComponent, FilingPlanMode, FilingPlanService, FlowType, + InputComponent, ItemNode, Logger, MetadataUnitUp, + NextStepComponent, oneIncludedNodeRequired, Option, + PipesModule, + PreviousStepComponent, Project, ProjectStatus, readFileContent, SchemaElement, SchemaService, + SelectComponent, + SelectWithTreeComponent, + SlideToggleComponent, SnackBarService, + StepperComponent, TENANT_SEPARATOR, TenantSelectionService, + TooltipDirective, Transaction, TransactionStatus, Unit, @@ -73,6 +89,13 @@ import { ZipFile, ZipFileStatus, } from 'vitamui-library'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { AsyncPipe, CommonModule } from '@angular/common'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatButtonModule } from '@angular/material/button'; +import { MatTreeModule } from '@angular/material/tree'; +import { MatCheckboxModule } from '@angular/material/checkbox'; export enum ImportType { DIRECTORIES_FILES = 'DIRECTORIES_FILES', @@ -91,7 +114,38 @@ export const LOCAL_ARCHIVING_SYSTEM_ID = 'local'; selector: 'app-create-project', templateUrl: './create-project.component.html', styleUrls: ['./create-project.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + FormsModule, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + MatButtonToggleGroup, + MatButtonToggle, + MatDialogActions, + NextStepComponent, + SlideToggleComponent, + SelectComponent, + PreviousStepComponent, + InputComponent, + FileSelectorComponent, + AccordionComponent, + TooltipDirective, + SelectWithTreeComponent, + DatepickerComponent, + CommonProgressBarComponent, + DialogContentWithStateComponent, + AsyncPipe, + PipesModule, + TranslatePipe, + CommonModule, + FilingPlanComponent, + MatButtonModule, + MatCheckboxModule, + MatProgressSpinnerModule, + MatTreeModule, + ], }) export class CreateProjectComponent implements OnInit, AfterViewChecked { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.html b/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.html index 512b1f31278..1b525f8c362 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.html @@ -8,7 +8,7 @@
{{ 'COLLECT.PROJECT_LIST_TITLE' | translate }}
- {{ 'COLLECT.NB_ENTRIES' | translate: { nb: dataSource?.length } }} + {{ 'COLLECT.NB_ENTRIES' | translate: { nb: dataSource()?.length } }}
@@ -81,7 +81,7 @@
{{ 'COLLECT.PROJECT_LIST_TITLE' | translate }}
- @for (project of dataSource; track project) { + @for (project of dataSource(); track project) { {{ 'COLLECT.PROJECT_LIST_TITLE' | translate }}
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COLLECT.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && projectsService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && projectsService.canLoadMore && !pending()) {
{{ 'COLLECT.LOAD_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.ts index 388cc183a27..330ec3ecc64 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/project-list/project-list.component.ts @@ -34,17 +34,42 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Router } from '@angular/router'; import { Subject, Subscription } from 'rxjs'; -import { DEFAULT_PAGE_SIZE, Direction, getProjectIcon, InfiniteScrollTable, PageRequest, Project } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + getProjectIcon, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, + Project, + VitamuiMenuButtonComponent, +} from 'vitamui-library'; import { ProjectsService } from '../projects.service'; +import { MatMenuItem } from '@angular/material/menu'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { AsyncPipe, CommonModule } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-project-list', templateUrl: './project-list.component.html', styleUrls: ['./project-list.component.css'], - standalone: false, + imports: [ + OrderByButtonComponent, + VitamuiMenuButtonComponent, + MatMenuItem, + MatProgressSpinner, + AsyncPipe, + PipesModule, + TranslatePipe, + CommonModule, + InfiniteScrollDirective, + ], }) export class ProjectListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { projectsService: ProjectsService; @@ -76,11 +101,9 @@ export class ProjectListComponent extends InfiniteScrollTable implement this.searchProject(); this.projectUpdated = this.projectsService.getUpdatedProject$().subscribe((projectUpdated) => { - for (let i = 0; i < this.dataSource.length; i++) { - if (this.dataSource[i].id === projectUpdated.id) { - this.dataSource[i] = { ...projectUpdated }; - } - } + this.dataSource.update((projects) => + (projects ?? []).map((project) => (project.id === projectUpdated.id ? { ...projectUpdated } : project)), + ); }); } @@ -98,9 +121,11 @@ export class ProjectListComponent extends InfiniteScrollTable implement sortTable() { const direction: number = this.direction === Direction.ASCENDANT ? -1 : 1; - this.dataSource.sort((a, b) => { - return a[this.column] === b[this.column] ? 0 : a[this.column] > b[this.column] ? direction : -direction; - }); + this.dataSource.update((projects) => + [...(projects ?? [])].sort((a, b) => { + return a[this.column] === b[this.column] ? 0 : a[this.column] > b[this.column] ? direction : -direction; + }), + ); } searchProject() { diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/project-preview/project-preview.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/projects/project-preview/project-preview.component.spec.ts index 13e8541db11..18b8d6b3d40 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/project-preview/project-preview.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/project-preview/project-preview.component.spec.ts @@ -45,13 +45,13 @@ import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Router } from '@angular/router'; import { - BASE_URL, FilingPlanService, LoggerModule, PaginatedResponse, Project, ProjectStatus, SchemaService, + SnackBarService, TenantSelectionService, Transaction, TransactionStatus, @@ -112,6 +112,7 @@ describe('ProjectPreviewComponent', () => { updateProjectContext: () => of(projectAfterUpdate), updateProjectAttachments: () => of(projectAfterUpdate), updateProjectConfiguration: () => of(projectAfterUpdate), + nextUpdatedProject: () => {}, getLegalStatusList: () => [ { id: 'Public Archive', value: 'Public archives' }, { id: 'Private Archive', value: 'Private archives' }, @@ -155,30 +156,34 @@ describe('ProjectPreviewComponent', () => { ], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ProjectsService, useValue: projectServiceMock }, { provide: MatDialogRef, useValue: { close: () => {}, }, }, - { provide: ProjectsApiService, useValue: projectApiServiceMock }, { provide: ActivatedRoute, useValue: { params: of('11') } }, - { provide: TenantSelectionService, useValue: tenantSelectionServiceMock }, - { provide: SchemaService, useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } }, - { - provide: FilingPlanService, - useValue: { - tree$: of([]), - expandChange$: EMPTY, - loadTree: () => of([]), - loadFilingPlan: () => of([]), - }, - }, { provide: Router, useValue: {} }, ], - }).compileComponents(); + }) + .overrideProvider(ProjectsService, { useValue: projectServiceMock }) + .overrideProvider(ProjectsApiService, { useValue: projectApiServiceMock }) + .overrideProvider(TenantSelectionService, { useValue: tenantSelectionServiceMock }) + .overrideProvider(SchemaService, { useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } }) + .overrideProvider(FilingPlanService, { + useValue: { + tree$: of([]), + expandChange$: EMPTY, + loadTree: () => of([]), + loadFilingPlan: () => of([]), + }, + }) + .overrideProvider(SnackBarService, { + useValue: { + open: vi.fn(), + }, + }) + .compileComponents(); }); beforeEach(async () => { @@ -227,8 +232,6 @@ describe('ProjectPreviewComponent', () => { component.form.get('messageIdentifier').setValue(projectAfterUpdate.messageIdentifier); component.update(); component.updateProject(true); - fixture.whenStable().then(() => { - expect(projectServiceMock.updateProjectDescription).toHaveBeenCalled(); - }); + expect(projectServiceMock.updateProjectDescription).toHaveBeenCalled(); })); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/project.module.ts b/ui/ui-frontend/projects/collect/src/app/collect/projects/project.module.ts index 25c06931853..279baccc26d 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/project.module.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/project.module.ts @@ -76,7 +76,9 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, VitamUILibraryModule, TranslatePipe, + ProjectsComponent, + ProjectListComponent, + CreateProjectComponent, ], - declarations: [ProjectsComponent, ProjectListComponent, CreateProjectComponent], }) export class ProjectModule {} diff --git a/ui/ui-frontend/projects/collect/src/app/collect/projects/projects.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/projects/projects.component.ts index cdc970f438f..b1101476082 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/projects/projects.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/projects/projects.component.ts @@ -34,20 +34,41 @@ * 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, OnDestroy, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnDestroy, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs'; -import { DEFAULT_PAGE_SIZE, Direction, PageRequest, SidenavPage } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + PageRequest, + SidenavPage, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { CreateProjectComponent } from './create-project/create-project.component'; import { ProjectListComponent } from './project-list/project-list.component'; import { ProjectsService } from './projects.service'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { NgClass } from '@angular/common'; +import { ProjectPreviewComponent } from './project-preview/project-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-projects', templateUrl: './projects.component.html', styleUrls: ['./projects.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + NgClass, + ProjectPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ProjectListComponent, + TranslatePipe, + ], }) export class ProjectsComponent extends SidenavPage implements OnDestroy { private dialog = inject(MatDialog); @@ -63,7 +84,8 @@ export class ProjectsComponent extends SidenavPage implements OnDestroy { const projectsService = inject(ProjectsService); const route = inject(ActivatedRoute); - super(route, projectsService); + super(projectsService); + route.params.subscribe((params) => { this.tenantIdentifier = params['tenantIdentifier']; }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/shared/sip-import-tracking.service.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/shared/sip-import-tracking.service.spec.ts index ca4485db4e3..65597f6d8b9 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/shared/sip-import-tracking.service.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/shared/sip-import-tracking.service.spec.ts @@ -50,8 +50,7 @@ describe('SipImportTrackingService', () => { transactionApiService = { getOperationStatus: vi.fn() }; TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [{ provide: TransactionApiService, useValue: transactionApiService }], - }); + }).overrideProvider(TransactionApiService, { useValue: transactionApiService }); service = TestBed.inject(SipImportTrackingService); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/transactions/transaction-list/transaction-list.component.html b/ui/ui-frontend/projects/collect/src/app/collect/transactions/transaction-list/transaction-list.component.html index 30630b80e10..469f34508e0 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/transactions/transaction-list/transaction-list.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/transactions/transaction-list/transaction-list.component.html @@ -10,8 +10,8 @@
{{ 'COLLECT.INGEST_LIST_TITLE' | translate }}
{{ - (dataSource?.length <= 1 ? 'COLLECT.SINGLE_TRANSACTION' : 'COLLECT.NB_ENTRIES_TRANSACTIONS') - | translate: { nb: dataSource?.length } + (dataSource()?.length <= 1 ? 'COLLECT.SINGLE_TRANSACTION' : 'COLLECT.NB_ENTRIES_TRANSACTIONS') + | translate: { nb: dataSource()?.length } }} @@ -56,7 +56,7 @@
{{ 'COLLECT.INGEST_LIST_TITLE' | translate }}
- @for (transaction of dataSource; track transaction) { + @for (transaction of dataSource(); track transaction) { @@ -83,7 +83,7 @@
{{ 'COLLECT.INGEST_LIST_TITLE' | translate }}
@@ -15,9 +13,7 @@

{{ 'SPACING.MARGIN' | translate }}

@for (margin of margins; track margin) { m-{{ margin }}
-
- {{ getMargin(el) }} -
+
}
@@ -25,7 +21,7 @@

{{ 'SPACING.MARGIN' | translate }}

{{ 'SPACING.GAP' | translate }}

@for (gap of gaps; track gap) { - hgap-{{ gap }} ({{ getGap(el) }}) + hgap-{{ gap }} ()
@@ -39,7 +35,7 @@

{{ 'SPACING.GAP' | translate }}

@for (gap of gaps; track gap) {
- gap-{{ gap }} ({{ getGap(el) }}) + gap-{{ gap }} ()
diff --git a/ui/ui-frontend/projects/design-system/src/app/components/tokens/spacing/spacing.component.ts b/ui/ui-frontend/projects/design-system/src/app/components/tokens/spacing/spacing.component.ts index 2abbcbf70b9..e9a6b3a4178 100644 --- a/ui/ui-frontend/projects/design-system/src/app/components/tokens/spacing/spacing.component.ts +++ b/ui/ui-frontend/projects/design-system/src/app/components/tokens/spacing/spacing.component.ts @@ -36,26 +36,15 @@ */ import { Component } from '@angular/core'; import { TranslatePipe } from '@ngx-translate/core'; +import { ComputedStyleDirective } from './computed-style.directive'; @Component({ templateUrl: './spacing.component.html', styleUrls: ['./spacing.component.scss'], - imports: [TranslatePipe], + imports: [TranslatePipe, ComputedStyleDirective], }) export class SpacingComponent { paddings = [0, 1, 2, 3, 4, 5, 6, 7, 8]; margins = [0, 1, 2, 3, 4, 5, 6, 7, 8, 'auto']; gaps = [0, 1, 2, 3, 4, 5, 6, 7, 8]; - - getPadding(element: HTMLElement) { - return getComputedStyle(element).padding; - } - - getMargin(element: HTMLElement) { - return getComputedStyle(element).margin; - } - - getGap(element: HTMLElement) { - return getComputedStyle(element).gap; - } } diff --git a/ui/ui-frontend/projects/design-system/src/app/components/tokens/typography/typography.component.ts b/ui/ui-frontend/projects/design-system/src/app/components/tokens/typography/typography.component.ts index 60bf56a03d0..6fda1c65a5c 100644 --- a/ui/ui-frontend/projects/design-system/src/app/components/tokens/typography/typography.component.ts +++ b/ui/ui-frontend/projects/design-system/src/app/components/tokens/typography/typography.component.ts @@ -36,13 +36,13 @@ */ import { Component } from '@angular/core'; import { TranslatePipe } from '@ngx-translate/core'; -import { EllipsisDirectiveModule, CommonTooltipModule } from 'vitamui-library'; -import { NgClass, NgTemplateOutlet } from '@angular/common'; +import { EllipsisDirective, TooltipDirective } from 'vitamui-library'; +import { CommonModule, NgClass, NgTemplateOutlet } from '@angular/common'; @Component({ templateUrl: './typography.component.html', styleUrls: ['./typography.component.scss'], - imports: [TranslatePipe, EllipsisDirectiveModule, NgClass, CommonTooltipModule, NgTemplateOutlet], + imports: [TranslatePipe, NgClass, TooltipDirective, NgTemplateOutlet, CommonModule, EllipsisDirective], }) export class TypographyComponent { textFlavors = ['', 'bold']; diff --git a/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.component.ts b/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.component.ts index 4e2ebe48c75..ae70362dcde 100644 --- a/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.component.ts +++ b/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.component.ts @@ -34,9 +34,11 @@ * 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, OnInit, inject } from '@angular/core'; -import { FormControl, Validators } from '@angular/forms'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, inject, OnInit } from '@angular/core'; +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { InputComponent } from 'vitamui-library'; +import { I18nPluralPipe } from '@angular/common'; const TRANSLATE_GET_PATH = 'TRANSLATION.TRANSLATE_GET'; @@ -44,7 +46,7 @@ const TRANSLATE_GET_PATH = 'TRANSLATION.TRANSLATE_GET'; selector: 'design-system-translation', templateUrl: './translation.component.html', styleUrls: ['./translation.component.scss'], - standalone: false, + imports: [InputComponent, ReactiveFormsModule, I18nPluralPipe, TranslatePipe], }) export class TranslationComponent implements OnInit { private translateService = inject(TranslateService); diff --git a/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.module.ts b/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.module.ts deleted file mode 100644 index bb682fffec3..00000000000 --- a/ui/ui-frontend/projects/design-system/src/app/components/translation/translation.module.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatInputModule } from '@angular/material/input'; -import { VitamUICommonModule } from 'vitamui-library'; -import { TranslationComponent } from './translation.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [TranslationComponent], - imports: [CommonModule, VitamUICommonModule, ReactiveFormsModule, MatInputModule, TranslatePipe], - exports: [TranslationComponent], -}) -export class TranslationModule {} diff --git a/ui/ui-frontend/projects/design-system/src/assets/config-dev.json b/ui/ui-frontend/projects/design-system/src/assets/config-dev.json new file mode 100644 index 00000000000..b8d3cf49457 --- /dev/null +++ b/ui/ui-frontend/projects/design-system/src/assets/config-dev.json @@ -0,0 +1,53 @@ +{ + "GATEWAY_ENABLED": true, + "REFERENTIAL_URL": "https://dev.vitamui.com:4202", + "VERSION_RELEASE": "8.1-SNAPSHOT", + "PLATFORM_NAME": "VITAM-UI", + "INGEST_URL": "https://dev.vitamui.com:4208/ingest", + "PORTAL_TITLE": "Portail des applications de l'archivage", + "MAX_STREET_LENGTH": 250, + "THEME_COLORS": { + "vitamui-primary": "#9C31B5", + "vitamui-secondary": "#296EBC", + "vitamui-tertiary": "#C22A40", + "vitamui-header-footer": "#ffffff", + "vitamui-background": "#FCF7FD" + }, + "PORTAL_MESSAGE": "Profitez d'un portail unique pour rechercher dans les archives de vos coffres, pour déposer des éléments en toute sécurité et pour imprimer des étiquettes en quelques clics.", + "UI_URL": "https://dev.vitamui.com:4242", + "ARCHIVES_SEARCH_URL": "https://dev.vitamui.com:4209/archive-search", + "PORTAL_URL": "https://dev.vitamui.com:4200", + "USER_LOGO": "logo_USER.png", + "CATEGORY_CONFIGURATION": [ + { + "displayTitle": true, + "identifier": "ingest_and_consultation", + "title": "Versement & consultation", + "order": 1 + }, + { + "displayTitle": true, + "identifier": "referential", + "title": "Référentiels", + "order": 2 + }, + { + "displayTitle": true, + "identifier": "supervision_and_audits", + "title": "Supervision & Audits", + "order": 3 + }, + { + "displayTitle": true, + "identifier": "security_and_application_rights", + "title": "Sécurité & droits applicatifs", + "order": 4 + }, + { + "displayTitle": true, + "identifier": "organization_and_user_rights", + "title": "Organisation & droits utilisateurs", + "order": 5 + } + ] +} diff --git a/ui/ui-frontend/projects/design-system/src/environments/environment.ts b/ui/ui-frontend/projects/design-system/src/environments/environment.ts index 1bea6cc2602..a90f99a4c4e 100644 --- a/ui/ui-frontend/projects/design-system/src/environments/environment.ts +++ b/ui/ui-frontend/projects/design-system/src/environments/environment.ts @@ -41,4 +41,5 @@ export const environment = { production: false, + configUrls: ['./assets/config-dev.json'], }; diff --git a/ui/ui-frontend/projects/design-system/src/main.ts b/ui/ui-frontend/projects/design-system/src/main.ts index a76b446c356..6e96989a1d4 100644 --- a/ui/ui-frontend/projects/design-system/src/main.ts +++ b/ui/ui-frontend/projects/design-system/src/main.ts @@ -34,16 +34,60 @@ * 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 { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowser } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom, LOCALE_ID } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import { + BASE_URL, + BaseUserInfoApiService, + ConfigService, + ENVIRONMENT, + loadConfigFactory, + LoggerModule, + provideI18n, + WINDOW_LOCATION, +} from 'vitamui-library'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { of } from 'rxjs'; +import { AppComponent } from './app/app.component'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { PreloadAllModules, provideRouter, withHashLocation, withPreloading } from '@angular/router'; +import { routes } from './app/app.routes'; +import { inject, provideAppInitializer } from '@angular/core'; +import { VitamUILibraryModule } from '../../vitamui-library/src/lib/vitamui-library.module'; if (environment.production) { enableProdMode(); } -platformBrowser() - .bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }) - .catch((err) => console.log(err)); +bootstrapApplication(AppComponent, { + providers: [ + provideRouter(routes, withPreloading(PreloadAllModules), withHashLocation()), + importProvidersFrom( + LoggerModule.forRoot(), + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: environment.production, + // Register the ServiceWorker as soon as the application is stable + // or after 30 seconds (whichever comes first). + registrationStrategy: 'registerWhenStable:30000', + }), + VitamUILibraryModule, // For Material tokens + ), + provideAppInitializer(async () => { + const configService = inject(ConfigService); + const environment = inject(ENVIRONMENT); + await loadConfigFactory(configService, environment)(); + }), + provideI18n(), + provideNativeDateAdapter(), + { provide: LOCALE_ID, useValue: 'fr' }, + { provide: ENVIRONMENT, useValue: environment }, + { provide: BASE_URL, useValue: '/FAKE' }, + { + provide: WINDOW_LOCATION, + useValue: window.location, + }, + { provide: BaseUserInfoApiService, useValue: { patchMyUserInfo: () => of(undefined) } }, // Make changing language work + ], +}).catch((err) => console.log(err)); diff --git a/ui/ui-frontend/projects/identity/src/app/app.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/app.component.spec.ts index 11f5b119500..4efe2fd0be2 100644 --- a/ui/ui-frontend/projects/identity/src/app/app.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/app.component.spec.ts @@ -36,40 +36,30 @@ */ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { TestBed, waitForAsync } from '@angular/core/testing'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Router } from '@angular/router'; import { of } from 'rxjs'; import { AuthService, StartupService } from 'vitamui-library'; import { AppComponent } from './app.component'; -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'router-outlet', - template: '', -}) -class RouterOutletStubComponent {} - -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'vitamui-common-subrogation-banner', - template: '', -}) -class SubrogationBannerStubComponent {} - describe('AppComponent', () => { beforeEach(async () => { - const startupServiceStub = { configurationLoaded: () => true, printConfiguration: () => {}, getPlatformName: () => '' }; + const startupServiceStub = { + configurationLoaded: () => true, + printConfiguration: () => {}, + getPlatformName: () => '', + getPortalUrl: () => '', + getConfigStringValue: () => '', + getHasSiteSelection: () => false, + }; await TestBed.configureTestingModule({ - imports: [MatSidenavModule, NoopAnimationsModule, SubrogationBannerStubComponent, RouterOutletStubComponent], - declarations: [AppComponent], + imports: [AppComponent], providers: [ { provide: StartupService, useValue: startupServiceStub }, { provide: AuthService, useValue: { userLoaded: of(null) } }, - { provide: Router, useValue: { navigate: () => {} } }, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents(); + }) + .overrideTemplate(AppComponent, '
') + .compileComponents(); }); it('should create the app', waitForAsync(() => { diff --git a/ui/ui-frontend/projects/identity/src/app/app.component.ts b/ui/ui-frontend/projects/identity/src/app/app.component.ts index e24b5e05168..04d6d570d72 100644 --- a/ui/ui-frontend/projects/identity/src/app/app.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/app.component.ts @@ -36,13 +36,14 @@ */ import { Component, inject } from '@angular/core'; import { Title } from '@angular/platform-browser'; -import { StartupService } from 'vitamui-library'; +import { FooterComponent, HeaderModule, StartupService, SubrogationModule, VitamuiBodyComponent } from 'vitamui-library'; +import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], - standalone: false, + imports: [HeaderModule, VitamuiBodyComponent, RouterOutlet, FooterComponent, SubrogationModule], }) export class AppComponent { title = 'Identity App'; diff --git a/ui/ui-frontend/projects/identity/src/app/app.module.ts b/ui/ui-frontend/projects/identity/src/app/app.module.ts deleted file mode 100644 index 9db7acd017b..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/app.module.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { DatePipe, registerLocaleData } from '@angular/common'; -import { default as localeFr } from '@angular/common/locales/fr'; -import { LOCALE_ID, NgModule } from '@angular/core'; -import { BrowserModule, Title } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { AuthenticationModule, provideI18n, VitamUICommonModule, WINDOW_LOCATION } from 'vitamui-library'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { CoreModule } from './core/core.module'; - -registerLocaleData(localeFr, 'fr'); - -@NgModule({ - declarations: [AppComponent], - imports: [ - AuthenticationModule.forRoot(), - CoreModule, - BrowserAnimationsModule, - BrowserModule, - VitamUICommonModule.forRoot(), - AppRoutingModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000', - }), - ], - providers: [ - provideI18n(), - Title, - { provide: LOCALE_ID, useValue: 'fr' }, - { provide: WINDOW_LOCATION, useValue: window.location }, - DatePipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/core/api/customer-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/core/api/customer-api.service.spec.ts index 1152ae3c22b..5bf6aec080f 100644 --- a/ui/ui-frontend/projects/identity/src/app/core/api/customer-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/core/api/customer-api.service.spec.ts @@ -34,23 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from '../../../environments/environment'; import { CustomerApiService } from './customer-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('CustomerApiService Identity', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/core/api/group-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/core/api/group-api.service.spec.ts index 98f73f07a7c..0e8cac947a5 100644 --- a/ui/ui-frontend/projects/identity/src/app/core/api/group-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/core/api/group-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from 'vitamui-library'; import { GroupApiService } from './group-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('GroupApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/core/api/user-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/core/api/user-api.service.spec.ts index 733f6f5c2c3..0e833cbc5c8 100644 --- a/ui/ui-frontend/projects/identity/src/app/core/api/user-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/core/api/user-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from 'vitamui-library'; import { UserApiService } from './user-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('UserApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/core/core.module.ts b/ui/ui-frontend/projects/identity/src/app/core/core.module.ts index 401b3bcd284..c6ae114a23c 100644 --- a/ui/ui-frontend/projects/identity/src/app/core/core.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/core/core.module.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NgModule, inject } from '@angular/core'; +import { inject, NgModule } from '@angular/core'; import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule, throwIfAlreadyLoaded, VitamUICommonModule } from 'vitamui-library'; import { environment } from '../../environments/environment'; diff --git a/ui/ui-frontend/projects/identity/src/app/core/customer.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/core/customer.service.spec.ts index eb847a2cf0c..4b8e51408de 100644 --- a/ui/ui-frontend/projects/identity/src/app/core/customer.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/core/customer.service.spec.ts @@ -34,15 +34,14 @@ * 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 { BASE_URL, CriteriaSearchQuery, Customer, ENVIRONMENT, LoggerModule, Operators, OtpState, SnackBarService } from 'vitamui-library'; +import { CriteriaSearchQuery, Customer, ENVIRONMENT, LoggerModule, Operators, OtpState, SnackBarService } from 'vitamui-library'; import { environment } from './../../environments/environment'; -import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { Type } from '@angular/core'; import { CustomerService } from './customer.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const expectedCustomer: Customer = { id: '42', @@ -99,14 +98,7 @@ describe('CustomerService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - CustomerService, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - { provide: SnackBarService, useValue: snackBarSpy }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [CustomerService, { provide: ENVIRONMENT, useValue: environment }, { provide: SnackBarService, useValue: snackBarSpy }], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/identity/src/app/core/customer.service.ts b/ui/ui-frontend/projects/identity/src/app/core/customer.service.ts index 658567da4bd..7dfefadadee 100644 --- a/ui/ui-frontend/projects/identity/src/app/core/customer.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/core/customer.service.ts @@ -36,10 +36,10 @@ */ import { Observable, Subject, zip } from 'rxjs'; import { map, tap } from 'rxjs/operators'; -import { CriteriaSearchQuery, Criterion, Customer, Logo, Operators, ThemeService, SnackBarService } from 'vitamui-library'; +import { CriteriaSearchQuery, Criterion, Customer, Logo, Operators, SnackBarService, ThemeService } from 'vitamui-library'; import { HttpResponse } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { AttachmentType } from '../customer/attachment.enum'; diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.spec.ts index 07c6f99fab2..89fd96681b0 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.spec.ts @@ -45,8 +45,7 @@ describe('CustomerAlertingComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [MatDialogModule], - declarations: [CustomerAlertingComponent], + imports: [MatDialogModule, CustomerAlertingComponent], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.ts index 3f54966f48a..aefdd7960f4 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-alerting/customer-alerting.component.ts @@ -35,11 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component } from '@angular/core'; +import { MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-customer-alerting', templateUrl: './customer-alerting.component.html', styleUrls: ['./customer-alerting.component.scss'], - standalone: false, + imports: [MatDialogContent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class CustomerAlertingComponent {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.component.ts index b111262e3e9..77a3ca1f786 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.component.ts @@ -34,17 +34,18 @@ * 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, Input, OnInit, inject } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { Color, Option, ThemeColorType, ThemeService } from 'vitamui-library'; +import { Component, inject, Input, OnInit } from '@angular/core'; +import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { Color, Option, SelectComponent, ThemeColorType, ThemeService } from 'vitamui-library'; import { Subscription } from 'rxjs'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { InputColorComponent } from './input-color/input-color.component'; @Component({ selector: 'app-customer-colors-input', templateUrl: './customer-colors-input.component.html', styleUrls: ['./customer-colors-input.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, InputColorComponent, SelectComponent, FormsModule, TranslatePipe], }) export class CustomerColorsInputComponent implements OnInit { private themeService = inject(ThemeService); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.module.ts deleted file mode 100644 index 37388414a8d..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/customer-colors-input.module.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; -import { ColorPickerDirective } from 'ngx-color-picker'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../../shared/shared.module'; -import { OwnerFormModule } from '../../owner-form/owner-form.module'; -import { CustomerColorsInputComponent } from './customer-colors-input.component'; -import { InputColorComponent } from './input-color/input-color.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - SharedModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - OwnerFormModule, - VitamUICommonModule, - ColorPickerDirective, - VitamUILibraryModule, - FormsModule, - TranslatePipe, - ], - declarations: [CustomerColorsInputComponent, InputColorComponent], - exports: [CustomerColorsInputComponent], -}) -export class CustomerColorsInputModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/input-color/input-color.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/input-color/input-color.component.ts index d361cb7ba79..5683a3455a5 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/input-color/input-color.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-colors-input/input-color/input-color.component.ts @@ -35,15 +35,16 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input, OnInit, ViewChild } from '@angular/core'; -import { AbstractControl, FormControl, ValidationErrors, ValidatorFn } from '@angular/forms'; +import { AbstractControl, FormControl, ReactiveFormsModule, ValidationErrors, ValidatorFn } from '@angular/forms'; import { ColorPickerDirective } from 'ngx-color-picker'; -import { hexToRgb, rgbToHsl, FormControlWarn } from 'vitamui-library'; +import { FormControlWarn, hexToRgb, InputComponent, PipesModule, rgbToHsl } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-input-color', templateUrl: './input-color.component.html', styleUrls: ['./input-color.component.scss'], - standalone: false, + imports: [InputComponent, ColorPickerDirective, ReactiveFormsModule, PipesModule, TranslatePipe], }) export class InputColorComponent implements OnInit { @Input() placeholder: string; diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.spec.ts index 3ebde470c30..487ed21f9db 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.spec.ts @@ -35,7 +35,6 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { Component, EventEmitter, forwardRef, Input, NO_ERRORS_SCHEMA, Output } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; @@ -45,9 +44,8 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; -import { BASE_URL, ConfirmDialogService, CountryService, LoggerModule, OtpState, StartupService, WINDOW_LOCATION } from 'vitamui-library'; +import { ConfirmDialogService, CountryService, LoggerModule, OtpState, StartupService, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { CustomerService } from '../../core/customer.service'; import { OwnerFormValidators } from '../owner-form/owner-form.validators'; @@ -56,7 +54,6 @@ import { TenantFormValidators } from '../tenant-create/tenant-form.validators'; import { TenantService } from '../tenant.service'; import { CustomerCreateComponent } from './customer-create.component'; import { CustomerCreateValidators } from './customer-create.validators'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'app-domains-input', @@ -68,7 +65,15 @@ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http' multi: true, }, ], - standalone: false, + imports: [ + MatButtonToggleModule, + MatFormFieldModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatSelectModule, + ReactiveFormsModule, + VitamUICommonTestModule, + ], }) class DomainInputStubComponent implements ControlValueAccessor { @Input() @@ -98,7 +103,15 @@ class DomainInputStubComponent implements ControlValueAccessor { multi: true, }, ], - standalone: false, + imports: [ + MatButtonToggleModule, + MatFormFieldModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatSelectModule, + ReactiveFormsModule, + VitamUICommonTestModule, + ], }) class OwnerFormStubComponent implements ControlValueAccessor { @Input() @@ -121,7 +134,15 @@ class OwnerFormStubComponent implements ControlValueAccessor { multi: true, }, ], - standalone: false, + imports: [ + MatButtonToggleModule, + MatFormFieldModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatSelectModule, + ReactiveFormsModule, + VitamUICommonTestModule, + ], }) class CustomerColorsInputStubComponent implements ControlValueAccessor { @Input() @@ -230,7 +251,6 @@ describe('CustomerCreateComponent', () => { .mockReturnValue(() => of(null)), }; await TestBed.configureTestingModule({ - declarations: [CustomerCreateComponent, OwnerFormStubComponent, CustomerColorsInputStubComponent, DomainInputStubComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ LoggerModule.forRoot(), @@ -239,15 +259,17 @@ describe('CustomerCreateComponent', () => { MatProgressBarModule, MatProgressSpinnerModule, MatSelectModule, - NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule, + CustomerCreateComponent, + OwnerFormStubComponent, + CustomerColorsInputStubComponent, + DomainInputStubComponent, ], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: StartupService, useValue: { getConfigNumberValue: () => 100 } }, { provide: CustomerService, useValue: customerServiceSpy }, { provide: CustomerCreateValidators, useValue: customerCreateValidatorsSpy }, @@ -258,8 +280,6 @@ describe('CustomerCreateComponent', () => { { provide: TenantFormValidators, useValue: tenantFormValidatorsSpy }, { provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } }, { provide: MatDialog, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }) .overrideComponent(CustomerCreateComponent, { diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.ts index c8fc0e00667..94c48f225de 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.component.ts @@ -35,9 +35,9 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { ComponentType } from '@angular/cdk/portal'; -import { Component, OnDestroy, OnInit, TemplateRef, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit, TemplateRef } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { finalize, merge, Observable, Subscription } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; import { @@ -45,10 +45,17 @@ import { CountryOption, CountryService, Customer, + DialogHeaderComponent, + InputComponent, Logo, + NextStepComponent, Option, OtpState, + PreviousStepComponent, + SelectComponent, + SlideToggleComponent, StartupService, + StepperComponent, VitamuiSelectOptions, } from 'vitamui-library'; import { CustomerService } from '../../core/customer.service'; @@ -56,12 +63,41 @@ import { TenantFormValidators } from '../tenant-create/tenant-form.validators'; import { CustomerAlertingComponent } from './customer-alerting/customer-alerting.component'; import { ALPHA_NUMERIC_REGEX, CUSTOMER_CODE_MAX_LENGTH, CustomerCreateValidators } from './customer-create.validators'; import { TenantService } from '../tenant.service'; +import { CdkStep, CdkStepperNext } from '@angular/cdk/stepper'; +import { NgTemplateOutlet } from '@angular/common'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { DomainsInputComponent } from '../../shared/domains-input/domains-input.component'; +import { GraphicIdentityComponent } from '../customer-preview/graphic-identity-tab/graphic-identity/graphic-identity.component'; +import { HomepageMessageComponent } from '../customer-preview/homepage-message-tab/homepage-message/homepage-message.component'; +import { OwnerFormComponent } from '../owner-form/owner-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-customer-create', templateUrl: './customer-create.component.html', styleUrls: ['./customer-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + InputComponent, + SelectComponent, + SlideToggleComponent, + MatDialogActions, + NextStepComponent, + NgTemplateOutlet, + MatButtonToggleGroup, + MatButtonToggle, + DomainsInputComponent, + PreviousStepComponent, + GraphicIdentityComponent, + HomepageMessageComponent, + OwnerFormComponent, + CdkStepperNext, + TranslatePipe, + ], }) export class CustomerCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.module.ts deleted file mode 100644 index 9ad1c5d1d7f..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-create/customer-create.module.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; - -import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { CustomerPreviewModule } from '../customer-preview/customer-preview.module'; -import { OwnerFormModule } from '../owner-form/owner-form.module'; -import { CustomerAlertingComponent } from './customer-alerting/customer-alerting.component'; -import { CustomerColorsInputModule } from './customer-colors-input/customer-colors-input.module'; -import { CustomerCreateComponent } from './customer-create.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - CustomerColorsInputModule, - SharedModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatSelectModule, - ReactiveFormsModule, - OwnerFormModule, - VitamUICommonModule, - CustomerPreviewModule, - MatDialogModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [CustomerCreateComponent, CustomerAlertingComponent], -}) -export class CustomerCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.html b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.html index 0f46287bdb0..8c50f05a398 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.html @@ -11,7 +11,7 @@
- @for (customer of dataSource; track customer) { + @for (customer of dataSource(); track customer) {
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && customerListService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && customerListService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.spec.ts index 180908b49f9..c189ccee3ec 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.spec.ts @@ -40,7 +40,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { By } from '@angular/platform-browser'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Router } from '@angular/router'; import { of, Subject } from 'rxjs'; @@ -49,14 +48,15 @@ import { InfiniteScrollStubDirective, VitamUICommonTestModule } from 'vitamui-li import { CustomerService } from '../../core/customer.service'; import { CustomerDataService } from '../customer.data.service'; import { OwnerCreateComponent } from '../owner-create/owner-create.component'; +import { OwnerService } from '../owner.service'; import { TenantService } from '../tenant.service'; import { CustomerListComponent } from './customer-list.component'; import { CustomerListService } from './customer-list.service'; +import { OwnerListComponent } from './owner-list/owner-list.component'; @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector selector: '[vitamuiCommonCollapseTriggerFor]', - standalone: false, }) class CollapseTriggerForStubDirective { @Input() @@ -67,7 +67,6 @@ class CollapseTriggerForStubDirective { // eslint-disable-next-line @angular-eslint/directive-selector selector: '[vitamuiCommonCollapse]', exportAs: 'vitamuiCommonCollapse', - standalone: false, }) class CollapseStubDirective { @Input() @@ -77,7 +76,7 @@ class CollapseStubDirective { @Component({ selector: 'app-owner-list', template: '', - standalone: false, + imports: [MatProgressSpinnerModule, VitamUICommonTestModule], }) class OwnerListStubComponent { @Input() @@ -102,7 +101,7 @@ class Page { } get loadMoreButton() { const buttons = fixture.nativeElement.querySelectorAll('.vitamui-min-content.vitamui-table-message'); - return buttons.length || !component.infiniteScrollDisabled ? buttons : [{ click: () => component.customerListService.loadMore() }]; + return buttons.length || !component.infiniteScrollDisabled() ? buttons : [{ click: () => component.customerListService.loadMore() }]; } get infiniteScroll() { return fixture.debugElement.query(By.directive(InfiniteScrollStubDirective)); @@ -270,6 +269,7 @@ describe('CustomerListComponent', () => { const tenantServiceSpy = { getTenantsByCustomerIds: () => of(tenants), + updated: new Subject(), }; const matDialogSpy = { open: vi.fn().mockName('MatDialog.open'), @@ -280,18 +280,34 @@ describe('CustomerListComponent', () => { matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - imports: [MatProgressSpinnerModule, NoopAnimationsModule, VitamUICommonTestModule], + imports: [ + MatProgressSpinnerModule, + VitamUICommonTestModule, + CustomerListComponent, + CollapseStubDirective, + CollapseTriggerForStubDirective, + OwnerListStubComponent, + ], schemas: [NO_ERRORS_SCHEMA], - declarations: [CustomerListComponent, CollapseStubDirective, CollapseTriggerForStubDirective, OwnerListStubComponent], providers: [ { provide: CustomerListService, useValue: customerListServiceSpy }, { provide: CustomerService, useValue: { updated: new Subject() } }, { provide: TenantService, useValue: tenantServiceSpy }, + { provide: OwnerService, useValue: { updated: new Subject() } }, { provide: MatDialog, useValue: matDialogSpy }, { provide: Router, useValue: routerSpy }, CustomerDataService, ], - }).compileComponents(); + }) + .overrideComponent(CustomerListComponent, { + remove: { + imports: [OwnerListComponent], + }, + add: { + imports: [OwnerListStubComponent], + }, + }) + .compileComponents(); const customerListService = TestBed.inject(CustomerListService); vi.spyOn(customerListService, 'search'); @@ -345,7 +361,7 @@ describe('CustomerListComponent', () => { }); it('should have a button to load more customers', () => { - component.infiniteScrollDisabled = true; + component.infiniteScrollDisabled.set(true); fixture.detectChanges(false); expect(page.loadMoreButton).toBeTruthy(); }); @@ -359,7 +375,7 @@ describe('CustomerListComponent', () => { it('should call loadMore()', () => { const customerListService = TestBed.inject(CustomerListService); - component.infiniteScrollDisabled = true; + component.infiniteScrollDisabled.set(true); fixture.detectChanges(false); page.loadMoreButton[0].click(); expect(customerListService.loadMore).toHaveBeenCalled(); @@ -434,7 +450,7 @@ describe('CustomerListComponent', () => { gdprAlert: false, gdprAlertDelay: 0, }); - expect(component.dataSource[1].name).toBe('Updated customer'); + expect(component.dataSource()[1].name).toBe('Updated customer'); }); function testRow(index: number) { diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.ts index 5263ef8c185..40a5712fc97 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.component.ts @@ -34,23 +34,46 @@ * 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, EventEmitter, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, OnDestroy, OnInit, Output } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; -import { Customer, DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, Owner, PageRequest, Tenant } from 'vitamui-library'; +import { + CollapseDirective, + Customer, + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + InfiniteScrollDirective, + InfiniteScrollTable, + Owner, + PageRequest, + Tenant, +} from 'vitamui-library'; import { CustomerService } from '../../core/customer.service'; import { CustomerDataService } from '../customer.data.service'; import { OwnerCreateComponent } from '../owner-create/owner-create.component'; import { TenantService } from '../tenant.service'; import { CustomerListService } from './customer-list.service'; +import { OwnerListComponent } from './owner-list/owner-list.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-customer-list', templateUrl: './customer-list.component.html', styleUrls: ['./customer-list.component.scss'], - standalone: false, + imports: [ + OwnerListComponent, + MatProgressSpinner, + TranslatePipe, + CollapseDirective, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class CustomerListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { customerListService: CustomerListService; @@ -84,7 +107,7 @@ export class CustomerListComponent extends InfiniteScrollTable impleme }); this.updatedData.subscribe(() => { - const customerIds = this.dataSource + const customerIds = (this.dataSource() ?? []) .filter((customer: Customer) => { const existingTenant = this.tenants.find((tenant) => tenant.customerId === customer.id); if (!existingTenant) { @@ -99,19 +122,23 @@ export class CustomerListComponent extends InfiniteScrollTable impleme this.tenantService.getTenantsByCustomerIds(customerIds).subscribe((results) => { this.customerDataService.addTenants(results); this.loaded = true; - this.pending = false; + this.pending.set(false); }); } else { this.loaded = true; - this.pending = false; + this.pending.set(false); } }); this.updatedCustomerSub = this.customerService.updated.subscribe((updatedCustomer: Customer) => { - const customerIndex = this.dataSource.findIndex((customer) => updatedCustomer.id === customer.id); - if (customerIndex > -1) { - this.dataSource[customerIndex] = updatedCustomer; - } + this.dataSource.update((customers) => { + const list = [...(customers ?? [])]; + const customerIndex = list.findIndex((customer) => updatedCustomer.id === customer.id); + if (customerIndex > -1) { + list[customerIndex] = updatedCustomer; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.module.ts deleted file mode 100644 index 70bd902140c..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.module.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatRippleModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule } from 'vitamui-library'; - -import { SharedModule } from '../../shared/shared.module'; -import { CustomerListComponent } from './customer-list.component'; -import { OwnerListComponent } from './owner-list/owner-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - SharedModule, - RouterModule, - MatRippleModule, - MatDialogModule, - MatProgressSpinnerModule, - VitamUICommonModule, - TranslatePipe, - ], - declarations: [CustomerListComponent, OwnerListComponent], - exports: [CustomerListComponent], -}) -export class CustomerListModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.spec.ts index 2b2a391246e..7a208430d7e 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.spec.ts @@ -34,13 +34,12 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { Type } from '@angular/core'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, Customer, Direction, ENVIRONMENT, LoggerModule, OtpState, PageRequest } from 'vitamui-library'; +import { Customer, Direction, ENVIRONMENT, LoggerModule, OtpState, PageRequest } from 'vitamui-library'; import { environment } from './../../../environments/environment'; import { CustomerListService } from './customer-list.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const expectedCustomersPage: { values: Customer[]; pageNum: number; pageSize: number; hasMore: boolean } = { values: [ @@ -301,12 +300,7 @@ describe('CustomerListService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.ts index 46d952f1e45..ff0f20c0d1a 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/customer-list.service.ts @@ -34,7 +34,7 @@ * 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 { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/owner-list/owner-list.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/owner-list/owner-list.component.ts index 85c9ab64b59..6eb43d63dc8 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-list/owner-list/owner-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-list/owner-list/owner-list.component.ts @@ -34,23 +34,25 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; -import type { Customer, Owner, Tenant } from 'vitamui-library'; +import { Customer, EllipsisDirective, Owner, Tenant, TooltipDirective } from 'vitamui-library'; import { CustomerDataService } from '../../customer.data.service'; import { OwnerCreateComponent } from '../../owner-create/owner-create.component'; import { OwnerService } from '../../owner.service'; import { TenantCreateComponent } from '../../tenant-create/tenant-create.component'; import { TenantService } from '../../tenant.service'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-owner-list', templateUrl: './owner-list.component.html', styleUrls: ['./owner-list.component.scss'], - standalone: false, + imports: [TooltipDirective, TranslatePipe, CommonModule, EllipsisDirective], }) export class OwnerListComponent implements OnDestroy, OnInit { private dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-popup.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-popup.component.ts index e4b724dfc2a..38aad63e89c 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-popup.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-popup.component.ts @@ -38,11 +38,12 @@ import { Component, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Customer } from 'vitamui-library'; +import { CustomerPreviewComponent } from './customer-preview.component'; @Component({ selector: 'app-customer-popup', template: '', - standalone: false, + imports: [CustomerPreviewComponent], }) export class CustomerPopupComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.spec.ts index c72eb43d627..9b775e2a6cd 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.spec.ts @@ -34,63 +34,71 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, Input, NO_ERRORS_SCHEMA, ViewChild, NgModule } from '@angular/core'; +import { Component, Input, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Subject } from 'rxjs'; -import { ENVIRONMENT, LoggerModule, StartupService, WINDOW_LOCATION } from 'vitamui-library'; import type { Customer } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; +import { ENVIRONMENT, OperationHistoryTabComponent, StartupService, WINDOW_LOCATION } from 'vitamui-library'; import { CustomerService } from '../../core/customer.service'; import { environment } from './../../../environments/environment'; import { CustomerPreviewComponent } from './customer-preview.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { SsoTabComponent } from './sso-tab/sso-tab.component'; +import { GraphicIdentityTabComponent } from './graphic-identity-tab/graphic-identity-tab.component'; +import { HomepageMessageTabComponent } from './homepage-message-tab/homepage-message-tab.component'; @Component({ selector: 'app-information-tab', template: '', - standalone: false, }) export class InformationTabStubComponent { - @Input() - customer: Customer; - @Input() - readOnly: boolean; - @Input() - gdprReadOnlyStatus: boolean; + @Input() customer: Customer; + @Input() readOnly: boolean; + @Input() gdprReadOnlyStatus: boolean; } @Component({ selector: 'app-sso-tab', template: '', - standalone: false, }) export class SsoTabStubComponent { - @Input() - customer: Customer; - @Input() - readOnly: boolean; + @Input() customer: Customer; + @Input() readOnly: boolean; } @Component({ selector: 'app-graphic-identity-tab', template: '', - standalone: false, }) export class GraphicIdentityTabStubComponent { - @Input() - customer: Customer; - @Input() - readOnly: boolean; + @Input() customer: Customer; + @Input() readOnly: boolean; +} + +@Component({ + selector: 'app-homepage-message-tab', + template: '', +}) +export class HomepageMessageTabStubComponent { + @Input() customer: Customer; + @Input() readOnly: boolean; +} + +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'vitamui-common-operation-history-tab', + template: '', +}) +export class OperationHistoryTabStubComponent { + @Input() id: string; + @Input() identifier: string; + @Input() collectionName: string; } @Component({ template: '', - standalone: false, + imports: [CustomerPreviewComponent], + schemas: [NO_ERRORS_SCHEMA], }) class TestHostComponent { customer: any; @@ -99,9 +107,6 @@ class TestHostComponent { component: CustomerPreviewComponent; } -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - describe('CustomerPreviewComponent', () => { let testhost: TestHostComponent; let fixture: ComponentFixture; @@ -113,26 +118,38 @@ describe('CustomerPreviewComponent', () => { const startupServiceStub = { getPortalUrl: () => 'https://dev.vitamui.com', getConfigStringValue: () => 'https://dev.vitamui.com/identity', + getConfigNumberValue: () => 0, }; await TestBed.configureTestingModule({ - declarations: [ - TestHostComponent, - CustomerPreviewComponent, - InformationTabStubComponent, - SsoTabStubComponent, - GraphicIdentityTabStubComponent, - ], - schemas: [NO_ERRORS_SCHEMA], - imports: [MatMenuModule, MatTabsModule, NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule, LoggerModule.forRoot()], + imports: [TestHostComponent], providers: [ { provide: CustomerService, useValue: customerServiceSpy }, { provide: StartupService, useValue: startupServiceStub }, { provide: WINDOW_LOCATION, useValue: {} }, { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideComponent(CustomerPreviewComponent, { + remove: { + imports: [ + InformationTabComponent, + SsoTabComponent, + GraphicIdentityTabComponent, + HomepageMessageTabComponent, + OperationHistoryTabComponent, + ], + }, + add: { + imports: [ + InformationTabStubComponent, + SsoTabStubComponent, + GraphicIdentityTabStubComponent, + HomepageMessageTabStubComponent, + OperationHistoryTabStubComponent, + ], + }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.ts index 25360c1175f..b490924877b 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.component.ts @@ -34,17 +34,40 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subscription } from 'rxjs'; import type { Customer } from 'vitamui-library'; +import { OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { CustomerService } from '../../core/customer.service'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { SsoTabComponent } from './sso-tab/sso-tab.component'; +import { GraphicIdentityTabComponent } from './graphic-identity-tab/graphic-identity-tab.component'; +import { HomepageMessageTabComponent } from './homepage-message-tab/homepage-message-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-customer-preview', templateUrl: './customer-preview.component.html', styleUrls: ['./customer-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + InformationTabComponent, + SsoTabComponent, + GraphicIdentityTabComponent, + HomepageMessageTabComponent, + OperationHistoryTabComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class CustomerPreviewComponent implements OnInit, OnDestroy { private customerService = inject(CustomerService); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.module.ts deleted file mode 100644 index 8f3fb6fd475..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/customer-preview.module.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { CustomParamsModule } from '../../shared/custom-params/custom-params.module'; -import { SharedModule } from '../../shared/shared.module'; -import { CustomerColorsInputModule } from '../customer-create/customer-colors-input/customer-colors-input.module'; -import { CustomerPreviewComponent } from './customer-preview.component'; -import { GraphicIdentityTabComponent } from './graphic-identity-tab/graphic-identity-tab.component'; -import { GraphicIdentityUpdateComponent } from './graphic-identity-tab/graphic-identity-update/graphic-identity-update.component'; - -import { GraphicIdentityFormComponent } from './graphic-identity-tab/graphic-identity/graphic-identity-form/graphic-identity-form.component'; -import { GraphicIdentityComponent } from './graphic-identity-tab/graphic-identity/graphic-identity.component'; -import { HomepageMessageTabComponent } from './homepage-message-tab/homepage-message-tab.component'; -import { HomepageMessageUpdateComponent } from './homepage-message-tab/homepage-message-update/homepage-message-update.component'; - -import { HomepageMessageTranslationComponent } from './homepage-message-tab/homepage-message/homepage-message-translation/homepage-message-translation'; -import { HomepageMessageComponent } from './homepage-message-tab/homepage-message/homepage-message.component'; -import { InformationTabComponent } from './information-tab/information-tab.component'; -import { IdentityProviderCreateComponent } from './sso-tab/identity-provider-create/identity-provider-create.component'; -import { IdentityProviderDetailsComponent } from './sso-tab/identity-provider-details/identity-provider-details.component'; -import { SsoTabComponent } from './sso-tab/sso-tab.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - CustomerColorsInputModule, - SharedModule, - RouterModule, - MatDialogModule, - MatMenuModule, - MatTabsModule, - MatSelectModule, - MatButtonToggleModule, - ReactiveFormsModule, - MatProgressBarModule, - MatProgressSpinnerModule, - VitamUICommonModule, - CustomParamsModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [ - CustomerPreviewComponent, - SsoTabComponent, - IdentityProviderCreateComponent, - IdentityProviderDetailsComponent, - InformationTabComponent, - GraphicIdentityTabComponent, - GraphicIdentityUpdateComponent, - GraphicIdentityComponent, - GraphicIdentityFormComponent, - HomepageMessageTabComponent, - HomepageMessageUpdateComponent, - HomepageMessageComponent, - HomepageMessageTranslationComponent, - ], - exports: [CustomerPreviewComponent, GraphicIdentityComponent, HomepageMessageComponent, HomepageMessageTranslationComponent], -}) -export class CustomerPreviewModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-tab.component.ts index 5a1f21138aa..82e8781c192 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-tab.component.ts @@ -34,21 +34,22 @@ * 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, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, inject, Input, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import type { Customer, Theme } from 'vitamui-library'; -import { ThemeColorType, ThemeService } from 'vitamui-library'; +import { Customer, PipesModule, Theme, ThemeColorType, ThemeService } from 'vitamui-library'; import { CustomerService } from '../../../core/customer.service'; import { GraphicIdentityUpdateComponent } from './graphic-identity-update/graphic-identity-update.component'; import { LogosSafeResourceUrl } from './logos-safe-resource-url.interface'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-graphic-identity-tab', templateUrl: './graphic-identity-tab.component.html', styleUrls: ['./graphic-identity-tab.component.scss'], - standalone: false, + imports: [MatProgressSpinner, PipesModule, TranslatePipe], }) export class GraphicIdentityTabComponent implements OnInit, OnDestroy { private customerService = inject(CustomerService); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.spec.ts deleted file mode 100644 index 1e29902c6fc..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.spec.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, forwardRef, Input } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { BASE_URL, Customer, ENVIRONMENT, InjectorModule, LoggerModule, OtpState, SnackBarService } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { environment } from './../../../../../environments/environment'; - -import { GraphicIdentityUpdateComponent } from './graphic-identity-update.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -const expectedCustomer: Customer = { - id: 'idCustomer', - identifier: '1', - enabled: true, - readonly: false, - hasCustomGraphicIdentity: false, - code: '154785', - name: 'nom du client', - companyName: 'nom de la société', - passwordRevocationDelay: 6, - otp: OtpState.DEACTIVATED, - idp: true, - address: { - street: '85 rue des bois', - zipCode: '75013', - city: 'Paris', - country: 'France', - }, - language: 'FRENCH', - emailDomains: ['domain.com'], - defaultEmailDomain: 'domain.com', - owners: [ - { - id: 'znvuzhvyvg', - identifier: '41', - code: '254791', - name: 'owner name', - companyName: 'company name', - address: { - street: '85 rue des bois', - zipCode: '75013', - city: 'Paris', - country: 'France', - }, - customerId: 'idCustomer', - readonly: false, - }, - ], - themeColors: {}, - gdprAlert: false, - gdprAlertDelay: 72, - portalMessages: {}, - portalTitles: {}, -}; - -@Component({ - selector: 'app-customer-colors-input', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => CustomerColorsInputStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class CustomerColorsInputStubComponent implements ControlValueAccessor { - @Input() - placeholder: string; - @Input() - spinnerDiameter = 25; - - writeValue() {} - - registerOnChange() {} - - registerOnTouched() {} -} - -describe('GraphicIdentityUpdateComponent', () => { - let component: GraphicIdentityUpdateComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - const matDialogRefSpy = { - close: vi.fn().mockName('MatDialogRef.close'), - }; - const snackBarSpy = { - open: vi.fn().mockName('SnackBarService.open'), - }; - await TestBed.configureTestingModule({ - declarations: [CustomerColorsInputStubComponent, GraphicIdentityUpdateComponent], - imports: [ReactiveFormsModule, VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: MatDialogRef, useValue: matDialogRefSpy }, - { provide: MAT_DIALOG_DATA, useValue: { customer: expectedCustomer, logo: null } }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: SnackBarService, useValue: snackBarSpy }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(GraphicIdentityUpdateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.ts index 072ac3da7cd..6e1cd09e2b8 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity-update/graphic-identity-update.component.ts @@ -34,20 +34,22 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { Customer, Logo } from 'vitamui-library'; import { CustomerService } from '../../../../core/customer.service'; import { LogosSafeResourceUrl } from './../logos-safe-resource-url.interface'; +import { GraphicIdentityComponent } from '../graphic-identity/graphic-identity.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-graphic-identity-update', templateUrl: './graphic-identity-update.component.html', styleUrls: ['./graphic-identity-update.component.scss'], - standalone: false, + imports: [GraphicIdentityComponent, MatDialogActions, TranslatePipe], }) export class GraphicIdentityUpdateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity-form/graphic-identity-form.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity-form/graphic-identity-form.component.ts index aa54e2cce2a..c199e5743cf 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity-form/graphic-identity-form.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity-form/graphic-identity-form.component.ts @@ -34,15 +34,17 @@ * 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, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { AttachmentType, Logo, ThemeService } from 'vitamui-library'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; +import { FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { AttachmentType, Logo, ThemeService, VitamuiDragDropFileComponent } from 'vitamui-library'; +import { CustomerColorsInputComponent } from '../../../../customer-create/customer-colors-input/customer-colors-input.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-graphic-identity-form', templateUrl: './graphic-identity-form.component.html', styleUrls: ['./graphic-identity-form.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, CustomerColorsInputComponent, VitamuiDragDropFileComponent, TranslatePipe], }) export class GraphicIdentityFormComponent implements OnInit { private themeService = inject(ThemeService); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity.component.ts index 4fd5ff5fa40..6666df310c3 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/graphic-identity-tab/graphic-identity/graphic-identity.component.ts @@ -34,13 +34,14 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms'; import { MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; -import type { Customer, Logo, Theme } from 'vitamui-library'; -import { ThemeColorType, ThemeService } from 'vitamui-library'; +import { Customer, Logo, SlideToggleComponent, Theme, ThemeColorType, ThemeService } from 'vitamui-library'; import type { LogosSafeResourceUrl } from './../logos-safe-resource-url.interface'; +import { GraphicIdentityFormComponent } from './graphic-identity-form/graphic-identity-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; interface ThemeColorGroup { [ThemeColorType.VITAMUI_PRIMARY]: FormControl; @@ -54,7 +55,7 @@ interface ThemeColorGroup { selector: 'app-graphic-identity', templateUrl: './graphic-identity.component.html', styleUrls: ['./graphic-identity.component.scss'], - standalone: false, + imports: [SlideToggleComponent, ReactiveFormsModule, GraphicIdentityFormComponent, TranslatePipe], }) export class GraphicIdentityComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-tab.component.ts index 43c630b4d92..4d7f9d0b3ef 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-tab.component.ts @@ -34,18 +34,19 @@ * 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, Input, OnDestroy, inject } from '@angular/core'; +import { Component, inject, Input, OnDestroy } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Subject } from 'rxjs'; -import type { Customer } from 'vitamui-library'; -import { StartupService } from 'vitamui-library'; +import { Customer, StartupService } from 'vitamui-library'; import { HomepageMessageUpdateComponent } from './homepage-message-update/homepage-message-update.component'; +import { KeyValuePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-homepage-message-tab', templateUrl: './homepage-message-tab.component.html', styleUrls: ['./homepage-message-tab.component.scss'], - standalone: false, + imports: [KeyValuePipe, TranslatePipe], }) export class HomepageMessageTabComponent implements OnDestroy { private dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-update/homepage-message-update.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-update/homepage-message-update.component.ts index f8b8f61acb6..1acaf6e8998 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-update/homepage-message-update.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message-update/homepage-message-update.component.ts @@ -34,19 +34,21 @@ * 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, OnDestroy, inject } from '@angular/core'; +import { Component, inject, OnDestroy } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ConfirmDialogService, Customer } from 'vitamui-library'; import { CustomerService } from '../../../../core/customer.service'; +import { HomepageMessageComponent } from '../homepage-message/homepage-message.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-homepage-message-update', templateUrl: './homepage-message-update.component.html', styleUrls: ['./homepage-message-update.component.scss'], - standalone: false, + imports: [HomepageMessageComponent, MatDialogActions, TranslatePipe], }) export class HomepageMessageUpdateComponent implements OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message-translation/homepage-message-translation.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message-translation/homepage-message-translation.ts index 47e58b2ebac..9fc2aadc134 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message-translation/homepage-message-translation.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message-translation/homepage-message-translation.ts @@ -35,15 +35,16 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; -import { FormGroup } from '@angular/forms'; +import { FormGroup, ReactiveFormsModule } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { Option } from 'vitamui-library'; +import { InputComponent, Option, SelectComponent } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-homepage-message-translation', templateUrl: './homepage-message-translation.html', styleUrls: ['./homepage-message-translation.scss'], - standalone: false, + imports: [ReactiveFormsModule, SelectComponent, InputComponent, TranslatePipe], }) export class HomepageMessageTranslationComponent implements OnInit, OnDestroy { @Input() diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message.component.ts index 24709ff80b0..563bc2361d3 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/homepage-message-tab/homepage-message/homepage-message.component.ts @@ -34,19 +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 { AfterViewInit, Component, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialogRef } from '@angular/material/dialog'; +import { AfterViewInit, Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; import { take, takeUntil } from 'rxjs/operators'; -import type { Customer, Option } from 'vitamui-library'; -import { LanguageService, StartupService } from 'vitamui-library'; +import { Customer, DialogHeaderComponent, InputComponent, LanguageService, Option, StartupService } from 'vitamui-library'; +import { HomepageMessageTranslationComponent } from './homepage-message-translation/homepage-message-translation'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-homepage-message', templateUrl: './homepage-message.component.html', styleUrls: ['./homepage-message.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + MatDialogContent, + ReactiveFormsModule, + InputComponent, + HomepageMessageTranslationComponent, + TranslatePipe, + ], }) export class HomepageMessageComponent implements OnInit, OnDestroy, AfterViewInit { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.spec.ts deleted file mode 100644 index 683094ae7fc..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.spec.ts +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, forwardRef, Input, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; -import type { AsyncValidator, Validator } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { EMPTY, of } from 'rxjs'; -import { BASE_URL, CountryService, LoggerModule, StartupService, WINDOW_LOCATION } from 'vitamui-library'; -import type { Customer } from 'vitamui-library'; -import { OtpState } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { CustomerService } from '../../../core/customer.service'; -import { CustomerCreateValidators } from '../../customer-create/customer-create.validators'; -import { InformationTabComponent } from './information-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -let expectedCustomer: Customer = { - id: '11', - identifier: '11', - code: '011000', - name: 'Kouygues Telecom', - companyName: 'Kouygues Telecom', - enabled: true, - readonly: false, - hasCustomGraphicIdentity: false, - language: 'FRENCH', - passwordRevocationDelay: 1, - otp: OtpState.OPTIONAL, - idp: false, - emailDomains: ['kouygues.com'], - defaultEmailDomain: 'kouygues.com', - address: { - street: '13 rue faubourg', - zipCode: '75009', - city: 'paris', - country: 'france', - }, - internalCode: '1', - owners: [], - themeColors: {}, - portalTitles: {}, - portalMessages: {}, - gdprAlert: false, - gdprAlertDelay: 72, -}; - -@Component({ - selector: 'app-editable-domain-input', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => EditableDomainInputStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class EditableDomainInputStubComponent implements ControlValueAccessor { - @Input() - validator: Validator; - @Input() - asyncValidator: AsyncValidator; - @Input() - defaultDomain: string; - - writeValue() {} - - registerOnChange() {} - - registerOnTouched() {} -} - -@Component({ - selector: 'app-customer-colors-input', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => CustomerColorsInputStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class CustomerColorsInputStubComponent implements ControlValueAccessor { - @Input() - placeholder: string; - @Input() - spinnerDiameter = 25; - - writeValue() {} - - registerOnChange() {} - - registerOnTouched() {} -} - -@Component({ - template: ` > - `, - standalone: false, -}) -class TestHostComponent { - customer = expectedCustomer; - readOnly = false; - gdprReadOnlyStatus = false; - - @ViewChild(InformationTabComponent, { static: false }) - component: InformationTabComponent; -} - -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('Customer InformationTabComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - expectedCustomer = { - id: '11', - identifier: '11', - code: '011000', - name: 'Kouygues Telecom', - companyName: 'Kouygues Telecom', - enabled: true, - readonly: false, - hasCustomGraphicIdentity: false, - language: 'FRENCH', - passwordRevocationDelay: 1, - otp: OtpState.OPTIONAL, - idp: false, - emailDomains: ['kouygues.com'], - defaultEmailDomain: 'kouygues.com', - address: { - street: '13 rue faubourg', - zipCode: '75009', - city: 'paris', - country: 'france', - }, - internalCode: '1', - owners: [], - themeColors: {}, - portalMessages: {}, - portalTitles: {}, - gdprAlert: false, - gdprAlertDelay: 72, - }; - const customerServiceSpy = { - patch: vi.fn().mockName('CustomerService.patch').mockReturnValue(of({})), - }; - const customerCreateValidatorsSpy = { - uniqueCode: vi - .fn() - .mockName('CustomerCreateValidators.uniqueCode') - .mockReturnValue(() => of(null)), - uniqueDomain: vi - .fn() - .mockName('CustomerCreateValidators.uniqueDomain') - .mockReturnValue(() => of(null)), - }; - - await TestBed.configureTestingModule({ - imports: [LoggerModule.forRoot(), NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule], - schemas: [NO_ERRORS_SCHEMA], - declarations: [InformationTabComponent, TestHostComponent, EditableDomainInputStubComponent, CustomerColorsInputStubComponent], - providers: [ - { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: StartupService, useValue: { getConfigNumberValue: () => 100 } }, - { provide: CustomerService, useValue: customerServiceSpy }, - { provide: CustomerCreateValidators, useValue: customerCreateValidatorsSpy }, - { provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }) - .overrideComponent(InformationTabComponent, { - set: { template: '' }, - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - - testhost.customer = expectedCustomer; - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - it('should have the correct fields', () => { - expect(testhost.component.form.get('id')).not.toBeNull(); - expect(testhost.component.form.get('code')).not.toBeNull(); - expect(testhost.component.form.get('name')).not.toBeNull(); - expect(testhost.component.form.get('companyName')).not.toBeNull(); - expect(testhost.component.form.get('passwordRevocationDelay')).not.toBeNull(); - expect(testhost.component.form.get('otp')).not.toBeNull(); - expect(testhost.component.form.get('address.street')).not.toBeNull(); - expect(testhost.component.form.get('address.zipCode')).not.toBeNull(); - expect(testhost.component.form.get('address.city')).not.toBeNull(); - expect(testhost.component.form.get('address.country')).not.toBeNull(); - expect(testhost.component.form.get('internalCode')).not.toBeNull(); - expect(testhost.component.form.get('language')).not.toBeNull(); - expect(testhost.component.form.get('emailDomains')).not.toBeNull(); - expect(testhost.component.form.get('defaultEmailDomain')).not.toBeNull(); - }); - - it('should have the required validator', () => { - testhost.component.form.setValue({ - id: null, - identifier: null, - code: null, - name: null, - companyName: null, - passwordRevocationDelay: null, - otp: null, - address: { - street: null, - zipCode: null, - city: null, - country: null, - }, - internalCode: null, - language: null, - emailDomains: null, - defaultEmailDomain: null, - gdprAlert: null, - gdprAlertDelay: null, - }); - expect(testhost.component.form.get('id').valid).toBeFalsy(); - expect(testhost.component.form.get('code').valid).toBeFalsy(); - expect(testhost.component.form.get('name').valid).toBeFalsy(); - expect(testhost.component.form.get('companyName').valid).toBeFalsy(); - expect(testhost.component.form.get('passwordRevocationDelay').valid).toBeFalsy(); - expect(testhost.component.form.get('otp').valid).toBeTruthy(); - expect(testhost.component.form.get('address.street').valid).toBeFalsy(); - expect(testhost.component.form.get('address.zipCode').valid).toBeFalsy(); - expect(testhost.component.form.get('address.city').valid).toBeFalsy(); - expect(testhost.component.form.get('address.country').valid).toBeFalsy(); - expect(testhost.component.form.get('language').valid).toBeFalsy(); - expect(testhost.component.form.get('emailDomains').valid).toBeFalsy(); - expect(testhost.component.form.get('defaultEmailDomain').valid).toBeFalsy(); - }); - - it('should have the pattern validator', () => { - const codeControl = testhost.component.form.get('code'); - codeControl.setValue('a'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('123456a'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('aaaaaa'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('1234'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('1234_'); - expect(codeControl.valid).toBeFalsy(); - codeControl.setValue('1234_qzdqzdzqdzqd48d5zq41d5qz1d654'); - expect(codeControl.valid).toBeFalsy(); - }); - - it('should be valid and call update()', () => { - testhost.component.form.setValue({ - id: expectedCustomer.id, - identifier: expectedCustomer.identifier, - code: expectedCustomer.code, - name: expectedCustomer.name, - companyName: expectedCustomer.companyName, - passwordRevocationDelay: expectedCustomer.passwordRevocationDelay, - otp: expectedCustomer.otp, - address: { - street: expectedCustomer.address.street, - zipCode: expectedCustomer.address.zipCode, - city: expectedCustomer.address.city, - country: expectedCustomer.address.country, - }, - internalCode: expectedCustomer.internalCode, - language: expectedCustomer.language, - emailDomains: expectedCustomer.emailDomains, - defaultEmailDomain: expectedCustomer.defaultEmailDomain, - gdprAlert: expectedCustomer.gdprAlert, - gdprAlertDelay: expectedCustomer.gdprAlertDelay, - }); - expect(testhost.component.form.valid).toBeTruthy(); - }); - - it('should disable then enable the form', () => { - testhost.component.readOnly = true; - expect(testhost.component.form.disabled).toBe(true); - testhost.component.readOnly = false; - expect(testhost.component.form.disabled).toBe(false); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.ts index 98e688d7ffd..8f16e03bd8a 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/information-tab/information-tab.component.ts @@ -34,16 +34,40 @@ * 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, Input, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { merge, of, Subscription } from 'rxjs'; import { catchError, debounceTime, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { CountryOption, Customer, OtpState } from 'vitamui-library'; -import { CountryService, diff, Option, StartupService } from 'vitamui-library'; +import { + CountryOption, + CountryService, + Customer, + diff, + EditableButtonToggleComponent, + EditableInputComponent, + EditableToggleGroupComponent, + FormFieldValueWrapperComponent, + Option, + OtpState, + SelectComponent, + SlideToggleComponent, + StartupService, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { CustomerService } from '../../../core/customer.service'; import { ALPHA_NUMERIC_REGEX, CUSTOMER_CODE_MAX_LENGTH, CustomerCreateValidators } from '../../customer-create/customer-create.validators'; +import { EditableDomainInputComponent } from '../../../shared/editable-field/editable-domain-input/editable-domain-input.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const UPDATE_DEBOUNCE_TIME = 200; @@ -51,7 +75,27 @@ const UPDATE_DEBOUNCE_TIME = 200; selector: 'app-information-tab', templateUrl: './information-tab.component.html', styleUrls: ['./information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + VitamUIFieldErrorComponent, + FormFieldValueWrapperComponent, + SelectComponent, + EditableDomainInputComponent, + SlideToggleComponent, + TranslatePipe, + CommonModule, + EditableButtonToggleComponent, + EditableInputComponent, + EditableToggleGroupComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class InformationTabComponent implements OnInit, OnDestroy { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.spec.ts index 9f2054b9454..0fca023cd5f 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.spec.ts @@ -41,7 +41,6 @@ import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelect, MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of, throwError as observableThrowError } from 'rxjs'; import { AuthnRequestBindingEnum, ConfirmDialogService, newFile } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -58,7 +57,7 @@ import { IdentityProviderCreateComponent } from './identity-provider-create.comp multi: true, }, ], - standalone: false, + imports: [MatProgressBarModule, ReactiveFormsModule, MatButtonToggleModule, MatSelectModule, VitamUICommonTestModule], }) class PatternStubComponent implements ControlValueAccessor { @Input() @@ -99,11 +98,11 @@ describe('IdentityProviderCreateComponent', () => { ReactiveFormsModule, MatButtonToggleModule, MatSelectModule, - NoopAnimationsModule, VitamUICommonTestModule, + IdentityProviderCreateComponent, + PatternStubComponent, ], schemas: [NO_ERRORS_SCHEMA], - declarations: [IdentityProviderCreateComponent, PatternStubComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: { customer: { id: '42', name: 'OwnerName' } } }, diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.ts index 26e193d78e9..f48d15af790 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-create/identity-provider-create.component.ts @@ -34,19 +34,53 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import { AuthnRequestBindingEnum, ConfirmDialogService, Customer, IdentityProvider } from 'vitamui-library'; +import { + AuthnRequestBindingEnum, + ConfirmDialogService, + Customer, + DialogHeaderComponent, + IdentityProvider, + InputComponent, + NextStepComponent, + PatternComponent, + PreviousStepComponent, + SelectComponent, + SlideToggleComponent, + StepperComponent, +} from 'vitamui-library'; import { IdentityProviderService } from '../identity-provider.service'; import JWS_ALGORITHMS, { ProtocoleType } from '../sso-tab-const'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { CustomParamsComponent } from '../../../../shared/custom-params/custom-params.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-identity-provider-create', templateUrl: './identity-provider-create.component.html', styleUrls: ['./identity-provider-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + SlideToggleComponent, + MatButtonToggleGroup, + MatButtonToggle, + InputComponent, + PatternComponent, + MatDialogActions, + NextStepComponent, + PreviousStepComponent, + SelectComponent, + CustomParamsComponent, + TranslatePipe, + ], }) export class IdentityProviderCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.spec.ts deleted file mode 100644 index f944f03cc62..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.spec.ts +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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, forwardRef, Input, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; -import type { AsyncValidator, Validator } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of } from 'rxjs'; - -import { AuthnRequestBindingEnum } from 'vitamui-library'; -import type { IdentityProvider } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { IdentityProviderService } from '../identity-provider.service'; -import { IdentityProviderDetailsComponent } from './identity-provider-details.component'; - -@Component({ - selector: 'app-editable-keystore', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => EditableKeystoreStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class EditableKeystoreStubComponent implements ControlValueAccessor { - @Input() - validator: Validator; - @Input() - asyncValidator: AsyncValidator; - @Input() - identityProvider: any; - @Input() - disabled: boolean; - writeValue() {} - registerOnChange() {} - registerOnTouched() {} -} - -@Component({ - selector: 'app-editable-patterns', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => EditablePatternStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class EditablePatternStubComponent implements ControlValueAccessor { - @Input() - validator: Validator; - @Input() - asyncValidator: AsyncValidator; - @Input() - options: any; - writeValue() {} - registerOnChange() {} - registerOnTouched() {} -} - -@Component({ - template: ` - - `, - standalone: false, -}) -class TestHostComponent { - @ViewChild(IdentityProviderDetailsComponent, { static: false }) - component: IdentityProviderDetailsComponent; - provider: IdentityProvider = { - propagateLogout: false, - id: '42', - customerId: '1234', - identifier: '2', - name: 'Test IDP', - technicalName: 'Test IDP', - internal: true, - keystorePassword: 'testpassword1234', - - patterns: ['test1.com', 'test3.com'], - enabled: true, - keystore: null, - idpMetadata: null, - readonly: false, - mailAttribute: 'mailAttribute', - identifierAttribute: 'identifierAttribute', - authnRequestBinding: AuthnRequestBindingEnum.POST, - autoProvisioningEnabled: false, - authnRequestSigned: false, - maximumAuthenticationLifetime: 0, - wantsAssertionsSigned: false, - }; - domains = [ - { value: 'test1.com', disabled: true }, - { value: 'test2.com', disabled: true }, - { value: 'test3.com', disabled: true }, - { value: 'test4.com', disabled: false }, - { value: 'test5.com', disabled: false }, - ]; - readOnly: boolean; -} - -describe('IdentityProviderDetailsComponent', () => { - it('TODO - skipped tests pending migration', () => { - // Placeholder: tests below are skipped pending migration - }); -}); - -describe.skip('IdentityProviderDetailsComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, NoopAnimationsModule, VitamUICommonTestModule], - declarations: [IdentityProviderDetailsComponent, TestHostComponent, EditableKeystoreStubComponent, EditablePatternStubComponent], - providers: [{ provide: IdentityProviderService, useValue: { patch: () => of(null), updateMetadataFile: () => of(null) } }], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - @NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) - class TestHostModule {} - describe('Class', () => { - it('should set the form value', () => { - expect(testhost.component.form.getRawValue()).toEqual({ - authnRequestBinding: 'POST', - autoProvisioningEnabled: false, - clientId: null, - clientSecret: null, - customParams: null, - discoveryUrl: null, - enabled: true, - identifier: '2', - identifierAttribute: 'identifierAttribute', - internal: true, - mailAttribute: 'mailAttribute', - name: 'Test IDP', - patterns: ['test1.com', 'test3.com'], - preferredJwsAlgorithm: null, - protocoleType: null, - scope: null, - useNonce: null, - usePkce: null, - useState: null, - }); - }); - - it('should enable the pattern used by the provider', () => { - expect(testhost.component.domains).toEqual([ - { value: 'test1.com', disabled: false }, - { value: 'test2.com', disabled: true }, - { value: 'test3.com', disabled: false }, - { value: 'test4.com', disabled: false }, - { value: 'test5.com', disabled: false }, - ]); - }); - - it('should have the correct fields', () => { - expect(testhost.component.form.get('id')).toBeNull(); - expect(testhost.component.form.get('identifier')).not.toBeNull(); - expect(testhost.component.form.get('enabled')).not.toBeNull(); - expect(testhost.component.form.get('name')).not.toBeNull(); - expect(testhost.component.form.get('internal')).not.toBeNull(); - expect(testhost.component.form.get('patterns')).not.toBeNull(); - expect(testhost.component.form.get('mailAttribute')).not.toBeNull(); - expect(testhost.component.form.get('identifierAttribute')).not.toBeNull(); - expect(testhost.component.form.get('authnRequestBinding')).not.toBeNull(); - expect(testhost.component.form.get('autoProvisioningEnabled')).not.toBeNull(); - }); - - it('should have the required validator', () => { - testhost.component.form.setValue({ - identifier: null, - enabled: null, - name: null, - internal: null, - patterns: null, - mailAttribute: null, - identifierAttribute: null, - authnRequestBinding: null, - autoProvisioningEnabled: null, - protocoleType: null, - clientId: null, - clientSecret: null, - customParams: null, - discoveryUrl: null, - scope: null, - preferredJwsAlgorithm: null, - useNonce: null, - usePkce: null, - useState: null, - }); - expect(testhost.component.form.get('enabled').valid).toBeFalsy(); - expect(testhost.component.form.get('identifier').valid).toBeFalsy(); - expect(testhost.component.form.get('name').valid).toBeFalsy(); - expect(testhost.component.form.get('internal').valid).toBeFalsy(); - expect(testhost.component.form.get('patterns').valid).toBeFalsy(); - expect(testhost.component.form.get('mailAttribute').valid).toBeTruthy(); - expect(testhost.component.form.get('authnRequestBinding').valid).toBeFalsy(); - expect(testhost.component.form.get('autoProvisioningEnabled').valid).toBeFalsy(); - }); - - it('should be valid and call patch()', waitForAsync(() => { - const providerService = TestBed.inject(IdentityProviderService); - vi.spyOn(providerService, 'patch').mockReturnValue(of(null)); - testhost.component.form.setValue({ - identifier: testhost.provider.identifier, - enabled: false, - name: testhost.provider.name, - internal: testhost.provider.internal, - patterns: testhost.provider.patterns, - mailAttribute: testhost.provider.mailAttribute, - identifierAttribute: testhost.provider.identifierAttribute, - authnRequestBinding: testhost.provider.authnRequestBinding, - autoProvisioningEnabled: false, - protocoleType: 'SAML', - clientId: 2, - clientSecret: 'secret', - discoveryUrl: 'discoveryUrl', - scope: 'private', - preferredJwsAlgorithm: 'HS-256', - customParams: { key: 'value' }, - useNonce: true, - usePkce: true, - useState: true, - }); - expect(testhost.component.form.valid).toBeTruthy(); - })); - - it('should call updateMetadataFile'); - - it('should disable then enable the form', () => { - testhost.readOnly = true; - fixture.detectChanges(); - expect(testhost.component.form.disabled).toBe(true); - expect(testhost.component.idpMetadata.disabled).toBe(true); - testhost.readOnly = false; - fixture.detectChanges(); - expect(testhost.component.form.disabled).toBe(false); - expect(testhost.component.idpMetadata.disabled).toBe(false); - }); - }); - - describe('DOM', () => { - it('TODO', () => { - // TODO - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.ts index b71f5f66816..38b19a5c588 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider-details/identity-provider-details.component.ts @@ -34,16 +34,40 @@ * 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, Input, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { merge } from 'rxjs'; import { debounceTime, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty, isEqual, isObject, mapObject, omit } from 'underscore'; -import type { IdentityProvider } from 'vitamui-library'; -import { AuthnRequestBindingEnum, newFile, SnackBarService } from 'vitamui-library'; +import { + AuthnRequestBindingEnum, + EditableButtonToggleComponent, + EditableFileComponent, + EditableInputComponent, + EditableToggleGroupComponent, + FormFieldValueWrapperComponent, + IdentityProvider, + newFile, + SelectComponent, + SlideToggleComponent, + SnackBarService, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { IdentityProviderService } from '../identity-provider.service'; import JWS_ALGORITHMS, { ProtocoleType } from '../sso-tab-const'; +import { EditablePatternsComponent } from '../../../../shared/editable-field/editable-patterns/editable-patterns.component'; +import { EditableKeystoreComponent } from '../../../../shared/editable-field/editable-keystore/editable-keystore.component'; +import { EditableCustomParamsComponent } from '../../../../shared/editable-field/editable-custom-params/editable-custom-params.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const UPDATE_DEBOUNCE_TIME = 200; @@ -51,7 +75,30 @@ const UPDATE_DEBOUNCE_TIME = 200; selector: 'app-identity-provider-details', templateUrl: './identity-provider-details.component.html', styleUrls: ['./identity-provider-details.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + SlideToggleComponent, + VitamUIFieldErrorComponent, + EditablePatternsComponent, + EditableKeystoreComponent, + EditableCustomParamsComponent, + FormFieldValueWrapperComponent, + SelectComponent, + TranslatePipe, + CommonModule, + EditableButtonToggleComponent, + EditableFileComponent, + EditableInputComponent, + EditableToggleGroupComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class IdentityProviderDetailsComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.spec.ts index 110beb9ba59..1ca4f971411 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.spec.ts @@ -34,10 +34,9 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { - BASE_URL, CriteriaSearchQuery, ENVIRONMENT, IdentityProvider, @@ -50,7 +49,6 @@ import { environment } from './../../../../environments/environment'; import { Type } from '@angular/core'; import { IdentityProviderService } from './identity-provider.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('IdentityProviderService', () => { let httpTestingController: HttpTestingController; @@ -98,11 +96,8 @@ describe('IdentityProviderService', () => { providers: [ IdentityProviderService, { provide: SnackBarService, useValue: snackBarSpy }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: WINDOW_LOCATION, useValue: {} }, { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.ts index 22d2a1383b8..bea283967c8 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/identity-provider.service.ts @@ -36,10 +36,10 @@ */ import { Observable, Subject } from 'rxjs'; import { map, tap } from 'rxjs/operators'; -import { Criterion, CriteriaSearchQuery, IdentityProvider, Operators, SnackBarService } from 'vitamui-library'; +import { CriteriaSearchQuery, Criterion, IdentityProvider, Operators, SnackBarService } from 'vitamui-library'; import { HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ProviderApiService } from './provider-api.service'; diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/provider-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/provider-api.service.spec.ts index 347e21a7fee..70e7aaf8aa9 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/provider-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/provider-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from 'vitamui-library'; import { ProviderApiService } from './provider-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('ProviderApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.spec.ts deleted file mode 100644 index 749522751ab..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.spec.ts +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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, Input, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatDialog } from '@angular/material/dialog'; -import { of, Subject } from 'rxjs'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { BASE_URL, OtpState, SnackBarService } from 'vitamui-library'; -import type { Customer, IdentityProvider } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { IdentityProviderService } from './identity-provider.service'; -import { ProviderApiService } from './provider-api.service'; -import { SsoTabComponent } from './sso-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -@Component({ - selector: 'app-identity-provider-details', - template: '', - standalone: false, -}) -class IdentityProviderDetailsStubComponent { - @Input() - identityProvider: IdentityProvider; - @Input() - domains: any; - @Input() - readOnly: boolean; -} - -@Component({ - template: ` `, - standalone: false, -}) -class TestHostComponent { - customer: Customer = { - id: '5ad5f14c894e6a414edc7b5ffd02766b442f4256b563a6e3909e05b9e3abf9ea', - identifier: '1', - code: '015000', - name: 'TeamVitamUI', - companyName: 'vitamui', - enabled: false, - readonly: false, - hasCustomGraphicIdentity: false, - language: 'FRENCH', - passwordRevocationDelay: 9, - otp: OtpState.OPTIONAL, - emailDomains: ['vitamui.com', '1test.com', 'test2.com', 'test3.com', 'test4.com', 'test5.com', 'test6.com'], - defaultEmailDomain: '1test.com', - address: { - street: '73 rue du Faubourg Poissonnière ', - zipCode: '75009', - city: 'Paris', - country: 'DK', - }, - owners: [], - themeColors: {}, - gdprAlert: false, - gdprAlertDelay: 72, - portalMessages: {}, - portalTitles: {}, - }; - @ViewChild(SsoTabComponent, { static: false }) - component: SsoTabComponent; -} - -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('SsoTabComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - let providers: any[]; - - beforeEach(async () => { - providers = [ - { - id: '5ad5f14c894e6a414edc7b60c5397d744f4b4ed8bd86934d0a8e8311add40f3f', - customerId: '5ad5f14c894e6a414edc7b5ffd02766b442f4256b563a6e3909e05b9e3abf9ea', - name: 'default', - internal: true, - enabled: true, - patterns: null, - keystoreBase64: null, - keystorePassword: null, - privateKeyPassword: null, - idpMetadata: null, - spMetadata: null, - }, - { - id: '5ad5f14e894e6a414edc7b91dc194c3187f143cbb7593242769a1706fd03d3f3', - customerId: '5ad5f14c894e6a414edc7b5ffd02766b442f4256b563a6e3909e05b9e3abf9ea', - name: 'TeamVitamUI', - internal: true, - enabled: true, - patterns: null, - keystoreBase64: null, - keystorePassword: null, - privateKeyPassword: null, - idpMetadata: null, - spMetadata: null, - }, - { - id: '5af95fae636f9114e074100590122991ac38418595cd0dab684fee3bccacd2dd', - customerId: '5ad5f14c894e6a414edc7b5ffd02766b442f4256b563a6e3909e05b9e3abf9ea', - name: 'test', - internal: false, - enabled: true, - patterns: ['vitamui.com'], - keystoreBase64: null, - keystorePassword: 'test', - privateKeyPassword: 'test', - idpMetadata: null, - spMetadata: null, - }, - ]; - - const matDialogSpy = { - open: vi.fn().mockName('MatDialog.open'), - }; - matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); - - await TestBed.configureTestingModule({ - declarations: [SsoTabComponent, IdentityProviderDetailsStubComponent, TestHostComponent], - imports: [VitamUICommonTestModule], - providers: [ - ProviderApiService, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: MatDialog, useValue: matDialogSpy }, - { provide: SnackBarService, useValue: { notifyDownloadStarted: vi.fn().mockName('SnackBarService.notifyDownloadStarted') } }, - { - provide: IdentityProviderService, - useValue: { - getAll: () => of(providers), - getDomainByCustomerId: () => of(['test1.com', 'test2.com']), - updated: new Subject(), - }, - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - it('should set the providers', () => { - expect(testhost.component.providers).toEqual(providers); - }); - - it('should call open', () => { - const matDialogSpy = TestBed.inject(MatDialog); - testhost.component.openCreateIDPDialog(); - expect(matDialogSpy.open).toHaveBeenCalled(); - }); - - describe('DOM', () => { - describe('Button "Create IDP"', () => { - it('should exist', () => { - const elButton = fixture.nativeElement.querySelector('button'); - expect(elButton).toBeTruthy(); - expect(elButton.textContent).toContain('CUSTOMER.SSO.BUTTON'); - }); - - it('should call openCreateIDPDialog()', () => { - vi.spyOn(testhost.component, 'openCreateIDPDialog').mockImplementation(() => {}); - const elButton = fixture.nativeElement.querySelector('button'); - elButton.click(); - expect(testhost.component.openCreateIDPDialog).toHaveBeenCalled(); - }); - - it('should be disabled', () => { - vi.spyOn(testhost.component, 'openCreateIDPDialog').mockImplementation(() => {}); - testhost.component.domains = [{ value: 'test.com', disabled: true }]; - expect(testhost.component.domainsAvailable).toBeFalsy(); - expect(testhost.component.openCreateIDPDialog).not.toHaveBeenCalled(); - }); - - it('should not show up in readonly mode', () => { - testhost.component.readOnly = true; - fixture.detectChanges(false); - expect(testhost.component.readOnly).toBe(true); - }); - }); - - describe('Providers List', () => { - it('should display the list of providers', () => { - const elProviders = fixture.nativeElement.querySelectorAll('.provider-item-content'); - expect(elProviders.length).toBe(3); - elProviders.forEach((elProvider: HTMLElement, index: number) => { - expect(elProvider.textContent).toContain(providers[index].name); - expect(elProvider.textContent).toContain(providers[index].internal ? 'CUSTOMER.SSO.TYPE_INTERNAL' : 'CUSTOMER.SSO.TYPE_EXTERNAL'); - expect(elProvider.textContent).toContain( - providers[index].enabled ? 'CUSTOMER.SSO.STATUS_ACTIVE' : 'CUSTOMER.SSO.STATUS_INACTIVE', - ); - }); - }); - - it('should select the provider on click', () => { - const elProviders = fixture.nativeElement.querySelectorAll('.provider-item-content'); - elProviders[0].click(); - fixture.detectChanges(); - expect(testhost.component.selectedIdentityProvider).toBe(testhost.component.providers[0]); - }); - }); - - describe('Provider Details', () => { - it('should not show if no provider is selected', () => { - const elProviderDetails = fixture.nativeElement.querySelector('app-identity-provider-details'); - expect(elProviderDetails).toBeFalsy(); - }); - - it('should show when a provider is selected', () => { - testhost.component.selectIdentityProvider(providers[0]); - expect(testhost.component.selectedIdentityProvider).toBe(providers[0]); - }); - - it('should have a "back" button', () => { - testhost.component.selectIdentityProvider(providers[0]); - expect(testhost.component.selectedIdentityProvider).toBeTruthy(); - testhost.component.selectedIdentityProvider = null; - expect(testhost.component.selectedIdentityProvider).toBeFalsy(); - }); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.ts index 91f4a88ff57..4c1367f446a 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer-preview/sso-tab/sso-tab.component.ts @@ -34,21 +34,23 @@ * 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, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, inject, Input, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import type { Customer, IdentityProvider } from 'vitamui-library'; -import { DownloadUtils, SnackBarService } from 'vitamui-library'; +import { DownloadUtils, SnackBarService, TooltipDirective } from 'vitamui-library'; import { IdentityProviderCreateComponent } from './identity-provider-create/identity-provider-create.component'; import { IdentityProviderService } from './identity-provider.service'; import { ProviderApiService } from './provider-api.service'; +import { IdentityProviderDetailsComponent } from './identity-provider-details/identity-provider-details.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-sso-tab', templateUrl: './sso-tab.component.html', styleUrls: ['./sso-tab.component.scss'], - standalone: false, + imports: [TooltipDirective, IdentityProviderDetailsComponent, TranslatePipe], }) export class SsoTabComponent implements OnDestroy, OnInit { dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer.component.spec.ts index eccdb309a85..c8055c4f319 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer.component.spec.ts @@ -36,20 +36,25 @@ */ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { EMPTY, of } from 'rxjs'; -import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { EMPTY, of, Subject } from 'rxjs'; +import { ENVIRONMENT, InjectorModule, LoggerModule, StartupService } from 'vitamui-library'; import { environment } from './../../environments/environment'; import { MatDialog } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; import { CustomerCreateComponent } from './customer-create/customer-create.component'; import { CustomerComponent } from './customer.component'; +import { CustomerListComponent } from './customer-list/customer-list.component'; +import { CustomerPreviewComponent } from './customer-preview/customer-preview.component'; +import { OwnerPreviewComponent } from './owner-preview/owner-preview.component'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { CustomerService } from '../core/customer.service'; +import { CustomerDataService } from './customer.data.service'; +import { OwnerService } from './owner.service'; +import { TenantService } from './tenant.service'; let component: CustomerComponent; let fixture: ComponentFixture; @@ -59,7 +64,7 @@ class Page { return fixture.nativeElement.querySelector('app-customer-list'); } get createCustomer() { - return fixture.nativeElement.querySelector('.vitamui-heading button:first-child'); + return fixture.nativeElement.querySelector('.vitamui-heading vitamui-banner button.btn.primary'); } } @@ -68,7 +73,7 @@ let page: Page; @Component({ selector: 'app-customer-list', template: '', - standalone: false, + imports: [MatMenuModule, MatSidenavModule, VitamUICommonTestModule], }) class CustomerListStubComponent { search() {} @@ -77,7 +82,7 @@ class CustomerListStubComponent { @Component({ selector: 'app-customer-preview', template: '', - standalone: false, + imports: [MatMenuModule, MatSidenavModule, VitamUICommonTestModule], }) class CustomerPreviewStubComponent { @Input() @@ -91,7 +96,7 @@ class CustomerPreviewStubComponent { @Component({ selector: 'app-owner-preview', template: '', - standalone: false, + imports: [MatMenuModule, MatSidenavModule, VitamUICommonTestModule], }) class OwnerPreviewStubComponent { @Input() @@ -105,6 +110,18 @@ class OwnerPreviewStubComponent { describe('CustomerComponent', () => { const customerServiceSpy = { getGdprReadOnlySettingStatus: () => of(true), + updated: new Subject(), + }; + const tenantServiceSpy = { + updated: new Subject(), + }; + const ownerServiceSpy = { + updated: new Subject(), + }; + const startupServiceStub = { + getPortalUrl: () => 'https://dev.vitamui.com', + getConfigStringValue: () => 'https://dev.vitamui.com/identity', + getConfigNumberValue: () => 0, }; beforeEach(async () => { @@ -114,15 +131,37 @@ describe('CustomerComponent', () => { matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - imports: [MatMenuModule, MatSidenavModule, NoopAnimationsModule, VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot()], - declarations: [CustomerComponent, CustomerListStubComponent, CustomerPreviewStubComponent, OwnerPreviewStubComponent], + imports: [ + MatMenuModule, + MatSidenavModule, + VitamUICommonTestModule, + InjectorModule, + LoggerModule.forRoot(), + CustomerComponent, + CustomerListStubComponent, + CustomerPreviewStubComponent, + OwnerPreviewStubComponent, + ], providers: [ { provide: CustomerService, useValue: customerServiceSpy }, + { provide: TenantService, useValue: tenantServiceSpy }, + { provide: OwnerService, useValue: ownerServiceSpy }, + { provide: CustomerDataService, useValue: {} }, + { provide: StartupService, useValue: startupServiceStub }, { provide: MatDialog, useValue: matDialogSpy }, - { provide: ActivatedRoute, useValue: { data: EMPTY } }, + { provide: ActivatedRoute, useValue: { data: EMPTY, snapshot: { data: { appId: 'CUSTOMERS_APP' } } } }, { provide: ENVIRONMENT, useValue: environment }, ], - }).compileComponents(); + }) + .overrideComponent(CustomerComponent, { + remove: { + imports: [CustomerListComponent, CustomerPreviewComponent, OwnerPreviewComponent], + }, + add: { + imports: [CustomerListStubComponent, CustomerPreviewStubComponent, OwnerPreviewStubComponent], + }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer.component.ts index 34088f17361..6f23090cd52 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer.component.ts @@ -34,25 +34,36 @@ * 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, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; -import { Customer, GlobalEventService, Owner, SidenavPage, Tenant } from 'vitamui-library'; +import { Customer, Owner, SidenavPage, Tenant, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { CustomerService } from '../core/customer.service'; import { CustomerCreateComponent } from './customer-create/customer-create.component'; import { CustomerListComponent } from './customer-list/customer-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { CustomerPreviewComponent } from './customer-preview/customer-preview.component'; +import { OwnerPreviewComponent } from './owner-preview/owner-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-customer', templateUrl: './customer.component.html', styleUrls: ['./customer.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + CustomerPreviewComponent, + OwnerPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + CustomerListComponent, + TranslatePipe, + ], }) export class CustomerComponent extends SidenavPage implements OnInit { private dialog = inject(MatDialog); - route: ActivatedRoute; - override globalEventService: GlobalEventService; customerService = inject(CustomerService); public customers: Customer[]; @@ -62,16 +73,6 @@ export class CustomerComponent extends SidenavPage im @ViewChild(CustomerListComponent, { static: true }) customerListComponent: CustomerListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - this.globalEventService = globalEventService; - } - ngOnInit() { this.customerService.getGdprReadOnlySettingStatus().subscribe((settingStatus) => { this.gdprReadOnlySettingStatus = settingStatus; diff --git a/ui/ui-frontend/projects/identity/src/app/customer/customer.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/customer.module.ts index 9a7da4a1437..35d20b492f4 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/customer.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/customer.module.ts @@ -41,36 +41,25 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; -import { CustomerCreateModule } from './customer-create/customer-create.module'; -import { CustomerListModule } from './customer-list/customer-list.module'; -import { CustomerPreviewModule } from './customer-preview/customer-preview.module'; + import { CustomerPopupComponent } from './customer-preview/customer-popup.component'; import { CustomerRoutingModule } from './customer-routing.module'; import { CustomerComponent } from './customer.component'; -import { OwnerCreateModule } from './owner-create/owner-create.module'; -import { OwnerPreviewModule } from './owner-preview/owner-preview.module'; -import { TenantCreateModule } from './tenant-create/tenant-create.module'; + import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ imports: [ CommonModule, - SharedModule, VitamUICommonModule, - CustomerCreateModule, - CustomerListModule, - CustomerPreviewModule, MatDialogModule, MatMenuModule, - OwnerPreviewModule, - OwnerCreateModule, - TenantCreateModule, MatSidenavModule, CustomerRoutingModule, TranslatePipe, + CustomerComponent, + CustomerPopupComponent, ], - declarations: [CustomerComponent, CustomerPopupComponent], exports: [], }) export class CustomerModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-api.service.spec.ts index 1666b9a1139..fcef0ea0daa 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from 'vitamui-library'; import { OwnerApiService } from './owner-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('OwnerApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.spec.ts index 626e1c7988e..c4d36097ef4 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.spec.ts @@ -39,7 +39,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService, Owner, Tenant } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -61,7 +60,7 @@ import { MatOptionModule } from '@angular/material/core'; multi: true, }, ], - standalone: false, + imports: [MatOptionModule, MatProgressBarModule, MatSelectModule, ReactiveFormsModule, VitamUICommonTestModule], }) class OwnerFormStubComponent implements ControlValueAccessor { @Input() @@ -124,8 +123,15 @@ describe('OwnerCreateComponent', () => { }; await TestBed.configureTestingModule({ - imports: [MatOptionModule, MatProgressBarModule, MatSelectModule, NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule], - declarations: [OwnerCreateComponent, OwnerFormStubComponent], + imports: [ + MatOptionModule, + MatProgressBarModule, + MatSelectModule, + ReactiveFormsModule, + VitamUICommonTestModule, + OwnerCreateComponent, + OwnerFormStubComponent, + ], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: { customer: { id: '42', name: 'OwnerName' } } }, diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.ts index 459c0737652..cdf74c84df9 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.component.ts @@ -34,21 +34,47 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { concatMap, finalize, Observable, Subscription } from 'rxjs'; -import { ConfirmDialogService, Customer, Owner, Tenant } from 'vitamui-library'; +import { + ConfirmDialogService, + Customer, + DialogHeaderComponent, + InputComponent, + Owner, + PreviousStepComponent, + SelectComponent, + StepperComponent, + Tenant, +} from 'vitamui-library'; import { OwnerService } from '../owner.service'; import { TenantFormValidators } from '../tenant-create/tenant-form.validators'; import { TenantService } from '../tenant.service'; import { map, tap } from 'rxjs/operators'; +import { CdkStep, CdkStepperNext } from '@angular/cdk/stepper'; +import { OwnerFormComponent } from '../owner-form/owner-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-owner-create', templateUrl: './owner-create.component.html', styleUrls: ['./owner-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + StepperComponent, + CdkStep, + ReactiveFormsModule, + MatDialogContent, + OwnerFormComponent, + MatDialogActions, + CdkStepperNext, + InputComponent, + SelectComponent, + PreviousStepComponent, + TranslatePipe, + ], }) export class OwnerCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.module.ts deleted file mode 100644 index 83b7a2c4a1d..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-create/owner-create.module.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { OwnerFormModule } from '../owner-form/owner-form.module'; -import { OwnerCreateComponent } from './owner-create.component'; -import { MatOptionModule } from '@angular/material/core'; -import { MatSelectModule } from '@angular/material/select'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatProgressBarModule, - ReactiveFormsModule, - OwnerFormModule, - VitamUICommonModule, - MatOptionModule, - MatSelectModule, - VitamUILibraryModule, - MatDialogModule, - TranslatePipe, - ], - declarations: [OwnerCreateComponent], -}) -export class OwnerCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.spec.ts deleted file mode 100644 index 484dd3b2af1..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.spec.ts +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { EMPTY, of, timer } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { BASE_URL, CountryService, LoggerModule, Owner, StartupService, WINDOW_LOCATION } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { OwnerService } from '../owner.service'; -import { OwnerFormComponent } from './owner-form.component'; -import { OwnerFormValidators } from './owner-form.validators'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -@Component({ - template: ` `, - standalone: false, -}) -class TesthostComponent { - owner: Owner = null; - customerId = '4242'; - @ViewChild(OwnerFormComponent, { static: false }) - ownerFormComponent: OwnerFormComponent; -} - -let testhost: TesthostComponent; -let fixture: ComponentFixture; - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('OwnerFormComponent', () => { - beforeEach(async () => { - const ownerServiceSpy = { - create: vi.fn().mockName('OwnerService.create').mockReturnValue(of({})), - }; - const ownerFormValidatorsSpy = { - uniqueCode: vi - .fn() - .mockName('OwnerFormValidators.uniqueCode') - .mockReturnValue(() => timer(10).pipe(map((): any => null))), - }; - - await TestBed.configureTestingModule({ - declarations: [OwnerFormComponent, TesthostComponent], - schemas: [NO_ERRORS_SCHEMA], - imports: [FormsModule, LoggerModule.forRoot(), MatSelectModule, NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule], - providers: [ - { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: OwnerService, useValue: ownerServiceSpy }, - { provide: OwnerFormValidators, useValue: ownerFormValidatorsSpy }, - { provide: StartupService, useValue: { getConfigNumberValue: () => 100 } }, - { provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }) - .overrideComponent(OwnerFormComponent, { set: { template: '' } }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - it('should set owner to null', () => { - expect(testhost.owner).toBe(null); - }); - - it('should set owner to a value', fakeAsync(() => { - const owner: Owner = { - id: null, - identifier: null, - customerId: '4242', - code: '43214345345', - name: 'Toto', - companyName: 'Toto & Co.', - address: { - street: 'Street name', - zipCode: '2134', - city: 'Paris', - country: 'FR', - }, - internalCode: null, - readonly: false, - }; - - testhost.ownerFormComponent.form.get('code').setValue(owner.code); - testhost.ownerFormComponent.form.get('name').setValue(owner.name); - testhost.ownerFormComponent.form.get('companyName').setValue(owner.companyName); - testhost.ownerFormComponent.form.get('address.street').setValue(owner.address.street); - testhost.ownerFormComponent.form.get('address.zipCode').setValue(owner.address.zipCode); - testhost.ownerFormComponent.form.get('address.city').setValue(owner.address.city); - testhost.ownerFormComponent.form.get('address.country').setValue(owner.address.country); - tick(10); - expect(testhost.owner).toEqual(owner); - })); - - it('should set owner to null when the form not valid', () => { - const owner: Owner = { - id: null, - identifier: null, - customerId: '4242', - code: 'invalid-code', - name: 'Toto', - companyName: 'Toto & Co.', - address: { - street: 'Street name', - zipCode: '2134', - city: 'Paris', - country: 'FR', - }, - readonly: false, - }; - - testhost.ownerFormComponent.form.get('code').setValue(owner.code); - testhost.ownerFormComponent.form.get('name').setValue(owner.name); - testhost.ownerFormComponent.form.get('companyName').setValue(owner.companyName); - testhost.ownerFormComponent.form.get('address.street').setValue(owner.address.street); - testhost.ownerFormComponent.form.get('address.zipCode').setValue(owner.address.zipCode); - testhost.ownerFormComponent.form.get('address.city').setValue(owner.address.city); - testhost.ownerFormComponent.form.get('address.country').setValue(owner.address.country); - expect(testhost.owner).toBe(null); - }); - - it('should set owner to null when the code is short ', () => { - const owner: Owner = { - id: null, - identifier: null, - customerId: '4242', - code: '135', //short code - name: 'Toto', - companyName: 'Toto & Co.', - address: { - street: 'Street name', - zipCode: '2134', - city: 'Paris', - country: 'FR', - }, - readonly: false, - }; - - testhost.ownerFormComponent.form.get('code').setValue(owner.code); - testhost.ownerFormComponent.form.get('name').setValue(owner.name); - testhost.ownerFormComponent.form.get('companyName').setValue(owner.companyName); - testhost.ownerFormComponent.form.get('address.street').setValue(owner.address.street); - testhost.ownerFormComponent.form.get('address.zipCode').setValue(owner.address.zipCode); - testhost.ownerFormComponent.form.get('address.city').setValue(owner.address.city); - testhost.ownerFormComponent.form.get('address.country').setValue(owner.address.country); - expect(testhost.owner).toBe(null); - }); - - it('should update the customerId', () => { - testhost.customerId = '5050505050'; - fixture.detectChanges(); - expect(testhost.ownerFormComponent.form.value.customerId).toBe(testhost.customerId); - }); - - it('should emit a value when the status changes', fakeAsync(() => { - const owner: Owner = { - id: null, - identifier: null, - customerId: '4242', - code: '43214345345', - name: 'Toto', - companyName: 'Toto & Co.', - address: { - street: 'Street name', - zipCode: '2134', - city: 'Paris', - country: 'FR', - }, - internalCode: null, - readonly: false, - }; - - testhost.ownerFormComponent.form.get('code').setValue(owner.code); - testhost.ownerFormComponent.form.get('name').setValue(owner.name); - testhost.ownerFormComponent.form.get('companyName').setValue(owner.companyName); - testhost.ownerFormComponent.form.get('address.street').setValue(owner.address.street); - testhost.ownerFormComponent.form.get('address.zipCode').setValue(owner.address.zipCode); - testhost.ownerFormComponent.form.get('address.city').setValue(owner.address.city); - testhost.ownerFormComponent.form.get('address.country').setValue(owner.address.country); - expect(testhost.ownerFormComponent.form.valid).toBe(false); - expect(testhost.owner).toBe(null); - tick(10); - expect(testhost.ownerFormComponent.form.valid).toBe(true); - expect(testhost.owner).toEqual(owner); - })); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.ts index a5e084ffcb3..8dea5d25e29 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.component.ts @@ -34,12 +34,11 @@ * 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, forwardRef, Input, OnDestroy, OnInit, inject } from '@angular/core'; -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { Component, forwardRef, inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms'; import { merge } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs/operators'; -import type { CountryOption, Customer, Owner } from 'vitamui-library'; -import { CountryService, Option, StartupService } from 'vitamui-library'; +import { CountryOption, CountryService, Customer, InputComponent, Option, Owner, SelectComponent, StartupService } from 'vitamui-library'; import { ALPHA_NUMERIC_REGEX, OWNER_CITY_MAX_LENGTH, @@ -51,6 +50,7 @@ import { OWNER_ZIP_CODE_MAX_LENGTH, OwnerFormValidators, } from './owner-form.validators'; +import { TranslatePipe } from '@ngx-translate/core'; export const OWNER_FORM_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -64,7 +64,7 @@ export const OWNER_FORM_VALUE_ACCESSOR: any = { templateUrl: './owner-form.component.html', styleUrls: ['./owner-form.component.scss'], providers: [OWNER_FORM_VALUE_ACCESSOR], - standalone: false, + imports: [ReactiveFormsModule, InputComponent, SelectComponent, TranslatePipe], }) export class OwnerFormComponent implements ControlValueAccessor, OnDestroy, OnInit { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.module.ts deleted file mode 100644 index 12fe3c1b2d5..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-form/owner-form.module.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { OwnerFormComponent } from './owner-form.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatFormFieldModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [OwnerFormComponent], - exports: [OwnerFormComponent], -}) -export class OwnerFormModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.spec.ts deleted file mode 100644 index 28bee6c7535..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.spec.ts +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDividerModule } from '@angular/material/divider'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { EMPTY, of, Subject } from 'rxjs'; -import { BASE_URL, CountryService, LoggerModule, Owner, SnackBarService, StartupService, Tenant, WINDOW_LOCATION } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { OwnerFormValidators } from '../../owner-form/owner-form.validators'; -import { OwnerService } from '../../owner.service'; -import { TenantFormValidators } from '../../tenant-create/tenant-form.validators'; -import { TenantService } from '../../tenant.service'; -import { InformationTabComponent } from './information-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -const expectedOwner: Owner = { - id: '5ad5f14c894e6a414edc7b63', - identifier: '1', - customerId: '42', - name: 'Julien Cornille', - code: '10234665', - companyName: 'vitamui', - address: { - street: '73 rue du Faubourg Poissonnière ', - zipCode: '75009', - city: 'Paris', - country: 'France', - }, - internalCode: '1', - readonly: false, -}; - -const expectedTenant: Tenant = { - id: '5ad5f14c894e6a414edc7b61adad48f0b8124fcda07b0ec1886c8d5d61c8f713', - ownerId: '5ad5f14c894e6a414edc7b62', - customerId: '42', - name: 'Emmanuel Deviller', - identifier: 7, - enabled: true, - proof: true, - readonly: false, - accessContractHoldingIdentifier: 'AC-000001', - accessContractLogbookIdentifier: 'AC-000002', - ingestContractHoldingIdentifier: 'IC-000001', - itemIngestContractIdentifier: 'IC-000001', -}; - -const owner = { - id: '5ad5f14c894e6a414edc7b62', - identifier: '5ad5f14c894e6a414edc7b62', - customerId: '42', - name: 'Emmanuel Deviller', - code: '10234501', - companyName: 'vitamui', - address: { - street: '73 rue du Faubourg Poissonnière ', - zipCode: '75009', - city: 'Paris', - country: 'France', - }, - internalCode: '1', - readonly: false, -}; - -@Component({ - template: ` `, - standalone: false, -}) -class TestHostComponent { - tenant: Tenant; - owner: Owner; - readonly = false; - - @ViewChild(InformationTabComponent, { static: false }) - component: InformationTabComponent; -} - -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('Owner InformationTabComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - const ownerServiceSpy = { - get: () => of(owner), - patch: () => of(owner), - updated: new Subject(), - }; - const ownerFormValidatorsSpy = { - uniqueCode: vi - .fn() - .mockName('OwnerFormValidators.uniqueCode') - .mockReturnValue(() => of(null)), - }; - const tenantFormValidatorsSpy = { - uniqueName: vi - .fn() - .mockName('TenantFormValidators.uniqueName') - .mockReturnValue(() => of(null)), - }; - - await TestBed.configureTestingModule({ - imports: [LoggerModule.forRoot(), MatDividerModule, NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule], - schemas: [NO_ERRORS_SCHEMA], - declarations: [TestHostComponent, InformationTabComponent], - providers: [ - { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: OwnerService, useValue: ownerServiceSpy }, - { provide: OwnerFormValidators, useValue: ownerFormValidatorsSpy }, - { provide: TenantFormValidators, useValue: tenantFormValidatorsSpy }, - { provide: TenantService, useValue: { patch: () => of(expectedTenant) } }, - { provide: StartupService, useValue: { getConfigNumberValue: () => 100 } }, - { provide: SnackBarService, useValue: { instant: () => EMPTY } }, - { provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }) - .overrideComponent(InformationTabComponent, { set: { template: '' } }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('Owner Form', () => { - beforeEach(() => { - testhost.owner = expectedOwner; - fixture.detectChanges(); - }); - - it('should have the correct fields', () => { - expect(testhost.component.ownerForm.get('id')).toBeDefined(); - expect(testhost.component.ownerForm.get('customerId')).toBeDefined(); - expect(testhost.component.ownerForm.get('code')).toBeDefined(); - expect(testhost.component.ownerForm.get('name')).toBeDefined(); - expect(testhost.component.ownerForm.get('companyName')).toBeDefined(); - expect(testhost.component.ownerForm.get('address.street')).toBeDefined(); - expect(testhost.component.ownerForm.get('address.zipCode')).toBeDefined(); - expect(testhost.component.ownerForm.get('address.city')).toBeDefined(); - expect(testhost.component.ownerForm.get('address.country')).toBeDefined(); - }); - - it('should have the required validator', () => { - testhost.component.ownerForm.setValue({ - id: null, - identifier: null, - customerId: null, - code: null, - name: null, - companyName: null, - address: { - street: null, - zipCode: null, - city: null, - country: null, - }, - internalCode: null, - }); - expect(testhost.component.ownerForm.get('id').valid).toBeFalsy(); - expect(testhost.component.ownerForm.get('customerId').valid).toBeFalsy(); - expect(testhost.component.ownerForm.get('code').valid).toBeFalsy(); - expect(testhost.component.ownerForm.get('name').valid).toBeFalsy(); - expect(testhost.component.ownerForm.get('companyName').valid).toBeFalsy(); - expect(testhost.component.ownerForm.get('address.street').valid).toBeTruthy(); - expect(testhost.component.ownerForm.get('address.zipCode').valid).toBeTruthy(); - expect(testhost.component.ownerForm.get('address.city').valid).toBeTruthy(); - expect(testhost.component.ownerForm.get('address.country').valid).toBeTruthy(); - expect(testhost.component.ownerForm.get('internalCode').valid).toBeTruthy(); - }); - - it('should have the pattern validator', () => { - const codeControl = testhost.component.ownerForm.get('code'); - codeControl.setValue('a'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('123456a'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('aaaaaa'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('1234'); - expect(codeControl.valid).toBeTruthy(); - codeControl.setValue('1234_'); - expect(codeControl.valid).toBeFalsy(); - codeControl.setValue('1234_qzdqzdzqdzqd48d5zq41d5qz1d654'); - expect(codeControl.valid).toBeFalsy(); - }); - - it('should be valid and call patch()', () => { - testhost.component.ownerForm.setValue({ - id: expectedOwner.id, - identifier: expectedOwner.identifier, - customerId: expectedOwner.customerId, - code: expectedOwner.code, - name: expectedOwner.name, - companyName: expectedOwner.companyName, - address: { - street: expectedOwner.address.street, - zipCode: expectedOwner.address.zipCode, - city: expectedOwner.address.city, - country: expectedOwner.address.country, - }, - internalCode: expectedOwner.internalCode, - }); - expect(testhost.component.ownerForm.valid).toBeTruthy(); - }); - }); - - describe('Tenant Form', () => { - beforeEach(() => { - testhost.tenant = expectedTenant; - fixture.detectChanges(); - }); - - it('should have the correct fields', () => { - expect(testhost.component.tenantForm.get('id')).toBeDefined(); - expect(testhost.component.tenantForm.get('identifier')).toBeDefined(); - expect(testhost.component.tenantForm.get('customerId')).toBeDefined(); - expect(testhost.component.tenantForm.get('ownerId')).toBeDefined(); - expect(testhost.component.tenantForm.get('name')).toBeDefined(); - expect(testhost.component.tenantForm.get('enabled')).toBeDefined(); - }); - - it('should have the required validator', () => { - testhost.component.tenantForm.setValue({ - id: null, - customerId: null, - ownerId: null, - identifier: null, - name: null, - enabled: null, - ingestContractHoldingIdentifier: null, - itemIngestContractIdentifier: null, - accessContractHoldingIdentifier: null, - accessContractLogbookIdentifier: null, - }); - expect(testhost.component.tenantForm.get('id').valid).toBeFalsy(); - expect(testhost.component.tenantForm.get('customerId').valid).toBeFalsy(); - expect(testhost.component.tenantForm.get('ownerId').valid).toBeFalsy(); - expect(testhost.component.tenantForm.get('identifier').valid).toBeFalsy(); - expect(testhost.component.tenantForm.get('name').valid).toBeFalsy(); - expect(testhost.component.tenantForm.get('enabled').valid).toBeFalsy(); - }); - - it('should be valid and call patch()', () => { - testhost.component.tenantForm.setValue({ - id: expectedTenant.id, - ownerId: expectedTenant.ownerId, - customerId: expectedTenant.customerId, - identifier: expectedTenant.identifier, - name: expectedTenant.name, - enabled: expectedTenant.enabled, - ingestContractHoldingIdentifier: expectedTenant.ingestContractHoldingIdentifier, - itemIngestContractIdentifier: expectedTenant.itemIngestContractIdentifier, - accessContractHoldingIdentifier: expectedTenant.accessContractHoldingIdentifier, - accessContractLogbookIdentifier: expectedTenant.accessContractLogbookIdentifier, - }); - expect(testhost.component.tenantForm.valid).toBeTruthy(); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.ts index c74cb2e352e..b629f8ad24c 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/information-tab/information-tab.component.ts @@ -34,18 +34,39 @@ * 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, Input, OnChanges, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input, OnChanges, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { merge, of } from 'rxjs'; import { catchError, debounceTime, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { CountryOption, Owner, Tenant } from 'vitamui-library'; -import { CountryService, diff, Option, StartupService } from 'vitamui-library'; +import { + CountryOption, + CountryService, + diff, + EditableInputComponent, + FormFieldValueWrapperComponent, + Option, + Owner, + SelectComponent, + StartupService, + Tenant, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { ALPHA_NUMERIC_REGEX, OWNER_CODE_MAX_LENGTH, OwnerFormValidators } from '../../owner-form/owner-form.validators'; import { OwnerService } from '../../owner.service'; import { TenantFormValidators } from '../../tenant-create/tenant-form.validators'; import { TenantService } from '../../tenant.service'; +import { MatDivider } from '@angular/material/divider'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const UPDATE_DEBOUNCE_TIME = 200; @@ -53,7 +74,24 @@ const UPDATE_DEBOUNCE_TIME = 200; selector: 'app-information-tab', templateUrl: './information-tab.component.html', styleUrls: ['./information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + VitamUIFieldErrorComponent, + FormFieldValueWrapperComponent, + SelectComponent, + MatDivider, + TranslatePipe, + CommonModule, + EditableInputComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class InformationTabComponent implements OnChanges, OnInit { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.spec.ts index 732e059ade6..e5b298caa16 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.spec.ts @@ -47,8 +47,7 @@ describe('OwnerOperationHistoryTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [VitamUICommonTestModule], - declarations: [OwnerOperationHistoryTabComponent], + imports: [VitamUICommonTestModule, OwnerOperationHistoryTabComponent], providers: [ { provide: AuthService, useValue: {} }, { provide: LogbookService, useValue: {} }, diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.ts index 25612f83e6c..0b16ebe7a51 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-operation-history-tab/owner-operation-history-tab.component.ts @@ -35,14 +35,18 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input, OnChanges, SimpleChanges, inject } from '@angular/core'; -import { AuthService, HistoryEvent, LogbookService } from 'vitamui-library'; +import type { HistoryEvent } from 'vitamui-library'; +import { AuthService, LogbookService, HistoryEventsComponent, CollapseComponent } from 'vitamui-library'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; const EVENT_LIMIT = 100; @Component({ selector: 'app-owner-operation-history-tab', templateUrl: './owner-operation-history-tab.component.html', styleUrls: ['./owner-operation-history-tab.component.scss'], - standalone: false, + imports: [MatProgressSpinner, HistoryEventsComponent, TranslatePipe, CollapseComponent, CommonModule], }) export class OwnerOperationHistoryTabComponent implements OnChanges { private authService = inject(AuthService); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-popup.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-popup.component.ts index 7c46d979292..5cf1adaab4a 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-popup.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-popup.component.ts @@ -39,11 +39,12 @@ import { ActivatedRoute } from '@angular/router'; import { Owner, Tenant } from 'vitamui-library'; import { OwnerService } from '../owner.service'; +import { OwnerPreviewComponent } from './owner-preview.component'; @Component({ selector: 'app-owner-popup', template: '', - standalone: false, + imports: [OwnerPreviewComponent], }) export class OwnerPopupComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.spec.ts index 9a3e696ded2..8296880e854 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.spec.ts @@ -34,26 +34,22 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatMenuModule } from '@angular/material/menu'; import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { TranslateService } from '@ngx-translate/core'; -import { EMPTY, of } from 'rxjs'; -import { BASE_URL, ENVIRONMENT, LoggerModule, SnackBarService, WINDOW_LOCATION } from 'vitamui-library'; +import { EMPTY } from 'rxjs'; +import { ENVIRONMENT, LoggerModule, SnackBarService, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { environment } from './../../../environments/environment'; import { OwnerPreviewComponent } from './owner-preview.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'app-information-tab', template: '', - standalone: false, + imports: [MatMenuModule, MatTabsModule, VitamUICommonTestModule], }) export class InformationTabStubComponent { @Input() owner: any; @@ -67,16 +63,19 @@ describe('OwnerPreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [OwnerPreviewComponent, InformationTabStubComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [MatMenuModule, MatTabsModule, NoopAnimationsModule, LoggerModule.forRoot(), VitamUICommonTestModule], + imports: [ + MatMenuModule, + MatTabsModule, + LoggerModule.forRoot(), + VitamUICommonTestModule, + OwnerPreviewComponent, + InformationTabStubComponent, + ], providers: [ { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ENVIRONMENT, useValue: environment }, { provide: SnackBarService, useValue: { instant: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.ts index f26512a5d04..5e5e6c49e0c 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.component.ts @@ -37,12 +37,30 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import type { Owner, Tenant } from 'vitamui-library'; +import { VitamuiSidenavHeaderComponent } from 'vitamui-library'; +import { MatTabGroup, MatTab } from '@angular/material/tabs'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { OwnerOperationHistoryTabComponent } from './owner-operation-history-tab/owner-operation-history-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-owner-preview', templateUrl: './owner-preview.component.html', styleUrls: ['./owner-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + InformationTabComponent, + OwnerOperationHistoryTabComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class OwnerPreviewComponent { @Input() owner: Owner; diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.module.ts deleted file mode 100644 index 680a7c872c4..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner-preview/owner-preview.module.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDividerModule } from '@angular/material/divider'; -import { MatMenuModule } from '@angular/material/menu'; - -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatTabsModule } from '@angular/material/tabs'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { InformationTabComponent } from './information-tab/information-tab.component'; -import { OwnerOperationHistoryTabComponent } from './owner-operation-history-tab/owner-operation-history-tab.component'; -import { OwnerPopupComponent } from './owner-popup.component'; -import { OwnerPreviewComponent } from './owner-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatDividerModule, - MatMenuModule, - MatProgressSpinnerModule, - MatTabsModule, - ReactiveFormsModule, - SharedModule, - TranslatePipe, - VitamUICommonModule, - VitamUILibraryModule, - ], - declarations: [OwnerPopupComponent, OwnerPreviewComponent, InformationTabComponent, OwnerOperationHistoryTabComponent], - exports: [OwnerPopupComponent, OwnerPreviewComponent], -}) -export class OwnerPreviewModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner.service.spec.ts index 8953e7afdba..fd9c1cc347c 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner.service.spec.ts @@ -34,14 +34,12 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Type } from '@angular/core'; -import { BASE_URL, Owner, SnackBarService } from 'vitamui-library'; +import { Owner, SnackBarService } from 'vitamui-library'; import { OwnerService } from './owner.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const expectedOwner: Owner = { id: '42', @@ -68,14 +66,7 @@ describe('OwnerService', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAnimationsModule], - providers: [ - OwnerService, - { provide: SnackBarService, useValue: snackBarSpy }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [OwnerService, { provide: SnackBarService, useValue: snackBarSpy }], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/owner.service.ts b/ui/ui-frontend/projects/identity/src/app/customer/owner.service.ts index 5cb7e9b3168..27930f954d3 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/owner.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/owner.service.ts @@ -38,7 +38,7 @@ import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; import { CriteriaSearchQuery, Criterion, Operators, Owner, SnackBarService } from 'vitamui-library'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { OwnerApiService } from './owner-api.service'; @Injectable({ diff --git a/ui/ui-frontend/projects/identity/src/app/customer/tenant-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/tenant-api.service.spec.ts index c4a9a79eff4..90d46317169 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/tenant-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/tenant-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from 'vitamui-library'; import { TenantApiService } from './tenant-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('TenantApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.spec.ts index fc298116ccc..57e786ce15f 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.spec.ts @@ -43,7 +43,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { TenantService } from '../tenant.service'; import { TenantCreateComponent } from './tenant-create.component'; @@ -74,9 +73,15 @@ describe('TenantCreateComponent', () => { }; await TestBed.configureTestingModule({ - imports: [MatSelectModule, MatOptionModule, MatProgressBarModule, NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule], + imports: [ + MatSelectModule, + MatOptionModule, + MatProgressBarModule, + ReactiveFormsModule, + VitamUICommonTestModule, + TenantCreateComponent, + ], schemas: [NO_ERRORS_SCHEMA], - declarations: [TenantCreateComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { diff --git a/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.ts b/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.ts index b270b1d9da4..7e11a2c02fe 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.component.ts @@ -34,21 +34,22 @@ * 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 { ConfirmDialogService, Owner, Tenant } from 'vitamui-library'; +import { ConfirmDialogService, DialogHeaderComponent, InputComponent, Owner, SelectComponent, Tenant } from 'vitamui-library'; -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { finalize, Subscription } from 'rxjs'; import { TenantService } from '../tenant.service'; import { TenantFormValidators } from './tenant-form.validators'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-tenant-create', templateUrl: './tenant-create.component.html', styleUrls: ['./tenant-create.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, ReactiveFormsModule, MatDialogContent, InputComponent, SelectComponent, MatDialogActions, TranslatePipe], }) export class TenantCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.module.ts b/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.module.ts deleted file mode 100644 index d7c88f1ae6f..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/customer/tenant-create/tenant-create.module.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { TenantCreateComponent } from './tenant-create.component'; -import { MatOptionModule } from '@angular/material/core'; -import { MatSelectModule } from '@angular/material/select'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatProgressBarModule, - ReactiveFormsModule, - VitamUICommonModule, - MatOptionModule, - MatSelectModule, - MatDialogModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [TenantCreateComponent], -}) -export class TenantCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.spec.ts index d6f25f34f88..4d084ef7e2f 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.spec.ts @@ -34,15 +34,14 @@ * 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 { BASE_URL, CriteriaSearchQuery, Operators, Owner, SnackBarService, Tenant } from 'vitamui-library'; +import { CriteriaSearchQuery, Operators, Owner, SnackBarService, Tenant } from 'vitamui-library'; -import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { TenantService } from './tenant.service'; import { Type } from '@angular/core'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const expectedTenant: Tenant = { id: '42', @@ -130,13 +129,7 @@ describe('TenantService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - TenantService, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: SnackBarService, useValue: snackBarSpy }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [TenantService, { provide: SnackBarService, useValue: snackBarSpy }], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.ts b/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.ts index b148ef64495..bf0e2a493e3 100644 --- a/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/customer/tenant.service.ts @@ -36,10 +36,10 @@ */ import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { CriteriaSearchQuery, Criterion, Operators, Tenant, SnackBarService } from 'vitamui-library'; +import { CriteriaSearchQuery, Criterion, Operators, SnackBarService, Tenant } from 'vitamui-library'; import { HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { TenantApiService } from './tenant-api.service'; diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.spec.ts index c68117874dd..8451a6e1b4d 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.spec.ts @@ -34,7 +34,6 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -44,13 +43,12 @@ import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule } from '@angular/material/select'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; -import { CollapseModule, ConfirmDialogService } from 'vitamui-library'; +import { CollapseComponent, ConfirmDialogService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ExternalParamProfileService } from '../external-param-profile.service'; import { ExternalParamProfileValidators } from '../external-param-profile.validators'; import { ExternalParamProfileCreateComponent } from './external-param-profile-create.component'; -import { DecimalPipe } from '@angular/common'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { CommonModule, DecimalPipe } from '@angular/common'; describe('ExternalParamProfileCreateComponent', () => { let component: ExternalParamProfileCreateComponent; @@ -78,17 +76,18 @@ describe('ExternalParamProfileCreateComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ExternalParamProfileCreateComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ BrowserAnimationsModule, - CollapseModule, FormsModule, MatButtonToggleModule, MatProgressBarModule, MatSelectModule, ReactiveFormsModule, VitamUICommonTestModule, + ExternalParamProfileCreateComponent, + CollapseComponent, + CommonModule, ], providers: [ DecimalPipe, @@ -102,8 +101,6 @@ describe('ExternalParamProfileCreateComponent', () => { }, { provide: ExternalParamProfileValidators, useValue: externalParamProfileValidators }, { provide: ExternalParamProfileService, useValue: externalParamProfileService }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }) .overrideComponent(ExternalParamProfileCreateComponent, { diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.ts index 7e903b7f0fa..4082e044b64 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-create/external-param-profile-create.component.ts @@ -34,22 +34,50 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Observable, Subscription } from 'rxjs'; -import { ConfirmDialogService, ExternalParamProfile, Option } from 'vitamui-library'; +import { + ConfirmDialogService, + DialogHeaderComponent, + ExternalParamProfile, + InputComponent, + NextStepComponent, + Option, + PreviousStepComponent, + SelectComponent, + SlideToggleComponent, + StepperComponent, + TooltipDirective, +} from 'vitamui-library'; import { ExternalParamProfileService } from '../external-param-profile.service'; import { ExternalParamProfileValidators } from '../external-param-profile.validators'; import { map } from 'rxjs/operators'; -import { TranslateService } from '@ngx-translate/core'; -import { DecimalPipe } from '@angular/common'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { AsyncPipe, DecimalPipe } from '@angular/common'; +import { CdkStep } from '@angular/cdk/stepper'; @Component({ selector: 'app-external-param-profile-create', templateUrl: './external-param-profile-create.component.html', styleUrls: ['./external-param-profile-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + SlideToggleComponent, + InputComponent, + SelectComponent, + MatDialogActions, + NextStepComponent, + TooltipDirective, + PreviousStepComponent, + AsyncPipe, + TranslatePipe, + ], }) export class ExternalParamProfileCreateComponent implements OnInit, OnDestroy { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.spec.ts index c8f80b38b71..9928dce28c3 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.spec.ts @@ -34,40 +34,25 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of, Subject } from 'rxjs'; -import { AuthService, BASE_URL, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { of, Subject } from 'rxjs'; +import { AuthService, ExternalParamProfile, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { environment } from '../../../environments/environment.prod'; -import { TestHostComponent } from '../../shared/domains-input/domains-input.component.spec'; import { ExternalParamProfileService } from '../external-param-profile.service'; import { ExternalParamProfileDetailComponent } from './external-param-profile-detail.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { InformationTabComponent } from './information-tab/information-tab.component'; @Component({ selector: 'app-information-tab', template: '', - standalone: false, }) class InformationTabStubComponent { - // @Input() profile: ExternalParamProfile; + @Input() externalParamProfile: ExternalParamProfile; @Input() readOnly: boolean; @Input() tenantIdentifier: string; } -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('ExternalParamProfilDetailComponent', () => { let component: ExternalParamProfileDetailComponent; let fixture: ComponentFixture; @@ -76,19 +61,19 @@ describe('ExternalParamProfilDetailComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [TestHostComponent, ExternalParamProfileDetailComponent, InformationTabStubComponent], - schemas: [NO_ERRORS_SCHEMA], - imports: [MatMenuModule, MatTabsModule, NoopAnimationsModule, LoggerModule.forRoot()], + imports: [LoggerModule.forRoot(), ExternalParamProfileDetailComponent], providers: [ - { provide: ExternalParamProfileService, useValue: { updated: new Subject() } }, + { provide: ExternalParamProfileService, useValue: { updated: new Subject(), getAllActiveAccessContracts: of() } }, { provide: AuthService, useValue: authServiceMock }, { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: environment, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideComponent(ExternalParamProfileDetailComponent, { + remove: { imports: [InformationTabComponent] }, + add: { imports: [InformationTabStubComponent] }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.ts index 460527d678a..f179c6c9fd8 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/external-param-profile-detail.component.ts @@ -34,17 +34,35 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subscription } from 'rxjs'; -import type { ExternalParamProfile } from 'vitamui-library'; +import { ExternalParamProfile, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { ExternalParamProfileService } from '../external-param-profile.service'; import { SharedService } from '../shared.service'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { ThresholdsTabComponent } from './thresholds-tab/thresholds-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { ReactiveFormsModule } from '@angular/forms'; @Component({ selector: 'app-external-param-profile-detail', templateUrl: './external-param-profile-detail.component.html', styleUrls: ['./external-param-profile-detail.component.css'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + InformationTabComponent, + ThresholdsTabComponent, + OperationHistoryTabComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ExternalParamProfileDetailComponent implements OnInit, OnDestroy { private sharedService = inject(SharedService); diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/information-tab/information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/information-tab/information-tab.component.ts index 1d8d327fc04..798193e3e44 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/information-tab/information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/information-tab/information-tab.component.ts @@ -34,20 +34,52 @@ * 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, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { of, skip, Subscription } from 'rxjs'; import { catchError, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEqual } from 'underscore'; -import type { ExternalParamProfile } from 'vitamui-library'; +import { + EditableInputComponent, + ExternalParamProfile, + SelectComponent, + SlideToggleComponent, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { ExternalParamProfileService } from '../../external-param-profile.service'; import { ExternalParamProfileValidators } from '../../external-param-profile.validators'; +import { CommonModule, NgStyle } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; @Component({ selector: 'app-information-tab', templateUrl: './information-tab.component.html', styleUrls: ['./information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + SlideToggleComponent, + NgStyle, + VitamUIFieldErrorComponent, + SelectComponent, + TranslatePipe, + CommonModule, + EditableInputComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class InformationTabComponent implements OnDestroy, OnInit, OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/thresholds-tab/thresholds-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/thresholds-tab/thresholds-tab.component.ts index 8708a1b0191..6d05ab8fb34 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/thresholds-tab/thresholds-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-detail/thresholds-tab/thresholds-tab.component.ts @@ -34,21 +34,20 @@ * 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, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { Component, inject, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { Subscription } from 'rxjs'; import { extend, isEmpty } from 'underscore'; -import type { ExternalParamProfile } from 'vitamui-library'; -import { diff, Option } from 'vitamui-library'; +import { diff, ExternalParamProfile, Option, SelectComponent, SlideToggleComponent, TooltipDirective } from 'vitamui-library'; import { ExternalParamProfileService } from '../../external-param-profile.service'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { DecimalPipe } from '@angular/common'; @Component({ selector: 'app-thresholds-tab', templateUrl: './thresholds-tab.component.html', styleUrls: ['./thresholds-tab.component.css'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, SelectComponent, TooltipDirective, TranslatePipe], }) export class ThresholdsTabComponent implements OnDestroy, OnInit, OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.html b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.html index 62f71978ecb..5b1a8b84fe0 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.html @@ -13,7 +13,7 @@
- @for (externalParamProfile of dataSource; track externalParamProfile) { + @for (externalParamProfile of dataSource(); track externalParamProfile) {
@@ -34,15 +34,15 @@
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && externalParamProfileServiceService.canLoadMore && !pending) { + @if (infiniteScrollDisabled && externalParamProfileServiceService.canLoadMore && !pending()) {
{{ 'COMMON.MORE_RESULT' | translate }}
diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.spec.ts index 583ccbfb3b4..97ad03a2c8b 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.spec.ts @@ -38,24 +38,16 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { TranslateLoader } from '@ngx-translate/core'; -import { Observable, of, Subject } from 'rxjs'; -import { CollapseModule } from 'vitamui-library'; +import { of, Subject } from 'rxjs'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ProfileValidators } from '../../hierarchy/profile.validators'; import { ProfileService } from '../../profile/profile.service'; import { ExternalParamProfileService } from '../external-param-profile.service'; import { ExternalParamProfileListComponent } from './external-param-profile-list.component'; - -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} +import { CollapseComponent } from 'vitamui-library'; +import { CommonModule } from '@angular/common'; describe('ExternalParamProfileListComponent', () => { let component: ExternalParamProfileListComponent; @@ -80,8 +72,15 @@ describe('ExternalParamProfileListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, MatProgressBarModule, CollapseModule, MatButtonToggleModule, VitamUICommonTestModule], - declarations: [ExternalParamProfileListComponent], + imports: [ + ReactiveFormsModule, + MatProgressBarModule, + MatButtonToggleModule, + VitamUICommonTestModule, + ExternalParamProfileListComponent, + CollapseComponent, + CommonModule, + ], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: ExternalParamProfileService, useValue: externalParamListServiceSpy }, diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.ts index 1f51518f859..ecfb56f7ebb 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-list/external-param-profile-list.component.ts @@ -34,7 +34,7 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subject, Subscription } from 'rxjs'; import { debounceTime, startWith } from 'rxjs/operators'; import { @@ -43,19 +43,24 @@ import { DEFAULT_PAGE_SIZE, Direction, ExternalParamProfile, + InfiniteScrollDirective, InfiniteScrollTable, PageRequest, + PipesModule, Profile, } from 'vitamui-library'; import { ProfileService } from '../../profile/profile.service'; import { ExternalParamProfileService } from '../external-param-profile.service'; import { SharedService } from '../shared.service'; +import { CommonModule, DecimalPipe, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-external-param-profile-list', templateUrl: './external-param-profile-list.component.html', styleUrls: ['./external-param-profile-list.component.css'], - standalone: false, + imports: [NgClass, MatProgressSpinner, DecimalPipe, PipesModule, TranslatePipe, CommonModule, InfiniteScrollDirective], }) export class ExternalParamProfileListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { externalParamProfileServiceService: ExternalParamProfileService; @@ -100,22 +105,26 @@ export class ExternalParamProfileListComponent extends InfiniteScrollTable { - const extParamProfileIndex = this.dataSource.findIndex((extParamProfile) => extParamProfile.id === externalParamProfile.id); - if (extParamProfileIndex > -1) { - this.dataSource[extParamProfileIndex] = { - id: externalParamProfile.id, - enabled: externalParamProfile.enabled, - name: externalParamProfile.name, - description: externalParamProfile.description, - accessContract: externalParamProfile.accessContract, - externalParamIdentifier: externalParamProfile.externalParamIdentifier, - profileIdentifier: externalParamProfile.profileIdentifier, - idExternalParam: externalParamProfile.idExternalParam, - idProfile: externalParamProfile.idProfile, - bulkOperationsThreshold: externalParamProfile.bulkOperationsThreshold, - usePlatformThreshold: externalParamProfile.usePlatformThreshold, - }; - } + this.dataSource.update((profiles) => { + const list = [...(profiles ?? [])]; + const extParamProfileIndex = list.findIndex((extParamProfile) => extParamProfile.id === externalParamProfile.id); + if (extParamProfileIndex > -1) { + list[extParamProfileIndex] = { + id: externalParamProfile.id, + enabled: externalParamProfile.enabled, + name: externalParamProfile.name, + description: externalParamProfile.description, + accessContract: externalParamProfile.accessContract, + externalParamIdentifier: externalParamProfile.externalParamIdentifier, + profileIdentifier: externalParamProfile.profileIdentifier, + idExternalParam: externalParamProfile.idExternalParam, + idProfile: externalParamProfile.idProfile, + bulkOperationsThreshold: externalParamProfile.bulkOperationsThreshold, + usePlatformThreshold: externalParamProfile.usePlatformThreshold, + }; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-service.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-service.service.spec.ts index 94a42e3aebc..cc438e04c0b 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-service.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile-service.service.spec.ts @@ -34,11 +34,9 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, LoggerModule, SnackBarService } from 'vitamui-library'; +import { LoggerModule, SnackBarService } from 'vitamui-library'; import { ExternalParamProfileService } from './external-param-profile.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ExternalParamProfileService', () => { let service: ExternalParamProfileService; @@ -48,13 +46,7 @@ describe('ExternalParamProfileService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - ExternalParamProfileService, - { provide: SnackBarService, useValue: snackBarSpy }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [ExternalParamProfileService, { provide: SnackBarService, useValue: snackBarSpy }], }); service = TestBed.inject(ExternalParamProfileService); }); diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.spec.ts index 4db90879cb3..a207eaf20b6 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.spec.ts @@ -35,16 +35,38 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; +import { ActivatedRoute } from '@angular/router'; +import { of, Subject } from 'rxjs'; import { InjectorModule, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ExternalParamProfileComponent } from './external-param-profile.component'; import { ExternalParamProfileService } from './external-param-profile.service'; +import { SharedService } from './shared.service'; +import { ExternalParamProfileDetailComponent } from './external-param-profile-detail/external-param-profile-detail.component'; +import { ExternalParamProfileListComponent } from './external-param-profile-list/external-param-profile-list.component'; + +@Component({ + selector: 'app-external-param-profile-detail', + template: '', +}) +class ExternalParamProfileDetailStubComponent { + @Input() externalParamProfile: any; + @Input() readOnly: boolean; + @Input() tenantIdentifier: string; +} + +@Component({ + selector: 'app-external-param-profile-list', + template: '', +}) +class ExternalParamProfileListStubComponent { + @Input() searchText: string; +} describe('ExternalParamProfileComponent', () => { let component: ExternalParamProfileComponent; @@ -52,20 +74,43 @@ describe('ExternalParamProfileComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ExternalParamProfileComponent], imports: [ VitamUICommonTestModule, - RouterTestingModule, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, MatSidenavModule, MatDialogModule, MatMenuModule, + ExternalParamProfileComponent, + ExternalParamProfileDetailStubComponent, + ExternalParamProfileListStubComponent, + ], + providers: [ + { + provide: ActivatedRoute, + useValue: { + data: of({ appId: 'EXTERNAL_PARAM_PROFILE_APP' }), + params: of({}), + snapshot: { data: { appId: 'EXTERNAL_PARAM_PROFILE_APP' } }, + }, + }, + { + provide: ExternalParamProfileService, + useValue: { updated: new Subject(), getOne: () => of(null), search: () => of([]), loadMore: () => of([]) }, + }, + { provide: SharedService, useValue: { getReadOnly: () => of(false) } }, ], - providers: [{ provide: ExternalParamProfileService, useValue: {} }], schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents(); + }) + .overrideComponent(ExternalParamProfileComponent, { + remove: { + imports: [ExternalParamProfileDetailComponent, ExternalParamProfileListComponent], + }, + add: { + imports: [ExternalParamProfileDetailStubComponent, ExternalParamProfileListStubComponent], + }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.ts index bba3ca6166b..6cf8d1b60f0 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.component.ts @@ -34,39 +34,40 @@ * 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, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { ExternalParamProfile, GlobalEventService, SidenavPage } from 'vitamui-library'; +import { ExternalParamProfile, SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { ExternalParamProfileCreateComponent } from './external-param-profile-create/external-param-profile-create.component'; import { ExternalParamProfileListComponent } from './external-param-profile-list/external-param-profile-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { ExternalParamProfileDetailComponent } from './external-param-profile-detail/external-param-profile-detail.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-external-param-profile', templateUrl: './external-param-profile.component.html', styleUrls: ['./external-param-profile.component.css'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + ExternalParamProfileDetailComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ExternalParamProfileListComponent, + TranslatePipe, + ], }) export class ExternalParamProfileComponent extends SidenavPage implements OnInit { dialog = inject(MatDialog); - route: ActivatedRoute; - override globalEventService: GlobalEventService; + private route = inject(ActivatedRoute); dto: ExternalParamProfile; tenantIdentifier: string; public search: string; @ViewChild(ExternalParamProfileListComponent, { static: true }) externalParamProfileListComponent: ExternalParamProfileListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - this.globalEventService = globalEventService; - } - ngOnInit(): void { this.route.params.subscribe((params) => { this.tenantIdentifier = params['tenantIdentifier']; diff --git a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.module.ts b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.module.ts index bb8272a62ca..e62e721d761 100644 --- a/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/external-param-profile/external-param-profile.module.ts @@ -36,7 +36,7 @@ */ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressBarModule } from '@angular/material/progress-bar'; @@ -44,9 +44,15 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTabsModule } from '@angular/material/tabs'; -import { LevelInputModule, RoleToggleModule, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; -import { GroupAttributionModule } from '../user/group-attribution/group-attribution.module'; +import { + LevelInputComponent, + RoleComponent, + RoleToggleComponent, + SlideToggleComponent, + VitamUICommonModule, + VitamUILibraryModule, +} from 'vitamui-library'; + import { ExternalParamProfileCreateComponent } from './external-param-profile-create/external-param-profile-create.component'; import { ExternalParamProfileDetailComponent } from './external-param-profile-detail/external-param-profile-detail.component'; import { InformationTabComponent } from './external-param-profile-detail/information-tab/information-tab.component'; @@ -61,8 +67,6 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ CommonModule, ExternalParamProfileRoutingModule, - GroupAttributionModule, - LevelInputModule, MatButtonToggleModule, MatDialogModule, MatMenuModule, @@ -72,19 +76,20 @@ import { TranslatePipe } from '@ngx-translate/core'; MatSidenavModule, MatTabsModule, ReactiveFormsModule, - RoleToggleModule, - SharedModule, VitamUICommonModule, VitamUILibraryModule, TranslatePipe, - ], - declarations: [ ExternalParamProfileComponent, ExternalParamProfileListComponent, ExternalParamProfileCreateComponent, ExternalParamProfileDetailComponent, InformationTabComponent, ThresholdsTabComponent, + FormsModule, + RoleComponent, + RoleToggleComponent, + SlideToggleComponent, + LevelInputComponent, ], }) export class ExternalParamProfileModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.spec.ts index 05b08fffcae..2d5ba3db31c 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.spec.ts @@ -71,19 +71,20 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { EMPTY, of } from 'rxjs'; -import { AuthService, ConfirmDialogService, Group, LevelInputModule, ProfileService } from 'vitamui-library'; +import { AuthService, ConfirmDialogService, Group, LevelInputComponent, ProfileService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { Component, forwardRef, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; +import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { GroupService } from '../group.service'; import { GroupValidators } from '../group.validators'; import { GroupCreateComponent } from './group-create.component'; +import { CommonModule } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-profiles-form', @@ -95,7 +96,6 @@ import { GroupCreateComponent } from './group-create.component'; multi: true, }, ], - standalone: false, }) class ProfilesFormStubComponent implements ControlValueAccessor { @Input() @@ -115,7 +115,6 @@ class ProfilesFormStubComponent implements ControlValueAccessor { multi: true, }, ], - standalone: false, }) class UnitsFormStubComponent implements ControlValueAccessor { writeValue() {} @@ -167,8 +166,16 @@ describe('GroupCreateComponent', () => { }; await TestBed.configureTestingModule({ - imports: [MatProgressBarModule, ReactiveFormsModule, NoopAnimationsModule, VitamUICommonTestModule, LevelInputModule], - declarations: [ProfilesFormStubComponent, UnitsFormStubComponent, GroupCreateComponent], + imports: [ + MatProgressBarModule, + ReactiveFormsModule, + VitamUICommonTestModule, + CommonModule, + FormsModule, + LevelInputComponent, + TranslatePipe, + GroupCreateComponent, + ], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.ts index fc062adf1c0..0b3fbf9e534 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.component.ts @@ -34,20 +34,54 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import { AuthService, buildValidators, ConfirmDialogService, MiscValidators } from 'vitamui-library'; +import { + AuthService, + buildValidators, + ConfirmDialogService, + DialogHeaderComponent, + InputComponent, + LevelInputComponent, + MiscValidators, + NextStepComponent, + PreviousStepComponent, + SlideToggleComponent, + StepperComponent, +} from 'vitamui-library'; import { GroupService } from '../group.service'; import { GroupValidators } from '../group.validators'; +import { CdkStep } from '@angular/cdk/stepper'; +import { ProfilesFormComponent } from '../../shared/profiles-form/profiles-form.component'; +import { UnitsFormComponent } from '../units-form/units-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-group-create', templateUrl: './group-create.component.html', styleUrls: ['./group-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + SlideToggleComponent, + InputComponent, + MatDialogActions, + NextStepComponent, + ProfilesFormComponent, + PreviousStepComponent, + UnitsFormComponent, + TranslatePipe, + CommonModule, + FormsModule, + LevelInputComponent, + ], }) export class GroupCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.module.ts b/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.module.ts deleted file mode 100644 index 021f0956e0d..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/group/group-create/group-create.module.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { UnitsFormModule } from '../units-form/units-form.module'; -import { GroupCreateComponent } from './group-create.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - SharedModule, - UnitsFormModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [GroupCreateComponent], -}) -export class GroupCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.html b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.html index 7c570011a56..0d86b5f9db1 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.html @@ -92,7 +92,7 @@
- @for (group of dataSource; track group) { + @for (group of dataSource(); track group) {
@@ -108,15 +108,15 @@
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && groupService.canLoadMore && !pending) { + @if (infiniteScrollDisabled && groupService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.spec.ts index ddbb974ce7e..bf8e4fff54d 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.spec.ts @@ -39,7 +39,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { By } from '@angular/platform-browser'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Router } from '@angular/router'; import { of, Subject } from 'rxjs'; @@ -96,7 +95,7 @@ class Page { get loadMoreButton() { return ( fixture.nativeElement.querySelector('.vitamui-table-message > .clickable') || - (component.infiniteScrollDisabled ? { click: () => component.groupService.loadMore() } : null) + (component.infiniteScrollDisabled() ? { click: () => component.groupService.loadMore() } : null) ); } get infiniteScroll() { @@ -154,8 +153,7 @@ describe('GroupListComponent', () => { matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - imports: [MatProgressSpinnerModule, NoopAnimationsModule, VitamUICommonTestModule, OrderByButtonComponent], - declarations: [GroupListComponent], + imports: [MatProgressSpinnerModule, VitamUICommonTestModule, OrderByButtonComponent, GroupListComponent], schemas: [NO_ERRORS_SCHEMA], providers: [ { provide: GroupService, useValue: groupListServiceSpy }, @@ -169,7 +167,7 @@ describe('GroupListComponent', () => {
@@ -180,7 +178,7 @@ describe('GroupListComponent', () => {
GROUP.HOME.RESULTS_TABLE.LEVEL
- @for (group of dataSource; track group) { + @for (group of dataSource(); track group) {
{{ group.name }}
@@ -190,7 +188,7 @@ describe('GroupListComponent', () => {
}
- @if (infiniteScrollDisabled) { + @if (infiniteScrollDisabled()) {
@@ -245,8 +243,8 @@ describe('GroupListComponent', () => { }); it('should have a button to load more profileGroups', () => { - component.infiniteScrollDisabled = true; - component.pending = false; + component.infiniteScrollDisabled.set(true); + component.pending.set(false); fixture.detectChanges(false); expect(page.loadMoreButton).toBeTruthy(); }); @@ -259,8 +257,8 @@ describe('GroupListComponent', () => { it('should call loadMore()', () => { const groupService = TestBed.inject(GroupService); - component.infiniteScrollDisabled = true; - component.pending = false; + component.infiniteScrollDisabled.set(true); + component.pending.set(false); fixture.detectChanges(false); page.loadMoreButton.click(); expect(groupService.loadMore).toHaveBeenCalled(); @@ -286,7 +284,7 @@ describe('GroupListComponent', () => { usersCount: 0, units: [], }); - expect(component.dataSource[1].name).toBe('Updated profileGroup'); + expect(component.dataSource()[1].name).toBe('Updated profileGroup'); }); function testRow(index: number) { diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.ts index 211420ee4a0..9fad2e5b55e 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.component.ts @@ -34,7 +34,7 @@ * 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, EventEmitter, Input, LOCALE_ID, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, LOCALE_ID, OnDestroy, OnInit, Output } from '@angular/core'; import { merge, Subject, Subscription } from 'rxjs'; import { @@ -42,18 +42,42 @@ import { CriteriaSearchQuery, DEFAULT_PAGE_SIZE, Direction, + EllipsisDirective, Group, + InfiniteScrollDirective, InfiniteScrollTable, + OrderByButtonComponent, PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, + TableFilterSearchComponent, } from 'vitamui-library'; import { GroupService } from '../group.service'; import { buildCriteriaFromGroupFilters } from './group-criteria-builder.util'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-group-list', templateUrl: './group-list.component.html', styleUrls: ['./group-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + TableFilterComponent, + TableFilterOptionComponent, + OrderByButtonComponent, + TableFilterSearchComponent, + NgClass, + MatProgressSpinner, + PipesModule, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class GroupListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { groupService: GroupService; @@ -98,10 +122,14 @@ export class GroupListComponent extends InfiniteScrollTable implements On this.refreshLevelOptions(); this.updatedGroupSub = this.groupService.updated.subscribe((updatedGroup: Group) => { - const profileGroupIndex = this.dataSource.findIndex((group) => updatedGroup.id === group.id); - if (profileGroupIndex > -1) { - this.dataSource[profileGroupIndex] = updatedGroup; - } + this.dataSource.update((groups) => { + const list = [...(groups ?? [])]; + const profileGroupIndex = list.findIndex((group) => updatedGroup.id === group.id); + if (profileGroupIndex > -1) { + list[profileGroupIndex] = updatedGroup; + } + return list; + }); }); const searchCriteriaChange = merge(this.searchChange, this.filterChange, this.orderChange); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.module.ts b/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.module.ts deleted file mode 100644 index e26c43dba56..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/group/group-list/group-list.module.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatRippleModule } from '@angular/material/core'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { RouterModule } from '@angular/router'; - -import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { GroupListComponent } from './group-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, SharedModule, RouterModule, MatRippleModule, MatProgressSpinnerModule, VitamUICommonModule, TranslatePipe], - declarations: [GroupListComponent], - exports: [GroupListComponent], -}) -export class GroupListModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-popup.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-popup.component.ts index fc09b488193..c614943c2be 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-popup.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-popup.component.ts @@ -38,11 +38,12 @@ import { Component, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Group } from 'vitamui-library'; +import { GroupPreviewComponent } from './group-preview.component'; @Component({ selector: 'app-group-popup', template: '', - standalone: false, + imports: [GroupPreviewComponent], }) export class GroupPopupComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.component.ts index a1e0272bcef..07e1b643905 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.component.ts @@ -34,18 +34,36 @@ * 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, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; import { Subscription } from 'rxjs'; import type { Group } from 'vitamui-library'; -import { AuthService, isLevelAllowed } from 'vitamui-library'; +import { AuthService, isLevelAllowed, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { GroupService } from '../group.service'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { ProfilesTabComponent } from './profiles-tab/profiles-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-group-preview', templateUrl: './group-preview.component.html', styleUrls: ['./group-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + InformationTabComponent, + ProfilesTabComponent, + OperationHistoryTabComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class GroupPreviewComponent implements OnInit, OnDestroy, OnChanges { private groupService = inject(GroupService); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.module.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.module.ts deleted file mode 100644 index a369ee52539..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/group-preview.module.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { UnitsFormModule } from '../units-form/units-form.module'; -import { GroupPopupComponent } from './group-popup.component'; -import { GroupPreviewComponent } from './group-preview.component'; -import { InformationTabComponent } from './information-tab/information-tab.component'; -import { UnitsEditComponent } from './information-tab/units-edit/units-edit.component'; -import { ProfilesEditComponent } from './profiles-tab/profiles-edit/profiles-edit.component'; -import { ProfilesTabComponent } from './profiles-tab/profiles-tab.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatMenuModule, - MatProgressBarModule, - MatTabsModule, - ReactiveFormsModule, - RouterModule, - SharedModule, - UnitsFormModule, - VitamUICommonModule, - VitamUILibraryModule, - MatDialogModule, - TranslatePipe, - ], - declarations: [ - GroupPopupComponent, - GroupPreviewComponent, - InformationTabComponent, - ProfilesTabComponent, - ProfilesEditComponent, - UnitsEditComponent, - ], - exports: [GroupPreviewComponent], -}) -export class GroupPreviewModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.spec.ts deleted file mode 100644 index d4a06c4ef44..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.spec.ts +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { EMPTY, of } from 'rxjs'; -import { AuthService, BASE_URL, CountryService, Group, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { GroupService } from '../../group.service'; -import { GroupValidators } from '../../group.validators'; -import { InformationTabComponent } from './information-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -let expectedGroup: Group; - -@Component({ - template: ` `, - standalone: false, -}) -class TestHostComponent { - group = expectedGroup; - readOnly = false; - - @ViewChild(InformationTabComponent, { static: false }) - component: InformationTabComponent; -} - -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('Profile Group InformationTabComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - const groupServiceSpy = { - patch: vi.fn().mockName('GroupService.patch').mockReturnValue(of({})), - }; - const groupValidatorsSpy = { - nameExists: vi - .fn() - .mockName('GroupValidators.nameExists') - .mockReturnValue(() => of(null)), - }; - const authServiceMock = { user: { level: '' } }; - const matDialogSpy = { - open: vi.fn().mockName('MatDialog.open'), - }; - matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); - - beforeEach(async () => { - expectedGroup = { - id: '42', - enabled: true, - identifier: '1', - customerId: '4242442', - name: 'Group Name', - description: 'Group Description', - level: '', - usersCount: 0, - profileIds: [], - profiles: [], - units: [], - readonly: false, - }; - - await TestBed.configureTestingModule({ - declarations: [InformationTabComponent, TestHostComponent], - schemas: [NO_ERRORS_SCHEMA], - imports: [ReactiveFormsModule, VitamUICommonTestModule, LoggerModule.forRoot()], - providers: [ - { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: MatDialog, useValue: matDialogSpy }, - { provide: GroupService, useValue: groupServiceSpy }, - { provide: GroupValidators, useValue: groupValidatorsSpy }, - { provide: AuthService, useValue: authServiceMock }, - { provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }) - .overrideComponent(InformationTabComponent, { set: { template: '' } }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('Class', () => { - it('should have the correct fields', () => { - expect(testhost.component.form.get('id')).not.toBeNull(); - expect(testhost.component.form.get('name')).not.toBeNull(); - expect(testhost.component.form.get('description')).not.toBeNull(); - }); - - it('should have the required validator', () => { - testhost.component.form.setValue({ - id: null, - identifier: null, - name: null, - level: null, - enabled: false, - description: null, - }); - expect(testhost.component.form.get('id').valid).toBeFalsy(); - expect(testhost.component.form.get('name').valid).toBeFalsy(); - expect(testhost.component.form.get('description').valid).toBeFalsy(); - }); - - it('should be valid and call patch()', () => { - testhost.component.form.setValue({ - id: expectedGroup.id, - identifier: expectedGroup.identifier, - enabled: expectedGroup.enabled, - name: expectedGroup.name, - level: '', - description: expectedGroup.description, - }); - expect(testhost.component.form.valid).toBeTruthy(); - }); - - it('should disable then enable the form', () => { - testhost.component.readOnly = true; - testhost.component.ngOnChanges({ - readOnly: { previousValue: false, currentValue: true, firstChange: false, isFirstChange: () => false }, - }); - expect(testhost.component.form.disabled).toBe(true); - testhost.component.readOnly = false; - testhost.component.ngOnChanges({ - readOnly: { previousValue: true, currentValue: false, firstChange: false, isFirstChange: () => false }, - }); - expect(testhost.component.form.disabled).toBe(false); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.ts index e7b3afe6e31..84953e09671 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/information-tab.component.ts @@ -34,19 +34,37 @@ * 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, Input, OnChanges, OnDestroy, SimpleChanges, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, inject, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { merge, of, Subscription } from 'rxjs'; import { catchError, debounceTime, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { Group } from 'vitamui-library'; -import { AuthService, buildValidators, diff } from 'vitamui-library'; +import { + AuthService, + buildValidators, + diff, + EditableInputComponent, + EditableLevelInputComponent, + EditableTextareaComponent, + Group, + SlideToggleComponent, + TooltipDirective, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { GroupService } from '../../group.service'; import { GroupValidators } from '../../group.validators'; import { UnitsEditComponent } from './units-edit/units-edit.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const DEBOUNCE_TIME = 200; @@ -54,7 +72,25 @@ const DEBOUNCE_TIME = 200; selector: 'app-information-tab', templateUrl: './information-tab.component.html', styleUrls: ['./information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + SlideToggleComponent, + TooltipDirective, + VitamUIFieldErrorComponent, + TranslatePipe, + CommonModule, + EditableInputComponent, + EditableLevelInputComponent, + EditableTextareaComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class InformationTabComponent implements OnDestroy, OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.spec.ts index 888d679f0dc..82e3da04664 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.spec.ts @@ -34,19 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { Component, forwardRef, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; -import { BASE_URL, ConfirmDialogService } from 'vitamui-library'; +import { ConfirmDialogService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { GroupService } from '../../../group.service'; import { UnitsEditComponent } from './units-edit.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'app-units-form', @@ -58,7 +55,7 @@ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http' multi: true, }, ], - standalone: false, + imports: [MatProgressBarModule, ReactiveFormsModule, VitamUICommonTestModule], }) class UnitsFormStubComponent { writeValue() {} @@ -78,17 +75,13 @@ describe('UnitsEditComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [UnitsEditComponent, UnitsFormStubComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [MatProgressBarModule, ReactiveFormsModule, NoopAnimationsModule, VitamUICommonTestModule], + imports: [MatProgressBarModule, ReactiveFormsModule, VitamUICommonTestModule, UnitsEditComponent, UnitsFormStubComponent], providers: [ { provide: MAT_DIALOG_DATA, useValue: { group: { id: '42', name: 'Test', units: [] } } }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: GroupService, useValue: { patch: () => of({ result: 'test' }) } }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ConfirmDialogService, useValue: { listenToEscapeKeyPress: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.ts index 49d3f565be9..3845a5ecc96 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/information-tab/units-edit/units-edit.component.ts @@ -37,19 +37,21 @@ import { Subscription } from 'rxjs'; import { take } from 'rxjs/operators'; -import { ConfirmDialogService, Group } from 'vitamui-library'; +import { ConfirmDialogService, DialogHeaderComponent, Group } from 'vitamui-library'; -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { GroupService } from '../../../group.service'; +import { UnitsFormComponent } from '../../../units-form/units-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-units-edit', templateUrl: './units-edit.component.html', styleUrls: ['./units-edit.component.css'], - standalone: false, + imports: [DialogHeaderComponent, MatDialogContent, ReactiveFormsModule, UnitsFormComponent, MatDialogActions, TranslatePipe], }) export class UnitsEditComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.spec.ts index 3e01f1aef64..bdea1ae82cb 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.spec.ts @@ -35,20 +35,16 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { EMPTY, of } from 'rxjs'; -import { BASE_URL, ConfirmDialogService } from 'vitamui-library'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { ConfirmDialogService } from 'vitamui-library'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Component, forwardRef, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { GroupService } from '../../../group.service'; import { ProfilesEditComponent } from './profiles-edit.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'app-profiles-form', @@ -60,7 +56,7 @@ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http' multi: true, }, ], - standalone: false, + imports: [MatProgressBarModule, ReactiveFormsModule, VitamUICommonTestModule], }) class ProfilesFormStubComponent { @Input() @@ -83,17 +79,13 @@ describe('ProfilesEditComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [ProfilesEditComponent, ProfilesFormStubComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [MatProgressBarModule, ReactiveFormsModule, NoopAnimationsModule, VitamUICommonTestModule], + imports: [MatProgressBarModule, ReactiveFormsModule, VitamUICommonTestModule, ProfilesEditComponent, ProfilesFormStubComponent], providers: [ { provide: MAT_DIALOG_DATA, useValue: { group: { id: '42', name: 'Test', profileIds: [] } } }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: GroupService, useValue: { patch: () => of({ result: 'test' }) } }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ConfirmDialogService, useValue: { listenToEscapeKeyPress: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.ts index f721bc3d127..b180742bb54 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-edit/profiles-edit.component.ts @@ -34,18 +34,20 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import { ConfirmDialogService, Group } from 'vitamui-library'; +import { ConfirmDialogService, DialogHeaderComponent, Group } from 'vitamui-library'; import { GroupService } from '../../../group.service'; +import { ProfilesFormComponent } from '../../../../shared/profiles-form/profiles-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-profiles-edit', templateUrl: './profiles-edit.component.html', styleUrls: ['./profiles-edit.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, ReactiveFormsModule, MatDialogContent, ProfilesFormComponent, MatDialogActions, TranslatePipe], }) export class ProfilesEditComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.spec.ts deleted file mode 100644 index a55738105f1..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.spec.ts +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatDialog } from '@angular/material/dialog'; - -import { of, Subject } from 'rxjs'; -import { ApplicationService, Group } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { GroupService } from '../../group.service'; -import { ProfilesEditComponent } from './profiles-edit/profiles-edit.component'; -import { ProfilesTabComponent } from './profiles-tab.component'; - -@Component({ - template: ` `, - standalone: false, -}) -class TesthostComponent { - readOnly = false; - - group: Group = { - id: '1', - customerId: '42', - name: 'Profile Group Name', - level: 'level', - usersCount: 0, - description: 'Profile Group Description', - profileIds: [], - units: [], - profiles: [ - { - id: '1', - name: 'profile 1', - description: 'description 1', - applicationName: 'app 1', - level: 'level', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 4, - tenantName: 'tenant 1', - tenantIdentifier: 1, - roles: [], - externalParamId: null, - readonly: false, - }, - { - id: '2', - name: 'profile 2', - description: 'description 2', - applicationName: 'app 1', - level: 'level', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 4, - tenantName: 'tenant 2', - tenantIdentifier: 2, - roles: [], - externalParamId: null, - readonly: false, - }, - { - id: '3', - name: 'profile 3', - description: 'description 3', - applicationName: 'app 2', - level: 'level', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 4, - tenantName: 'tenant 1', - tenantIdentifier: 1, - roles: [], - externalParamId: null, - readonly: false, - }, - ], - readonly: true, - }; -} - -const expectedApp = [ - { - id: 'CUSTOMERS_APP', - identifier: 'CUSTOMERS_APP', - name: 'Organisations', - url: '', - }, - { - id: 'ARCHIVE_APP', - identifier: 'ARCHIVE_APP', - name: 'Archives', - url: '', - }, - { - id: 'USERS_APP', - identifier: 'USERS_APP', - name: 'Utilisateurs', - url: '', - }, - { - id: 'GROUPS_APP', - identifier: 'GROUPS_APP', - name: 'Groupes de profils', - url: '', - }, - { - id: 'PROFILES_APP', - identifier: 'PROFILES_APP', - name: 'Profils APP Utilisateurs', - url: '', - }, -]; - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('ProfilesTabComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - const matDialogSpy = { - open: vi.fn().mockName('MatDialog.open'), - }; - matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [VitamUICommonTestModule], - declarations: [ProfilesTabComponent, TesthostComponent], - providers: [ - { provide: MatDialog, useValue: matDialogSpy }, - { provide: GroupService, useValue: { updated: new Subject() } }, - { provide: ApplicationService, useValue: { list: () => of(expectedApp), buildApplications: () => expectedApp } }, - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - it('should open the profile edit dialog', () => { - const elButton = fixture.nativeElement.querySelector('button'); - const matDialog = TestBed.inject(MatDialog); - expect(elButton).toBeTruthy(); - expect(elButton.textContent).toContain('COMMON.UPDATE'); - elButton.click(); - expect(matDialog.open).toHaveBeenCalledWith(ProfilesEditComponent, { - data: { - group: testhost.group, - }, - autoFocus: false, - disableClose: true, - }); - }); - - it('should not show the edit button', () => { - testhost.readOnly = true; - fixture.detectChanges(false); - expect(testhost.readOnly).toBe(true); - }); - - it('should display a list of profiles', () => { - testhost.group = { - id: '1', - customerId: '42', - name: 'Profile Group Name', - usersCount: 0, - level: 'level', - description: 'Profile Group Description', - profileIds: [], - units: [], - profiles: [ - { - id: '1', - name: 'profile 1', - description: 'description 1', - applicationName: 'app 1', - level: 'level', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 4, - tenantName: 'tenant 1', - tenantIdentifier: 2, - roles: [], - externalParamId: null, - readonly: false, - }, - { - id: '2', - name: 'profile 2', - description: 'description 2', - applicationName: 'app 1', - level: 'level', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 4, - tenantName: 'tenant 2', - tenantIdentifier: 2, - roles: [], - externalParamId: null, - readonly: false, - }, - { - id: '3', - name: 'profile 3', - description: 'description 3', - applicationName: 'app 2', - level: 'level', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 4, - tenantName: 'tenant 1', - tenantIdentifier: 2, - roles: [], - externalParamId: null, - readonly: false, - }, - ], - readonly: true, - }; - fixture.detectChanges(); - const elList = fixture.nativeElement.querySelector('.vitamui-profile-list'); - expect(elList).toBeTruthy(); - const elRows = fixture.nativeElement.querySelectorAll('.medium'); - expect(elRows.length).toBe(3); - testhost.group.profiles.forEach((profile: any, index: number) => { - const elDetails = elRows[index]; - expect(elDetails.textContent).toContain(profile.tenantName + ' : ' + profile.name); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.ts index ebc215153a2..ceeb33e2402 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group-preview/profiles-tab/profiles-tab.component.ts @@ -34,18 +34,19 @@ * 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, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, inject, Input, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import type { Group, Profile } from 'vitamui-library'; +import { Group, Profile, TooltipDirective } from 'vitamui-library'; import { GroupService } from '../../group.service'; import { ProfilesEditComponent } from './profiles-edit/profiles-edit.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-profiles-tab', templateUrl: './profiles-tab.component.html', styleUrls: ['./profiles-tab.component.scss'], - standalone: false, + imports: [TooltipDirective, TranslatePipe], }) export class ProfilesTabComponent implements OnInit, OnDestroy { private dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group.component.spec.ts index cd37023bfdc..f558fb9f72c 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group.component.spec.ts @@ -37,18 +37,18 @@ import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; -import { EMPTY, of } from 'rxjs'; -import { ENVIRONMENT, InjectorModule, LoggerModule, SearchBarComponent, SnackBarService } from 'vitamui-library'; -import type { Group } from 'vitamui-library'; +import { EMPTY, of, Subject } from 'rxjs'; +import { ENVIRONMENT, Group, InjectorModule, LoggerModule, SearchBarComponent, SnackBarService } from 'vitamui-library'; import { environment } from './../../environments/environment'; import { MatDialog } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { GroupCreateComponent } from './group-create/group-create.component'; import { GroupComponent } from './group.component'; +import { GroupListComponent } from './group-list/group-list.component'; +import { GroupPreviewComponent } from './group-preview/group-preview.component'; import { DownloadSnackBarService } from 'projects/referential/src/app/core/service/download-snack-bar.service'; import { GroupService } from './group.service'; @@ -60,7 +60,7 @@ class Page { return fixture.nativeElement.querySelector('app-group-list'); } get createGroup() { - return fixture.nativeElement.querySelector('button'); + return fixture.nativeElement.querySelector('.vitamui-heading vitamui-banner button.btn.primary'); } } @@ -69,11 +69,10 @@ let page: Page; @Component({ selector: 'app-group-list', template: '', - standalone: false, + imports: [MatMenuModule, MatSidenavModule, VitamUICommonTestModule], }) class GroupListStubComponent { - // eslint-disable-next-line @angular-eslint/no-input-rename - @Input('search') + @Input() searchText: string; search() {} @@ -82,7 +81,7 @@ class GroupListStubComponent { @Component({ selector: 'app-group-preview', template: '', - standalone: false, + imports: [MatMenuModule, MatSidenavModule, VitamUICommonTestModule], }) class GroupPreviewStubComponent { @Input() @@ -100,27 +99,43 @@ describe('GroupComponent', () => { const snackBarSpy = { open: vi.fn().mockName('SnackBarService.open'), }; + const groupServiceSpy = { + search: () => of([]), + loadMore: () => of([]), + updated: new Subject(), + getNonEmptyLevels: () => of([]), + }; await TestBed.configureTestingModule({ imports: [ MatMenuModule, MatSidenavModule, - NoopAnimationsModule, VitamUICommonTestModule, InjectorModule, SearchBarComponent, LoggerModule.forRoot(), + GroupComponent, + GroupListStubComponent, + GroupPreviewStubComponent, ], - declarations: [GroupComponent, GroupListStubComponent, GroupPreviewStubComponent], providers: [ { provide: MatDialog, useValue: matDialogSpy }, - { provide: ActivatedRoute, useValue: { data: EMPTY } }, + { provide: ActivatedRoute, useValue: { data: EMPTY, snapshot: { data: { appId: 'GROUPS_APP' } } } }, { provide: ENVIRONMENT, useValue: environment }, { provide: SnackBarService, useValue: snackBarSpy }, { provide: DownloadSnackBarService, useValue: {} }, - { provide: GroupService, useValue: {} }, + { provide: GroupService, useValue: groupServiceSpy }, ], - }).compileComponents(); + }) + .overrideComponent(GroupComponent, { + remove: { + imports: [GroupListComponent, GroupPreviewComponent], + }, + add: { + imports: [GroupListStubComponent, GroupPreviewStubComponent], + }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/identity/src/app/group/group.component.ts b/ui/ui-frontend/projects/identity/src/app/group/group.component.ts index 67ef988947a..d5690ab6762 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group.component.ts @@ -71,25 +71,34 @@ import { GroupService } from './group.service'; * 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, ViewChild, inject } from '@angular/core'; +import { Component, inject, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; -import { GlobalEventService, Group, SidenavPage, SnackBarService } from 'vitamui-library'; +import { Group, SidenavPage, SnackBarService, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { GroupCreateComponent } from './group-create/group-create.component'; import { GroupListComponent } from './group-list/group-list.component'; import { DownloadSnackBarService } from 'projects/referential/src/app/core/service/download-snack-bar.service'; import { finalize } from 'rxjs/operators'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { GroupPreviewComponent } from './group-preview/group-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-group', templateUrl: './group.component.html', styleUrls: ['./group.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + GroupPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + GroupListComponent, + TranslatePipe, + ], }) export class GroupComponent extends SidenavPage { - route: ActivatedRoute; - override globalEventService: GlobalEventService; private dialog = inject(MatDialog); private downloadSnackBarService = inject(DownloadSnackBarService); private snackBarService = inject(SnackBarService); @@ -101,16 +110,6 @@ export class GroupComponent extends SidenavPage { @ViewChild(GroupListComponent, { static: true }) groupListComponent: GroupListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - this.globalEventService = globalEventService; - } - openCreateGroupDialog(): void { const dialogRef = this.dialog.open(GroupCreateComponent, { disableClose: true }); dialogRef.afterClosed().subscribe((result) => { diff --git a/ui/ui-frontend/projects/identity/src/app/group/group.module.ts b/ui/ui-frontend/projects/identity/src/app/group/group.module.ts index 3d05c58bb31..a23c2622136 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group.module.ts @@ -42,28 +42,21 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; -import { GroupCreateModule } from './group-create/group-create.module'; -import { GroupListModule } from './group-list/group-list.module'; -import { GroupPreviewModule } from './group-preview/group-preview.module'; + import { GroupRoutingModule } from './group-routing.module'; import { GroupComponent } from './group.component'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [GroupComponent], imports: [ CommonModule, VitamUICommonModule, - SharedModule, - GroupCreateModule, - GroupListModule, - GroupPreviewModule, MatDialogModule, MatMenuModule, MatSidenavModule, GroupRoutingModule, TranslatePipe, + GroupComponent, ], providers: [provideHttpClient(withInterceptorsFromDi())], }) diff --git a/ui/ui-frontend/projects/identity/src/app/group/group.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/group/group.service.spec.ts index 1fd1a71a000..6d638d25650 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group.service.spec.ts @@ -34,14 +34,13 @@ * 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 { BASE_URL, CriteriaSearchQuery, Direction, Group, Operators, PageRequest, SnackBarService } from 'vitamui-library'; +import { CriteriaSearchQuery, Direction, Group, Operators, PageRequest, SnackBarService } from 'vitamui-library'; -import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { Type } from '@angular/core'; import { GroupService } from './group.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('GroupService', () => { let httpTestingController: HttpTestingController; @@ -54,16 +53,7 @@ describe('GroupService', () => { TestBed.configureTestingModule({ imports: [], - providers: [ - GroupService, - { provide: SnackBarService, useValue: snackBarSpy }, - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [GroupService, { provide: SnackBarService, useValue: snackBarSpy }], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/identity/src/app/group/group.service.ts b/ui/ui-frontend/projects/identity/src/app/group/group.service.ts index 3839c1d1511..4dc80b18887 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/group.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/group.service.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { CriteriaSearchQuery, Criterion, Group, Operators, SearchService, SnackBarService } from 'vitamui-library'; diff --git a/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.component.ts b/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.component.ts index b7acff9f22f..44b52f5e5ca 100644 --- a/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.component.ts @@ -34,9 +34,19 @@ * 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, forwardRef, Input, OnInit, inject } from '@angular/core'; -import { AbstractControl, ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, ValidationErrors } from '@angular/forms'; +import { Component, forwardRef, inject, Input, OnInit } from '@angular/core'; +import { + AbstractControl, + ControlValueAccessor, + FormControl, + NG_VALUE_ACCESSOR, + ReactiveFormsModule, + ValidationErrors, +} from '@angular/forms'; import { GroupValidators } from '../group.validators'; +import { EllipsisDirective, InputComponent } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; export const UNITS_FORM_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -52,7 +62,7 @@ export const UNITS_FORM_VALUE_ACCESSOR: any = { templateUrl: './units-form.component.html', styleUrls: ['./units-form.component.scss'], providers: [UNITS_FORM_VALUE_ACCESSOR], - standalone: false, + imports: [InputComponent, ReactiveFormsModule, TranslatePipe, CommonModule, EllipsisDirective], }) export class UnitsFormComponent implements ControlValueAccessor, OnInit { private groupValidators = inject(GroupValidators); diff --git a/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.module.ts b/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.module.ts deleted file mode 100644 index 54cd4fa7a27..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/group/units-form/units-form.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatSelectModule } from '@angular/material/select'; -import { VitamUICommonModule } from 'vitamui-library'; -import { UnitsFormComponent } from './units-form.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, CommonModule, ReactiveFormsModule, MatSelectModule, VitamUICommonModule, TranslatePipe], - declarations: [UnitsFormComponent], - exports: [UnitsFormComponent], -}) -export class UnitsFormModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.spec.ts index a12826cddc5..2f5d6219626 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.spec.ts @@ -36,15 +36,16 @@ */ import { Component, forwardRef, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; +import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; -import { AuthService, ConfirmDialogService, LevelInputModule } from 'vitamui-library'; +import { AuthService, ConfirmDialogService, LevelInputComponent } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { HierarchyService } from '../hierarchy.service'; import { HierarchyCreateComponent } from './hierarchy-create.component'; +import { CommonModule } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-profiles-form', @@ -56,7 +57,6 @@ import { HierarchyCreateComponent } from './hierarchy-create.component'; multi: true, }, ], - standalone: false, }) class ProfilesFormStubComponent implements ControlValueAccessor { @Input() @@ -81,8 +81,17 @@ describe('HierarchyCreateComponent', () => { }; await TestBed.configureTestingModule({ - imports: [MatProgressBarModule, ReactiveFormsModule, NoopAnimationsModule, VitamUICommonTestModule, LevelInputModule], - declarations: [ProfilesFormStubComponent, HierarchyCreateComponent], + imports: [ + MatProgressBarModule, + ReactiveFormsModule, + VitamUICommonTestModule, + CommonModule, + FormsModule, + LevelInputComponent, + TranslatePipe, + HierarchyCreateComponent, + ProfilesFormStubComponent, + ], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: { tenantId: 10 } }, diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.ts index dec1fd2ff3e..f527d3d1051 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.component.ts @@ -34,18 +34,42 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { Observable, Subscription, forkJoin } from 'rxjs'; -import { AuthService, ConfirmDialogService, CriteriaSearchQuery, Operators, Profile, buildValidators } from 'vitamui-library'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { forkJoin, Observable, Subscription } from 'rxjs'; +import { + AuthService, + buildValidators, + ConfirmDialogService, + CriteriaSearchQuery, + DialogHeaderComponent, + LevelInputComponent, + Operators, + Profile, + SlideToggleComponent, +} from 'vitamui-library'; import { HierarchyService } from '../hierarchy.service'; +import { ProfilesFormComponent } from '../../shared/profiles-form/profiles-form.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-hierarchy-create', templateUrl: './hierarchy-create.component.html', styleUrls: ['./hierarchy-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + MatDialogContent, + SlideToggleComponent, + ProfilesFormComponent, + MatDialogActions, + TranslatePipe, + CommonModule, + FormsModule, + LevelInputComponent, + ], }) export class HierarchyCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.module.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.module.ts deleted file mode 100644 index e7dfbabac50..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-create/hierarchy-create.module.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { HierarchyCreateComponent } from './hierarchy-create.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - SharedModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [HierarchyCreateComponent], - exports: [HierarchyCreateComponent], -}) -export class HierarchyCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.spec.ts deleted file mode 100644 index 50fb6d2279e..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.spec.ts +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, Input, NO_ERRORS_SCHEMA, ViewChild, NgModule } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; -import { EMPTY, of, Subject } from 'rxjs'; -import { environment } from './../../../environments/environment'; - -import { AuthService, BASE_URL, ENVIRONMENT, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; -import type { Profile } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { HierarchyService } from '../hierarchy.service'; -import { HierarchyDetailComponent } from './hierarchy-detail.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -@Component({ - selector: 'app-information-tab', - template: '', - standalone: false, -}) -class InformationTabStubComponent { - @Input() profile: Profile; - @Input() readOnly: boolean; -} - -@Component({ - selector: 'app-side-panel', - template: ` `, - standalone: false, -}) -class SidePanelStubComponent { - @Input() popup: boolean; - @Input() popupUrl: string; -} - -@Component({ - template: '', - standalone: false, -}) -class TestHostComponent { - profile: any; - isPopup = false; - - @ViewChild(HierarchyDetailComponent, { static: false }) component: HierarchyDetailComponent; -} - -@NgModule({ declarations: [SidePanelStubComponent, TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('HierarchyDetailComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - const authServiceMock = { user: { level: '' } }; - - const expectedProfile = { - id: '42', - name: 'Profile Name', - description: 'description', - level: '', - groupsCount: 1, - applicationName: 'USERS_APP', - enabled: true, - usersCount: 0, - tenant: { - id: '42', - name: 'tenant name', - identifier: 754123, - owner: { - id: 'owner_id', - code: '745987', - name: 'Owner name', - companyName: 'The company name', - address: { - street: 'rue des bois', - zipCode: '75019', - city: 'Paris', - country: 'FRANCE', - }, - customerId: 'customer_id', - readonly: false, - }, - ownerId: 'owner_id', - customerId: 'customer_id', - enabled: true, - proof: false, - readonly: false, - }, - tenantIdentifier: '42', - roles: ['role_name'], - readonly: false, - }; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [TestHostComponent, HierarchyDetailComponent, SidePanelStubComponent, InformationTabStubComponent], - schemas: [NO_ERRORS_SCHEMA], - imports: [MatMenuModule, MatTabsModule, NoopAnimationsModule, LoggerModule.forRoot(), VitamUICommonTestModule], - providers: [ - { provide: ActivatedRoute, useValue: { data: of({ isPopup: true, profile: expectedProfile }) } }, - { provide: HierarchyService, useValue: { updated: new Subject() } }, - { provide: AuthService, useValue: authServiceMock }, - { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - testhost.profile = expectedProfile; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should have a header', () => { - const elTitle = fixture.nativeElement.querySelector('vitamui-common-sidenav-header'); - expect(elTitle).toBeTruthy(); - }); - - it('should have a mat-tab-group', () => { - const elTabGroup = fixture.nativeElement.querySelector('.mat-mdc-tab-group'); - expect(elTabGroup).toBeTruthy(); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.ts index bb7c6f5a36d..88b5eeb540e 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.component.ts @@ -34,18 +34,34 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subscription } from 'rxjs'; import type { Profile } from 'vitamui-library'; -import { AuthService, isLevelAllowed } from 'vitamui-library'; +import { AuthService, isLevelAllowed, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { HierarchyService } from '../hierarchy.service'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-hierarchy-detail', templateUrl: './hierarchy-detail.component.html', styleUrls: ['./hierarchy-detail.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + InformationTabComponent, + OperationHistoryTabComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class HierarchyDetailComponent implements OnInit, OnDestroy { private hierarchyService = inject(HierarchyService); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.module.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.module.spec.ts deleted file mode 100644 index 7ad45114378..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.module.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { HierarchyDetailModule } from './hierarchy-detail.module'; - -describe('HierarchyDetailModule', () => { - let hierarchyDetailModule: HierarchyDetailModule; - - beforeEach(() => { - hierarchyDetailModule = new HierarchyDetailModule(); - }); - - it('should create an instance', () => { - expect(hierarchyDetailModule).toBeTruthy(); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.module.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.module.ts deleted file mode 100644 index d1434a73979..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-detail.module.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; -import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { HierarchyDetailComponent } from './hierarchy-detail.component'; -import { HierarchyPopupComponent } from './hierarchy-popup.component'; -import { InformationTabComponent } from './information-tab/information-tab.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, SharedModule, MatMenuModule, MatTabsModule, ReactiveFormsModule, VitamUICommonModule, TranslatePipe], - declarations: [HierarchyPopupComponent, HierarchyDetailComponent, InformationTabComponent], - exports: [HierarchyDetailComponent], -}) -export class HierarchyDetailModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-popup.component.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-popup.component.ts index ac11ecc5441..1a3b67d707e 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-popup.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/hierarchy-popup.component.ts @@ -38,11 +38,12 @@ import { Component, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Profile } from 'vitamui-library'; +import { HierarchyDetailComponent } from './hierarchy-detail.component'; @Component({ selector: 'app-hierarchy-popup', template: '', - standalone: false, + imports: [HierarchyDetailComponent], }) export class HierarchyPopupComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.spec.ts deleted file mode 100644 index 5ed05e13ed4..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.spec.ts +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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, forwardRef, Input, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; -import type { AsyncValidator, Validator } from '@angular/forms'; -import { of, Subject } from 'rxjs'; - -import { AuthService, CountryService } from 'vitamui-library'; -import type { Profile } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { HierarchyService } from '../../hierarchy.service'; -import { ProfileValidators } from '../../profile.validators'; -import { InformationTabComponent } from './information-tab.component'; - -@Component({ - selector: 'app-editable-textarea', - template: '{{value}}', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => EditableTextAreaStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class EditableTextAreaStubComponent implements ControlValueAccessor { - @Input() - validator: Validator; - @Input() - asyncValidator: AsyncValidator; - value: string; - writeValue(value: string) { - this.value = value; - } - registerOnChange() {} - registerOnTouched() {} -} - -@Component({ - template: ` `, - standalone: false, -}) -class TestHostComponent { - profile: Profile = { - id: '1', - name: 'ProfileName', - description: 'Profile description...', - level: '', - customerId: 'customerId', - groupsCount: 1, - enabled: true, - usersCount: 42, - tenantName: 'tenant name', - tenantIdentifier: 420, - applicationName: 'CUSTOMERS_APP', - roles: [ - { - name: 'ROLE_MFA_USERS', - }, - { - name: 'ROLE_UPDATE_STANDARD_USERS', - }, - { - name: 'ROLE_GENERIC_USERS', - }, - ], - readonly: false, - externalParamId: null, - }; - readOnly = false; - - @ViewChild(InformationTabComponent, { static: false }) - component: InformationTabComponent; -} - -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('Hierarchy InformationTabComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - const hierarchyServiceMock = { update: of({}), updated: new Subject() }; - const profileValidatorsSpy = { - nameExists: vi - .fn() - .mockName('ProfileValidators.nameExists') - .mockReturnValue(() => of(null)), - }; - const authServiceMock = { user: { level: '' } }; - - await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, VitamUICommonTestModule], - schemas: [NO_ERRORS_SCHEMA], - declarations: [InformationTabComponent, TestHostComponent, EditableTextAreaStubComponent], - providers: [ - { provide: HierarchyService, useValue: hierarchyServiceMock }, - { provide: ProfileValidators, useValue: profileValidatorsSpy }, - { provide: AuthService, useValue: authServiceMock }, - { provide: CountryService, useValue: {} }, - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should have all the fields', () => { - let element = fixture.nativeElement.querySelector('vitamui-common-editable-input[formControlName=name]'); - expect(element).toBeTruthy(); - expect(element.textContent).toContain('ProfileName'); - expect(element.attributes.maxlength.value).toBe('100'); - - element = fixture.nativeElement.querySelector('vitamui-common-editable-textarea[formControlName=description]'); - expect(element).toBeTruthy(); - expect(element.textContent).toContain('Profile description...'); - expect(element.attributes.maxlength.value).toBe('250'); - - element = fixture.nativeElement.querySelector('vitamui-slide-toggle[formControlName=enabled]'); - expect(element).toBeTruthy(); - expect(element.textContent).toContain('HIERARCHY.INFORMATIONS.ACTIVE_SWITCH'); - }); - }); - - describe('Component', () => { - it('TODO', () => { - // TODO - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.ts index f9191032c90..83b08897e7a 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-detail/information-tab/information-tab.component.ts @@ -34,16 +34,35 @@ * 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, Input, OnChanges, OnDestroy, SimpleChanges, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { merge, of, Subscription } from 'rxjs'; import { catchError, debounceTime, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { Profile } from 'vitamui-library'; -import { AuthService, buildValidators, diff } from 'vitamui-library'; +import { + AuthService, + buildValidators, + diff, + EditableInputComponent, + EditableLevelInputComponent, + EditableTextareaComponent, + Profile, + SlideToggleComponent, + TooltipDirective, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { HierarchyService } from '../../hierarchy.service'; import { ProfileValidators } from '../../profile.validators'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const DEBOUNCE_TIME = 400; @@ -51,7 +70,25 @@ const DEBOUNCE_TIME = 400; selector: 'app-information-tab', templateUrl: './information-tab.component.html', styleUrls: ['./information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + SlideToggleComponent, + TooltipDirective, + VitamUIFieldErrorComponent, + TranslatePipe, + CommonModule, + EditableInputComponent, + EditableLevelInputComponent, + EditableTextareaComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class InformationTabComponent implements OnDestroy, OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.html b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.html index 563ae02f4a0..b8f9ecd0b48 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.html @@ -11,7 +11,7 @@
- @for (profile of dataSource; track profile) { + @for (profile of dataSource(); track profile) {
@@ -33,15 +33,15 @@
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && hierarchyService.canLoadMore && !pending) { + @if (infiniteScrollDisabled && hierarchyService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.spec.ts index ae8c360ca96..401a5d907d3 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.spec.ts @@ -93,8 +93,7 @@ describe('HierarchyListComponent', () => { }; await TestBed.configureTestingModule({ - imports: [MatProgressSpinnerModule, VitamUICommonTestModule], - declarations: [HierarchyListComponent], + imports: [MatProgressSpinnerModule, VitamUICommonTestModule, HierarchyListComponent], providers: [ { provide: HierarchyService, useValue: hierarchyListServiceSpy }, { provide: Router, useValue: routerSpy }, diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.ts index f505006f358..4cae12be0c5 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.component.ts @@ -42,17 +42,23 @@ import { CriteriaSearchQuery, Criterion, Direction, + EllipsisDirective, + InfiniteScrollDirective, InfiniteScrollTable, Operators, PageRequest, + PipesModule, Profile, } from 'vitamui-library'; -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { DEFAULT_PAGE_SIZE } from '../../core/customer.service'; import { HierarchyService } from '../hierarchy.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -60,7 +66,7 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-hierarchy-list', templateUrl: './hierarchy-list.component.html', styleUrls: ['./hierarchy-list.component.scss'], - standalone: false, + imports: [NgClass, MatProgressSpinner, PipesModule, TranslatePipe, CommonModule, EllipsisDirective, InfiniteScrollDirective], }) export class HierarchyListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { hierarchyService: HierarchyService; @@ -89,25 +95,29 @@ export class HierarchyListComponent extends InfiniteScrollTable impleme this.hierarchyService = hierarchyService; this.updatedProfileSub = this.hierarchyService.updated.subscribe((updatedProfile: Profile) => { - const profileIndex = this.dataSource.findIndex((profile) => updatedProfile.id === profile.id); - if (profileIndex > -1) { - this.dataSource[profileIndex] = { - id: this.dataSource[profileIndex].id, - enabled: updatedProfile.enabled, - name: updatedProfile.name, - level: updatedProfile.level, - customerId: this.dataSource[profileIndex].customerId, - groupsCount: this.dataSource[profileIndex].groupsCount, - description: updatedProfile.description, - usersCount: this.dataSource[profileIndex].usersCount, - tenantName: this.dataSource[profileIndex].tenantName, - tenantIdentifier: this.dataSource[profileIndex].tenantIdentifier, - applicationName: this.dataSource[profileIndex].applicationName, - roles: this.dataSource[profileIndex].roles, - readonly: this.dataSource[profileIndex].readonly, - externalParamId: this.dataSource[profileIndex].externalParamId, - }; - } + this.dataSource.update((profiles) => { + const list = [...(profiles ?? [])]; + const profileIndex = list.findIndex((profile) => updatedProfile.id === profile.id); + if (profileIndex > -1) { + list[profileIndex] = { + id: list[profileIndex].id, + enabled: updatedProfile.enabled, + name: updatedProfile.name, + level: updatedProfile.level, + customerId: list[profileIndex].customerId, + groupsCount: list[profileIndex].groupsCount, + description: updatedProfile.description, + usersCount: list[profileIndex].usersCount, + tenantName: list[profileIndex].tenantName, + tenantIdentifier: list[profileIndex].tenantIdentifier, + applicationName: list[profileIndex].applicationName, + roles: list[profileIndex].roles, + readonly: list[profileIndex].readonly, + externalParamId: list[profileIndex].externalParamId, + }; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.module.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.module.spec.ts deleted file mode 100644 index 9db09adebb9..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.module.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { HierarchyListModule } from './hierarchy-list.module'; - -describe('HierarchyListModule', () => { - let hierarchyListModule: HierarchyListModule; - - beforeEach(() => { - hierarchyListModule = new HierarchyListModule(); - }); - - it('should create an instance', () => { - expect(hierarchyListModule).toBeTruthy(); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.module.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.module.ts deleted file mode 100644 index 283dbdb4776..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy-list/hierarchy-list.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; - -import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { HierarchyListComponent } from './hierarchy-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, SharedModule, MatProgressSpinnerModule, VitamUICommonModule, TranslatePipe], - declarations: [HierarchyListComponent], - exports: [HierarchyListComponent], -}) -export class HierarchyListModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.component.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.component.ts index be55c3caf73..b038546c2a3 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.component.ts @@ -34,23 +34,34 @@ * 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, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { GlobalEventService, Profile, SidenavPage } from 'vitamui-library'; +import { Profile, SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { HierarchyCreateComponent } from './hierarchy-create/hierarchy-create.component'; import { HierarchyListComponent } from './hierarchy-list/hierarchy-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { HierarchyDetailComponent } from './hierarchy-detail/hierarchy-detail.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-hierarchy', templateUrl: './hierarchy.component.html', styleUrls: ['./hierarchy.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + HierarchyDetailComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + HierarchyListComponent, + TranslatePipe, + ], }) export class HierarchyComponent extends SidenavPage implements OnInit { dialog = inject(MatDialog); - route: ActivatedRoute; - override globalEventService: GlobalEventService; + private route = inject(ActivatedRoute); public profiles: Profile[]; public search: string; @@ -58,16 +69,6 @@ export class HierarchyComponent extends SidenavPage implements OnInit { @ViewChild(HierarchyListComponent, { static: true }) hierarchyListComponent: HierarchyListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - this.globalEventService = globalEventService; - } - ngOnInit() { this.route.paramMap.subscribe((paramMap) => { this.tenantIdentifier = +paramMap.get('tenantIdentifier'); diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.module.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.module.ts index 2106c275903..86f1e204057 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.module.ts @@ -42,10 +42,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; -import { HierarchyCreateModule } from './hierarchy-create/hierarchy-create.module'; -import { HierarchyDetailModule } from './hierarchy-detail/hierarchy-detail.module'; -import { HierarchyListModule } from './hierarchy-list/hierarchy-list.module'; + import { HierarchyRoutingModule } from './hierarchy-routing.module'; import { HierarchyComponent } from './hierarchy.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -54,17 +51,13 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ CommonModule, VitamUICommonModule, - SharedModule, - HierarchyListModule, - HierarchyDetailModule, - HierarchyCreateModule, MatButtonToggleModule, MatProgressBarModule, ReactiveFormsModule, MatSidenavModule, HierarchyRoutingModule, TranslatePipe, + HierarchyComponent, ], - declarations: [HierarchyComponent], }) export class HierarchyModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.service.spec.ts index c85134e7e58..68535715eb3 100644 --- a/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/hierarchy/hierarchy.service.spec.ts @@ -34,13 +34,10 @@ * 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 { BASE_URL, SnackBarService } from 'vitamui-library'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { SnackBarService } from 'vitamui-library'; import { TestBed } from '@angular/core/testing'; import { HierarchyService } from './hierarchy.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('HierarchyService', () => { beforeEach(() => { @@ -50,13 +47,7 @@ describe('HierarchyService', () => { TestBed.configureTestingModule({ imports: [], - providers: [ - HierarchyService, - { provide: SnackBarService, useValue: snackBarSpy }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [HierarchyService, { provide: SnackBarService, useValue: snackBarSpy }], }); }); diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.component.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.component.ts index 4384f71df7e..9ecce7f46e7 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.component.ts @@ -35,21 +35,50 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Subscription } from 'rxjs'; -import { ApplicationId, AuthService, AuthUser, buildValidators, ConfirmDialogService, Profile, Role } from 'vitamui-library'; - -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { + ApplicationId, + AuthService, + AuthUser, + buildValidators, + ConfirmDialogService, + DialogHeaderComponent, + InputComponent, + LevelInputComponent, + Profile, + Role, + RoleComponent, + RoleToggleComponent, + SlideToggleComponent, +} from 'vitamui-library'; + +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { CustomerService } from '../../core/customer.service'; import { ProfileService } from '../profile.service'; import { ProfileValidators } from '../profile.validators'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-profile-create', templateUrl: './profile-create.component.html', styleUrls: ['./profile-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + MatDialogContent, + SlideToggleComponent, + InputComponent, + MatDialogActions, + TranslatePipe, + CommonModule, + FormsModule, + LevelInputComponent, + RoleComponent, + RoleToggleComponent, + ], }) export class ProfileCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.module.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.module.ts deleted file mode 100644 index 6d239ebfeb7..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-create/profile-create.module.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { RoleToggleModule, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { GroupAttributionModule } from '../../user/group-attribution/group-attribution.module'; -import { ProfileCreateComponent } from './profile-create.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - GroupAttributionModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - RoleToggleModule, - SharedModule, - VitamUICommonModule, - VitamUILibraryModule, - MatDialogModule, - TranslatePipe, - ], - declarations: [ProfileCreateComponent], -}) -export class ProfileCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/information-tab/information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/information-tab/information-tab.component.ts index 39cf95130dd..31ed2bdadf4 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/information-tab/information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/information-tab/information-tab.component.ts @@ -34,23 +34,63 @@ * 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, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { of, Subscription } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import { AuthService, buildValidators, diff, Role } from 'vitamui-library'; -import type { Profile } from 'vitamui-library'; +import { + AuthService, + buildValidators, + diff, + EditableInputComponent, + EditableLevelInputComponent, + Profile, + Role, + RoleComponent, + RoleToggleComponent, + SlideToggleComponent, + TooltipDirective, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { ProfileService } from '../../profile.service'; import { ProfileValidators } from '../../profile.validators'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-information-tab', templateUrl: './information-tab.component.html', styleUrls: ['./information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + SlideToggleComponent, + TooltipDirective, + VitamUIFieldErrorComponent, + TranslatePipe, + CommonModule, + EditableInputComponent, + EditableLevelInputComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + RoleComponent, + RoleToggleComponent, + ], }) export class InformationTabComponent implements OnDestroy, OnInit, OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.spec.ts deleted file mode 100644 index 1c266cb0fed..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.spec.ts +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; -import { EMPTY, of, Subject } from 'rxjs'; -import { AuthService, BASE_URL, ENVIRONMENT, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; -import type { Profile } from 'vitamui-library'; -import { environment } from './../../../environments/environment'; - -import { Component, Input, NO_ERRORS_SCHEMA, ViewChild, NgModule } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; - -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { ProfileService } from '../profile.service'; -import { ProfileDetailComponent } from './profile-detail.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -@Component({ - selector: 'app-information-tab', - template: '', - standalone: false, -}) -class InformationTabStubComponent { - @Input() profile: Profile; - @Input() readOnly: boolean; -} - -@Component({ - selector: 'app-profile-group-tab', - template: '', - standalone: false, -}) -class ProfileGroupTabStubComponent { - @Input() profile: Profile; - @Input() readOnly: boolean; -} - -@Component({ - selector: 'app-side-panel', - template: ` `, - standalone: false, -}) -class SidePanelStubComponent { - @Input() popup: boolean; - @Input() popupUrl: string; -} - -@Component({ - template: '', - standalone: false, -}) -class TestHostComponent { - profile: any; - isPopup = false; - - @ViewChild(ProfileDetailComponent, { static: false }) component: ProfileDetailComponent; -} - -@NgModule({ declarations: [SidePanelStubComponent, TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('ProfileDetailComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - const authServiceMock = { user: { level: '' } }; - - const expectedProfile = { - id: '42', - name: 'Profile Name', - description: 'description', - level: '', - groupsCount: 0, - applicationName: 'USERS_APP', - enabled: true, - usersCount: 0, - tenant: { - id: '42', - name: 'tenant name', - identifier: 754123, - owner: { - id: 'owner_id', - code: '745987', - name: 'Owner name', - companyName: 'The company name', - address: { - street: 'rue des bois', - zipCode: '75019', - city: 'Paris', - country: 'FRANCE', - }, - customerId: 'customer_id', - readonly: false, - }, - ownerId: 'owner_id', - customerId: 'customer_id', - enabled: true, - proof: false, - readonly: false, - }, - tenantIdentifier: '42', - roles: ['role_name'], - readonly: false, - }; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - TestHostComponent, - ProfileDetailComponent, - SidePanelStubComponent, - InformationTabStubComponent, - ProfileGroupTabStubComponent, - ], - schemas: [NO_ERRORS_SCHEMA], - imports: [MatMenuModule, MatTabsModule, NoopAnimationsModule, LoggerModule.forRoot(), VitamUICommonTestModule], - providers: [ - { provide: ActivatedRoute, useValue: { data: of({ isPopup: true, profile: expectedProfile }) } }, - { provide: ProfileService, useValue: { updated: new Subject() } }, - { provide: AuthService, useValue: authServiceMock }, - { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - testhost.profile = expectedProfile; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should have a header', () => { - const elTitle = fixture.nativeElement.querySelector('vitamui-common-sidenav-header'); - expect(elTitle).toBeTruthy(); - }); - - it('should have a mat-tab-group', () => { - const elTabGroup = fixture.nativeElement.querySelector('.mat-mdc-tab-group'); - expect(elTabGroup).toBeTruthy(); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.ts index 7294e2e0a25..912c82fe914 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.component.ts @@ -34,18 +34,33 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subscription } from 'rxjs'; -import { AuthService, isLevelAllowed } from 'vitamui-library'; import type { Profile } from 'vitamui-library'; - +import { AuthService, isLevelAllowed, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { ProfileService } from '../profile.service'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { InformationTabComponent } from './information-tab/information-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-profile-detail', templateUrl: './profile-detail.component.html', styleUrls: ['./profile-detail.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + InformationTabComponent, + OperationHistoryTabComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ProfileDetailComponent implements OnInit, OnDestroy { private rngProfileService = inject(ProfileService); diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.module.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.module.ts deleted file mode 100644 index ea1a64fad35..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-detail.module.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; - -import { RoleToggleModule, VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { InformationTabComponent } from './information-tab/information-tab.component'; -import { ProfileDetailComponent } from './profile-detail.component'; -import { ProfilePopupComponent } from './profile-popup.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - SharedModule, - MatMenuModule, - MatTabsModule, - ReactiveFormsModule, - VitamUICommonModule, - RoleToggleModule, - TranslatePipe, - ], - declarations: [ProfilePopupComponent, ProfileDetailComponent, InformationTabComponent], - exports: [ProfileDetailComponent], -}) -export class ProfileDetailModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-popup.component.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-popup.component.ts index 4766bd10f64..59cc03496c6 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-popup.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile-detail/profile-popup.component.ts @@ -38,11 +38,12 @@ import { Component, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Profile } from 'vitamui-library'; +import { ProfileDetailComponent } from './profile-detail.component'; @Component({ selector: 'app-profile-popup', template: '', - standalone: false, + imports: [ProfileDetailComponent], }) export class ProfilePopupComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.html b/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.html index 0d348f61789..bdbc74b968c 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.html @@ -10,7 +10,7 @@
- @for (profile of dataSource; track profile) { + @for (profile of dataSource(); track profile) {
@@ -30,15 +30,15 @@
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && rngProfileService.canLoadMore && !pending) { + @if (infiniteScrollDisabled && rngProfileService.canLoadMore && !pending()) {
A{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.ts index 13d4719b5e6..adb561cac32 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.component.ts @@ -34,7 +34,7 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { merge, Subject, Subscription } from 'rxjs'; import { debounceTime, startWith } from 'rxjs/operators'; import { @@ -44,12 +44,18 @@ import { Criterion, DEFAULT_PAGE_SIZE, Direction, + EllipsisDirective, + InfiniteScrollDirective, InfiniteScrollTable, Operators, PageRequest, + PipesModule, Profile, } from 'vitamui-library'; import { ProfileService } from '../profile.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -57,7 +63,7 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-profile-list', templateUrl: './profile-list.component.html', styleUrls: ['./profile-list.component.scss'], - standalone: false, + imports: [NgClass, MatProgressSpinner, PipesModule, TranslatePipe, CommonModule, EllipsisDirective, InfiniteScrollDirective], }) export class ProfileListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { rngProfileService: ProfileService; @@ -88,26 +94,30 @@ export class ProfileListComponent extends InfiniteScrollTable implement this.rngProfileService = rngProfileService; this.updatedProfileSub = this.rngProfileService.updated.subscribe((updatedProfile: Profile) => { - const profileIndex = this.dataSource.findIndex((profile) => updatedProfile.id === profile.id); - if (profileIndex > -1) { - this.dataSource[profileIndex] = { - id: this.dataSource[profileIndex].id, - identifier: updatedProfile.identifier, - enabled: updatedProfile.enabled, - name: updatedProfile.name, - level: updatedProfile.level, - customerId: updatedProfile.customerId, - groupsCount: updatedProfile.groupsCount, - description: updatedProfile.description, - usersCount: this.dataSource[profileIndex].usersCount, - tenantIdentifier: this.dataSource[profileIndex].tenantIdentifier, - tenantName: this.dataSource[profileIndex].tenantName, - applicationName: this.dataSource[profileIndex].applicationName, - roles: this.dataSource[profileIndex].roles, - readonly: this.dataSource[profileIndex].readonly, - externalParamId: this.dataSource[profileIndex].externalParamId, - }; - } + this.dataSource.update((profiles) => { + const list = [...(profiles ?? [])]; + const profileIndex = list.findIndex((profile) => updatedProfile.id === profile.id); + if (profileIndex > -1) { + list[profileIndex] = { + id: list[profileIndex].id, + identifier: updatedProfile.identifier, + enabled: updatedProfile.enabled, + name: updatedProfile.name, + level: updatedProfile.level, + customerId: updatedProfile.customerId, + groupsCount: updatedProfile.groupsCount, + description: updatedProfile.description, + usersCount: list[profileIndex].usersCount, + tenantIdentifier: list[profileIndex].tenantIdentifier, + tenantName: list[profileIndex].tenantName, + applicationName: list[profileIndex].applicationName, + roles: list[profileIndex].roles, + readonly: list[profileIndex].readonly, + externalParamId: list[profileIndex].externalParamId, + }; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.module.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.module.ts deleted file mode 100644 index 1fa02da7d1d..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile-list/profile-list.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; - -import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { ProfileListComponent } from './profile-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, SharedModule, MatProgressSpinnerModule, VitamUICommonModule, TranslatePipe], - declarations: [ProfileListComponent], - exports: [ProfileListComponent], -}) -export class ProfileListModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile.component.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile.component.ts index d9cdc211347..a9e774706e2 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile.component.ts @@ -34,40 +34,39 @@ * 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 { GlobalEventService, Profile, SidenavPage } from 'vitamui-library'; +import { Profile, SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, inject, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; import { ProfileCreateComponent } from './profile-create/profile-create.component'; import { ProfileListComponent } from './profile-list/profile-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { ProfileDetailComponent } from './profile-detail/profile-detail.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-profile', templateUrl: './profile.component.html', styleUrls: ['./profile.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + ProfileDetailComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ProfileListComponent, + TranslatePipe, + ], }) export class ProfileComponent extends SidenavPage { dialog = inject(MatDialog); - route: ActivatedRoute; - override globalEventService: GlobalEventService; public search: string; @ViewChild(ProfileListComponent, { static: true }) profileListComponent: ProfileListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - this.globalEventService = globalEventService; - } - openProfilAdminCreateDialog() { const dialogRef = this.dialog.open(ProfileCreateComponent, { disableClose: true }); dialogRef.afterClosed().subscribe((result) => { diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile.module.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile.module.ts index 8222f322006..a881947823a 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile.module.ts @@ -36,19 +36,14 @@ */ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatMenuModule } from '@angular/material/menu'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { LevelInputModule, VitamUICommonModule } from 'vitamui-library'; +import { LevelInputComponent, VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; -import { GroupAttributionModule } from '../user/group-attribution/group-attribution.module'; -import { ProfileCreateModule } from './profile-create/profile-create.module'; -import { ProfileDetailModule } from './profile-detail/profile-detail.module'; -import { ProfileListModule } from './profile-list/profile-list.module'; import { ProfileRoutingModule } from './profile-routing.module'; import { ProfileComponent } from './profile.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -57,20 +52,16 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ CommonModule, VitamUICommonModule, - SharedModule, MatButtonToggleModule, MatMenuModule, - ProfileListModule, - ProfileDetailModule, MatProgressBarModule, ReactiveFormsModule, - ProfileCreateModule, - GroupAttributionModule, - LevelInputModule, MatSidenavModule, ProfileRoutingModule, TranslatePipe, + ProfileComponent, + FormsModule, + LevelInputComponent, ], - declarations: [ProfileComponent], }) export class ProfileModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/profile/profile.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/profile/profile.service.spec.ts index 94c0e3236ec..2fe2f7fe8ea 100644 --- a/ui/ui-frontend/projects/identity/src/app/profile/profile.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/profile/profile.service.spec.ts @@ -34,13 +34,12 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { Type } from '@angular/core'; -import { BASE_URL, Profile, SnackBarService } from 'vitamui-library'; +import { Profile, SnackBarService } from 'vitamui-library'; import { ProfileService } from './profile.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ProfileService', () => { let httpTestingController: HttpTestingController; @@ -53,16 +52,7 @@ describe('ProfileService', () => { TestBed.configureTestingModule({ imports: [], - providers: [ - ProfileService, - { provide: SnackBarService, useValue: snackBarSpy }, - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [ProfileService, { provide: SnackBarService, useValue: snackBarSpy }], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.component.ts index f1f8bde004b..ca3fbf628bf 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.component.ts @@ -36,8 +36,11 @@ */ import { ENTER } from '@angular/cdk/keycodes'; import { AfterContentInit, Component, ContentChildren, forwardRef, Input, QueryList } from '@angular/core'; -import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { VitamUIFieldErrorComponent } from 'vitamui-library'; +import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; +import { InputComponent, VitamUIFieldErrorComponent } from 'vitamui-library'; +import { KeyValuePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; + export const LIST_INPUT_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -50,7 +53,7 @@ export const LIST_INPUT_ACCESSOR: any = { templateUrl: './custom-params.component.html', styleUrls: ['./custom-params.component.scss'], providers: [LIST_INPUT_ACCESSOR], - standalone: false, + imports: [InputComponent, ReactiveFormsModule, KeyValuePipe, TranslatePipe], }) export class CustomParamsComponent implements AfterContentInit, ControlValueAccessor { @Input() keyPlaceholder: string; diff --git a/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.module.ts b/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.module.ts deleted file mode 100644 index d3972d07925..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/custom-params/custom-params.module.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { VitamUICommonModule } from 'vitamui-library'; -import { CustomParamsComponent } from './custom-params.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, ReactiveFormsModule, MatProgressSpinnerModule, VitamUICommonModule, TranslatePipe], - declarations: [CustomParamsComponent], - exports: [CustomParamsComponent], -}) -export class CustomParamsModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.spec.ts index c0cffd973d0..5850819ac23 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.spec.ts @@ -34,7 +34,7 @@ * 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, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; +import { Component, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -46,7 +46,8 @@ import { DomainsInputComponent } from './domains-input.component'; @Component({ template: '', - standalone: false, + imports: [DomainsInputComponent, FormsModule], + schemas: [NO_ERRORS_SCHEMA], }) export class TestHostComponent { @ViewChild(DomainsInputComponent, { static: false }) @@ -58,9 +59,6 @@ export class TestHostComponent { let testhost: TestHostComponent; let fixture: ComponentFixture; -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - describe('DomainsInputComponent', () => { beforeEach(async () => { const customerCreateValidatorsSpy = { @@ -68,8 +66,7 @@ describe('DomainsInputComponent', () => { }; await TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatProgressSpinnerModule], - declarations: [TestHostComponent, DomainsInputComponent], + imports: [FormsModule, ReactiveFormsModule, MatProgressSpinnerModule, DomainsInputComponent, TestHostComponent], providers: [{ provide: CustomerCreateValidators, useValue: customerCreateValidatorsSpy }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.ts index 8157ae25dde..244a7afdd0e 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.component.ts @@ -36,7 +36,9 @@ */ import { ENTER } from '@angular/cdk/keycodes'; import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core'; -import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; export const DOMAINS_INPUT_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -50,7 +52,7 @@ export const DOMAINS_INPUT_ACCESSOR: any = { templateUrl: './domains-input.component.html', styleUrls: ['./domains-input.component.scss'], providers: [DOMAINS_INPUT_ACCESSOR], - standalone: false, + imports: [ReactiveFormsModule, MatProgressSpinner, TranslatePipe], }) export class DomainsInputComponent implements ControlValueAccessor { @Input() placeholder: string; diff --git a/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.module.ts b/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.module.ts deleted file mode 100644 index 75bf83e67eb..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/domains-input/domains-input.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { VitamUICommonModule } from 'vitamui-library'; - -import { DomainsInputComponent } from './domains-input.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, ReactiveFormsModule, MatProgressSpinnerModule, VitamUICommonModule, TranslatePipe], - declarations: [DomainsInputComponent], - exports: [DomainsInputComponent], -}) -export class DomainsInputModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-custom-params/editable-custom-params.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-custom-params/editable-custom-params.component.ts index 170d4fe7b5e..a0d931bb237 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-custom-params/editable-custom-params.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-custom-params/editable-custom-params.component.ts @@ -34,9 +34,14 @@ * 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, ElementRef, EventEmitter, forwardRef, Input, Output, inject } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, ElementRef, EventEmitter, forwardRef, inject, Input, Output } from '@angular/core'; +import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent } from 'vitamui-library'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { CustomParamsComponent } from '../../custom-params/custom-params.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { KeyValuePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; export const EDITABLE_DOMAIN_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -50,7 +55,15 @@ export const EDITABLE_DOMAIN_INPUT_VALUE_ACCESSOR: any = { selector: 'editable-custom-params', templateUrl: './editable-custom-params.component.html', providers: [EDITABLE_DOMAIN_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [ + CdkOverlayOrigin, + CustomParamsComponent, + ReactiveFormsModule, + MatProgressSpinner, + CdkConnectedOverlay, + KeyValuePipe, + TranslatePipe, + ], }) export class EditableCustomParamsComponent extends EditableFieldComponent { array: any[] = []; diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.spec.ts deleted file mode 100644 index e4131a604ff..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.spec.ts +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { of } from 'rxjs'; - -import { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { Component, EventEmitter, forwardRef, Input, NO_ERRORS_SCHEMA, Output, ViewChild, NgModule } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { CustomerCreateValidators } from '../../../customer/customer-create/customer-create.validators'; -import { EditableDomainInputComponent } from './editable-domain-input.component'; - -@Component({ - selector: 'app-domains-input', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => DomainInputStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class DomainInputStubComponent implements ControlValueAccessor { - @Input() - placeholder: string; - @Input() - selected: string; - @Input() - spinnerDiameter = 25; - - @Output() - selectedChange = new EventEmitter(); - - writeValue() {} - registerOnChange() {} - registerOnTouched() {} -} -@Component({ - template: ` - - `, - standalone: false, -}) -class TesthostComponent { - value: string[]; - defaultValue: string; - label = 'Test label'; - - @ViewChild(EditableDomainInputComponent, { static: false }) - component: EditableDomainInputComponent; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditableDomainInputComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - const customerCreateValidatorsSpy = { - uniqueCode: vi - .fn() - .mockName('CustomerCreateValidators.uniqueCode') - .mockReturnValue(() => of(null)), - uniqueDomain: vi - .fn() - .mockName('CustomerCreateValidators.uniqueDomain') - .mockReturnValue(() => of(null)), - }; - - await TestBed.configureTestingModule({ - imports: [OverlayModule, FormsModule, ReactiveFormsModule, MatProgressSpinnerModule, VitamUICommonTestModule], - declarations: [TesthostComponent, EditableDomainInputComponent, DomainInputStubComponent], - providers: [{ provide: CustomerCreateValidators, useValue: customerCreateValidatorsSpy }], - schemas: [NO_ERRORS_SCHEMA], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should display the label', () => { - const elLabel = fixture.nativeElement.querySelector('label'); - expect(elLabel.textContent).toContain('Test label'); - }); - - it('should display the list of domains', waitForAsync(() => { - testhost.value = ['test1.com', 'test2.com', 'test3.com']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elDomains = fixture.nativeElement.querySelectorAll( - '.editable-field .editable-field-content .editable-field-text-content > div', - ); - expect(elDomains.length).toBe(3); - expect(elDomains[0].textContent).toContain(testhost.value[0]); - expect(elDomains[1].textContent).toContain(testhost.value[1]); - expect(elDomains[2].textContent).toContain(testhost.value[2]); - }); - })); - - it('should display "SHARED.DOMAIN_INPUT.DEFAULT_DOMAIN" next to the selected domain', waitForAsync(() => { - testhost.value = ['test1.com', 'test2.com', 'test3.com', 'test4.com']; - testhost.defaultValue = testhost.value[1]; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elDomains = fixture.nativeElement.querySelectorAll( - '.editable-field .editable-field-content .editable-field-text-content > div', - ); - expect(elDomains.length).toBe(4); - expect(elDomains[1].textContent).toContain('SHARED.DOMAIN_INPUT.DEFAULT_DOMAIN'); - }); - })); - - it('should have a app-domains-input', () => { - const elDomainInput = fixture.nativeElement.querySelector('.editable-field-control > app-domains-input'); - expect(elDomainInput).toBeTruthy(); - }); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeTruthy(); - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.control.markAsDirty(); - fixture.detectChanges(false); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - fixture.detectChanges(false); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-cancel') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have a spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(true); - fixture.detectChanges(false); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeTruthy(); - }); - - it('should hide the spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(false); - fixture.detectChanges(false); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeFalsy(); - }); - }); - - describe('Class', () => { - it('should set the control value', waitForAsync(() => { - testhost.value = ['test1.com', 'test2.com']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - }); - })); - - describe('canConfirm', () => { - it('should return true when the edit mode is active, the value has changed and is valid', () => { - testhost.component.editMode = true; - testhost.component.control.setValue(['test1.com', 'test2.com']); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return true when the edit mode is active, the selected value has changed and is valid', () => { - testhost.value = ['test1.com', 'test2.com']; - testhost.defaultValue = 'test1.com'; - fixture.detectChanges(); - testhost.component.editMode = true; - testhost.component.selected = 'test2.com'; - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue(['test1.com', 'test2.com']); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test2.com']); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test2.com']); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - it('should emit a new value', waitForAsync(() => { - testhost.value = ['test1.com', 'test2.com']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test3.com', 'test4.com']); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual(['test1.com', 'test2.com']); - testhost.component.confirm(); - expect(testhost.value).toEqual(['test1.com', 'test3.com', 'test4.com']); - }); - })); - - it('should reverse the changes', waitForAsync(() => { - testhost.value = ['test1.com', 'test2.com']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test3.com', 'test4.com']); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual(['test1.com', 'test2.com']); - testhost.component.cancel(); - fixture.detectChanges(); - expect(testhost.value).toEqual(['test1.com', 'test2.com']); - expect(testhost.component.control.value).toEqual(['test1.com', 'test2.com']); - }); - })); - - it('should set the selected value', () => { - testhost.defaultValue = 'default.com'; - fixture.detectChanges(); - expect(testhost.component.defaultDomain).toBe('default.com'); - }); - - it('should emit a new selected value', () => { - testhost.value = ['test1.com', 'test2.com', 'default.com']; - testhost.defaultValue = 'default.com'; - fixture.detectChanges(); - expect(testhost.component.defaultDomain).toBe('default.com'); - testhost.component.enterEditMode(); - testhost.component.selected = 'test2.com'; - expect(testhost.defaultValue).toBe('default.com'); - testhost.component.confirm(); - expect(testhost.defaultValue).toBe('test2.com'); - }); - - it('should reverse the selected value', () => { - testhost.value = ['test1.com', 'test2.com', 'default.com']; - testhost.defaultValue = 'default.com'; - fixture.detectChanges(); - testhost.component.enterEditMode(); - expect(testhost.component.defaultDomain).toBe('default.com'); - testhost.component.selected = 'test2.com'; - testhost.component.cancel(); - expect(testhost.defaultValue).toBe('default.com'); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.ts index d249fb4b3f8..3255498300f 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-domain-input/editable-domain-input.component.ts @@ -34,10 +34,16 @@ * 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, ElementRef, EventEmitter, forwardRef, Input, Output, inject } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, ElementRef, EventEmitter, forwardRef, inject, Input, Output } from '@angular/core'; +import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent } from 'vitamui-library'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { NgStyle } from '@angular/common'; +import { DomainsInputComponent } from '../../domains-input/domains-input.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; + export const EDITABLE_DOMAIN_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -49,7 +55,7 @@ export const EDITABLE_DOMAIN_INPUT_VALUE_ACCESSOR: any = { selector: 'app-editable-domain-input', templateUrl: './editable-domain-input.component.html', providers: [EDITABLE_DOMAIN_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [CdkOverlayOrigin, NgStyle, DomainsInputComponent, ReactiveFormsModule, MatProgressSpinner, CdkConnectedOverlay, TranslatePipe], }) export class EditableDomainInputComponent extends EditableFieldComponent { @Input() diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-field.module.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-field.module.ts index 968c0432cb1..b529fcce676 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-field.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-field.module.ts @@ -34,40 +34,60 @@ * 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 { OverlayModule } from '@angular/cdk/overlay'; -import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; +import { OverlayModule } from '@angular/cdk/overlay'; -import { LevelInputModule, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { CustomParamsModule } from '../custom-params/custom-params.module'; -import { DomainsInputModule } from '../domains-input/domains-input.module'; +import { LevelInputComponent, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; +import { CustomParamsComponent } from '../custom-params/custom-params.component'; +import { DomainsInputComponent } from '../domains-input/domains-input.component'; import { EditableCustomParamsComponent } from './editable-custom-params/editable-custom-params.component'; import { EditableDomainInputComponent } from './editable-domain-input/editable-domain-input.component'; import { EditableKeystoreComponent } from './editable-keystore/editable-keystore.component'; import { EditablePatternsComponent } from './editable-patterns/editable-patterns.component'; import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @NgModule({ imports: [ - CommonModule, - CustomParamsModule, - DomainsInputModule, + VitamUICommonModule, + VitamUILibraryModule, FormsModule, - LevelInputModule, + ReactiveFormsModule, MatButtonToggleModule, MatProgressSpinnerModule, MatSelectModule, OverlayModule, - ReactiveFormsModule, + TranslatePipe, + CustomParamsComponent, + DomainsInputComponent, + EditableDomainInputComponent, + EditablePatternsComponent, + EditableKeystoreComponent, + EditableCustomParamsComponent, + CommonModule, + LevelInputComponent, + ], + exports: [ + LevelInputComponent, VitamUICommonModule, VitamUILibraryModule, + FormsModule, + ReactiveFormsModule, + MatButtonToggleModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, TranslatePipe, + CustomParamsComponent, + DomainsInputComponent, + EditableDomainInputComponent, + EditablePatternsComponent, + EditableKeystoreComponent, + EditableCustomParamsComponent, ], - declarations: [EditableDomainInputComponent, EditablePatternsComponent, EditableKeystoreComponent, EditableCustomParamsComponent], - exports: [EditableDomainInputComponent, EditablePatternsComponent, EditableKeystoreComponent, EditableCustomParamsComponent], }) export class EditableFieldModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.spec.ts deleted file mode 100644 index 59b0b717634..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.spec.ts +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { Component, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { ReactiveFormsModule, Validators } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of, throwError as observableThrowError } from 'rxjs'; - -import { AuthnRequestBindingEnum, IdentityProvider, newFile } from 'vitamui-library'; -import { input, VitamUICommonTestModule } from 'vitamui-library/testing'; -import { IdentityProviderService } from '../../../customer/customer-preview/sso-tab/identity-provider.service'; -import { EditableKeystoreComponent } from './editable-keystore.component'; - -@Component({ - template: ` `, - standalone: false, -}) -class TesthostComponent { - identityProvider: IdentityProvider = { - propagateLogout: false, - id: '1', - customerId: '2', - name: 'testIDP', - technicalName: 'Test IDP', - internal: false, - keystorePassword: null, - keystore: null, - idpMetadata: null, - patterns: ['test1.com', 'test2.com'], - enabled: true, - readonly: false, - authnRequestBinding: AuthnRequestBindingEnum.POST, - autoProvisioningEnabled: false, - authnRequestSigned: false, - maximumAuthenticationLifetime: 0, - wantsAssertionsSigned: false, - }; - disabled: boolean; - @ViewChild(EditableKeystoreComponent, { static: false }) - component: EditableKeystoreComponent; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditableKeystoreComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, OverlayModule, VitamUICommonTestModule, NoopAnimationsModule], - declarations: [TesthostComponent, EditableKeystoreComponent], - providers: [{ provide: IdentityProviderService, useValue: { updateKeystore: () => of(null) } }], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(testhost.component.editMode).toBe(true); - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.file = newFile([''], 'test.jks'); - testhost.component.control.setValue('password1234'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(false); - const elButton = (overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') || - fixture.nativeElement.querySelector('.editable-field-actions button.editable-field-confirm')) as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - testhost.component.cancel(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have an input file', () => { - const elInput = fixture.nativeElement.querySelector('input[type=file]'); - expect(elInput).toBeTruthy(); - }); - - it('should have a password input', () => { - const elInput = fixture.nativeElement.querySelector('input[type=password]'); - expect(elInput).toBeTruthy(); - input(elInput, 'password1234'); - expect(testhost.component.control.value).toBe('password1234'); - }); - - it('should display the file name', waitForAsync(() => { - testhost.component.file = newFile([''], 'test.jks'); - testhost.component.editMode = true; - fixture.detectChanges(false); - const elFileName = fixture.nativeElement.querySelector('.vitamui-input-file-filename'); - expect(elFileName).toBeTruthy(); - expect(testhost.component.file.name).toBe('test.jks'); - })); - - it('should display the errors', () => { - testhost.component.control.setErrors({ badPassword: true }); - fixture.detectChanges(false); - expect(testhost.component.control.hasError('badPassword')).toBe(true); - }); - }); - - describe('Class', () => { - describe('canConfirm', () => { - it('should return true when the edit mode is active, the file and password are set', () => { - testhost.component.editMode = true; - testhost.component.file = newFile([''], 'test-file.txt'); - testhost.component.control.setValue('password'); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - describe('setFile', () => { - it('should set the file', () => { - const expectedFile = newFile([''], 'test.jks'); - const mockFileList = { - item: () => expectedFile, - length: 1, - [Symbol.iterator]: function* () { - yield expectedFile; - }, - } as unknown as FileList; - testhost.component.setFile(mockFileList); - expect(testhost.component.file).toBe(expectedFile); - }); - }); - - describe('confirm', () => { - it('should call updateKeystore', () => { - const idpService = TestBed.inject(IdentityProviderService); - vi.spyOn(idpService, 'updateKeystore'); - testhost.component.editMode = true; - const expectedFile = newFile([''], 'test.jks'); - testhost.component.file = expectedFile; - testhost.component.control.setValue('password'); - testhost.component.confirm(); - expect(idpService.updateKeystore).toHaveBeenCalledWith(testhost.identityProvider.id, expectedFile, 'password'); - expect(testhost.component.editMode).toBe(false); - }); - - it('should not call updateKeystore', () => { - const idpService = TestBed.inject(IdentityProviderService); - vi.spyOn(idpService, 'updateKeystore'); - testhost.component.editMode = true; - const expectedFile = newFile([''], 'test.jks'); - testhost.component.file = expectedFile; - testhost.component.confirm(); - expect(idpService.updateKeystore).not.toHaveBeenCalled(); - testhost.component.file = null; - testhost.component.control.setValue('password'); - testhost.component.confirm(); - expect(idpService.updateKeystore).not.toHaveBeenCalled(); - }); - - it('should set the error', () => { - const idpService = TestBed.inject(IdentityProviderService); - vi.spyOn(idpService, 'updateKeystore').mockReturnValue(observableThrowError(null)); - testhost.component.editMode = true; - const expectedFile = newFile([''], 'test.jks'); - testhost.component.file = expectedFile; - testhost.component.control.setValue('password'); - testhost.component.confirm(); - expect(idpService.updateKeystore).toHaveBeenCalled(); - expect(testhost.component.control.errors).toEqual({ badPassword: true }); - }); - }); - - describe('cancel', () => { - it('should close the editMode', () => { - testhost.component.editMode = true; - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should set the file to null', () => { - testhost.component.editMode = true; - testhost.component.file = newFile([''], 'test.jks'); - testhost.component.cancel(); - expect(testhost.component.file).toBeNull(); - }); - - it('should reset the password', () => { - testhost.component.editMode = true; - testhost.component.control.setValue('password'); - testhost.component.cancel(); - expect(testhost.component.control.value).toBeNull(); - }); - }); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.ts index 8130e5d7642..709387d1042 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-keystore/editable-keystore.component.ts @@ -34,18 +34,21 @@ * 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 { EditableFieldComponent, newFile } from 'vitamui-library'; -import type { IdentityProvider } from 'vitamui-library'; +import { EditableFieldComponent, IdentityProvider, newFile } from 'vitamui-library'; -import { Component, ElementRef, Input, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, inject, Input, ViewChild } from '@angular/core'; import { IdentityProviderService } from '../../../customer/customer-preview/sso-tab/identity-provider.service'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { ReactiveFormsModule } from '@angular/forms'; +import { TranslatePipe } from '@ngx-translate/core'; + /*eslint no-use-before-define: "error"*/ @Component({ selector: 'app-editable-keystore', templateUrl: './editable-keystore.component.html', styleUrls: ['./editable-keystore.component.scss'], - standalone: false, + imports: [CdkOverlayOrigin, ReactiveFormsModule, CdkConnectedOverlay, TranslatePipe], }) export class EditableKeystoreComponent extends EditableFieldComponent { private identityProviderService = inject(IdentityProviderService); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.spec.ts deleted file mode 100644 index a77f02df596..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.spec.ts +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { Component, forwardRef, Input, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelect } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; - -import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { EditablePatternsComponent } from './editable-patterns.component'; - -@Component({ - selector: 'app-pattern', - template: '', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => PatternStubComponent), - multi: true, - }, - ], - standalone: false, -}) -class PatternStubComponent implements ControlValueAccessor { - @Input() - options: Array<{ - value: string; - disabled?: boolean; - }>; - @Input() - vitamuiMiniMode = false; - - @ViewChild('select', { static: true }) - select: MatSelect; - - writeValue() {} - registerOnChange() {} - registerOnTouched() {} -} - -@Component({ - template: ` `, - standalone: false, -}) -class TesthostComponent { - value: string[]; - options = [ - { value: 'test1.com', disabled: false }, - { value: 'test2.com', disabled: false }, - { value: 'test3.com', disabled: false }, - { value: 'test4.com', disabled: true }, - { value: 'test5.com', disabled: true }, - ]; - label = 'Test label'; - @ViewChild(EditablePatternsComponent, { static: false }) - component: EditablePatternsComponent; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditablePatternsComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, OverlayModule, MatProgressSpinnerModule, NoopAnimationsModule, VitamUICommonTestModule], - declarations: [TesthostComponent, EditablePatternsComponent, PatternStubComponent], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should display the label', () => { - const elLabel = fixture.nativeElement.querySelector('label'); - expect(elLabel.textContent).toContain('Test label'); - }); - - it('should display the list of patterns', waitForAsync(() => { - testhost.value = ['test1.com', 'test3.com']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elPatterns = fixture.nativeElement.querySelectorAll( - '.editable-field .editable-field-content .editable-field-text-content > div', - ); - expect(elPatterns.length).toBe(2); - expect(elPatterns[0].textContent).toContain(testhost.value[0]); - expect(elPatterns[1].textContent).toContain(testhost.value[1]); - }); - })); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeTruthy(); - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test3.com']); - testhost.component.control.markAsDirty(); - fixture.detectChanges(false); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - fixture.detectChanges(false); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-cancel') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have a spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(true); - fixture.detectChanges(false); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeTruthy(); - }); - - it('should hide the spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(false); - fixture.detectChanges(false); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeFalsy(); - }); - }); - - describe('Class', () => { - it('should set the control value', waitForAsync(() => { - testhost.value = ['test1.com', 'test3.com']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toBe(testhost.value); - }); - })); - - describe('canConfirm', () => { - it('should return true when the edit mode is active, the value has changed and is valid', () => { - testhost.component.editMode = true; - testhost.component.control.setValue(['test1.com', 'test3.com']); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue(['test1.com', 'test3.com']); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test3.com']); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(['test1.com', 'test3.com']); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - it('should emit a new value', waitForAsync(() => { - const originValue = ['test1.com', 'test3.com']; - const newValue = ['test2.com']; - testhost.value = originValue; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue(newValue); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual(originValue); - testhost.component.confirm(); - expect(testhost.value).toEqual(newValue); - }); - })); - - it('should reverse the changes', waitForAsync(() => { - const originValue = ['test1.com', 'test3.com']; - const newValue = ['test2.com']; - testhost.value = originValue; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue(newValue); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual(originValue); - testhost.component.cancel(); - fixture.detectChanges(); - expect(testhost.value).toEqual(originValue); - expect(testhost.component.control.value).toEqual(originValue); - }); - })); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.ts index 4b8432b6ba7..084ce094402 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/editable-field/editable-patterns/editable-patterns.component.ts @@ -34,11 +34,13 @@ * 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, ElementRef, forwardRef, Input, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, forwardRef, inject, Input, ViewChild } from '@angular/core'; import { DOCUMENT } from '@angular/common'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent, PatternComponent } from 'vitamui-library'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; export const EDITABLE_PATTERNS_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -51,7 +53,7 @@ export const EDITABLE_PATTERNS_INPUT_VALUE_ACCESSOR: any = { selector: 'app-editable-patterns', templateUrl: './editable-patterns.component.html', providers: [EDITABLE_PATTERNS_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [CdkOverlayOrigin, PatternComponent, ReactiveFormsModule, MatProgressSpinner, CdkConnectedOverlay], }) export class EditablePatternsComponent extends EditableFieldComponent { private document = inject(DOCUMENT); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.spec.ts deleted file mode 100644 index 30772a9c69a..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.spec.ts +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of } from 'rxjs'; -import { ApplicationApiService, ApplicationService, ProfileService, SelectComponent } from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; - -import { ProfilesFormComponent } from './profiles-form.component'; - -const expectedProfiles = [ - { - id: '1', - name: 'profile 1', - description: 'description 1', - applicationName: 'CUSTOMERS_APP', - tenantIdentifier: 1, - tenantName: 'tenant 1', - tenant: { id: '11', name: 'tenant 1', identifier: 1 }, - }, - { - id: '2', - name: 'profile 2', - description: 'description 2', - applicationName: 'CUSTOMERS_APP', - tenantIdentifier: 2, - tenantName: 'tenant 2', - tenant: { id: '22', name: 'tenant 2', identifier: 2 }, - }, - { - id: '3', - name: 'profile 3', - description: 'description 3', - applicationName: 'USERS_APP', - tenantIdentifier: 1, - tenantName: 'tenant 1', - tenant: { id: '11', name: 'tenant 1', identifier: 1 }, - }, - { - id: '4', - name: 'profile 4', - description: 'description 4', - applicationName: 'GROUPS_APP', - tenantIdentifier: 3, - tenantName: 'tenant 3', - tenant: { id: '33', name: 'tenant 3', identifier: 3 }, - }, - { - id: '5', - name: 'profile 5', - description: 'description 5', - applicationName: 'PROFILES_APP', - tenantIdentifier: 4, - tenantName: 'tenant 4', - tenant: { id: '44', name: 'tenant 4', identifier: 4 }, - }, - { - id: '6', - name: 'profile 6', - description: 'description 6', - applicationName: 'CUSTOMERS_APP', - tenantIdentifier: 1, - tenantName: 'tenant 1', - tenant: { id: '11', name: 'tenant 1', identifier: 1 }, - }, -]; - -const expectedApp = [ - { - id: 'CUSTOMERS_APP', - identifier: 'CUSTOMERS_APP', - name: 'Organisations', - url: '', - }, - { - id: 'ARCHIVE_APP', - identifier: 'ARCHIVE_APP', - name: 'Archives', - url: '', - }, - { - id: 'USERS_APP', - identifier: 'USERS_APP', - name: 'Utilisateurs', - url: '', - }, - { - id: 'GROUPS_APP', - identifier: 'GROUPS_APP', - name: 'Groupes de profils', - url: '', - }, - { - id: 'PROFILES_APP', - identifier: 'PROFILES_APP', - name: 'Profils APP Utilisateurs', - url: '', - }, -]; - -@Component({ - template: ` `, - standalone: false, -}) -class TesthostComponent { - profiles: string[]; - - @ViewChild(ProfilesFormComponent, { static: false }) - component: ProfilesFormComponent; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('ProfilesFormComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatProgressSpinnerModule, - MatSelectModule, - NoopAnimationsModule, - VitamUICommonTestModule, - SelectComponent, - ], - declarations: [ProfilesFormComponent, TesthostComponent], - providers: [ - { provide: ProfileService, useValue: { list: () => of(expectedProfiles) } }, - { provide: ApplicationApiService, useValue: { listNames: () => of(expectedApp) } }, - { provide: ApplicationService, useValue: { list: () => of(expectedApp), buildApplications: () => expectedApp } }, - ], - schemas: [NO_ERRORS_SCHEMA], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should have 3 select inputs', () => { - const elInputs = fixture.nativeElement.querySelectorAll('vitamui-select'); - expect(elInputs.length).toBe(3); - }); - - it('should have an "Add" button', () => { - const elAddButton = fixture.nativeElement.querySelector('button[type=button]'); - expect(elAddButton).toBeTruthy(); - expect(elAddButton.textContent).toContain('COMMON.ADD'); - vi.spyOn(testhost.component, 'add'); - testhost.component.profileSelect.setValue(expectedProfiles[3].id); - fixture.detectChanges(); - elAddButton.click(); - expect(testhost.component.add).toHaveBeenCalled(); - }); - - it('should have a list of the profiles', () => { - testhost.component.profileIds = ['2', '5']; - fixture.detectChanges(); - const elHeaders = fixture.nativeElement.querySelectorAll('.vitamui-table-head'); - expect(elHeaders).toBeTruthy(); - - const elRows = fixture.nativeElement.querySelectorAll('.vitamui-row'); - expect(elRows.length).toBe(2); - const elCells = elRows[0].querySelectorAll('div'); - expect(elCells.length).toBe(4); - expect(elCells[0].textContent).toContain('Organisations'); - expect(elCells[1].textContent).toContain('tenant 2'); - expect(elCells[2].textContent).toContain('profile 2'); - const elDelButton = elCells[3].querySelector('button'); - expect(elDelButton).toBeTruthy(); - vi.spyOn(testhost.component, 'remove'); - elDelButton.click(); - expect(testhost.component.remove).toHaveBeenCalledWith(0); - }); - }); - - describe('Component', () => { - it('should fill the application tree', () => { - expect(testhost.component.applications).toEqual( - expect.arrayContaining([ - { - key: 'GROUPS_APP', - label: 'Groupes de profils', - children: [ - { - key: '3', - label: 'tenant 3', - children: [{ key: expectedProfiles[3].id, label: expectedProfiles[3].name, info: expectedProfiles[3].description }], - }, - ], - }, - { - key: 'CUSTOMERS_APP', - label: 'Organisations', - children: [ - { - key: '1', - label: 'tenant 1', - children: [ - { key: expectedProfiles[0].id, label: expectedProfiles[0].name, info: expectedProfiles[0].description }, - { key: expectedProfiles[5].id, label: expectedProfiles[5].name, info: expectedProfiles[5].description }, - ], - }, - { - key: '2', - label: 'tenant 2', - children: [{ key: expectedProfiles[1].id, label: expectedProfiles[1].name, info: expectedProfiles[1].description }], - }, - ], - }, - { - key: 'PROFILES_APP', - label: 'Profils APP Utilisateurs', - children: [ - { - key: '4', - label: 'tenant 4', - children: [{ key: expectedProfiles[4].id, label: expectedProfiles[4].name, info: expectedProfiles[4].description }], - }, - ], - }, - { - key: 'USERS_APP', - label: 'Utilisateurs', - children: [ - { - key: '1', - label: 'tenant 1', - children: [{ key: expectedProfiles[2].id, label: expectedProfiles[2].name, info: expectedProfiles[2].description }], - }, - ], - }, - ]), - ); - }); - - it('should add the profile Id to the list', () => { - testhost.component.profileSelect.setValue(expectedProfiles[3].id); - testhost.component.add(); - fixture.detectChanges(); - expect(testhost.profiles).toEqual(['4']); - }); - - it('should remove the profile Id from the list', waitForAsync(() => { - testhost.profiles = ['3', '4']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - testhost.component.remove(0); - fixture.detectChanges(); - expect(testhost.profiles).toEqual(['4']); - }); - })); - - it('should not show profiles which are already selected', waitForAsync(() => { - testhost.profiles = ['2']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - testhost.component.appSelect.setValue('ARCHIVE_APP'); - testhost.component.tenantSelect.setValue('2'); - fixture.detectChanges(); - expect(testhost.component.filteredProfiles.length).toBe(0); - }); - })); - - it('should toggle the tenant select', () => { - expect(testhost.component.tenantSelect.disabled).toBeTruthy(); - testhost.component.appSelect.setValue('CUSTOMERS_APP'); - expect(testhost.component.tenantSelect.disabled).toBeFalsy(); - }); - - it('should toggle the profile select', () => { - testhost.component.appSelect.setValue('CUSTOMERS_APP'); - expect(testhost.component.profileSelect.disabled).toBeTruthy(); - testhost.component.tenantSelect.setValue('1'); - expect(testhost.component.profileSelect.disabled).toBeFalsy(); - }); - - it('should not show the app 2', waitForAsync(() => { - testhost.profiles = ['3']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.applications.length).toBe(3); - expect(testhost.component.applications[0].key).toBe('GROUPS_APP'); - expect(testhost.component.applications[1].key).toBe('CUSTOMERS_APP'); - expect(testhost.component.applications[2].key).toBe('PROFILES_APP'); - }); - })); - - it('should not show the tenant 2', waitForAsync(() => { - testhost.profiles = ['2']; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - testhost.component.appSelect.setValue('CUSTOMERS_APP'); - expect(testhost.component.filteredTenants.length).toBe(1); - expect(testhost.component.filteredTenants[0].key).toBe('1'); - }); - })); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.ts b/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.ts index eabc7954d73..5a15d00c9dd 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.component.ts @@ -34,12 +34,23 @@ * 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, ElementRef, forwardRef, Input, OnInit, SimpleChanges, ViewChild, OnChanges, inject } from '@angular/core'; -import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { Component, ElementRef, forwardRef, inject, Input, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core'; +import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms'; import { shareReplay } from 'rxjs/operators'; -import { ApplicationApiService, IdentifierName, Option, Profile, ProfileService, SelectComponent } from 'vitamui-library'; +import { + ApplicationApiService, + EllipsisDirective, + IdentifierName, + Option, + Profile, + ProfileService, + SelectComponent, +} from 'vitamui-library'; import { OptionTree } from './option-tree.interface'; import { zip } from 'rxjs'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { CommonModule, NgClass } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; export const PROFILES_FORM_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -52,7 +63,7 @@ export const PROFILES_FORM_VALUE_ACCESSOR: any = { templateUrl: './profiles-form.component.html', styleUrls: ['./profiles-form.component.scss'], providers: [PROFILES_FORM_VALUE_ACCESSOR], - standalone: false, + imports: [MatProgressSpinner, SelectComponent, ReactiveFormsModule, NgClass, TranslatePipe, CommonModule, EllipsisDirective], }) export class ProfilesFormComponent implements ControlValueAccessor, OnInit, OnChanges { private rngProfileService = inject(ProfileService); diff --git a/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.module.ts b/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.module.ts deleted file mode 100644 index 1ba57538855..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/shared/profiles-form/profiles-form.module.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { ProfilesFormComponent } from './profiles-form.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - ReactiveFormsModule, - MatProgressSpinnerModule, - MatSelectModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [ProfilesFormComponent], - exports: [ProfilesFormComponent], -}) -export class ProfilesFormModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/shared/shared.module.ts b/ui/ui-frontend/projects/identity/src/app/shared/shared.module.ts index c6e928e1a5b..043dd53f174 100644 --- a/ui/ui-frontend/projects/identity/src/app/shared/shared.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/shared/shared.module.ts @@ -34,24 +34,44 @@ * 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 { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { CollapseModule, LevelInputModule, VitamUICommonModule } from 'vitamui-library'; -import { DomainsInputModule } from './domains-input/domains-input.module'; -import { EditableFieldModule } from './editable-field/editable-field.module'; -import { ProfilesFormModule } from './profiles-form/profiles-form.module'; +import { CollapseComponent, LevelInputComponent, VitamUICommonModule } from 'vitamui-library'; +import { DomainsInputComponent } from './domains-input/domains-input.component'; +import { EditableCustomParamsComponent } from './editable-field/editable-custom-params/editable-custom-params.component'; +import { EditableDomainInputComponent } from './editable-field/editable-domain-input/editable-domain-input.component'; +import { EditableKeystoreComponent } from './editable-field/editable-keystore/editable-keystore.component'; +import { EditablePatternsComponent } from './editable-field/editable-patterns/editable-patterns.component'; +import { ProfilesFormComponent } from './profiles-form/profiles-form.component'; +import { FormsModule } from '@angular/forms'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @NgModule({ imports: [ + VitamUICommonModule, + DomainsInputComponent, + EditableDomainInputComponent, + EditablePatternsComponent, + EditableKeystoreComponent, + EditableCustomParamsComponent, + ProfilesFormComponent, CommonModule, - CollapseModule, - DomainsInputModule, - EditableFieldModule, - ProfilesFormModule, - LevelInputModule, + FormsModule, + LevelInputComponent, + TranslatePipe, + CollapseComponent, + ], + exports: [ + CollapseComponent, + LevelInputComponent, VitamUICommonModule, + DomainsInputComponent, + EditableDomainInputComponent, + EditablePatternsComponent, + EditableKeystoreComponent, + EditableCustomParamsComponent, + ProfilesFormComponent, ], - exports: [CollapseModule, DomainsInputModule, EditableFieldModule, ProfilesFormModule, LevelInputModule, VitamUICommonModule], }) export class SharedModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.spec.ts index 61da85ab597..7013e0957c1 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.spec.ts @@ -34,15 +34,14 @@ * 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 { AuthService, BASE_URL, CriteriaSearchQuery, ENVIRONMENT, LoggerModule, Operators } from 'vitamui-library'; +import { AuthService, CriteriaSearchQuery, ENVIRONMENT, LoggerModule, Operators } from 'vitamui-library'; import { environment } from './../../environments/environment'; -import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { Type } from '@angular/core'; import { CustomerSelectService } from './customer-select.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('CustomerSelectService', () => { let httpTestingController: HttpTestingController; @@ -56,10 +55,7 @@ describe('CustomerSelectService', () => { providers: [ CustomerSelectService, { provide: AuthService, useValue: authStubService }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }); diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.ts b/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.ts index cd0bca25536..7ebdd88dcb7 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/customer-select.service.ts @@ -39,7 +39,7 @@ import { catchError, map } from 'rxjs/operators'; import { CriteriaSearchQuery, Customer, MenuOption, Operators } from 'vitamui-library'; import { HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { CustomerApiService } from '../core/api/customer-api.service'; diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.html b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.html index 9194882a61c..36a9d3217c0 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.html @@ -10,7 +10,7 @@
- @for (subrogableUser of dataSource; track subrogableUser) { + @for (subrogableUser of dataSource(); track subrogableUser) {
@@ -80,15 +80,15 @@
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && subrogationService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && subrogationService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.ts b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.ts index 34f3387e41c..9f2d4ea3e24 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogate-user/subrogate-user-list/subrogate-user-list.component.ts @@ -44,7 +44,9 @@ import { Criterion, DEFAULT_PAGE_SIZE, Direction, + EllipsisDirective, Group, + InfiniteScrollDirective, InfiniteScrollTable, Operators, PageRequest, @@ -53,11 +55,14 @@ import { SubrogationUser, } from 'vitamui-library'; -import { Component, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, inject, Input, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { SubrogationService } from '../../subrogation.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; const MINIMUM_CRITICALITY = 0; const AVERAGE_CRITICALITY = 1; @@ -67,7 +72,7 @@ const MAXIMUM_CRITICALITY = 2; selector: 'app-subrogate-user-list', templateUrl: './subrogate-user-list.component.html', styleUrls: ['./subrogate-user-list.component.scss'], - standalone: false, + imports: [NgClass, MatProgressSpinner, TranslatePipe, CommonModule, EllipsisDirective, InfiniteScrollDirective], }) export class SubrogateUserListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { subrogationService: SubrogationService; @@ -110,7 +115,7 @@ export class SubrogateUserListComponent extends InfiniteScrollTable { - const groupIds = new Set(this.dataSource.map((subrogationUser: SubrogationUser) => subrogationUser.groupId)); + const groupIds = new Set((this.dataSource() ?? []).map((subrogationUser: SubrogationUser) => subrogationUser.groupId)); const observables = new Array>(); groupIds.forEach((groupId) => { @@ -127,7 +132,7 @@ export class SubrogateUserListComponent extends InfiniteScrollTable !subrogationUser.criticality) .forEach((subrogationUser: SubrogationUser) => { const subrogateUserGroup = this.getGroup(subrogationUser); @@ -141,11 +146,11 @@ export class SubrogateUserListComponent extends InfiniteScrollTable(); - constructor() { - const route = inject(ActivatedRoute); - - super(route); - - this.route = route; - } - ngOnInit() { this.customerSelectService .getAll(true) diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.module.ts b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.module.ts index 341793760fc..47173aa6a66 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.module.ts @@ -44,7 +44,7 @@ import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; + import { SubrogateUserListComponent } from './subrogate-user/subrogate-user-list/subrogate-user-list.component'; import { SubrogateUserComponent } from './subrogate-user/subrogate-user.component'; import { SubrogationRoutingModule } from './subrogation-routing.module'; @@ -61,11 +61,11 @@ import { TranslatePipe } from '@ngx-translate/core'; MatSelectModule, MatSidenavModule, ReactiveFormsModule, - SharedModule, SubrogationRoutingModule, VitamUICommonModule, TranslatePipe, + SubrogateUserListComponent, + SubrogateUserComponent, ], - declarations: [SubrogateUserListComponent, SubrogateUserComponent], }) export class SubrogationModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.service.spec.ts index 2c6a9dcc952..3b7d24d4d2e 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/subrogation.service.spec.ts @@ -34,25 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; -import { BASE_URL, SubrogationApiService, WINDOW_LOCATION } from 'vitamui-library'; +import { SubrogationApiService, WINDOW_LOCATION } from 'vitamui-library'; import { SubrogationService } from './subrogation.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('SubrogationService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - SubrogationService, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: WINDOW_LOCATION, useValue: {} }, - { provide: SubrogationApiService, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [SubrogationService, { provide: WINDOW_LOCATION, useValue: {} }, { provide: SubrogationApiService, useValue: {} }], }); }); diff --git a/ui/ui-frontend/projects/identity/src/app/subrogation/user-generic-api.service.spec.ts b/ui/ui-frontend/projects/identity/src/app/subrogation/user-generic-api.service.spec.ts index 7928c5ea497..2ee5aa01fd4 100644 --- a/ui/ui-frontend/projects/identity/src/app/subrogation/user-generic-api.service.spec.ts +++ b/ui/ui-frontend/projects/identity/src/app/subrogation/user-generic-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from 'vitamui-library'; import { UserGenericApiService } from './user-generic-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('UserGenericApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.component.ts b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.component.ts index 2eef1e68cab..a0863d5f6b0 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.component.ts @@ -36,11 +36,13 @@ */ import { User } from 'vitamui-library'; -import { Component, forwardRef, OnInit, inject } from '@angular/core'; +import { Component, forwardRef, inject, OnInit } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { GroupSelection } from '../group-selection.interface'; import { UserService } from '../user.service'; +import { GroupListComponent } from './group-list/group-list.component'; +import { TranslatePipe } from '@ngx-translate/core'; export const GROUP_ATTRIBUTION_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -54,7 +56,7 @@ export const GROUP_ATTRIBUTION_VALUE_ACCESSOR: any = { templateUrl: './group-attribution.component.html', styleUrls: ['./group-attribution.component.scss'], providers: [GROUP_ATTRIBUTION_VALUE_ACCESSOR], - standalone: false, + imports: [MatDialogContent, GroupListComponent, MatDialogActions, TranslatePipe], }) export class GroupAttributionComponent implements OnInit { private userService = inject(UserService); diff --git a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.module.ts b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.module.ts index ee28cad22b9..376c147f944 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-attribution.module.ts @@ -34,19 +34,30 @@ * 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 { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { CollapseDirectiveModule, VitamUICommonModule } from 'vitamui-library'; +import { CollapseContainerDirective, CollapseDirective, CollapseTriggerForDirective, VitamUICommonModule } from 'vitamui-library'; import { SharedModule } from '../../shared/shared.module'; import { GroupAttributionComponent } from './group-attribution.component'; import { GroupDetailComponent } from './group-detail/group-detail.component'; import { GroupListComponent } from './group-list/group-list.component'; import { MatDialogModule } from '@angular/material/dialog'; import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @NgModule({ - imports: [CommonModule, SharedModule, CollapseDirectiveModule, VitamUICommonModule, MatDialogModule, TranslatePipe], - declarations: [GroupAttributionComponent, GroupDetailComponent, GroupListComponent], + imports: [ + SharedModule, + VitamUICommonModule, + MatDialogModule, + TranslatePipe, + GroupAttributionComponent, + GroupDetailComponent, + GroupListComponent, + CollapseContainerDirective, + CollapseDirective, + CollapseTriggerForDirective, + CommonModule, + ], exports: [GroupAttributionComponent, GroupDetailComponent, GroupListComponent], }) export class GroupAttributionModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-detail/group-detail.component.ts b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-detail/group-detail.component.ts index 3b1a2c624e9..a7b727c7c52 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-detail/group-detail.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-detail/group-detail.component.ts @@ -34,15 +34,17 @@ * 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, Input, OnInit, inject } from '@angular/core'; -import type { Group, Profile } from 'vitamui-library'; +import { Component, inject, Input, OnInit } from '@angular/core'; +import { EllipsisDirective, Group, Profile, TooltipDirective } from 'vitamui-library'; import { GroupService } from '../../../group/group.service'; +import { CommonModule, TitleCasePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-group-detail', templateUrl: './group-detail.component.html', styleUrls: ['./group-detail.component.scss'], - standalone: false, + imports: [TooltipDirective, TitleCasePipe, TranslatePipe, CommonModule, EllipsisDirective], }) export class GroupDetailComponent implements OnInit { private groupService = inject(GroupService); diff --git a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-list/group-list.component.ts b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-list/group-list.component.ts index 935d2dfbb49..8be1f86dbbe 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-list/group-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/group-attribution/group-list/group-list.component.ts @@ -34,15 +34,19 @@ * 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, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { Profile } from 'vitamui-library'; +import { CollapseDirective, EllipsisDirective, Profile, SearchBarComponent } from 'vitamui-library'; import { GroupSelection } from './../../group-selection.interface'; +import { GroupDetailComponent } from '../group-detail/group-detail.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-group-list', templateUrl: './group-list.component.html', styleUrls: ['./group-list.component.scss'], - standalone: false, + imports: [SearchBarComponent, GroupDetailComponent, TranslatePipe, CollapseDirective, CommonModule, EllipsisDirective], }) export class GroupListComponent implements OnInit { data = inject(MAT_DIALOG_DATA); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.component.ts index 26bb7b443ad..4e217b207d9 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.component.ts @@ -34,9 +34,9 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, ValidationErrors, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, ValidationErrors, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Observable, Subscription } from 'rxjs'; import { AdminUserProfile, @@ -45,12 +45,19 @@ import { CountryOption, CountryService, Customer, + DialogHeaderComponent, Group, + InputComponent, isRootLevel, Logger, + NextStepComponent, Option, OtpState, + PreviousStepComponent, + SelectComponent, + SlideToggleComponent, StartupService, + StepperComponent, UserInfo, } from 'vitamui-library'; import { GroupSelection } from './../group-selection.interface'; @@ -59,6 +66,10 @@ import { UserInfoService } from './../user-info.service'; import { distinctUntilChanged, map, tap } from 'rxjs/operators'; import { UserService } from '../user.service'; import { UserCreateValidators } from './user-create.validators'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { GroupListComponent } from '../group-attribution/group-list/group-list.component'; +import { TranslatePipe } from '@ngx-translate/core'; const emailFirstPartValidator: RegExp = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+$/; @@ -66,7 +77,23 @@ const emailFirstPartValidator: RegExp = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+$/; selector: 'app-user-create', templateUrl: './user-create.component.html', styleUrls: ['./user-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + SlideToggleComponent, + InputComponent, + SelectComponent, + MatButtonToggleGroup, + MatButtonToggle, + MatDialogActions, + NextStepComponent, + GroupListComponent, + PreviousStepComponent, + TranslatePipe, + ], }) export class UserCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.module.ts b/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.module.ts deleted file mode 100644 index dd63bce37c1..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/user/user-create/user-create.module.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatSelectModule } from '@angular/material/select'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { GroupAttributionModule } from '../group-attribution/group-attribution.module'; -import { UserCreateComponent } from './user-create.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - GroupAttributionModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatSelectModule, - ReactiveFormsModule, - SharedModule, - VitamUICommonModule, - VitamUILibraryModule, - MatDialogModule, - TranslatePipe, - ], - declarations: [UserCreateComponent], -}) -export class UserCreateModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-criteria-builder.util.ts b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-criteria-builder.util.ts index c0f2c25640f..14fd96ed4f1 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-criteria-builder.util.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-criteria-builder.util.ts @@ -34,7 +34,7 @@ * 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 { buildCriteriaFromFilters, Criterion, Operators, QueryOperator, CriteriaSearchQuery } from 'vitamui-library'; +import { buildCriteriaFromFilters, CriteriaSearchQuery, Criterion, Operators, QueryOperator } from 'vitamui-library'; const USER_FILTER_CONVERTER: Readonly<{ [key: string]: (values: any[]) => Array }> = { status: (statusList: string[]): CriteriaSearchQuery[] => { diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.html b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.html index 92f37932de0..11012796a31 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.html +++ b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.html @@ -85,7 +85,7 @@ @@ -120,9 +120,9 @@ {{ 'USER.HOME.RESULTS_TABLE.GROUP' | translate }}
- @if (groups) { + @if (groups()) {
- @for (user of dataSource; track user; let index = $index) { + @for (user of dataSource(); track user; let index = $index) {
@@ -178,7 +178,7 @@ }
- @if (!dataSource || pending || !groups) { + @if (!dataSource() || pending() || !groups()) {
diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.ts index d2a22473afe..34c3d5b47ef 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.component.ts @@ -37,36 +37,53 @@ import { merge, Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { + AdminUserProfile, ApplicationId, AuthService, buildCriteriaFromSearch, CriteriaSearchQuery, DEFAULT_PAGE_SIZE, Direction, + EllipsisDirective, + Group, + HasAnyRoleDirective, + InfiniteScrollDirective, InfiniteScrollTable, + OrderByButtonComponent, PageRequest, + PipesModule, Role, SnackBarService, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, + TableFilterSearchComponent, + User, } from 'vitamui-library'; -import type { AdminUserProfile, Group, User } from 'vitamui-library'; import { Component, + effect, ElementRef, EventEmitter, + inject, Input, + input, LOCALE_ID, OnDestroy, OnInit, Output, + signal, TemplateRef, ViewChild, - inject, } from '@angular/core'; import { CustomerService } from '../../core/customer.service'; import { UserService } from '../user.service'; import { buildCriteriaFromUserFilters } from './user-criteria-builder.util'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { CommonModule, DatePipe, UpperCasePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -74,7 +91,22 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-user-list', templateUrl: './user-list.component.html', styleUrls: ['./user-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + TableFilterComponent, + TableFilterOptionComponent, + OrderByButtonComponent, + TableFilterSearchComponent, + MatProgressSpinner, + UpperCasePipe, + DatePipe, + PipesModule, + TranslatePipe, + CommonModule, + EllipsisDirective, + HasAnyRoleDirective, + InfiniteScrollDirective, + ], }) export class UserListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { private customerService = inject(CustomerService); @@ -102,8 +134,8 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe level: null, group: null, }; - groupFilterOptions: Array<{ value: string; label: string }> = []; - levelFilterOptions: Array<{ value: string; label: string }> = []; + groupFilterOptions = signal>([]); + levelFilterOptions = signal>([]); orderBy = 'lastname'; direction = Direction.ASCENDANT; genericUserRole: Readonly<{ appId: ApplicationId; tenantIdentifier: number; roles: Role[] }>; @@ -126,22 +158,7 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe } private _connectedUserInfo: AdminUserProfile; - @Input() - get groups(): Group[] { - return this._groups; - } - set groups(groupList: Group[]) { - this._groups = groupList; - if (groupList) { - this.updateData(groupList); - - this.updatedData.subscribe(() => { - this.updateData(groupList); - }); - } - } - - private _groups: Group[]; + readonly groups = input(null); constructor() { const userService = inject(UserService); @@ -154,6 +171,13 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe tenantIdentifier: +this.authService.user.proofTenantIdentifier, roles: [Role.ROLE_GENERIC_USERS], }; + + effect(() => { + const groupList = this.groups(); + if (groupList) { + this.updateData(groupList); + } + }); } ngOnInit() { @@ -161,16 +185,29 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe this.refreshLevelOptions(); this.updatedUserSub = this.userService.userUpdated.subscribe((updatedUser: User) => { - const userIndex = this.dataSource.findIndex((user) => updatedUser.id === user.id); + const userIndex = (this.dataSource() ?? []).findIndex((user) => updatedUser.id === user.id); if (userIndex > -1) { this.userService.get(updatedUser.id).subscribe((user: User) => { - this.dataSource[userIndex] = user; + this.dataSource.update((users) => { + const list = [...(users ?? [])]; + list[userIndex] = user; + return list; + }); }); } }); const searchCriteriaChange = merge(this.searchChange, this.filterChange, this.orderChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); + this.updatedUserSub.add( + this.updatedData.subscribe(() => { + const groupList = this.groups(); + if (groupList) { + this.updateData(groupList); + } + }), + ); + searchCriteriaChange.subscribe(() => { const query: CriteriaSearchQuery = { criteria: [...buildCriteriaFromUserFilters(this.filterMap), ...buildCriteriaFromSearch(this._searchText, this.searchKeys)], @@ -182,7 +219,7 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe } updateData(groups: Group[]) { - const groupIds = new Set(this.dataSource.map((user: User) => user.groupId)); + const groupIds = new Set((this.dataSource() ?? []).map((user: User) => user.groupId)); groupIds.forEach((groupId) => { const existingGroup = this.userGroups.find((group) => group.id === groupId); @@ -193,14 +230,14 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe } } }); - this.groupFilterOptions = this.userGroups.map((group) => ({ value: group.id, label: group.group.name })); - this.groupFilterOptions.sort(sortByLabel(this.locale)); + this.groupFilterOptions.set(this.userGroups.map((group) => ({ value: group.id, label: group.group.name }))); + this.groupFilterOptions().sort(sortByLabel(this.locale)); } refreshLevelOptions(query?: CriteriaSearchQuery) { this.userService.getLevelsNoEmpty(query).subscribe((levels) => { - this.levelFilterOptions = levels.map((level) => ({ value: level, label: level })); - this.levelFilterOptions.sort(sortByLabel(this.locale)); + this.levelFilterOptions.set(levels.map((level) => ({ value: level, label: level }))); + this.levelFilterOptions().sort(sortByLabel(this.locale)); }); } @@ -210,7 +247,7 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe } getGroup(user: User) { - const userGroup = this.groups.find((group) => group.id === user.groupId); + const userGroup = this.groups()?.find((group) => group.id === user.groupId); return userGroup ? userGroup : undefined; } @@ -237,7 +274,7 @@ export class UserListComponent extends InfiniteScrollTable implements OnDe checkInactifUsers() { this.customerService.getMyCustomer().subscribe((customer) => { if (customer.gdprAlert) { - this.dataSource + (this.dataSource() ?? []) .filter((user: User) => user.status === 'DISABLED' && user.disablingDate !== null) .forEach((u: User) => { this.totalMonth = diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.module.ts b/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.module.ts deleted file mode 100644 index c2bdcb72433..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/user/user-list/user-list.module.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { VitamUICommonModule } from 'vitamui-library'; - -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { RouterModule } from '@angular/router'; - -import { SharedModule } from '../../shared/shared.module'; -import { UserListComponent } from './user-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, RouterModule, MatProgressSpinnerModule, VitamUICommonModule, SharedModule, MatSelectModule, TranslatePipe], - declarations: [UserListComponent], - exports: [UserListComponent], -}) -export class UserListModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-group-tab/user-group-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-group-tab/user-group-tab.component.ts index 795a3041275..5cdbe44affe 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-group-tab/user-group-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-group-tab/user-group-tab.component.ts @@ -34,23 +34,23 @@ * 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, Input, OnChanges, OnDestroy, inject } from '@angular/core'; +import { Component, inject, Input, OnChanges, OnDestroy } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { Subject } from 'rxjs'; -import { AuthService, isRootLevel } from 'vitamui-library'; -import type { AdminUserProfile, Group, Profile, User } from 'vitamui-library'; +import { AdminUserProfile, AuthService, Group, isRootLevel, Profile, TooltipDirective, User } from 'vitamui-library'; import { GroupService } from '../../../group/group.service'; import { GroupAttributionComponent } from '../../group-attribution/group-attribution.component'; import { GroupSelection } from '../../group-selection.interface'; import { UserService } from '../../user.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-user-group-tab', templateUrl: './user-group-tab.component.html', styleUrls: ['./user-group-tab.component.scss'], - standalone: false, + imports: [TooltipDirective, TranslatePipe], }) export class UserGroupTabComponent implements OnChanges, OnDestroy { groupAttrDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.spec.ts b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.spec.ts deleted file mode 100644 index b36ccac8add..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.spec.ts +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { EMPTY, of } from 'rxjs'; -import { - AdminUserProfile, - AuthService, - BASE_URL, - CountryService, - Customer, - LoggerModule, - OtpState, - User, - UserInfo, - WINDOW_LOCATION, -} from 'vitamui-library'; -import { VitamUICommonTestModule } from 'vitamui-library/testing'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { UserCreateValidators } from '../../user-create/user-create.validators'; -import { UserInfoService } from '../../user-info.service'; -import { UserService } from '../../user.service'; -import { UserInfoTabComponent } from './user-information-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -let expectedUser: User = { - id: 'idUser', - identifier: '8', - email: 'eDeviller@test-domain.com', - firstname: 'Emmanuel', - lastname: 'Deviller', - mobile: '', - userInfoId: '', - phone: '', - level: '', - groupId: 'profile_group_id', - customerId: '42', - otp: false, - status: 'ENABLED', - type: 'ENABLED', - subrogeable: false, - nbFailedAttempts: 0, - lastConnection: '2018-07-04T16:00:00.126+02:00', - readonly: false, - address: { - street: '13 rue faubourg', - zipCode: '75009', - city: 'paris', - country: 'france', - }, - siteCode: '001', - disablingDate: null, - centerCodes: ['000001'], - autoProvisioningEnabled: false, -}; -let userInfolanguage: UserInfo = { - id: '1', - language: 'fr', -}; -let expectedCustomer: Customer = { - id: 'idCustomer', - identifier: '1', - enabled: true, - readonly: false, - hasCustomGraphicIdentity: false, - code: '154785', - name: 'nom du client', - companyName: 'nom de la société', - passwordRevocationDelay: 6, - otp: OtpState.DEACTIVATED, - idp: true, - address: { - street: '85 rue des bois', - zipCode: '75013', - city: 'Paris', - country: 'France', - }, - language: 'FRENCH', - emailDomains: ['domain.com'], - defaultEmailDomain: 'domain.com', - owners: [ - { - id: 'znvuzhvyvg', - identifier: '41', - code: '254791', - name: 'owner name', - companyName: 'company name', - address: { - street: '85 rue des bois', - zipCode: '75013', - city: 'Paris', - country: 'France', - }, - customerId: 'idCustomer', - readonly: false, - }, - ], - themeColors: {}, - gdprAlert: false, - gdprAlertDelay: 72, - portalMessages: {}, - portalTitles: {}, -}; - -let expectedAdminUserProfile: AdminUserProfile = { - multifactorAllowed: true, - createUser: true, - genericAllowed: true, - anonymizationAllowed: false, - standardAttrsAllowed: true, - type: 'type', - profilGroupIds: ['profile_group_id'], - profilGroup: [ - { - id: 'profile_group_id', - name: 'profile_group_name', - description: 'Une description du profil group', - }, - ], -}; - -@Component({ - template: ` `, - standalone: false, -}) -class TestHostComponent { - user = expectedUser; - customer = expectedCustomer; - readOnly = false; - adminUserProfile = expectedAdminUserProfile; - userInfo = userInfolanguage; - - @ViewChild(UserInfoTabComponent, { static: false }) - component: UserInfoTabComponent; -} - -@NgModule({ declarations: [TestHostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('UserInfoTabComponent', () => { - let testhost: TestHostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - expectedUser = { - id: 'idUser', - identifier: '8', - email: 'eDeviller@test-domain.com', - firstname: 'Emmanuel', - lastname: 'Deviller', - mobile: '', - userInfoId: '', - phone: '', - level: '', - groupId: 'profile_group_id', - customerId: '42', - otp: false, - status: 'ENABLED', - type: 'ENABLED', - subrogeable: false, - nbFailedAttempts: 0, - lastConnection: '2018-07-04T16:00:00.126+02:00', - readonly: false, - address: { - street: '13 rue faubourg', - zipCode: '75009', - city: 'paris', - country: 'france', - }, - siteCode: '001', - disablingDate: null, - centerCodes: ['000001'], - autoProvisioningEnabled: false, - }; - expectedCustomer = { - id: 'idCustomer', - identifier: '41', - enabled: true, - readonly: false, - hasCustomGraphicIdentity: false, - code: '154785', - name: 'nom du client', - companyName: 'nom de la société', - passwordRevocationDelay: 6, - otp: OtpState.DEACTIVATED, - idp: true, - address: { - street: '85 rue des bois', - zipCode: '75013', - city: 'Paris', - country: 'France', - }, - language: 'FRENCH', - emailDomains: ['domain.com'], - defaultEmailDomain: 'domain.com', - owners: [ - { - id: 'znvuzhvyvg', - identifier: '41', - code: '254791', - name: 'owner name', - companyName: 'company name', - address: { - street: '85 rue des bois', - zipCode: '75013', - city: 'Paris', - country: 'France', - }, - customerId: 'idCustomer', - readonly: false, - }, - ], - themeColors: {}, - gdprAlert: false, - gdprAlertDelay: 72, - portalMessages: {}, - portalTitles: {}, - }; - expectedAdminUserProfile = { - multifactorAllowed: true, - createUser: true, - genericAllowed: true, - anonymizationAllowed: false, - standardAttrsAllowed: true, - type: 'type', - profilGroupIds: ['profile_group_id'], - profilGroup: [ - { - id: 'profile_group_id', - name: 'profile_group_name', - description: 'Une description du profil group', - }, - ], - }; - userInfolanguage = { - id: '1', - language: 'fr', - }; - const userServiceSpy = { - patch: vi.fn().mockName('UserService.patch').mockReturnValue(of({})), - }; - const userInfoServiceSpy = { - patch: vi.fn().mockName('UserInfoService.patch').mockReturnValue(of({})), - }; - - const userCreateValidatorsSpy = { - uniqueEmail: vi - .fn() - .mockName('userCreateValidators.uniqueEmail') - .mockReturnValue(() => of(null)), - }; - - await TestBed.configureTestingModule({ - imports: [LoggerModule.forRoot(), MatButtonToggleModule, NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule], - declarations: [UserInfoTabComponent, TestHostComponent], - schemas: [NO_ERRORS_SCHEMA], - providers: [ - { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: UserService, useValue: userServiceSpy }, - { provide: UserInfoService, useValue: userInfoServiceSpy }, - { provide: UserCreateValidators, useValue: userCreateValidatorsSpy }, - { provide: AuthService, useValue: { user: {} } }, - { provide: CountryService, useValue: { getAvailableCountries: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }) - .overrideComponent(UserInfoTabComponent, { set: { template: '' } }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TestHostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - - testhost.user = expectedUser; - testhost.userInfo = userInfolanguage; - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - it('should have the correct fields', () => { - expect(testhost.component.form.get('id')).toBeDefined(); - expect(testhost.component.form.get('firstname')).toBeDefined(); - expect(testhost.component.form.get('lastname')).toBeDefined(); - expect(testhost.component.form.get('email')).toBeDefined(); - expect(testhost.component.form.get('mobile')).toBeDefined(); - expect(testhost.component.form.get('phone')).toBeDefined(); - expect(testhost.component.form.get('language')).toBeDefined(); - expect(testhost.component.form.get('otp')).toBeDefined(); - expect(testhost.component.form.get('type')).toBeDefined(); - expect(testhost.component.form.get('customerId')).toBeDefined(); - expect(testhost.component.form.get('groupId')).toBeDefined(); - expect(testhost.component.form.get('code')).toBeDefined(); - }); - - it('should have the email validator', () => { - const emailControl = testhost.component.form.get('email'); - emailControl.setValue('name'); - expect(emailControl.valid).toBeFalsy(); - emailControl.setValue('name@'); - expect(emailControl.valid).toBeFalsy(); - emailControl.setValue('name@domaine.test'); - expect(emailControl.valid).toBeTruthy(); - }); - - it('should disable then enable the form', () => { - testhost.component.readOnly = true; - testhost.component.ngOnChanges({ - readOnly: { previousValue: false, currentValue: true, firstChange: false, isFirstChange: () => false }, - }); - expect(testhost.component.form.disabled).toBe(true); - testhost.component.readOnly = false; - testhost.component.ngOnChanges({ - readOnly: { previousValue: true, currentValue: false, firstChange: false, isFirstChange: () => false }, - }); - expect(testhost.component.form.disabled).toBe(false); - }); -}); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.ts index b69a6b3ea1e..f9ce569bba8 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-information-tab/user-information-tab.component.ts @@ -34,17 +34,44 @@ * 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, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, inject, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { merge, of } from 'rxjs'; import { catchError, debounceTime, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { AdminUserProfile, CountryOption, Customer, User, UserInfo } from 'vitamui-library'; -import { CountryService, diff, Option, OtpState, StartupService } from 'vitamui-library'; +import { + AdminUserProfile, + CountryOption, + CountryService, + Customer, + diff, + EditableEmailInputComponent, + EditableInputComponent, + FormFieldValueWrapperComponent, + Option, + OtpState, + PipesModule, + SelectComponent, + SlideToggleComponent, + StartupService, + TooltipDirective, + User, + UserInfo, + VitamUIFieldErrorComponent, +} from 'vitamui-library'; import { UserInfoService } from '../../user-info.service'; import { UserCreateValidators } from '../../user-create/user-create.validators'; import { UserService } from '../../user.service'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { CommonModule } from '@angular/common'; const UPDATE_DEBOUNCE_TIME = 200; @@ -52,7 +79,27 @@ const UPDATE_DEBOUNCE_TIME = 200; selector: 'app-user-info-tab', templateUrl: './user-information-tab.component.html', styleUrls: ['./user-information-tab.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + VitamUIFieldErrorComponent, + FormFieldValueWrapperComponent, + SelectComponent, + SlideToggleComponent, + TooltipDirective, + PipesModule, + TranslatePipe, + CommonModule, + EditableEmailInputComponent, + EditableInputComponent, + FormsModule, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ], }) export class UserInfoTabComponent implements OnChanges, OnInit { private userService = inject(UserService); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-popup.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-popup.component.ts index 00753e79e56..bc49be40d22 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-popup.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-popup.component.ts @@ -40,11 +40,12 @@ import { Component, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { CustomerService } from '../../core/customer.service'; +import { UserPreviewComponent } from './user-preview.component'; @Component({ selector: 'app-profile-group-popup', template: '', - standalone: false, + imports: [UserPreviewComponent], }) export class UserPopupComponent { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.component.ts index 69e2664faa4..ef13d0c33bd 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.component.ts @@ -34,24 +34,59 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; -import { AuthService, isLevelAllowed, StartupService } from 'vitamui-library'; -import type { AdminUserProfile, Customer, Group, User, UserInfo } from 'vitamui-library'; +import { + AdminUserProfile, + AuthService, + Customer, + Group, + isLevelAllowed, + MultiOperationHistoryTabComponent, + StartupService, + User, + UserInfo, + VitamuiMenuButtonComponent, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; import { UserInfoService } from './../user-info.service'; import { UserApiService } from '../../core/api/user-api.service'; import { GroupService } from '../../group/group.service'; import { GroupSelection } from '../group-selection.interface'; import { UserService } from '../user.service'; +import { MatMenuItem } from '@angular/material/menu'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { UserInfoTabComponent } from './user-information-tab/user-information-tab.component'; +import { UserGroupTabComponent } from './user-group-tab/user-group-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-user-preview', templateUrl: './user-preview.component.html', styleUrls: ['./user-preview.component.scss'], - standalone: false, + imports: [ + VitamuiMenuButtonComponent, + MatMenuItem, + MatTabGroup, + MatTab, + UserInfoTabComponent, + UserGroupTabComponent, + MultiOperationHistoryTabComponent, + MatDialogContent, + MatDialogActions, + MatDialogClose, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class UserPreviewComponent implements OnDestroy, OnInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.module.ts b/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.module.ts deleted file mode 100644 index 26e22e0c926..00000000000 --- a/ui/ui-frontend/projects/identity/src/app/user/user-preview/user-preview.module.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; - -import { VitamUICommonModule, VitamUILibraryModule, CommonTooltipModule } from 'vitamui-library'; -import { SharedModule } from '../../shared/shared.module'; -import { UserGroupTabComponent } from './user-group-tab/user-group-tab.component'; -import { UserInfoTabComponent } from './user-information-tab/user-information-tab.component'; -import { UserPopupComponent } from './user-popup.component'; -import { UserPreviewComponent } from './user-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatDialogModule, - MatMenuModule, - MatTabsModule, - ReactiveFormsModule, - RouterModule, - SharedModule, - TranslatePipe, - VitamUICommonModule, - VitamUILibraryModule, - CommonTooltipModule, - ], - declarations: [UserPopupComponent, UserPreviewComponent, UserInfoTabComponent, UserGroupTabComponent], - exports: [UserPreviewComponent], -}) -export class UserPreviewModule {} diff --git a/ui/ui-frontend/projects/identity/src/app/user/user.component.html b/ui/ui-frontend/projects/identity/src/app/user/user.component.html index 7d0a32c6e0f..c67190f21ee 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user.component.html +++ b/ui/ui-frontend/projects/identity/src/app/user/user.component.html @@ -1,7 +1,7 @@ @if (openedItem) { - + } @@ -12,7 +12,7 @@
{{ 'APPLICATION.USERS_APP.TITLE' | translate }}
- @if (groups) { + @if (groups()) { @@ -25,7 +25,7 @@
{{ 'APPLICATION.USERS_APP.TITLE' | translate }}
- +
diff --git a/ui/ui-frontend/projects/identity/src/app/user/user.component.ts b/ui/ui-frontend/projects/identity/src/app/user/user.component.ts index de4b636eb38..5165a40c4e5 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user.component.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user.component.ts @@ -34,9 +34,8 @@ * 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, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnInit, signal, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; import { DownloadSnackBarService } from 'projects/referential/src/app/core/service/download-snack-bar.service'; import { Subscription } from 'rxjs'; import { finalize } from 'rxjs/operators'; @@ -46,31 +45,42 @@ import { Customer, DEFAULT_PAGE_SIZE, Direction, - GlobalEventService, Group, PageRequest, SidenavPage, - User, SnackBarService, + User, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, } from 'vitamui-library'; import { CustomerService } from '../core/customer.service'; import { GroupService } from '../group/group.service'; import { UserCreateComponent } from './user-create/user-create.component'; import { UserListComponent } from './user-list/user-list.component'; import { UserService } from './user.service'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { UserPreviewComponent } from './user-preview/user-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-user', templateUrl: './user.component.html', styleUrls: ['./user.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + UserPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + UserListComponent, + TranslatePipe, + ], }) export class UserComponent extends SidenavPage implements OnInit { dialog = inject(MatDialog); userService = inject(UserService); - route: ActivatedRoute; customerService = inject(CustomerService); - override globalEventService: GlobalEventService; groupService = inject(GroupService); private authService = inject(AuthService); private downloadSnackBarService = inject(DownloadSnackBarService); @@ -80,31 +90,21 @@ export class UserComponent extends SidenavPage implements OnInit { public connectedUserInfo: AdminUserProfile; public customer: Customer; public search: string; - public groups: Group[]; + public groups = signal(null); public exportLoading = false; @ViewChild(UserListComponent, { static: true }) userListComponent: UserListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - this.globalEventService = globalEventService; - } - ngOnInit() { this.customerService.getMyCustomer().subscribe((customer) => (this.customer = customer)); - this.groupService.getAll(true).subscribe((data: Group[]) => (this.groups = data)); + this.groupService.getAll(true).subscribe((data: Group[]) => this.groups.set(data)); this.connectedUserInfo = this.userService.getUserProfileInfo(this.authService.user); } openCreateUserDialog(): void { const dialogRef = this.dialog.open(UserCreateComponent, { disableClose: true, - data: { userInfo: this.connectedUserInfo, customer: this.customer, groups: this.groups }, + data: { userInfo: this.connectedUserInfo, customer: this.customer, groups: this.groups() }, }); dialogRef.afterClosed().subscribe((result) => { if (result) { diff --git a/ui/ui-frontend/projects/identity/src/app/user/user.module.ts b/ui/ui-frontend/projects/identity/src/app/user/user.module.ts index e03ea939d1d..d6b181c1191 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user.module.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user.module.ts @@ -42,11 +42,6 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { SharedModule } from '../shared/shared.module'; -import { GroupAttributionModule } from './group-attribution/group-attribution.module'; -import { UserCreateModule } from './user-create/user-create.module'; -import { UserListModule } from './user-list/user-list.module'; -import { UserPreviewModule } from './user-preview/user-preview.module'; import { UserRoutingModule } from './user-routing.module'; import { UserComponent } from './user.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -55,18 +50,13 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ CommonModule, VitamUICommonModule, - SharedModule, - UserCreateModule, - UserListModule, MatDialogModule, MatMenuModule, - UserPreviewModule, - GroupAttributionModule, MatSidenavModule, FormsModule, UserRoutingModule, TranslatePipe, + UserComponent, ], - declarations: [UserComponent], }) export class UserModule {} diff --git a/ui/ui-frontend/projects/identity/src/main.ts b/ui/ui-frontend/projects/identity/src/main.ts index a76b446c356..82316e98aa3 100644 --- a/ui/ui-frontend/projects/identity/src/main.ts +++ b/ui/ui-frontend/projects/identity/src/main.ts @@ -34,16 +34,43 @@ * 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 { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowser } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom, LOCALE_ID } from '@angular/core'; +import { bootstrapApplication, BrowserModule, Title } from '@angular/platform-browser'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import { AuthenticationModule, provideI18n, VitamUICommonModule, VitamUILibraryModule, WINDOW_LOCATION } from 'vitamui-library'; +import { DatePipe } from '@angular/common'; +import { CoreModule } from './app/core/core.module'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { AppRoutingModule } from './app/app-routing.module'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { AppComponent } from './app/app.component'; if (environment.production) { enableProdMode(); } -platformBrowser() - .bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }) - .catch((err) => console.log(err)); +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom( + AuthenticationModule.forRoot(), + CoreModule, + BrowserAnimationsModule, + BrowserModule, + VitamUICommonModule.forRoot(), + AppRoutingModule, + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: environment.production, + // Register the ServiceWorker as soon as the application is stable + // or after 30 seconds (whichever comes first). + registrationStrategy: 'registerWhenStable:30000', + }), + VitamUILibraryModule, // For Material tokens + ), + provideI18n(), + Title, + { provide: LOCALE_ID, useValue: 'fr' }, + { provide: WINDOW_LOCATION, useValue: window.location }, + DatePipe, + ], +}).catch((err) => console.log(err)); diff --git a/ui/ui-frontend/projects/ingest/src/app/app.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/app.component.spec.ts index ddec3fc99d7..5dd3e795427 100644 --- a/ui/ui-frontend/projects/ingest/src/app/app.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/app.component.spec.ts @@ -39,7 +39,6 @@ import { Component } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Router } from '@angular/router'; import { of } from 'rxjs'; @@ -49,14 +48,14 @@ import { AppComponent } from './app.component'; @Component({ selector: 'router-outlet', template: '', - standalone: false, + imports: [MatSidenavModule], }) class RouterOutletStubComponent {} @Component({ selector: 'vitamui-common-subrogation-banner', template: '', - standalone: false, + imports: [MatSidenavModule], }) class SubrogationBannerStubComponent {} @@ -64,8 +63,7 @@ describe('AppComponent', () => { beforeEach(async () => { const startupServiceStub = { configurationLoaded: () => true, printConfiguration: () => {}, getPlatformName: () => '' }; await TestBed.configureTestingModule({ - imports: [MatSidenavModule, NoopAnimationsModule], - declarations: [AppComponent, SubrogationBannerStubComponent, RouterOutletStubComponent], + imports: [MatSidenavModule, SubrogationBannerStubComponent, RouterOutletStubComponent, AppComponent], providers: [ { provide: StartupService, useValue: startupServiceStub }, { provide: AuthService, useValue: { userLoaded: of(null) } }, diff --git a/ui/ui-frontend/projects/ingest/src/app/app.component.ts b/ui/ui-frontend/projects/ingest/src/app/app.component.ts index 195b00794d1..49cef51126f 100644 --- a/ui/ui-frontend/projects/ingest/src/app/app.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/app.component.ts @@ -36,13 +36,14 @@ */ import { Component, inject } from '@angular/core'; import { Title } from '@angular/platform-browser'; -import { StartupService } from 'vitamui-library'; +import { FooterComponent, HeaderModule, StartupService, SubrogationModule, VitamuiBodyComponent } from 'vitamui-library'; +import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], - standalone: false, + imports: [HeaderModule, VitamuiBodyComponent, RouterOutlet, FooterComponent, SubrogationModule], }) export class AppComponent { title = 'Ingest App'; diff --git a/ui/ui-frontend/projects/ingest/src/app/app.module.ts b/ui/ui-frontend/projects/ingest/src/app/app.module.ts deleted file mode 100644 index a2d54c8efdb..00000000000 --- a/ui/ui-frontend/projects/ingest/src/app/app.module.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { DatePipe, registerLocaleData } from '@angular/common'; -import { default as localeFr } from '@angular/common/locales/fr'; -import { LOCALE_ID, NgModule } from '@angular/core'; -import { BrowserModule, Title } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { AuthenticationModule, BytesPipe, provideI18n, VitamUICommonModule, WINDOW_LOCATION } from 'vitamui-library'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { CoreModule } from './core/core.module'; -import { HoldingFillingSchemeModule } from './holding-filling-scheme/holding-filling-scheme.module'; -import { IngestModule } from './ingest/ingest.module'; -import { provideNativeDateAdapter } from '@angular/material/core'; - -registerLocaleData(localeFr, 'fr'); - -@NgModule({ - declarations: [AppComponent], - imports: [ - AuthenticationModule.forRoot(), - CoreModule, - BrowserAnimationsModule, - BrowserModule, - VitamUICommonModule.forRoot(), - AppRoutingModule, - IngestModule, - HoldingFillingSchemeModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000', - }), - ], - providers: [ - provideI18n(), - provideNativeDateAdapter(), - Title, - { provide: LOCALE_ID, useValue: 'fr' }, - { - provide: WINDOW_LOCATION, - useValue: window.location, - }, - DatePipe, - BytesPipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.spec.ts b/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.spec.ts index 76879423c30..6f2ee0dfe80 100644 --- a/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.spec.ts @@ -35,23 +35,15 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { TestBed } from '@angular/core/testing'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from '../../../environments/environment.prod'; import { IngestApiService } from './ingest-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('IngestApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); it('should be created', () => { diff --git a/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.ts b/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.ts index ed7405de55e..1ea37689cd5 100644 --- a/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.ts +++ b/ui/ui-frontend/projects/ingest/src/app/core/api/ingest-api.service.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpRequest } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { BASE_URL, PageRequest, PaginatedHttpClient, PaginatedResponse, VitamuiHttpHeaders } from 'vitamui-library'; diff --git a/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.spec.ts index 2353d9888e2..a5bad846693 100644 --- a/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.spec.ts @@ -39,13 +39,11 @@ import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { EMPTY, of } from 'rxjs'; -import { BASE_URL, BytesPipe, ConfirmDialogService, LoggerModule, StartupService } from 'vitamui-library'; +import { BytesPipe, ConfirmDialogService, LoggerModule, StartupService } from 'vitamui-library'; import { UploadComponent } from './upload.component'; import { UploadService } from './upload.service'; import { DecimalPipe } from '@angular/common'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('UploadComponent', () => { let component: UploadComponent; @@ -62,8 +60,7 @@ describe('UploadComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [UploadComponent], - imports: [MatProgressBarModule, LoggerModule.forRoot()], + imports: [MatProgressBarModule, LoggerModule.forRoot(), UploadComponent], providers: [ FormBuilder, { provide: MatDialogRef, useValue: matDialogRefSpy }, @@ -73,9 +70,6 @@ describe('UploadComponent', () => { { provide: StartupService, useValue: { getReferentialUrl: () => '' } }, DecimalPipe, BytesPipe, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }) .overrideTemplate(UploadComponent, '
') diff --git a/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.ts b/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.ts index 2a58d918bea..a1a7e1d1c5b 100644 --- a/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/core/common/upload.component.ts @@ -35,14 +35,14 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, inject, OnInit, ViewChild } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { SnackBarService, StartupService } from 'vitamui-library'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { DialogHeaderComponent, FileSelectorComponent, SnackBarService, StartupService } from 'vitamui-library'; import { IngestType } from './ingest-type.enum'; import { UploadService } from './upload.service'; import { MatSnackBarRef } from '@angular/material/snack-bar'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; const FILE_MAX_SIZE = 10737418240; @@ -50,7 +50,7 @@ const FILE_MAX_SIZE = 10737418240; selector: 'app-upload', templateUrl: './upload.component.html', styleUrls: ['./upload.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, MatDialogContent, FileSelectorComponent, ReactiveFormsModule, MatDialogActions, TranslatePipe], }) export class UploadComponent implements OnInit { data = inject(MAT_DIALOG_DATA); diff --git a/ui/ui-frontend/projects/ingest/src/app/core/common/upload.module.ts b/ui/ui-frontend/projects/ingest/src/app/core/common/upload.module.ts deleted file mode 100644 index 8593940e4dc..00000000000 --- a/ui/ui-frontend/projects/ingest/src/app/core/common/upload.module.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { UploadComponent } from './upload.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [UploadComponent], -}) -export class UploadModule {} diff --git a/ui/ui-frontend/projects/ingest/src/app/core/core.module.ts b/ui/ui-frontend/projects/ingest/src/app/core/core.module.ts index 46c612ff254..51e345b6fbb 100644 --- a/ui/ui-frontend/projects/ingest/src/app/core/core.module.ts +++ b/ui/ui-frontend/projects/ingest/src/app/core/core.module.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NgModule, inject } from '@angular/core'; +import { inject, NgModule } from '@angular/core'; import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule, throwIfAlreadyLoaded, VitamUICommonModule } from 'vitamui-library'; import { environment } from '../../environments/environment'; diff --git a/ui/ui-frontend/projects/ingest/src/app/core/service/ingest-referential.service.spec.ts b/ui/ui-frontend/projects/ingest/src/app/core/service/ingest-referential.service.spec.ts index 05ea3ea390a..cd4d8cc3ba0 100644 --- a/ui/ui-frontend/projects/ingest/src/app/core/service/ingest-referential.service.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/core/service/ingest-referential.service.spec.ts @@ -34,11 +34,9 @@ * 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 { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { Type } from '@angular/core'; import { inject, TestBed } from '@angular/core/testing'; -import { BASE_URL } from 'vitamui-library'; import { IngestReferentialService } from './ingest-referential.service'; describe('IngestReferentialService', () => { @@ -48,12 +46,7 @@ describe('IngestReferentialService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - IngestReferentialService, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [IngestReferentialService], }); httpTestingController = TestBed.inject(HttpTestingController as Type); diff --git a/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.spec.ts index 33a289278f6..cd900118fc7 100644 --- a/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.spec.ts @@ -38,8 +38,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDatepickerModule } from '@angular/material/datepicker'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { Component } from '@angular/core'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; @@ -57,7 +56,15 @@ import { HoldingFillingSchemeComponent } from './holding-filling-scheme.componen @Component({ selector: 'app-ingest-list', template: '', - standalone: false, + imports: [ + MatDatepickerModule, + MatMenuModule, + MatSidenavModule, + InjectorModule, + VitamUICommonTestModule, + BrowserAnimationsModule, + MatDialogModule, + ], }) class IngestListStubComponent {} @@ -81,23 +88,25 @@ describe('HoldingFilingSchemeComponent', () => { MatMenuModule, MatSidenavModule, InjectorModule, - RouterTestingModule, VitamUICommonTestModule, BrowserAnimationsModule, LoggerModule.forRoot(), - RouterTestingModule, - NoopAnimationsModule, SearchBarComponent, MatDialogModule, + HoldingFillingSchemeComponent, + IngestListStubComponent, ], - declarations: [HoldingFillingSchemeComponent, IngestListStubComponent], providers: [ FormBuilder, { provide: MatDialog, useValue: matDialogSpy }, { provide: IngestService, useValue: ingestServiceMock }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'HOLDING_FILLING_SCHEME_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'HOLDING_FILLING_SCHEME_APP' }), + snapshot: { data: { appId: 'HOLDING_FILLING_SCHEME_APP' } }, + }, }, { provide: environment, useValue: environment }, ], diff --git a/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.ts b/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.ts index 92de1cd564e..161fb6c0551 100644 --- a/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.component.ts @@ -34,37 +34,39 @@ * 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, OnInit, inject } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { GlobalEventService, SidenavPage } from 'vitamui-library'; +import { SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { IngestType } from '../core/common/ingest-type.enum'; import { UploadComponent } from '../core/common/upload.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { UploadTrackingComponent } from '../shared/upload-tracking/upload-tracking.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-holding-filling-scheme', templateUrl: './holding-filling-scheme.component.html', styleUrls: ['./holding-filling-scheme.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + UploadTrackingComponent, + TranslatePipe, + ], }) export class HoldingFillingSchemeComponent extends SidenavPage implements OnInit { private router = inject(Router); - private route: ActivatedRoute; + private route = inject(ActivatedRoute); dialog = inject(MatDialog); IngestType = IngestType; tenantIdentifier: string; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - } - ngOnInit() { this.route.params.subscribe((params) => { this.tenantIdentifier = params['tenantIdentifier']; diff --git a/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.module.ts b/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.module.ts index 9b5af872927..45b877c1e1f 100644 --- a/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.module.ts +++ b/ui/ui-frontend/projects/ingest/src/app/holding-filling-scheme/holding-filling-scheme.module.ts @@ -43,8 +43,6 @@ import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { UploadModule } from '../core/common/upload.module'; -import { UploadTrackingModule } from '../shared/upload-tracking/upload-tracking.module'; import { HoldingFillingSchemeRoutingModule } from './holding-filling-scheme-routing.module'; import { HoldingFillingSchemeComponent } from './holding-filling-scheme.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -58,11 +56,9 @@ import { TranslatePipe } from '@ngx-translate/core'; MatProgressBarModule, MatSidenavModule, ReactiveFormsModule, - UploadModule, - UploadTrackingModule, VitamUICommonModule, TranslatePipe, + HoldingFillingSchemeComponent, ], - declarations: [HoldingFillingSchemeComponent], }) export class HoldingFillingSchemeModule {} diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.html b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.html index 52a204db425..3ed6a630753 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.html +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.html @@ -25,7 +25,7 @@
{{ 'INGEST_LIST.STATUS' | translate }}
- @for (ingest of dataSource; track ingest; let index = $index) { + @for (ingest of dataSource(); track ingest; let index = $index) {
@@ -93,7 +93,7 @@ }
- @if (!pending && !ingestService.canLoadMore) { + @if (!pending() && !ingestService.canLoadMore) {
{{ 'INGEST_LIST.NORESULTS' | translate }}
} @else {
diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.spec.ts index 4333f524f37..ab91286b2c9 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.spec.ts @@ -52,8 +52,7 @@ describe('IngestListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [IngestListComponent], - imports: [], + imports: [IngestListComponent], providers: [{ provide: IngestService, useValue: ingestServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.ts index 893135f3d96..b1b9fa0dc07 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.component.ts @@ -34,15 +34,24 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; -import { Subject, merge } from 'rxjs'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { merge, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { Direction, InfiniteScrollTable, PageRequest } from 'vitamui-library'; -import { DEFAULT_PAGE_SIZE } from 'vitamui-library'; -import { IngestStatus } from '../../models/logbook-event.interface'; +import { + DEFAULT_PAGE_SIZE, + Direction, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, +} from 'vitamui-library'; import type { LogbookOperation } from '../../models/logbook-event.interface'; -import { ingestStatus, ingestStatusVisualColor } from '../../models/logbook-event.interface'; +import { IngestStatus, ingestStatus, ingestStatusVisualColor } from '../../models/logbook-event.interface'; import { IngestService } from '../ingest.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -55,7 +64,7 @@ export class IngestFilters { selector: 'app-ingest-list', templateUrl: './ingest-list.component.html', styleUrls: ['./ingest-list.component.scss'], - standalone: false, + imports: [OrderByButtonComponent, MatProgressSpinner, PipesModule, TranslatePipe, CommonModule, InfiniteScrollDirective], }) export class IngestListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { ingestService: IngestService; @@ -78,11 +87,15 @@ export class IngestListComponent extends InfiniteScrollTable implements OnD @Input() set ingestThatHasChanged(ingest: LogbookOperation) { - if (!this.dataSource) { + if (!this.dataSource()) { return; } - const index = this.dataSource.findIndex((o) => o.id === ingest.id); - this.dataSource[index] = ingest; + const index = this.dataSource().findIndex((o) => o.id === ingest.id); + this.dataSource.update((ingests) => { + const next = [...(ingests ?? [])]; + next[index] = ingest; + return next; + }); } private _filters: IngestFilters; @@ -123,7 +136,7 @@ export class IngestListComponent extends InfiniteScrollTable implements OnD element.rightsStatementIdentifier = JSON.parse(element.rightsStatementIdentifier); } }); - this.dataSource = data; + this.dataSource.set(data); }); const searchCriteriaChange = merge(this.searchChange, this.filterChange, this.orderChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); @@ -133,7 +146,7 @@ export class IngestListComponent extends InfiniteScrollTable implements OnD const pageRequest = new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, this.direction, JSON.stringify(query)); this.search(pageRequest); }); - this.updatedData.subscribe(() => this.ingestService.logbookOperationsReloaded.next(this.dataSource)); + this.updatedData.subscribe(() => this.ingestService.logbookOperationsReloaded.next(this.dataSource())); } ngOnDestroy() { diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.module.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.module.ts deleted file mode 100644 index a6f503ee0a4..00000000000 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-list/ingest-list.module.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { VitamUICommonModule } from 'vitamui-library'; -import { IngestListComponent } from './ingest-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [IngestListComponent], - imports: [CommonModule, MatProgressSpinnerModule, VitamUICommonModule, TranslatePipe], - exports: [IngestListComponent], -}) -export class IngestListModule {} diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.spec.ts index f5f01d99bc0..e6b0121adb7 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.spec.ts @@ -34,13 +34,11 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { IngestService } from '../../ingest.service'; import { EventDisplayHelperService } from '../event-display-helper.service'; import { IngestErrorsDetailsTabComponent } from './ingest-errors-details-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('IngestErrorsDetailsTabComponent', () => { let component: IngestErrorsDetailsTabComponent; @@ -48,14 +46,11 @@ describe('IngestErrorsDetailsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [IngestErrorsDetailsTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [], + imports: [IngestErrorsDetailsTabComponent], providers: [ { provide: IngestService, useValue: {} }, { provide: EventDisplayHelperService, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.ts index 84bea1d00fa..8ef5495aba7 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-errors-details-tab/ingest-errors-details-tab.component.ts @@ -35,17 +35,27 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { NestedTreeControl } from '@angular/cdk/tree'; -import { Component, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; -import { MatTreeNestedDataSource } from '@angular/material/tree'; +import { Component, inject, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { + MatNestedTreeNode, + MatTree, + MatTreeNestedDataSource, + MatTreeNode, + MatTreeNodeDef, + MatTreeNodeOutlet, + MatTreeNodeToggle, +} from '@angular/material/tree'; import type { LogbookOperation } from '../../../models/logbook-event.interface'; import type { Event } from '../event'; import { EventDisplayHelperService } from '../event-display-helper.service'; +import { NgClass } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-errors-details-tab', templateUrl: './ingest-errors-details-tab.component.html', styleUrls: ['./ingest-errors-details-tab.component.css'], - standalone: false, + imports: [MatTree, MatTreeNodeDef, MatTreeNode, MatTreeNodeToggle, NgClass, MatNestedTreeNode, MatTreeNodeOutlet, TranslatePipe], }) export class IngestErrorsDetailsTabComponent implements OnInit, OnChanges { private eventDisplayHelper = inject(EventDisplayHelperService); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.spec.ts index 340be2b2317..908ed03547b 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.spec.ts @@ -46,8 +46,7 @@ describe('EventDisplayComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [EventDisplayComponent], - imports: [], + imports: [EventDisplayComponent], providers: [{ provide: IngestService, useValue: {} }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.ts index ba15c75e8bc..93eda6e1ad9 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/event-display/event-display.component.ts @@ -34,14 +34,16 @@ * 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, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { Event } from '../../../event'; +import { EventTypeLabelComponent } from 'vitamui-library'; +import { NgClass } from '@angular/common'; @Component({ selector: 'app-vitam-event-display', templateUrl: './event-display.component.html', styleUrls: ['./event-display.component.scss'], - standalone: false, + imports: [EventTypeLabelComponent, NgClass, forwardRef(() => EventDisplayComponent)], }) export class EventDisplayComponent implements OnInit { @Input() event: Event; diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.spec.ts index 394d59eeb94..09b96e53147 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.spec.ts @@ -55,8 +55,7 @@ describe('IngestEventDetailComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [IngestEventDetailComponent], - imports: [MatMenuModule, BrowserAnimationsModule], + imports: [MatMenuModule, BrowserAnimationsModule, IngestEventDetailComponent], providers: [ { provide: IngestService, useValue: {} }, { diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.ts index e8e4eea5794..9a1d2304fd7 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-event-detail/ingest-event-detail.component.ts @@ -34,16 +34,17 @@ * 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, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; +import { Component, inject, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import type { LogbookOperation } from '../../../../models/logbook-event.interface'; import type { Event } from '../../event'; import { EventDisplayHelperService } from '../../event-display-helper.service'; +import { EventDisplayComponent } from './event-display/event-display.component'; @Component({ selector: 'app-ingest-event-detail', templateUrl: './ingest-event-detail.component.html', styleUrls: ['./ingest-event-detail.component.scss'], - standalone: false, + imports: [EventDisplayComponent], }) export class IngestEventDetailComponent implements OnInit, OnChanges { private eventDisplayHelper = inject(EventDisplayHelperService); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.spec.ts index 25f26d6008b..9f9ced87f58 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.spec.ts @@ -48,8 +48,7 @@ describe('IngestInformationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [IngestInformationTabComponent], - imports: [VitamUICommonTestModule], + imports: [VitamUICommonTestModule, IngestInformationTabComponent], providers: [ { provide: ApplicationService, useValue: { getUrl$: () => of('') } }, { provide: IngestReferentialService, useValue: { resolveNames: () => of({}) } }, diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.ts index 3e3c23bc452..20acb143eed 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-information-tab/ingest-information-tab.component.ts @@ -34,25 +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, Input, OnChanges, inject } from '@angular/core'; -import { ApplicationId, ApplicationService } from 'vitamui-library'; -import { IngestStatus } from '../../../models/logbook-event.interface'; +import { Component, inject, Input, OnChanges } from '@angular/core'; +import { ApplicationId, ApplicationService, DataComponent, PipesModule } from 'vitamui-library'; import type { AgIdExtDeflateJson, EvDetDataDeflateJson, IngestReferentialNames, LogbookOperation, } from '../../../models/logbook-event.interface'; -import { ingestHasEvents, ingestLastEvent, ingestStatus } from '../../../models/logbook-event.interface'; -import { Observable, ReplaySubject, of } from 'rxjs'; +import { ingestHasEvents, ingestLastEvent, IngestStatus, ingestStatus } from '../../../models/logbook-event.interface'; +import { Observable, of, ReplaySubject } from 'rxjs'; import { catchError, map, startWith, switchMap } from 'rxjs/operators'; import { IngestReferentialService } from '../../../core/service/ingest-referential.service'; +import { IngestEventDetailComponent } from './ingest-event-detail/ingest-event-detail.component'; +import { AsyncPipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-information-tab', templateUrl: './ingest-information-tab.component.html', styleUrls: ['./ingest-information-tab.component.scss'], - standalone: false, + imports: [DataComponent, IngestEventDetailComponent, AsyncPipe, PipesModule, TranslatePipe], }) export class IngestInformationTabComponent implements OnChanges { private applicationService = inject(ApplicationService); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.spec.ts index c67de15c525..d0a2d5f0eec 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.spec.ts @@ -37,19 +37,13 @@ import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatMenuModule } from '@angular/material/menu'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { of } from 'rxjs'; -import { BASE_URL, LogbookService } from 'vitamui-library'; +import { LogbookService } from 'vitamui-library'; import { LogbookOperation } from '../../models/logbook-event.interface'; import { IngestService } from '../ingest.service'; import { IngestPreviewComponent } from './ingest-preview.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: string): string { return value; @@ -59,13 +53,18 @@ class MockTruncatePipe implements PipeTransform { describe('IngestPreviewComponent test:', () => { let component: IngestPreviewComponent; let fixture: ComponentFixture; - const logbookOperation: LogbookOperation = { id: 'aeeaaaaaaoem5lyiaa3lialtbt3j6haaaaaq', agIdExt: {}, events: [{}] }; + const logbookOperation: LogbookOperation = { + id: 'aeeaaaaaaoem5lyiaa3lialtbt3j6haaaaaq', + agIdExt: {}, + events: [ + { id: 'ev1', evParentId: null, evType: 'INGEST', evDateTime: '2020-01-01T00:00:00', evDetData: null, outcome: 'OK', outMessg: '' }, + ], + }; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [IngestPreviewComponent, MockTruncatePipe], schemas: [NO_ERRORS_SCHEMA], - imports: [MatMenuModule], + imports: [MatMenuModule, IngestPreviewComponent, MockTruncatePipe], providers: [ { provide: LogbookService, useValue: {} }, { @@ -75,9 +74,6 @@ describe('IngestPreviewComponent test:', () => { logbookOperationsReloaded: of([logbookOperation]), }, }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.ts index a11082a2a26..4b341ae9d7b 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.component.ts @@ -34,19 +34,40 @@ * 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, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { first } from 'rxjs/operators'; -import { LogbookService } from 'vitamui-library'; -import { IngestStatus } from '../../models/logbook-event.interface'; +import { LogbookService, PipesModule, TooltipDirective, VitamuiMenuButtonComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import type { LogbookOperation } from '../../models/logbook-event.interface'; -import { ingestStatus, ingestStatusVisualColor } from '../../models/logbook-event.interface'; +import { IngestStatus, ingestStatus, ingestStatusVisualColor } from '../../models/logbook-event.interface'; import { IngestService } from '../ingest.service'; +import { MatMenuItem } from '@angular/material/menu'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { IngestInformationTabComponent } from './ingest-information-tab/ingest-information-tab.component'; +import { IngestErrorsDetailsTabComponent } from './ingest-errors-details-tab/ingest-errors-details-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-ingest-preview', templateUrl: './ingest-preview.component.html', styleUrls: ['./ingest-preview.component.scss'], - standalone: false, + imports: [ + VitamuiMenuButtonComponent, + MatMenuItem, + TooltipDirective, + MatTabGroup, + MatTab, + IngestInformationTabComponent, + IngestErrorsDetailsTabComponent, + PipesModule, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class IngestPreviewComponent implements OnInit, OnChanges { private logbookService = inject(LogbookService); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.module.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.module.ts deleted file mode 100644 index 8fef3ca5dd2..00000000000 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest-preview/ingest-preview.module.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatTabsModule } from '@angular/material/tabs'; -import { MatTreeModule } from '@angular/material/tree'; -import { RouterModule } from '@angular/router'; - -import { VitamUICommonModule } from 'vitamui-library'; -import { IngestErrorsDetailsTabComponent } from './ingest-errors-details-tab/ingest-errors-details-tab.component'; -import { EventDisplayComponent } from './ingest-information-tab/ingest-event-detail/event-display/event-display.component'; -import { IngestEventDetailComponent } from './ingest-information-tab/ingest-event-detail/ingest-event-detail.component'; -import { IngestInformationTabComponent } from './ingest-information-tab/ingest-information-tab.component'; -import { IngestPreviewComponent } from './ingest-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [ - IngestPreviewComponent, - IngestInformationTabComponent, - IngestEventDetailComponent, - EventDisplayComponent, - IngestErrorsDetailsTabComponent, - ], - imports: [ - CommonModule, - RouterModule, - VitamUICommonModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - MatTreeModule, - TranslatePipe, - ], - exports: [IngestPreviewComponent, IngestInformationTabComponent, IngestEventDetailComponent, EventDisplayComponent], - schemas: [CUSTOM_ELEMENTS_SCHEMA], -}) -export class IngestPreviewModule {} diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.spec.ts index 3c8b9f1daef..2e65bcc6b17 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.spec.ts @@ -38,9 +38,7 @@ import type { Mock } from 'vitest'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDatepickerModule } from '@angular/material/datepicker'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { IngestComponent } from './ingest.component'; @@ -58,7 +56,7 @@ import { IngestService } from './ingest.service'; @Component({ selector: 'app-ingest-list', template: '', - standalone: false, + imports: [MatDatepickerModule, MatMenuModule, MatSidenavModule, VitamUICommonTestModule], }) export class IngestListStubComponent { emitOrderChange() {} @@ -88,15 +86,12 @@ describe('IngestComponent test:', () => { MatMenuModule, MatSidenavModule, InjectorModule, - RouterTestingModule, VitamUICommonTestModule, - BrowserAnimationsModule, LoggerModule.forRoot(), - RouterTestingModule, - NoopAnimationsModule, SearchBarComponent, + IngestComponent, + IngestListStubComponent, ], - declarations: [IngestComponent, IngestListStubComponent], providers: [ FormBuilder, { provide: MatDialog, useValue: matDialogSpy }, @@ -104,7 +99,11 @@ describe('IngestComponent test:', () => { { provide: UploadService, useValue: uploadServiceSpy }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'INGEST_MANAGEMENT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'INGEST_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'INGEST_MANAGEMENT_APP' } }, + }, }, { provide: environment, useValue: environment }, ], diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.ts index a1aea50a786..b404949210f 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.component.ts @@ -35,22 +35,54 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, HostListener, inject, OnInit, viewChild } from '@angular/core'; -import { FormBuilder } from '@angular/forms'; +import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { AdminUserProfile, Direction, GlobalEventService, SearchBarComponent, SidenavPage } from 'vitamui-library'; +import { + AdminUserProfile, + DatepickerComponent, + Direction, + SearchBarComponent, + SidenavPage, + TooltipDirective, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { IngestList } from '../core/common/ingest-list'; import { IngestType } from '../core/common/ingest-type.enum'; import { UploadComponent } from '../core/common/upload.component'; import { UploadService } from '../core/common/upload.service'; import { LogbookOperation } from '../models/logbook-event.interface'; import { IngestListComponent } from './ingest-list/ingest-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { IngestPreviewComponent } from './ingest-preview/ingest-preview.component'; +import { NgStyle } from '@angular/common'; +import { MatMenuItem } from '@angular/material/menu'; +import { UploadTrackingComponent } from '../shared/upload-tracking/upload-tracking.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest', templateUrl: './ingest.component.html', styleUrls: ['./ingest.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + IngestPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + TooltipDirective, + NgStyle, + VitamuiMenuButtonComponent, + MatMenuItem, + ReactiveFormsModule, + DatepickerComponent, + UploadTrackingComponent, + IngestListComponent, + TranslatePipe, + ], }) export class IngestComponent extends SidenavPage implements OnInit { private readonly route = inject(ActivatedRoute); @@ -72,12 +104,6 @@ export class IngestComponent extends SidenavPage implements On ingestList: IngestList = new IngestList(); ingestThatHasChanged: LogbookOperation | null = null; - constructor() { - const globalEventService = inject(GlobalEventService); - const route = inject(ActivatedRoute); - super(route, globalEventService); - } - ngOnInit(): void { this.initTenantFromRoute(); this.initDateRangeForm(); diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.module.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.module.ts index 144f0a707b9..cc4180ddea2 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.module.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.module.ts @@ -43,10 +43,6 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; import { VitamUICommonModule } from 'vitamui-library'; -import { UploadModule } from '../core/common/upload.module'; -import { UploadTrackingModule } from '../shared/upload-tracking/upload-tracking.module'; -import { IngestListModule } from './ingest-list/ingest-list.module'; -import { IngestPreviewModule } from './ingest-preview/ingest-preview.module'; import { IngestRoutingModule } from './ingest-routing.module'; import { IngestComponent } from './ingest.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -54,19 +50,15 @@ import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ imports: [ CommonModule, - IngestListModule, - IngestPreviewModule, IngestRoutingModule, MatDatepickerModule, MatDialogModule, MatMenuModule, MatSidenavModule, ReactiveFormsModule, - UploadModule, - UploadTrackingModule, VitamUICommonModule, TranslatePipe, + IngestComponent, ], - declarations: [IngestComponent], }) export class IngestModule {} diff --git a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.service.ts b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.service.ts index 0c8b4739b95..4e62c848a84 100644 --- a/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.service.ts +++ b/ui/ui-frontend/projects/ingest/src/app/ingest/ingest.service.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { IngestApiService } from '../core/api/ingest-api.service'; diff --git a/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.spec.ts b/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.spec.ts index 99ede0d20af..932efb3c705 100644 --- a/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.spec.ts +++ b/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.spec.ts @@ -38,7 +38,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; import { LoggerModule } from 'vitamui-library'; import { IngestList } from '../../core/common/ingest-list'; @@ -55,8 +54,7 @@ describe('UploadTrackingComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [MatProgressBarModule, NoopAnimationsModule, LoggerModule.forRoot()], - declarations: [UploadTrackingComponent], + imports: [MatProgressBarModule, LoggerModule.forRoot(), UploadTrackingComponent], providers: [FormBuilder, { provide: UploadService, useValue: UploadServiceSpy }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.ts b/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.ts index a5af38b7178..274f32f11a6 100644 --- a/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.ts +++ b/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.component.ts @@ -37,12 +37,16 @@ import { Component, inject } from '@angular/core'; import { IngestList } from '../../core/common/ingest-list'; import { UploadService } from '../../core/common/upload.service'; +import { MatProgressBar } from '@angular/material/progress-bar'; +import { DecimalPipe, KeyValuePipe } from '@angular/common'; +import { PipesModule } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-upload-tracking', templateUrl: './upload-tracking.component.html', styleUrls: ['./upload-tracking.component.scss'], - standalone: false, + imports: [MatProgressBar, DecimalPipe, KeyValuePipe, PipesModule, TranslatePipe], }) export class UploadTrackingComponent { private uploadSipService = inject(UploadService); diff --git a/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.module.ts b/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.module.ts deleted file mode 100644 index 4c21f18019a..00000000000 --- a/ui/ui-frontend/projects/ingest/src/app/shared/upload-tracking/upload-tracking.module.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { PipesModule, VitamUICommonModule } from 'vitamui-library'; -import { UploadTrackingComponent } from './upload-tracking.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - PipesModule, - ReactiveFormsModule, - VitamUICommonModule, - TranslatePipe, - ], - - declarations: [UploadTrackingComponent], - exports: [UploadTrackingComponent], -}) -export class UploadTrackingModule {} diff --git a/ui/ui-frontend/projects/ingest/src/main.ts b/ui/ui-frontend/projects/ingest/src/main.ts index a76b446c356..bbf8ccfa738 100644 --- a/ui/ui-frontend/projects/ingest/src/main.ts +++ b/ui/ui-frontend/projects/ingest/src/main.ts @@ -34,16 +34,53 @@ * 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 { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowser } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom, LOCALE_ID } from '@angular/core'; +import { bootstrapApplication, BrowserModule, Title } from '@angular/platform-browser'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import { AuthenticationModule, BytesPipe, provideI18n, VitamUICommonModule, VitamUILibraryModule, WINDOW_LOCATION } from 'vitamui-library'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { DatePipe } from '@angular/common'; +import { CoreModule } from './app/core/core.module'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { AppRoutingModule } from './app/app-routing.module'; +import { IngestModule } from './app/ingest/ingest.module'; +import { HoldingFillingSchemeModule } from './app/holding-filling-scheme/holding-filling-scheme.module'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { AppComponent } from './app/app.component'; if (environment.production) { enableProdMode(); } -platformBrowser() - .bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }) - .catch((err) => console.log(err)); +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom( + AuthenticationModule.forRoot(), + CoreModule, + BrowserAnimationsModule, + BrowserModule, + VitamUICommonModule.forRoot(), + AppRoutingModule, + IngestModule, + HoldingFillingSchemeModule, + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: environment.production, + // Register the ServiceWorker as soon as the application is stable + // or after 30 seconds (whichever comes first). + registrationStrategy: 'registerWhenStable:30000', + }), + VitamUILibraryModule, // For Material tokens + ), + provideI18n(), + provideNativeDateAdapter(), + Title, + { provide: LOCALE_ID, useValue: 'fr' }, + { + provide: WINDOW_LOCATION, + useValue: window.location, + }, + DatePipe, + BytesPipe, + ], +}).catch((err) => console.log(err)); diff --git a/ui/ui-frontend/projects/pastis/src/app/app.component.spec.ts b/ui/ui-frontend/projects/pastis/src/app/app.component.spec.ts index 4f4bc5ccacd..c8a4c4d487a 100644 --- a/ui/ui-frontend/projects/pastis/src/app/app.component.spec.ts +++ b/ui/ui-frontend/projects/pastis/src/app/app.component.spec.ts @@ -37,7 +37,6 @@ import { Component } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Router } from '@angular/router'; import { of } from 'rxjs'; import { AuthService, StartupService } from 'vitamui-library'; @@ -61,8 +60,7 @@ describe('AppComponent', () => { beforeEach(async () => { const startupServiceStub = { configurationLoaded: () => true, printConfiguration: () => {} }; await TestBed.configureTestingModule({ - imports: [MatSidenavModule, NoopAnimationsModule, SubrogationBannerStubComponent, RouterOutletStubComponent], - declarations: [AppComponent], + imports: [MatSidenavModule, SubrogationBannerStubComponent, RouterOutletStubComponent, AppComponent], providers: [ { provide: StartupService, useValue: startupServiceStub }, { provide: AuthService, useValue: { userLoaded: of(null) } }, diff --git a/ui/ui-frontend/projects/pastis/src/app/app.component.ts b/ui/ui-frontend/projects/pastis/src/app/app.component.ts index be41b4b9407..5b5ccf18fa8 100644 --- a/ui/ui-frontend/projects/pastis/src/app/app.component.ts +++ b/ui/ui-frontend/projects/pastis/src/app/app.component.ts @@ -36,12 +36,15 @@ */ import { Component } from '@angular/core'; import { environment } from '../environments/environment'; +import { FooterComponent, HeaderModule, SubrogationModule, VitamuiBodyComponent } from 'vitamui-library'; +import { MatToolbar } from '@angular/material/toolbar'; +import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], - standalone: false, + imports: [HeaderModule, MatToolbar, VitamuiBodyComponent, RouterOutlet, FooterComponent, SubrogationModule], }) export class AppComponent { title = 'Pastis Application'; diff --git a/ui/ui-frontend/projects/pastis/src/app/app.module.ts b/ui/ui-frontend/projects/pastis/src/app/app.module.ts index 90b36c80e16..519b561e9e5 100644 --- a/ui/ui-frontend/projects/pastis/src/app/app.module.ts +++ b/ui/ui-frontend/projects/pastis/src/app/app.module.ts @@ -34,79 +34,12 @@ * 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 { DatePipe, registerLocaleData } from '@angular/common'; +import { registerLocaleData } from '@angular/common'; import { default as localeFr } from '@angular/common/locales/fr'; -import { inject, LOCALE_ID, NgModule, provideAppInitializer } from '@angular/core'; -import { MatToolbarModule } from '@angular/material/toolbar'; -import { BrowserModule, Title } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { - AuthenticationModule, - BASE_URL, - ENVIRONMENT, - InjectorModule, - LoggerModule, - provideI18n, - StartupService, - ThemeService, - VitamUICommonModule, - WINDOW_LOCATION, -} from 'vitamui-library'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; import { PastisConfiguration } from './core/classes/pastis-configuration'; -import { NoAuthenticationModule } from './standalone/no-authentication.module'; -import { StandaloneStartupService } from './standalone/standalone-startup.service'; -import { StandaloneThemeService } from './standalone/standalone-theme.service'; -import { provideNativeDateAdapter } from '@angular/material/core'; export function PastisConfigurationFactory(appConfig: PastisConfiguration) { return () => appConfig.initConfiguration(); } registerLocaleData(localeFr, 'fr'); - -const startupServiceClass = environment.standalone ? StandaloneStartupService : StartupService; -const themeServiceClass = environment.standalone ? StandaloneThemeService : ThemeService; -const authenticationModuleClass = environment.standalone ? NoAuthenticationModule : AuthenticationModule.forRoot(); - -@NgModule({ - declarations: [AppComponent], - imports: [ - authenticationModuleClass, - InjectorModule, - LoggerModule.forRoot(), - BrowserAnimationsModule, - BrowserModule, - VitamUICommonModule.forRoot(), - AppRoutingModule, - MatToolbarModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000', - }), - ], - providers: [ - provideI18n(), - provideNativeDateAdapter(), - Title, - { provide: LOCALE_ID, useValue: 'fr' }, - { provide: WINDOW_LOCATION, useValue: window.location }, - PastisConfiguration, - { provide: BASE_URL, useValue: './pastis-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideAppInitializer(() => { - const initializerFn = PastisConfigurationFactory(inject(PastisConfiguration)); - return initializerFn(); - }), - { provide: StartupService, useClass: startupServiceClass }, - { provide: ThemeService, useClass: themeServiceClass }, - DatePipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/ui/ui-frontend/projects/pastis/src/app/core/core.module.ts b/ui/ui-frontend/projects/pastis/src/app/core/core.module.ts index 7bfad6b7b1d..913f60adae1 100644 --- a/ui/ui-frontend/projects/pastis/src/app/core/core.module.ts +++ b/ui/ui-frontend/projects/pastis/src/app/core/core.module.ts @@ -36,15 +36,13 @@ */ import { CommonModule } from '@angular/common'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NgModule, inject } from '@angular/core'; +import { inject, NgModule } from '@angular/core'; import { throwIfAlreadyLoaded, VitamUICommonModule } from 'vitamui-library'; -import { PastisMaterialModule } from '../material.module'; -import { SharedModule } from '../shared/shared.module'; @NgModule({ declarations: [], exports: [VitamUICommonModule], - imports: [CommonModule, VitamUICommonModule, PastisMaterialModule, SharedModule], + imports: [CommonModule, VitamUICommonModule], providers: [provideHttpClient(withInterceptorsFromDi())], }) export class CoreModule { diff --git a/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts b/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts index d43df9aaa78..f91bd5b9ef2 100644 --- a/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts +++ b/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts @@ -71,7 +71,7 @@ same conditions as regards security. 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 { Injectable, OnDestroy, inject } from '@angular/core'; +import { Injectable, OnDestroy, inject, signal } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { BehaviorSubject, finalize, mergeMap, Observable, Subscription } from 'rxjs'; import { FileNode, TypeConstants } from '../../models/file-node'; @@ -102,7 +102,7 @@ export class FileService implements OnDestroy { nodeChange = new BehaviorSubject(null); filteredNode = new BehaviorSubject(null); - currentTreeLoaded = false; + currentTreeLoaded = signal(false); parentNodeMap = new Map(); private _profileServiceGetProfileSubscription: Subscription; @@ -120,7 +120,7 @@ export class FileService implements OnDestroy { this.profileService.profileId = profileResponse.id; this.currentTree.next([profileResponse.profile]); - this.currentTreeLoaded = true; + this.currentTreeLoaded.set(true); if (profileResponse.notice) { this.notice.next(profileResponse.notice); this.setNotice(false); @@ -176,7 +176,7 @@ export class FileService implements OnDestroy { node.external = node.sedaData.external; } - this.linkFileNodeToSedaData(node, node.children); + this.linkFileNodeToSedaData(node, node.children ?? []); }); } @@ -205,10 +205,13 @@ export class FileService implements OnDestroy { } findChildById(nodeId: number, node: FileNode): FileNode { + if (!node) { + return undefined; + } if (nodeId === node.id) { return node; } - for (const child of node.children) { + for (const child of node.children ?? []) { if (child.id === nodeId) { return child; } @@ -263,7 +266,7 @@ export class FileService implements OnDestroy { return fileTree; } - for (const child of fileTree.children) { + for (const child of fileTree.children ?? []) { const result = this.getFileNodeByPredicate(child, predicate); if (result) { return result; diff --git a/ui/ui-frontend/projects/pastis/src/app/main/main.component.html b/ui/ui-frontend/projects/pastis/src/app/main/main.component.html index 029f66b8c47..3d77048f89a 100644 --- a/ui/ui-frontend/projects/pastis/src/app/main/main.component.html +++ b/ui/ui-frontend/projects/pastis/src/app/main/main.component.html @@ -1,10 +1,10 @@ -@if (pending) { +@if (pending()) {
} -@if (!opened) { +@if (!opened()) { @@ -15,11 +15,12 @@ #sidenav (closed)="events.push('close!')" (opened)="events.push('open!')" - [(opened)]="opened" + [opened]="opened()" + (openedChange)="openedChanged($event)" class="pastis-side-nav" mode="side" > - @if (fileService.currentTreeLoaded) { + @if (fileService.currentTreeLoaded()) { } diff --git a/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts b/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts index 14522811809..45332aedb1e 100644 --- a/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts +++ b/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts @@ -72,7 +72,8 @@ 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 { CdkTextareaAutosize } from '@angular/cdk/text-field'; -import { Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; import { ActivatedRoute, Router } from '@angular/router'; import { finalize, map, Subscription, switchMap } from 'rxjs'; import { FileService } from '../core/services/file.service'; @@ -86,12 +87,26 @@ import { SpinnerOverlayService } from 'vitamui-library'; import { tap } from 'rxjs/operators'; import { ProfileType } from '../models/profile-type.enum'; import { ProfileVersion } from '../models/profile-version.enum'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { MatButton } from '@angular/material/button'; +import { MatIcon } from '@angular/material/icon'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { FileTreeMetadataComponent } from '../profile/edit-profile/file-tree-metadata/file-tree-metadata.component'; @Component({ selector: 'app-home', templateUrl: './main.component.html', styleUrls: ['./main.component.scss'], - standalone: false, + imports: [ + MatProgressSpinner, + MatButton, + MatIcon, + MatSidenavContainer, + MatSidenav, + EditProfileComponent, + MatSidenavContent, + FileTreeMetadataComponent, + ], }) export class MainComponent implements OnInit, OnDestroy { fileService = inject(FileService); @@ -107,9 +122,8 @@ export class MainComponent implements OnInit, OnDestroy { @ViewChild(EditProfileComponent) editProfileComponent: EditProfileComponent; - opened: boolean; - pending: boolean; - pendingSub: Subscription; + opened = toSignal(this.sideNavService.isOpened, { initialValue: true }); + pending = toSignal(this.sideNavService.isPending, { initialValue: false }); events: string[] = []; uploadedProfileResponse: ProfileResponse; @@ -119,18 +133,12 @@ export class MainComponent implements OnInit, OnDestroy { private _profileLoadingSubscription: Subscription; constructor() { - this.sideNavService.isOpened.subscribe((status) => { - this.opened = status; - }); - this.pendingSub = this.sideNavService.isPending.subscribe((status) => { - this.pending = status; - }); const navigation = this.router.getCurrentNavigation(); this.uploadedProfileByFile = navigation?.extras.state?.['payload']; } ngOnInit() { - this.fileService.currentTreeLoaded = false; + this.fileService.currentTreeLoaded.set(false); this._routeParamsSubscription = this.route.params.subscribe((params) => { const profileId = params['id']; @@ -153,14 +161,21 @@ export class MainComponent implements OnInit, OnDestroy { }); } }); - this.opened = true; + this.sideNavService.show(); } openSideNav() { - this.opened = true; this.sideNavService.show(); } + openedChanged(opened: boolean) { + if (opened) { + this.sideNavService.show(); + } else { + this.sideNavService.hide(); + } + } + insertionItem($event: FileNodeInsertParams) { const names: string[] = $event.elementsToAdd.map((e) => e.name); this.editProfileComponent.fileTreeComponent.insertItem($event.node, names); @@ -191,7 +206,6 @@ export class MainComponent implements OnInit, OnDestroy { if (this._profileLoadingSubscription != null) { this._profileLoadingSubscription.unsubscribe(); } - if (this.pendingSub) this.pendingSub.unsubscribe(); } private loadProfileById(profileId: string) { diff --git a/ui/ui-frontend/projects/pastis/src/app/material.module.ts b/ui/ui-frontend/projects/pastis/src/app/material.module.ts deleted file mode 100644 index 8c76846f682..00000000000 --- a/ui/ui-frontend/projects/pastis/src/app/material.module.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { NgModule } from '@angular/core'; - -import { MatButtonModule } from '@angular/material/button'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatCardModule } from '@angular/material/card'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatOptionModule, MatRippleModule } from '@angular/material/core'; -import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatDividerModule } from '@angular/material/divider'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatGridListModule } from '@angular/material/grid-list'; -import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; -import { MatListModule } from '@angular/material/list'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatRadioModule } from '@angular/material/radio'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatSortModule } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; -import { MatTabsModule } from '@angular/material/tabs'; -import { MatToolbarModule } from '@angular/material/toolbar'; -import { MatTreeModule } from '@angular/material/tree'; - -@NgModule({ - imports: [ - MatButtonModule, - MatToolbarModule, - MatProgressSpinnerModule, - MatGridListModule, - MatSidenavModule, - MatCardModule, - MatDatepickerModule, - MatSelectModule, - MatOptionModule, - MatCheckboxModule, - MatRadioModule, - MatTreeModule, - MatTableModule, - MatSortModule, - MatProgressBarModule, - MatMenuModule, - MatRippleModule, - MatTabsModule, - MatFormFieldModule, - MatInputModule, - MatListModule, - MatIconModule, - MatDialogModule, - MatDividerModule, - MatButtonToggleModule, - ], - exports: [ - MatButtonModule, - MatMenuModule, - MatToolbarModule, - MatCardModule, - MatProgressSpinnerModule, - MatGridListModule, - MatSidenavModule, - MatTabsModule, - MatFormFieldModule, - MatInputModule, - MatListModule, - MatDatepickerModule, - MatSelectModule, - MatOptionModule, - MatCheckboxModule, - MatRadioModule, - MatTreeModule, - MatDialogModule, - MatTableModule, - MatSortModule, - MatProgressBarModule, - MatRippleModule, - MatIconModule, - MatDividerModule, - MatButtonToggleModule, - ], -}) -export class PastisMaterialModule {} diff --git a/ui/ui-frontend/projects/pastis/src/app/pastis/pastis.module.ts b/ui/ui-frontend/projects/pastis/src/app/pastis/pastis.module.ts index 8a9585e521b..698cbe10566 100644 --- a/ui/ui-frontend/projects/pastis/src/app/pastis/pastis.module.ts +++ b/ui/ui-frontend/projects/pastis/src/app/pastis/pastis.module.ts @@ -57,7 +57,7 @@ import { MainComponent } from '../main/main.component'; import { FileTreeModule } from '../profile/edit-profile/file-tree/file-tree.module'; import { ProfileModule } from '../profile/profile.module'; import { SedaVisualizerComponent } from '../seda-visualizer/seda-visualizer.component'; -import { SharedModule } from '../shared/shared.module'; + import { UserActionAddMetadataComponent } from '../user-actions/add-metadata/add-metadata.component'; import { UserActionRemoveMetadataComponent } from '../user-actions/remove-metadata/remove-metadata.component'; import { UserActionsModule } from '../user-actions/user-actions.module'; @@ -68,7 +68,6 @@ import { TranslatePipe } from '@ngx-translate/core'; imports: [ CoreModule, ProfileModule, - SharedModule, UserActionsModule, FileTreeModule, CommonModule, @@ -93,8 +92,11 @@ import { TranslatePipe } from '@ngx-translate/core'; MatIconModule, MatTabsModule, TranslatePipe, + MainComponent, + UserActionRemoveMetadataComponent, + UserActionAddMetadataComponent, + SedaVisualizerComponent, ], - declarations: [MainComponent, UserActionRemoveMetadataComponent, UserActionAddMetadataComponent, SedaVisualizerComponent], exports: [], schemas: [CUSTOM_ELEMENTS_SCHEMA], }) diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.spec.ts b/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.spec.ts index 1c223563cfc..1b972f272ce 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.spec.ts +++ b/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.spec.ts @@ -44,7 +44,6 @@ import { BehaviorSubject, of } from 'rxjs'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; import { ProfileType } from '../../models/profile-type.enum'; import { MatRadioModule } from '@angular/material/radio'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('CreateProfilNoticeComponent', () => { let component: CreateProfilNoticeComponent; @@ -77,15 +76,7 @@ describe('CreateProfilNoticeComponent', () => { mockAppService.isApplicationExternalIdentifierEnabled.mockReturnValue(externalIdSubject.asObservable()); TestBed.configureTestingModule({ - imports: [ - ReactiveFormsModule, - MatRadioModule, - InputComponent, - SelectComponent, - SlideToggleComponent, - NoopAnimationsModule, - CreateProfilNoticeComponent, - ], + imports: [ReactiveFormsModule, MatRadioModule, InputComponent, SelectComponent, SlideToggleComponent, CreateProfilNoticeComponent], providers: [ FormBuilder, { provide: MatDialogRef, useValue: mockDialogRef }, diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.ts b/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.ts index 782213ec452..a167292b8df 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.ts +++ b/ui/ui-frontend/projects/pastis/src/app/profile/create-profil-notice/create-profil-notice.component.ts @@ -34,31 +34,32 @@ * 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, computed, effect, Injector, OnDestroy, OnInit, signal, inject } from '@angular/core'; +import { Component, computed, effect, inject, Injector, OnDestroy, OnInit, signal } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatDialogRef } from '@angular/material/dialog'; +import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { MatRadioModule } from '@angular/material/radio'; import { ApplicationService, MiscValidators, Option, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; import { ProfileType } from '../../models/profile-type.enum'; import { ProfileVersionOptions } from '../../models/profile-version.enum'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ProfileService } from '../../core/services/profile.service'; import { Subscription } from 'rxjs'; import { Notice } from '../../models/notice.model'; -import { PastisMaterialModule } from '../../material.module'; + import { PastisGenericPopupComponent } from '../../shared/pastis-generic-popup/pastis-generic-popup.component'; import { IdentifierExistsValidator } from '../../validators/IdentifierExistsValidator'; -import { TranslatePipe } from '@ngx-translate/core'; @Component({ imports: [ VitamUILibraryModule, ReactiveFormsModule, VitamUICommonModule, - PastisMaterialModule, PastisGenericPopupComponent, TranslatePipe, + MatDialogModule, + MatRadioModule, ], selector: 'app-create-profil-notice', templateUrl: './create-profil-notice.component.html', diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/create-profile/create-profile.component.ts b/ui/ui-frontend/projects/pastis/src/app/profile/create-profile/create-profile.component.ts index 113716db568..77b958838e4 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/create-profile/create-profile.component.ts +++ b/ui/ui-frontend/projects/pastis/src/app/profile/create-profile/create-profile.component.ts @@ -71,12 +71,16 @@ same conditions as regards security. 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, OnInit, inject } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { ProfileType } from '../../models/profile-type.enum'; import { ProfileVersion, ProfileVersionOptions } from '../../models/profile-version.enum'; import { PastisDialogData } from '../../shared/pastis-dialog/classes/pastis-dialog-data'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { DialogHeaderComponent, TooltipDirective } from 'vitamui-library'; +import { PastisGenericPopupComponent } from '../../shared/pastis-generic-popup/pastis-generic-popup.component'; +import { MatRadioButton, MatRadioGroup } from '@angular/material/radio'; +import { TranslatePipe } from '@ngx-translate/core'; export interface CreateProfileFormResult { profileType: ProfileType; @@ -88,7 +92,18 @@ export interface CreateProfileFormResult { selector: 'pastis-create-profile', templateUrl: './create-profile.component.html', styleUrls: ['./create-profile.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + MatDialogContent, + FormsModule, + ReactiveFormsModule, + PastisGenericPopupComponent, + TooltipDirective, + MatRadioGroup, + MatRadioButton, + MatDialogActions, + TranslatePipe, + ], }) export class CreateProfileComponent implements OnInit { private fb = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html index a6d8ab3d287..7e652e8d089 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html +++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html @@ -24,7 +24,7 @@
- @if (fileService.currentTreeLoaded) { + @if (fileService.currentTreeLoaded()) {
- @if (fileService.currentTreeLoaded) { + @if (fileService.currentTreeLoaded()) {
- @if (fileService.currentTreeLoaded) { + @if (fileService.currentTreeLoaded()) {
- @if (fileService.currentTreeLoaded) { + @if (fileService.currentTreeLoaded()) { nodes?.length > 0 && nodes.every((node) => Boolean(node)))) .subscribe((data) => { + // Refresh profile-dependent fields set asynchronously by FileService.updateTreeWithProfile. + // The currentTreeLoaded signal change triggers the zoneless change detection that renders them. + this.sedaVersionLabel = this.profileService.getSedaVersionLabel(); + this.isAUP = this.profileService.isMode(ProfileType.PUA); + this.selectedIndex = this.profileService.isMode(ProfileType.PA) ? 0 : 2; const [tree] = data; const nodeName = this.profileService.isMode(ProfileType.PA) ? this.rootTabMetadataName : tree.name; const node = this.fileService.getTree(nodeName); diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/attributes/attributes.component.ts b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/attributes/attributes.component.ts index e7a170eacc5..81ceadb2a11 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/attributes/attributes.component.ts +++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/attributes/attributes.component.ts @@ -71,10 +71,22 @@ same conditions as regards security. 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { MatCheckboxChange } from '@angular/material/checkbox'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { MatTableDataSource } from '@angular/material/table'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { + MatCell, + MatCellDef, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, + MatHeaderRow, + MatHeaderRowDef, + MatRow, + MatRowDef, + MatTable, + MatTableDataSource, +} from '@angular/material/table'; import { FileService } from 'projects/pastis/src/app/core/services/file.service'; import { PopupService } from 'projects/pastis/src/app/core/services/popup.service'; import { SedaService } from 'projects/pastis/src/app/core/services/seda.service'; @@ -85,13 +97,52 @@ import { AttributeData } from '../../../../models/edit-attribute-models'; import { CardinalityConstants, DataTypeConstants, FileNode, TypeConstants, ValueOrDataConstants } from '../../../../models/file-node'; import { SedaData } from '../../../../models/seda-data'; import { FileTreeMetadataService } from '../file-tree-metadata.service'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { CommonModule, NgClass, NgStyle } from '@angular/common'; +import { EditableTextareaComponent, TooltipDirective } from 'vitamui-library'; +import { MatOption, MatSelect, MatSelectModule } from '@angular/material/select'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; @Component({ // eslint-disable-next-line @angular-eslint/component-selector selector: 'pastis-edit-attributes', templateUrl: './attributes.component.html', styleUrls: ['./attributes.component.scss'], - standalone: false, + imports: [ + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + MatCheckbox, + MatCellDef, + MatCell, + FormsModule, + NgStyle, + NgClass, + TooltipDirective, + MatSelect, + MatOption, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow, + TranslatePipe, + CommonModule, + EditableTextareaComponent, + MatButtonToggleModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + MatSelectModule, + OverlayModule, + ReactiveFormsModule, + ], }) export class AttributesPopupComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html index 9c119ec9635..40b0e5f9941 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html +++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html @@ -16,9 +16,9 @@
- @if (breadcrumbDataMetadata) { + @if (breadcrumbDataMetadata()) { }
@@ -56,9 +56,9 @@
[searchbarPlaceholder]="'PROFILE.EDIT_PROFILE.FILE_TREE_METADATA.SEARCH_PLACEHOLDER' | translate" > - @if (checkElementType() && resolveButtonLabel(clickedNode) !== null) { + @if (checkElementType() && resolveButtonLabel(clickedNode()) !== null) { } @@ -67,7 +67,7 @@
@if (shouldLoadMetadataTable()) { - +
- @for (accessionRegisterDetail of dataSource; track accessionRegisterDetail) { + @for (accessionRegisterDetail of dataSource(); track accessionRegisterDetail) { @@ -120,15 +120,15 @@
@@ -76,8 +76,8 @@
{{ accessionRegisterDetail.endDate | dateTime: 'dd/MM/yyyy' }} {{ accessionRegisterDetail.obIdIn }}
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'ACCESSION_REGISTER.LIST.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && accessionRegistersService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && accessionRegistersService.canLoadMore && !pending()) {
{{ 'ACCESSION_REGISTER.LIST.LOAD_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.spec.ts index 5a171b43e5c..5ab29c32dc9 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.spec.ts @@ -34,7 +34,6 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @@ -43,7 +42,6 @@ import { Direction, InfiniteScrollTable, PageRequest, SearchService } from 'vita import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { AccessionRegistersService } from '../accession-register.service'; import { AccessionRegisterListComponent } from './accession-register-list.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('AccessionRegisterListComponent', () => { let fixture: ComponentFixture; @@ -77,14 +75,11 @@ describe('AccessionRegisterListComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [AccessionRegisterListComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [VitamUICommonTestModule, MatProgressSpinnerModule], + imports: [VitamUICommonTestModule, MatProgressSpinnerModule, AccessionRegisterListComponent], providers: [ { provide: AccessionRegistersService, useValue: accessionRegistersService }, { provide: SearchService, useValue: searchService }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); fixture = TestBed.createComponent(AccessionRegisterListComponent); diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.ts index 30b7301783f..24b263d00cd 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-list/accession-register-list.component.ts @@ -34,18 +34,46 @@ * 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, EventEmitter, Input, LOCALE_ID, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, LOCALE_ID, OnDestroy, OnInit, Output } from '@angular/core'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { withLatestFrom } from 'rxjs/operators'; -import { AccessionRegisterDetail, DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, OjectUtils, PageRequest } from 'vitamui-library'; +import { + AccessionRegisterDetail, + DEFAULT_PAGE_SIZE, + Direction, + InfiniteScrollDirective, + InfiniteScrollTable, + OjectUtils, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterDirective, + TableFilterSearchComponent, + TooltipDirective, +} from 'vitamui-library'; import { AccessionRegisterSearchDto } from '../../models/accession-register-export-csv.interface'; import { AccessionRegistersService } from '../accession-register.service'; +import { AsyncPipe, CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-accession-register-list', templateUrl: './accession-register-list.component.html', styleUrls: ['./accession-register-list.component.scss'], - standalone: false, + imports: [ + NgClass, + OrderByButtonComponent, + TableFilterDirective, + TableFilterSearchComponent, + TooltipDirective, + MatProgressSpinner, + AsyncPipe, + PipesModule, + TranslatePipe, + CommonModule, + InfiniteScrollDirective, + ], }) export class AccessionRegisterListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { accessionRegistersService: AccessionRegistersService; diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-detail/accession-register-detail.component.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-detail/accession-register-detail.component.ts index 23c6ed0b613..4e2cf34a6de 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-detail/accession-register-detail.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-detail/accession-register-detail.component.ts @@ -36,12 +36,15 @@ */ import { Component, Input, OnInit } from '@angular/core'; import type { AccessionRegisterDetail } from 'vitamui-library'; +import { DataComponent } from 'vitamui-library'; +import { DatePipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-accession-register-detail', templateUrl: './accession-register-detail.component.html', styleUrls: ['./accession-register-detail.component.scss'], - standalone: false, + imports: [DataComponent, DatePipe, TranslatePipe], }) export class AccessionRegisterDetailComponent implements OnInit { @Input() diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.spec.ts index 433dad21100..ffc4c5124c4 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.spec.ts @@ -76,8 +76,8 @@ describe('AccessionRegisterOperationsListComponent', () => { LoggerModule.forRoot(), MatIconModule, BrowserAnimationsModule, + AccessionRegisterOperationsListComponent, ], - declarations: [AccessionRegisterOperationsListComponent], providers: [], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.ts index 856ade47444..fb6750c0fee 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-operations-list/accession-register-operations-list.component.ts @@ -34,15 +34,24 @@ * 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, Input, OnChanges, SimpleChanges, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; -import { Direction, RegisterValueEventModel, RegisterValueEventType } from 'vitamui-library'; +import { Component, inject, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { + Direction, + OrderByButtonComponent, + RegisterValueEventModel, + RegisterValueEventType, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, +} from 'vitamui-library'; +import { DatePipe } from '@angular/common'; @Component({ selector: 'app-accession-register-operations-list', templateUrl: './accession-register-operations-list.component.html', styleUrls: ['./accession-register-operations-list.component.scss'], - standalone: false, + imports: [TableFilterDirective, TableFilterComponent, TableFilterOptionComponent, OrderByButtonComponent, DatePipe, TranslatePipe], }) export class AccessionRegisterOperationsListComponent implements OnChanges { private translateService = inject(TranslateService); diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.spec.ts index d1f6bda5a8d..212e537920c 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.spec.ts @@ -43,17 +43,8 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTreeModule } from '@angular/material/tree'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { - AccessionRegisterDetail, - BASE_URL, - ENVIRONMENT, - InjectorModule, - LoggerModule, - StartupService, - WINDOW_LOCATION, -} from 'vitamui-library'; +import { AccessionRegisterDetail, ENVIRONMENT, InjectorModule, LoggerModule, StartupService, WINDOW_LOCATION } from 'vitamui-library'; import { environment } from '../../../environments/environment.prod'; import { AccessionRegistersService } from '../accession-register.service'; import { AccessionRegisterPreviewComponent } from './accession-register-preview.component'; @@ -62,10 +53,7 @@ describe('AccessionRegisterPreviewComponent', () => { let component: AccessionRegisterPreviewComponent; let fixture: ComponentFixture; - @Pipe({ - name: 'truncate', - standalone: false, - }) + @Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -76,6 +64,7 @@ describe('AccessionRegisterPreviewComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' }), + snapshot: { data: { appId: 'ARCHIVE_SEARCH_MANAGEMENT_APP' } }, }; const AccessionRegistersServiceMock = { @@ -92,14 +81,13 @@ describe('AccessionRegisterPreviewComponent', () => { MatSidenavModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, MatIconModule, BrowserAnimationsModule, + AccessionRegisterPreviewComponent, + MockTruncatePipe, ], - declarations: [AccessionRegisterPreviewComponent, MockTruncatePipe], providers: [ { provide: AccessionRegistersService, useValue: AccessionRegistersServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: ENVIRONMENT, useValue: environment }, { provide: WINDOW_LOCATION, useValue: window.location }, diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.ts index 18d06dee65d..1aabaade505 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register-preview/accession-register-preview.component.ts @@ -35,13 +35,30 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import type { AccessionRegisterDetail } from 'vitamui-library'; +import { AccessionRegisterDetail, VitamuiSidenavHeaderComponent } from 'vitamui-library'; +import { AccessionRegisterDetailComponent } from './accession-register-detail/accession-register-detail.component'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { AccessionRegisterOperationsListComponent } from './accession-register-operations-list/accession-register-operations-list.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-accession-register-preview', templateUrl: './accession-register-preview.component.html', styleUrls: ['./accession-register-preview.component.scss'], - standalone: false, + imports: [ + AccessionRegisterDetailComponent, + MatTabGroup, + MatTab, + AccessionRegisterOperationsListComponent, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class AccessionRegisterPreviewComponent { @Input() diff --git a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register.component.ts b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register.component.ts index 0a45ca9d346..9675e749e42 100644 --- a/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/accession-register/accession-register.component.ts @@ -34,18 +34,44 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { AccessionRegisterDetail, ExternalParameters, ExternalParametersService, SidenavPage } from 'vitamui-library'; +import { + AccessionRegisterDetail, + ExternalParameters, + ExternalParametersService, + SidenavPage, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { AccessionRegistersService } from './accession-register.service'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { AsyncPipe, NgClass } from '@angular/common'; +import { AccessionRegisterPreviewComponent } from './accession-register-preview/accession-register-preview.component'; +import { AccessionRegisterAdvancedSearchComponent } from './accession-register-advanced-search/accession-register-advanced-search.component'; +import { AccessionRegisterFacetsComponent } from './accession-register-facets/accession-register-facets.component'; +import { AccessionRegisterListComponent } from './accession-register-list/accession-register-list.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-accession-register', templateUrl: './accession-register.component.html', styleUrls: ['./accession-register.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + NgClass, + AccessionRegisterPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + AccessionRegisterAdvancedSearchComponent, + AccessionRegisterFacetsComponent, + AccessionRegisterListComponent, + AsyncPipe, + TranslatePipe, + ], }) export class AccessionRegisterComponent extends SidenavPage implements OnInit, OnDestroy { private accessionRegistersService: AccessionRegistersService; @@ -58,9 +84,8 @@ export class AccessionRegisterComponent extends SidenavPage { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'DSL_APP' }), + snapshot: { data: { appId: 'DSL_APP' } }, }; await TestBed.configureTestingModule({ @@ -82,12 +82,11 @@ describe('AdminDslComponent', () => { InjectorModule, LoggerModule.forRoot(), MatSelectModule, - NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule, VitamUILibraryModule, + AdminDslComponent, ], - declarations: [AdminDslComponent], providers: [ FormBuilder, { provide: Router, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.component.ts b/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.component.ts index 184ee890994..50700255723 100644 --- a/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.component.ts @@ -36,21 +36,39 @@ */ import { Clipboard } from '@angular/cdk/clipboard'; import { Component, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; -import { AppRootComponent, DslQueryType, Option, SnackBarService, AccessContractService } from 'vitamui-library'; +import { + AccessContractService, + DslQueryType, + InputComponent, + Option, + SelectComponent, + SnackBarService, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { AdminDslService } from './admin-dsl.service'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; @Component({ selector: 'app-admin-dsl', templateUrl: './admin-dsl.component.html', styleUrls: ['./admin-dsl.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + ReactiveFormsModule, + SelectComponent, + InputComponent, + TranslatePipe, + ], }) -export class AdminDslComponent extends AppRootComponent { - private route: ActivatedRoute; +export class AdminDslComponent { + private route = inject(ActivatedRoute); private adminDslService = inject(AdminDslService); private snackBarService = inject(SnackBarService); private accessContractService = inject(AccessContractService); @@ -67,11 +85,6 @@ export class AdminDslComponent extends AppRootComponent { })); constructor() { - const route = inject(ActivatedRoute); - - super(route); - this.route = route; - this.route.params.subscribe((params) => { if (params['tenantIdentifier']) { this.tenantId = params['tenantIdentifier']; diff --git a/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.module.ts b/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.module.ts index 9b5129dcfe3..7c5756da1e5 100644 --- a/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.module.ts @@ -68,7 +68,7 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, VitamUILibraryModule, TranslatePipe, + AdminDslComponent, ], - declarations: [AdminDslComponent], }) export class AdminDslModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.service.ts b/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.service.ts index 8b48834a1e1..1a304cc006c 100644 --- a/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/admin-dsl/admin-dsl.service.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpErrorResponse, HttpHeaders } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { of } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { SearchUnitApiService, VitamuiHttpHeaders } from 'vitamui-library'; diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.spec.ts index 169e07aa67e..bc535b6c324 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.spec.ts @@ -44,9 +44,8 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; -import { ConfirmDialogService, AgencyService } from 'vitamui-library'; +import { AgencyService, ConfirmDialogService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { AgencyCreateComponent } from './agency-create.component'; import { AgencyCreateValidators } from './agency-create.validators'; @@ -61,7 +60,15 @@ import { AgencyCreateValidators } from './agency-create.validators'; multi: true, }, ], - standalone: false, + imports: [ + ReactiveFormsModule, + MatFormFieldModule, + MatSelectModule, + MatButtonToggleModule, + MatProgressBarModule, + MatProgressSpinnerModule, + VitamUICommonTestModule, + ], }) class DomainInputStubComponent implements ControlValueAccessor { @Input() @@ -130,11 +137,11 @@ describe('AgencyCreateComponent', () => { MatSelectModule, MatButtonToggleModule, MatProgressBarModule, - NoopAnimationsModule, MatProgressSpinnerModule, VitamUICommonTestModule, + AgencyCreateComponent, + DomainInputStubComponent, ], - declarations: [AgencyCreateComponent, DomainInputStubComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.ts index c607d02b33b..193edae4ff7 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.component.ts @@ -34,17 +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, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { Agency, ConfirmDialogService, AgencyService } from 'vitamui-library'; +import { Component, inject, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { Agency, AgencyService, ConfirmDialogService, DialogHeaderComponent, InputComponent } from 'vitamui-library'; import { AgencyCreateValidators } from './agency-create.validators'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-agency-create', templateUrl: './agency-create.component.html', styleUrls: ['./agency-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + MatDialogContent, + ReactiveFormsModule, + InputComponent, + MatProgressSpinner, + MatDialogActions, + TranslatePipe, + ], }) export class AgencyCreateComponent implements OnInit { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.module.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.module.ts deleted file mode 100644 index 1851dc389a2..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-create/agency-create.module.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../../../../identity/src/app/shared/shared.module'; -import { AgencyCreateComponent } from './agency-create.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - SharedModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - MatProgressSpinnerModule, - MatDialogModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [AgencyCreateComponent], -}) -export class AgencyCreateModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.html b/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.html index d9ba5cf1765..3af210d8af9 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.html @@ -21,7 +21,7 @@
- @for (agency of dataSource; track agency) { + @for (agency of dataSource(); track agency) {
@@ -47,12 +47,12 @@
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
}
diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.spec.ts index a72af86d863..a2950474359 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.spec.ts @@ -34,28 +34,19 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { ActivatedRoute } from '@angular/router'; -import { TranslateLoader } from '@ngx-translate/core'; import { EMPTY, of } from 'rxjs'; -import { AgencyService, AuthService, BASE_URL, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { AgencyService, AuthService, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { AgencyListComponent } from './agency-list.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const authServiceMock = { user: { proofTenantIdentifier: '1' } }; const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), paramMap: EMPTY }; -class FakeLoader implements TranslateLoader { - getTranslation() { - return of({}); - } -} - describe('AgencyListComponent', () => { let component: AgencyListComponent; let fixture: ComponentFixture; @@ -65,13 +56,10 @@ describe('AgencyListComponent', () => { schemas: [CUSTOM_ELEMENTS_SCHEMA], imports: [LoggerModule.forRoot(), VitamUICommonTestModule, MatProgressSpinnerModule], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: WINDOW_LOCATION, useValue: {} }, { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: AuthService, useValue: authServiceMock }, { provide: MatDialog, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.ts index 4eb398dbd6f..b8d69c3af6a 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-list/agency-list.component.ts @@ -39,8 +39,9 @@ import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { merge, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, map, takeUntil, tap } from 'rxjs/operators'; -import type { AdminUserProfile, Agency } from 'vitamui-library'; import { + AdminUserProfile, + Agency, AgencyService, ApplicationId, DEFAULT_PAGE_SIZE, @@ -51,9 +52,7 @@ import { SecurityService, VitamUICommonModule, } from 'vitamui-library'; -import { AgencyCreateModule } from '../agency-create/agency-create.module'; -import { ImportDialogModule } from '../../shared/import-dialog/import-dialog.module'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { TranslatePipe } from '@ngx-translate/core'; @@ -64,7 +63,7 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-agency-list', templateUrl: './agency-list.component.html', styleUrls: ['./agency-list.component.scss'], - imports: [AgencyCreateModule, ImportDialogModule, MatProgressSpinnerModule, MatSidenavModule, VitamUICommonModule, TranslatePipe], + imports: [MatProgressSpinnerModule, MatSidenavModule, VitamUICommonModule, TranslatePipe], }) export class AgencyListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { agencyService: AgencyService; @@ -168,10 +167,14 @@ export class AgencyListComponent extends InfiniteScrollTable implements private replaceUpdatedAgency(): void { this.agencyService.updated.pipe(takeUntil(this.destroyer$)).subscribe((updatedAgency: Agency) => { - const index = this.dataSource.findIndex((item: Agency) => item.id === updatedAgency.id); - if (index !== -1) { - this.dataSource[index] = updatedAgency; - } + this.dataSource.update((agencies) => { + const list = [...(agencies ?? [])]; + const index = list.findIndex((item: Agency) => item.id === updatedAgency.id); + if (index !== -1) { + list[index] = updatedAgency; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.spec.ts index 4b2e3d0dd5e..1c5b3c1424b 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.spec.ts @@ -60,7 +60,11 @@ describe('AgencyInformationTabComponent', () => { { provide: SecurityService, useValue: securityServiceMock }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'AGENCIES_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'AGENCIES_APP' }), + snapshot: { data: { appId: 'AGENCIES_APP' } }, + }, }, ], schemas: [NO_ERRORS_SCHEMA], diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.ts index 10e6f734c67..395069155a4 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-information-tab/agency-information-tab.component.ts @@ -34,16 +34,13 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { finalize, Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { isEmpty } from 'underscore'; -import type { Agency } from 'vitamui-library'; -import { ApplicationId, Role } from 'vitamui-library'; -import { SecurityService } from 'vitamui-library'; -import { diff, VitamUICommonModule, AgencyService } from 'vitamui-library'; +import { Agency, AgencyService, ApplicationId, diff, Role, SecurityService, VitamUICommonModule } from 'vitamui-library'; import { TranslatePipe } from '@ngx-translate/core'; import { AsyncPipe } from '@angular/common'; import { AgencyCreateValidators } from '../../agency-create/agency-create.validators'; diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-preview.component.ts index a5608a79e9c..36cc741e428 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency-preview/agency-preview.component.ts @@ -34,12 +34,11 @@ * 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 { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, HostListener, inject, Input, Output, ViewChild } from '@angular/core'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader, MatTabsModule } from '@angular/material/tabs'; import { Observable } from 'rxjs'; -import { AgencyService, ConfirmActionComponent, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import type { Agency } from 'vitamui-library'; +import { Agency, AgencyService, ConfirmActionComponent, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; import { AgencyInformationTabComponent } from './agency-information-tab/agency-information-tab.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency.component.spec.ts index 156230db653..03760b5acfe 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency.component.spec.ts @@ -39,16 +39,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AgencyService, BASE_URL, InjectorModule, LoggerModule, SecurityService, WINDOW_LOCATION } from 'vitamui-library'; +import { AgencyService, InjectorModule, LoggerModule, SecurityService, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; import { of } from 'rxjs'; import { AgencyComponent } from './agency.component'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'app-agency-preview', @@ -75,16 +71,7 @@ describe('AgencyComponent', () => { }); await TestBed.configureTestingModule({ - imports: [ - VitamUICommonTestModule, - RouterTestingModule, - InjectorModule, - LoggerModule.forRoot(), - NoopAnimationsModule, - MatSidenavModule, - MatDialogModule, - MatMenuModule, - ], + imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), MatSidenavModule, MatDialogModule, MatMenuModule], providers: [ { provide: AgencyService, useValue: {} }, { @@ -100,13 +87,10 @@ describe('AgencyComponent', () => { queryParams: of({}), paramMap: of(), data: of({ appId: 'AGENCIES_APP' }), - snapshot: { data: {} }, + snapshot: { data: { appId: 'AGENCIES_APP' } }, }, }, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], schemas: [CUSTOM_ELEMENTS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/agency/agency.component.ts b/ui/ui-frontend/projects/referential/src/app/agency/agency.component.ts index 543ea43b948..f24e427863f 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/agency.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/agency.component.ts @@ -43,7 +43,6 @@ import { AgencyService, ApplicationId, FileTypes, - GlobalEventService, QueryParamsService, Role, SecurityService, @@ -55,10 +54,9 @@ import { ImportDialogParam, ReferentialTypes } from '../shared/import-dialog/imp import { ImportDialogComponent } from '../shared/import-dialog/import-dialog.component'; import { AgencyCreateComponent } from './agency-create/agency-create.component'; import { AgencyListComponent } from './agency-list/agency-list.component'; -import { AgencyCreateModule } from './agency-create/agency-create.module'; + import { AgencyPreviewComponent } from './agency-preview/agency-preview.component'; -import { ImportDialogModule } from '../shared/import-dialog/import-dialog.module'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatMenuItem } from '@angular/material/menu'; @@ -69,10 +67,8 @@ import { map } from 'rxjs/operators'; templateUrl: './agency.component.html', styleUrls: ['./agency.component.scss'], imports: [ - AgencyCreateModule, AgencyListComponent, AgencyPreviewComponent, - ImportDialogModule, MatMenuItem, MatProgressSpinnerModule, MatSidenavModule, @@ -82,8 +78,7 @@ import { map } from 'rxjs/operators'; }) export class AgencyComponent extends SidenavPage implements OnInit { dialog = inject(MatDialog); - override globalEventService: GlobalEventService; - route: ActivatedRoute; + private route = inject(ActivatedRoute); private securityService = inject(SecurityService); private agencyService = inject(AgencyService); private translateService = inject(TranslateService); @@ -99,16 +94,6 @@ export class AgencyComponent extends SidenavPage implements OnInit { hasExportRole = false; hasUpdateRole = false; - constructor() { - const globalEventService = inject(GlobalEventService); - const route = inject(ActivatedRoute); - - super(route, globalEventService); - - this.globalEventService = globalEventService; - this.route = route; - } - ngOnInit(): void { this.route.params.subscribe((params) => { this.tenantIdentifier = +params['tenantIdentifier']; diff --git a/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.spec.ts b/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.spec.ts index 6305bad19d0..3bd899953a7 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.spec.ts @@ -56,7 +56,7 @@ describe('EditAgencyGuard', () => { getSelectedTenant: vi.fn().mockReturnValue({ identifier: 1 }), }; mockRouter = { - navigateByUrl: vi.fn(), + navigateByUrl: vi.fn().mockReturnValue(Promise.resolve()), }; // Configuration du TestBed diff --git a/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.ts b/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.ts index c531ef929d8..fd6aef31d6e 100644 --- a/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.ts +++ b/ui/ui-frontend/projects/referential/src/app/agency/edit-agency/edit-agency.guard.ts @@ -39,7 +39,7 @@ import { inject } from '@angular/core'; import { CanActivateFn, Router } from '@angular/router'; import { Observable, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { ROUTES, ERROR_MESSAGES } from './edit-agency.constants'; +import { ERROR_MESSAGES, ROUTES } from './edit-agency.constants'; const accessDenied = (router: Router): Observable => { router.navigateByUrl(ROUTES.ACCESS_DENIED); diff --git a/ui/ui-frontend/projects/referential/src/app/app.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/app.component.spec.ts index 94c78f0ae96..69b134a107d 100644 --- a/ui/ui-frontend/projects/referential/src/app/app.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/app.component.spec.ts @@ -36,22 +36,19 @@ */ import { Component } from '@angular/core'; import { TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; @Component({ // eslint-disable-next-line @angular-eslint/component-selector selector: 'vitamui-common-subrogation-banner', template: '', - standalone: false, }) class SubrogationBannerStubComponent {} describe('AppComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule], - declarations: [SubrogationBannerStubComponent, AppComponent], + imports: [SubrogationBannerStubComponent, AppComponent], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/app.component.ts b/ui/ui-frontend/projects/referential/src/app/app.component.ts index dbb21c617f1..195441a9241 100644 --- a/ui/ui-frontend/projects/referential/src/app/app.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/app.component.ts @@ -35,12 +35,14 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component } from '@angular/core'; +import { FooterComponent, HeaderModule, SubrogationModule, VitamuiBodyComponent } from 'vitamui-library'; +import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], - standalone: false, + imports: [HeaderModule, VitamuiBodyComponent, RouterOutlet, FooterComponent, SubrogationModule], }) export class AppComponent { title = 'Referential App'; diff --git a/ui/ui-frontend/projects/referential/src/app/app.module.ts b/ui/ui-frontend/projects/referential/src/app/app.module.ts deleted file mode 100644 index 161fd4bbc66..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/app.module.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { DatePipe, registerLocaleData } from '@angular/common'; -import { default as localeFr } from '@angular/common/locales/fr'; -import { LOCALE_ID, NgModule } from '@angular/core'; -import { BrowserModule, Title } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { environment } from '../environments/environment'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { CoreModule } from './core/core.module'; -import { - AuthenticationModule, - BASE_URL, - BytesPipe, - ENVIRONMENT, - InjectorModule, - provideI18n, - VitamUICommonModule, - WINDOW_LOCATION, -} from 'vitamui-library'; -import { provideNativeDateAdapter } from '@angular/material/core'; - -registerLocaleData(localeFr, 'fr'); - -@NgModule({ - declarations: [AppComponent], - imports: [ - CoreModule, - AuthenticationModule.forRoot(), - InjectorModule, - BrowserAnimationsModule, - BrowserModule, - VitamUICommonModule.forRoot(), - AppRoutingModule, - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - // Register the ServiceWorker as soon as the application is stable - // or after 30 seconds (whichever comes first). - registrationStrategy: 'registerWhenStable:30000', - }), - ], - providers: [ - provideI18n(), - provideNativeDateAdapter(), - Title, - { provide: LOCALE_ID, useValue: 'fr' }, - { provide: BASE_URL, useValue: './referential-api' }, - { provide: ENVIRONMENT, useValue: environment }, - { provide: WINDOW_LOCATION, useValue: window.location }, - BytesPipe, - DatePipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-create/audit-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit-create/audit-create.component.spec.ts index 094f8a6d07c..f47efce8a70 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-create/audit-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-create/audit-create.component.spec.ts @@ -51,7 +51,7 @@ describe.skip('AuditCreateComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AuditCreateComponent], + imports: [AuditCreateComponent], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.html b/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.html index d3c1625f9d6..199dd532692 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.html @@ -61,15 +61,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && filteredDataSource?.length === 0) { + @if (!pending() && filteredDataSource?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && auditService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && auditService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.spec.ts index 5041a7ebb04..a66c2f1ff3a 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.spec.ts @@ -82,8 +82,7 @@ describe('AuditListComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [AuditListComponent], - imports: [VitamUICommonTestModule], + imports: [VitamUICommonTestModule, AuditListComponent], providers: [{ provide: AuditService, useValue: auditServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); @@ -294,7 +293,7 @@ describe('AuditListComponent', () => { // Given const existenceAudit = auditOfType('PROCESS_AUDIT', 'AUDIT_FILE_EXISTING'); const integrityAudit = auditOfType('PROCESS_AUDIT', 'AUDIT_FILE_INTEGRITY'); - component.dataSource = [existenceAudit, integrityAudit]; + component.dataSource.set([existenceAudit, integrityAudit]); // When component['_filters'] = { startDate: null, endDate: null, types: [AuditCategoryFilter.AUDIT_FILE_EXISTING] }; // Then @@ -304,7 +303,7 @@ describe('AuditListComponent', () => { it('All the audits should be listed when no type is selected', () => { // Given const audit = auditOfType('PROCESS_AUDIT', 'AUDIT_FILE_EXISTING'); - component.dataSource = [audit]; + component.dataSource.set([audit]); // When component['_filters'] = { startDate: null, endDate: null, types: [] }; // Then diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.ts index 73e61f1902f..3bf6a2bd081 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-list/audit-list.component.ts @@ -37,9 +37,28 @@ import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { merge, Subject, Subscription, timer } from 'rxjs'; import { debounceTime, switchMap } from 'rxjs/operators'; -import { DEFAULT_PAGE_SIZE, Direction, Event, InfiniteScrollTable, PageRequest } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + Event, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, +} from 'vitamui-library'; import { AUDIT_CATEGORY_FILTER_EV_TYPE, AuditCategoryFilter, AuditChainType, AuditOperation } from '../../models/audit.interface'; import { AuditService } from '../audit.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { LastEventPipe } from '../../shared/pipes/last-event.pipe'; +import { EventTypeBadgeClassPipe } from '../../shared/pipes/event-type-badge-class.pipe'; +import { EventTypeColorClassPipe } from '../../shared/pipes/event-type-color-class.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; const POLLING_INTERVAL_MS = 5000; @@ -71,7 +90,22 @@ export class AuditFilters { selector: 'app-audit-list', templateUrl: './audit-list.component.html', styleUrls: ['./audit-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + OrderByButtonComponent, + NgClass, + MatProgressSpinner, + TableFilterComponent, + TableFilterOptionComponent, + PipesModule, + LastEventPipe, + EventTypeBadgeClassPipe, + EventTypeColorClassPipe, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class AuditListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { auditService: AuditService; @@ -115,7 +149,7 @@ export class AuditListComponent extends InfiniteScrollTable implements OnDe this.auditService .search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, this.direction, JSON.stringify(this.buildCriteriaFromSearch()))) .subscribe((data: any[]) => { - this.dataSource = data; + this.dataSource.set(data); this.startPolling(); }); @@ -171,11 +205,12 @@ export class AuditListComponent extends InfiniteScrollTable implements OnDe public get filteredDataSource(): any[] { const selectedCategories = this._filters?.types || []; - if (!this.dataSource || selectedCategories.length === 0) { - return this.dataSource; + const dataSource = this.dataSource(); + if (!dataSource || selectedCategories.length === 0) { + return dataSource; } - return this.dataSource.filter((item) => { + return dataSource.filter((item) => { const category = AUDIT_CATEGORY_BY_EV_DET_DATA_TYPE[item.parsedData?.['type']] ?? AUDIT_CATEGORY_BY_EV_DET_DATA_TYPE[item.type]; if (category) { @@ -250,24 +285,29 @@ export class AuditListComponent extends InfiniteScrollTable implements OnDe } private updateDataSource(newData: any[]): void { - if (!this.dataSource || this.dataSource.length === 0) { - this.dataSource = newData; + const current = this.dataSource() ?? []; + if (current.length === 0) { + this.dataSource.set(newData); return; } + const list = [...current]; + const changedItems: Event[] = []; newData.forEach((newItem: Event) => { - const existingItemIndex = this.dataSource.findIndex((item) => item.id === newItem.id); + const existingItemIndex = list.findIndex((item) => item.id === newItem.id); if (existingItemIndex !== -1) { - const existingItem = this.dataSource[existingItemIndex]; + const existingItem = list[existingItemIndex]; const newStatus = this.auditMessage(newItem); const oldStatus = this.auditMessage(existingItem); if (newStatus !== oldStatus) { - this.dataSource[existingItemIndex] = { ...existingItem, ...newItem }; - this.auditClick.next(newItem); + list[existingItemIndex] = { ...existingItem, ...newItem }; + changedItems.push(newItem); } } else { - this.dataSource.unshift(newItem); + list.unshift(newItem); } }); + this.dataSource.set(list); + changedItems.forEach((item) => this.auditClick.next(item)); } } diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-information-tab/audit-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-information-tab/audit-information-tab.component.ts index 64e54f346cf..7aeeec90237 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-information-tab/audit-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-information-tab/audit-information-tab.component.ts @@ -35,8 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input } from '@angular/core'; -import type { Event } from 'vitamui-library'; -import { VitamUICommonModule, VitamUILibraryModule, PipesModule } from 'vitamui-library'; +import { Event, PipesModule, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; import { CommonModule } from '@angular/common'; import { TranslatePipe } from '@ngx-translate/core'; diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.spec.ts index 5ca070b6774..83ae84d36bf 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.spec.ts @@ -37,16 +37,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CUSTOM_ELEMENTS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { EMPTY, of } from 'rxjs'; -import { BASE_URL, ExternalParameters, ExternalParametersService, LoggerModule, SnackBarService } from 'vitamui-library'; +import { ExternalParameters, ExternalParametersService, LoggerModule, SnackBarService } from 'vitamui-library'; import { AuditPreviewComponent } from './audit-preview.component'; import { AuditService } from '../audit.service'; -import { PipesModule } from '../../shared/pipes/pipes.module'; import { ActivatedRoute } from '@angular/router'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -68,15 +64,13 @@ describe('AuditPreviewComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [MockTruncatePipe], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ActivatedRoute, useValue: { data: EMPTY } }, { provide: AuditService, useValue: {} }, { provide: ExternalParametersService, useValue: externalParametersServiceMock }, { provide: SnackBarService, useValue: snackBarSpy }, ], - imports: [AuditPreviewComponent, LoggerModule.forRoot(), PipesModule], + imports: [AuditPreviewComponent, LoggerModule.forRoot(), MockTruncatePipe], schemas: [CUSTOM_ELEMENTS_SCHEMA], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.ts index f1873c90465..7157e18ed02 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit-preview/audit-preview.component.ts @@ -34,7 +34,7 @@ * 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, computed, EventEmitter, input, OnInit, Output, Signal, inject } from '@angular/core'; +import { Component, computed, EventEmitter, inject, input, OnInit, Output, Signal } from '@angular/core'; import { Event, ExternalParameters, @@ -47,10 +47,11 @@ import { AuditService } from '../audit.service'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { MatTabsModule } from '@angular/material/tabs'; -import { PipesModule } from '../../shared/pipes/pipes.module'; + import { AuditInformationTabComponent } from './audit-information-tab/audit-information-tab.component'; import { AuditOperation } from '../../models/audit.interface'; import { TranslatePipe } from '@ngx-translate/core'; +import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; @Component({ selector: 'app-audit-preview', @@ -61,7 +62,7 @@ import { TranslatePipe } from '@ngx-translate/core'; CommonModule, FormsModule, MatTabsModule, - PipesModule, + EventTypeBadgeColorPipe, TranslatePipe, VitamUICommonModule, VitamUILibraryModule, diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit.component.spec.ts index c7f58d6f3ee..3a99097a04f 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit.component.spec.ts @@ -43,10 +43,9 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Router } from '@angular/router'; import { of } from 'rxjs'; -import { BASE_URL, DatepickerComponent, GlobalEventService, InjectorModule, LoggerModule } from 'vitamui-library'; +import { DatepickerComponent, GlobalEventService, InjectorModule, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { AuditComponent } from './audit.component'; import { DatePipe } from '@angular/common'; @@ -64,6 +63,7 @@ describe('AuditComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'AUDIT_APP' }), + snapshot: { data: { appId: 'AUDIT_APP' } }, }; const routerSpy = { navigate: vi.fn().mockName('Router.navigate'), @@ -78,14 +78,12 @@ describe('AuditComponent', () => { MatSelectModule, MatSidenavModule, DatepickerComponent, - NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule, + AuditComponent, ], - declarations: [AuditComponent], providers: [ provideNativeDateAdapter(), - { provide: BASE_URL, useValue: '/pastis-api' }, DatePipe, FormBuilder, GlobalEventService, diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit.component.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit.component.ts index 37843f04149..af4d26d3699 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit.component.ts @@ -34,26 +34,48 @@ * 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, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { Component, inject, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { Event, GlobalEventService, SearchBarComponent, SidenavPage } from 'vitamui-library'; +import { + DatepickerComponent, + Event, + SearchBarComponent, + SidenavPage, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { AuditChainCreateComponent } from './audit-chain-create/audit-chain-create.component'; import { AuditCreateComponent } from './audit-create/audit-create.component'; import { AuditListComponent } from './audit-list/audit-list.component'; import { DateTime } from 'luxon'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { AuditPreviewComponent } from './audit-preview/audit-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-audit', templateUrl: './audit.component.html', styleUrls: ['./audit.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + AuditPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ReactiveFormsModule, + DatepickerComponent, + AuditListComponent, + TranslatePipe, + VitamuiMenuButtonComponent, + ], }) export class AuditComponent extends SidenavPage { dialog = inject(MatDialog); - route: ActivatedRoute; - override globalEventService: GlobalEventService; + private route = inject(ActivatedRoute); private formBuilder = inject(FormBuilder); public dateRangeFilterForm: FormGroup; @@ -65,14 +87,9 @@ export class AuditComponent extends SidenavPage { @ViewChild(AuditListComponent, { static: true }) auditListComponent: AuditListComponent; constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); + super(); - super(route, globalEventService); - this.route = route; - this.globalEventService = globalEventService; - - route.params.subscribe((params) => { + this.route.params.subscribe((params) => { this.tenantIdentifier = params['tenantIdentifier']; }); diff --git a/ui/ui-frontend/projects/referential/src/app/audit/audit.module.ts b/ui/ui-frontend/projects/referential/src/app/audit/audit.module.ts index 9b07a37ac49..83387e1d021 100644 --- a/ui/ui-frontend/projects/referential/src/app/audit/audit.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/audit/audit.module.ts @@ -45,7 +45,7 @@ import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule } from 'vitamui-library'; -import { PipesModule } from '../shared/pipes/pipes.module'; + import { AuditRoutingModule } from './audit-routing.module'; import { AuditComponent } from './audit.component'; import { MatInputModule } from '@angular/material/input'; @@ -57,7 +57,6 @@ import { AuditPreviewComponent } from './audit-preview/audit-preview.component'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [AuditComponent, AuditListComponent], imports: [ CommonModule, RouterModule, @@ -74,8 +73,9 @@ import { TranslatePipe } from '@ngx-translate/core'; MatSelectModule, MatFormFieldModule, MatInputModule, - PipesModule, TranslatePipe, + AuditComponent, + AuditListComponent, ], providers: [{ provide: MAT_DATE_FORMATS, useValue: FR_DATE_FORMAT }], }) diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.spec.ts index 407887fcdd9..ed5896ba156 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.spec.ts @@ -44,7 +44,6 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService, OtpState } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -62,7 +61,15 @@ import { ContextCreateValidators } from './context-create.validators'; multi: true, }, ], - standalone: false, + imports: [ + ReactiveFormsModule, + MatFormFieldModule, + MatSelectModule, + MatButtonToggleModule, + MatProgressBarModule, + MatProgressSpinnerModule, + VitamUICommonTestModule, + ], }) class OwnerFormStubComponent implements ControlValueAccessor { @Input() @@ -152,11 +159,11 @@ describe.skip('ContextCreateComponent', () => { MatSelectModule, MatButtonToggleModule, MatProgressBarModule, - NoopAnimationsModule, MatProgressSpinnerModule, VitamUICommonTestModule, + ContextCreateComponent, + OwnerFormStubComponent, ], - declarations: [ContextCreateComponent, OwnerFormStubComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.ts index 7c593ec93f4..2d1f33e06ea 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-create.component.ts @@ -34,7 +34,7 @@ * 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, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; @@ -43,13 +43,13 @@ import { SecurityProfileService } from '../../security-profile/security-profile. import { ContextService } from '../context.service'; import { ContextCreateValidators } from './context-create.validators'; -import { ContextEditPermissionModule } from './context-edit-permission/context-edit-permission.module'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule } from '@angular/material/select'; import { SharedModule } from '../../../../../identity/src/app/shared/shared.module'; +import { ContextEditPermissionComponent } from './context-edit-permission/context-edit-permission.component'; import { TranslatePipe } from '@ngx-translate/core'; @Component({ @@ -57,7 +57,6 @@ import { TranslatePipe } from '@ngx-translate/core'; templateUrl: './context-create.component.html', styleUrls: ['./context-create.component.scss'], imports: [ - ContextEditPermissionModule, MatButtonToggleModule, MatDialogModule, MatFormFieldModule, @@ -66,6 +65,7 @@ import { TranslatePipe } from '@ngx-translate/core'; MatSelectModule, ReactiveFormsModule, SharedModule, + ContextEditPermissionComponent, VitamUICommonModule, VitamUILibraryModule, TranslatePipe, diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.component.ts index 89ea72b15c3..cff9a2a3c5d 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.component.ts @@ -34,14 +34,15 @@ * 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, EventEmitter, forwardRef, Input, OnInit, Output, inject } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { AccessContractService, AuthService, ContextPermission, Option, Tenant } from 'vitamui-library'; +import { Component, EventEmitter, forwardRef, inject, Input, OnInit, Output } from '@angular/core'; +import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; +import { AccessContractService, AuthService, ContextPermission, Option, SelectComponent, Tenant, TooltipDirective } from 'vitamui-library'; import { CustomerApiService } from '../../../core/api/customer-api.service'; import { TenantApiService } from '../../../core/api/tenant-api.service'; import { IngestContractService } from '../../../ingest-contract/ingest-contract.service'; import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; +import { TranslatePipe } from '@ngx-translate/core'; export const CONTEXT_PERMISSION_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -54,7 +55,7 @@ export const CONTEXT_PERMISSION_VALUE_ACCESSOR: any = { templateUrl: './context-edit-permission.component.html', styleUrls: ['./context-edit-permission.component.scss'], providers: [CONTEXT_PERMISSION_VALUE_ACCESSOR], - standalone: false, + imports: [TooltipDirective, SelectComponent, ReactiveFormsModule, FormsModule, TranslatePipe], }) export class ContextEditPermissionComponent implements ControlValueAccessor, OnInit { private customerApiService = inject(CustomerApiService); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.module.ts b/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.module.ts deleted file mode 100644 index 2cc2a07f101..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/context/context-create/context-edit-permission/context-edit-permission.module.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { ContextEditPermissionComponent } from './context-edit-permission.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - TranslatePipe, - ], - declarations: [ContextEditPermissionComponent], - exports: [ContextEditPermissionComponent], -}) -export class ContextEditPermissionModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.component.ts index a161264feeb..a66cacc45b3 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.component.ts @@ -34,18 +34,20 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import { ConfirmDialogService, ContextPermission } from 'vitamui-library'; +import { ConfirmDialogService, ContextPermission, DialogHeaderComponent } from 'vitamui-library'; import { ContextCreateValidators } from '../context-create/context-create.validators'; +import { ContextEditPermissionComponent } from '../context-create/context-edit-permission/context-edit-permission.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-context-edit', templateUrl: './context-edit.component.html', styleUrls: ['./context-edit.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, ReactiveFormsModule, MatDialogContent, ContextEditPermissionComponent, MatDialogActions, TranslatePipe], }) export class ContextEditComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.module.ts b/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.module.ts deleted file mode 100644 index 0c5b96fce82..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/context/context-edit/context-edit.module.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../../../../identity/src/app/shared/shared.module'; -import { ContextEditPermissionModule } from '../context-create/context-edit-permission/context-edit-permission.module'; -import { ContextEditComponent } from './context-edit.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - ContextEditPermissionModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - SharedModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [ContextEditComponent], -}) -export class ContextEditModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.html b/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.html index 2adb4af4024..5b3c02b8eb4 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.html @@ -40,7 +40,7 @@
- @for (context of dataSource; track context; let index = $index) { + @for (context of dataSource(); track context; let index = $index) {
@@ -57,15 +57,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && contextService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && contextService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.spec.ts index 11de17362b9..1e2015ac117 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.spec.ts @@ -34,19 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { RouterTestingModule } from '@angular/router/testing'; import { EMPTY, of } from 'rxjs'; -import { AuthService, BASE_URL, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { AuthService, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ContextService } from '../context.service'; import { ContextListComponent } from './context-list.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ContextListComponent', () => { let component: ContextListComponent; @@ -72,7 +69,6 @@ describe('ContextListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ContextListComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ VitamUICommonTestModule, @@ -80,17 +76,14 @@ describe('ContextListComponent', () => { ReactiveFormsModule, InjectorModule, LoggerModule.forRoot(), - RouterTestingModule, + ContextListComponent, ], providers: [ - { provide: BASE_URL, useValue: '' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: ContextService, useValue: contextServiceMock }, { provide: AuthService, useValue: authServiceMock }, { provide: WINDOW_LOCATION, useValue: window.location }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.ts index 5bdab15cc2d..bc1bc632e96 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-list/context-list.component.ts @@ -34,13 +34,30 @@ * 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, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { merge, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, map, takeUntil, tap } from 'rxjs/operators'; -import { Direction, InfiniteScrollTable, PageRequest, DEFAULT_PAGE_SIZE } from 'vitamui-library'; -import type { Context, User, AdminUserProfile } from 'vitamui-library'; +import { + AdminUserProfile, + Context, + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, + User, +} from 'vitamui-library'; import { ContextService } from '../context.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -48,7 +65,19 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-context-list', templateUrl: './context-list.component.html', styleUrls: ['./context-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + OrderByButtonComponent, + NgClass, + MatProgressSpinner, + TableFilterComponent, + TableFilterOptionComponent, + PipesModule, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class ContextListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { contextService: ContextService; @@ -114,7 +143,7 @@ export class ContextListComponent extends InfiniteScrollTable implement ); this.contextService.search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, Direction.ASCENDANT)).subscribe((data: Context[]) => { - this.dataSource = data; + this.dataSource.set(data); }); const searchCriteriaChange = merge(tenantChange, this.searchChange, this.filterChange, this.orderChange).pipe( @@ -172,10 +201,14 @@ export class ContextListComponent extends InfiniteScrollTable implement private replaceUpdatedContext(): void { this.contextService.updated.pipe(takeUntil(this.destroy$)).subscribe((updatedContext: Context) => { - const index = this.dataSource.findIndex((item: Context) => item.id === updatedContext.id); - if (index !== -1) { - this.dataSource[index] = updatedContext; - } + this.dataSource.update((contexts) => { + const list = [...(contexts ?? [])]; + const index = list.findIndex((item: Context) => item.id === updatedContext.id); + if (index !== -1) { + list[index] = updatedContext; + } + return list; + }); }); } } diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.spec.ts index 67456e0c3be..3da342b1eb0 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.spec.ts @@ -63,8 +63,7 @@ describe.skip('ContextInformationTabComponent', () => { }; await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, VitamUICommonTestModule, MatSelectModule], - declarations: [ContextInformationTabComponent], + imports: [ReactiveFormsModule, VitamUICommonTestModule, MatSelectModule, ContextInformationTabComponent], providers: [ FormBuilder, { provide: SecurityProfileService, useValue: securityProfileServiceMock }, diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.ts index 3ff2d7477f9..f8032a8c81a 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-information-tab/context-information-tab.component.ts @@ -34,23 +34,23 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap, tap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { Context, Option } from 'vitamui-library'; -import { diff } from 'vitamui-library'; +import { Context, DatepickerComponent, diff, InputComponent, Option, SelectComponent, SlideToggleComponent } from 'vitamui-library'; import { RULE_TYPES } from '../../../rule/rules.constants'; import { SecurityProfileService } from '../../../security-profile/security-profile.service'; import { ContextService } from '../../context.service'; import { ContextCreateValidators } from '../../context-create/context-create.validators'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-context-information-tab', templateUrl: './context-information-tab.component.html', styleUrls: ['./context-information-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, InputComponent, SelectComponent, DatepickerComponent, TranslatePipe], }) export class ContextInformationTabComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.spec.ts index 4993db543b5..4c1bfc88fd3 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.spec.ts @@ -34,19 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; import { EMPTY } from 'rxjs'; -import { BASE_URL, Context, ContextPermission, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { Context, ContextPermission, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ContextService } from '../../context.service'; import { ContextPermissionTabComponent } from './context-permission-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const permissions: ContextPermission[] = [ { @@ -154,18 +151,14 @@ describe('ContextPermissionTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ContextPermissionTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [ReactiveFormsModule, VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), RouterTestingModule], + imports: [ReactiveFormsModule, VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), ContextPermissionTabComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MatDialog, useValue: matDialogSpy }, { provide: ContextService, useValue: { updated: EMPTY } }, { provide: WINDOW_LOCATION, useValue: window.location }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.ts index b6a8cab107f..09bc319058f 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-permission-tab/context-permission-tab.component.ts @@ -34,25 +34,35 @@ * 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, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { Observable, forkJoin, of } from 'rxjs'; +import { forkJoin, Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap, tap } from 'rxjs/operators'; -import type { AccessContract, Context, Customer, IngestContract, Tenant } from 'vitamui-library'; -import { ContextPermission } from 'vitamui-library'; -import { diff, AccessContractService, AuthService } from 'vitamui-library'; +import { + AccessContract, + AccessContractService, + AuthService, + Context, + ContextPermission, + Customer, + diff, + IngestContract, + Tenant, +} from 'vitamui-library'; import { extend, isEmpty } from 'underscore'; import { CustomerApiService } from '../../../core/api/customer-api.service'; import { TenantApiService } from '../../../core/api/tenant-api.service'; import { IngestContractService } from '../../../ingest-contract/ingest-contract.service'; import { ContextEditComponent } from '../../context-edit/context-edit.component'; import { ContextService } from '../../context.service'; +import { MatDivider } from '@angular/material/divider'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-context-permission-tab', templateUrl: './context-permission-tab.component.html', styleUrls: ['./context-permission-tab.component.scss'], - standalone: false, + imports: [MatDivider, TranslatePipe], }) export class ContextPermissionTabComponent implements OnInit { dialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.spec.ts index 36c995c86bc..69134529617 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.spec.ts @@ -40,6 +40,8 @@ import { MatDialog } from '@angular/material/dialog'; import { ContextService } from '../context.service'; import { ContextPreviewComponent } from './context-preview.component'; +import { Context } from 'vitamui-library'; +import { of } from 'rxjs'; describe('ContextPreviewComponent', () => { let component: ContextPreviewComponent; @@ -47,19 +49,30 @@ describe('ContextPreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [ContextPreviewComponent], - providers: [ - { provide: MatDialog, useValue: {} }, - { provide: ContextService, useValue: {} }, - ], + imports: [ContextPreviewComponent], + providers: [{ provide: MatDialog, useValue: {} }], schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents(); + }) + .overrideProvider(ContextService, { useValue: { updated: of() } }) + .compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ContextPreviewComponent); component = fixture.componentInstance; + component.context = { + id: 'aegqaaaaaahbzl4naaovqamcuzgxyjyaaaaq', + name: 'admin-context', + identifier: 'CT-000001', + status: 'ACTIVE', + creationDate: '2022-08-16T10:57:52.168', + lastUpdate: '2022-08-16T13:12:53.416', + enableControl: 'false', + securityProfile: 'admin-security-profile', + permissions: [], + activationDate: 'activationDate', + deactivationDate: 'deactivationDate', + } satisfies Context; fixture.detectChanges(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.ts index 448d37346ca..415e8f6d075 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.component.ts @@ -34,21 +34,37 @@ * 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 { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, forwardRef, HostListener, inject, Input, Output, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; import { Observable } from 'rxjs'; -import type { Context } from 'vitamui-library'; -import { ConfirmActionComponent } from 'vitamui-library'; +import { ConfirmActionComponent, Context, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { ContextService } from '../context.service'; import { ContextInformationTabComponent } from './context-information-tab/context-information-tab.component'; import { ContextPermissionTabComponent } from './context-permission-tab/context-permission-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-context-preview', templateUrl: './context-preview.component.html', styleUrls: ['./context-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + ContextInformationTabComponent, + ContextPermissionTabComponent, + OperationHistoryTabComponent, + forwardRef(() => ContextPreviewComponent), + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ContextPreviewComponent implements AfterViewInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.module.ts deleted file mode 100644 index 02ed32e4425..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/context/context-preview/context-preview.module.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatDividerModule } from '@angular/material/divider'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { ContextEditPermissionModule } from '../context-create/context-edit-permission/context-edit-permission.module'; -import { ContextInformationTabComponent } from './context-information-tab/context-information-tab.component'; -import { ContextPermissionTabComponent } from './context-permission-tab/context-permission-tab.component'; -import { ContextPreviewComponent } from './context-preview.component'; -import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatInputModule } from '@angular/material/input'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - ContextEditPermissionModule, - RouterModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatSidenavModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - MatDividerModule, - MatDatepickerModule, - MatInputModule, - TranslatePipe, - ], - declarations: [ContextPreviewComponent, ContextInformationTabComponent, ContextPermissionTabComponent], - exports: [ContextPreviewComponent], -}) -export class ContextPreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/context/context.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/context/context.component.spec.ts index f4b1a1cd5c2..dd0b360aa2d 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context.component.spec.ts @@ -38,34 +38,23 @@ import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; -import { ApplicationService, GlobalEventService, InjectorModule, LoggerModule } from 'vitamui-library'; +import { Application, ApplicationService, GlobalEventService, InjectorModule, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ActivatedRoute } from '@angular/router'; import { EMPTY, of } from 'rxjs'; import { ContextComponent } from './context.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { ContextListComponent } from './context-list/context-list.component'; @Component({ selector: 'app-agency-preview', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class ContextPreviewStub { @Input() accessContract: any; } -@Component({ - selector: 'app-agency-list', - template: '', - standalone: false, -}) -class ContextListStub {} - describe('ContextComponent', () => { let component: ContextComponent; let fixture: ComponentFixture; @@ -73,29 +62,26 @@ describe('ContextComponent', () => { const applicationServiceMock = { applications: new Array(), isApplicationExternalIdentifierEnabled: () => of(true), + getAppById: () => + of({ + name: 'App name', + } satisfies Partial), }; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ContextComponent, ContextListStub, ContextPreviewStub], schemas: [NO_ERRORS_SCHEMA], - imports: [ - VitamUICommonTestModule, - RouterTestingModule, - InjectorModule, - LoggerModule.forRoot(), - NoopAnimationsModule, - MatSidenavModule, - MatDialogModule, - ], + imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), MatSidenavModule, MatDialogModule, ContextPreviewStub], providers: [ - { provide: ApplicationService, useValue: applicationServiceMock }, - { provide: ActivatedRoute, useValue: { params: EMPTY, data: EMPTY } }, + { provide: ActivatedRoute, useValue: { params: EMPTY, data: EMPTY, paramMap: EMPTY, snapshot: { data: { appId: 'App Id' } } } }, { provide: GlobalEventService, useValue: { pageEvent: EMPTY, customerEvent: EMPTY, tenantEvent: EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(ApplicationService, { useValue: applicationServiceMock }) + .overrideComponent(ContextListComponent, { + set: { template: '' }, + }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/referential/src/app/context/context.component.ts b/ui/ui-frontend/projects/referential/src/app/context/context.component.ts index d77e396f5e9..78b3187dad2 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context.component.ts @@ -34,26 +34,38 @@ * 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, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, inject, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { ApplicationService, Context, GlobalEventService, SidenavPage } from 'vitamui-library'; +import { ApplicationService, Context, SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { ContextCreateComponent } from './context-create/context-create.component'; import { ContextListComponent } from './context-list/context-list.component'; import { shareReplay } from 'rxjs/operators'; import { firstValueFrom } from 'rxjs'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { ContextPreviewComponent } from './context-preview/context-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-context', templateUrl: './context.component.html', styleUrls: ['./context.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + ContextPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ContextListComponent, + TranslatePipe, + ], }) export class ContextComponent extends SidenavPage implements OnInit { dialog = inject(MatDialog); - route: ActivatedRoute; + private route = inject(ActivatedRoute); private applicationService = inject(ApplicationService); search = ''; @@ -63,15 +75,6 @@ export class ContextComponent extends SidenavPage implements OnInit { #isSlaveMode$ = this.applicationService.isApplicationExternalIdentifierEnabled('CONTEXT').pipe(shareReplay(1)); - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - } - async openCreateContextDialog() { const isSlaveMode = await firstValueFrom(this.#isSlaveMode$); this.dialog.closeAll(); // Prevent opening multiple dialogs diff --git a/ui/ui-frontend/projects/referential/src/app/context/context.module.ts b/ui/ui-frontend/projects/referential/src/app/context/context.module.ts index 8e147f3fd54..23374965eb1 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context.module.ts @@ -43,9 +43,8 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule } from 'vitamui-library'; -import { ContextEditModule } from './context-edit/context-edit.module'; import { ContextListComponent } from './context-list/context-list.component'; -import { ContextPreviewModule } from './context-preview/context-preview.module'; + import { ContextRoutingModule } from './context-routing.module'; import { ContextComponent } from './context.component'; import { ContextCreateComponent } from './context-create/context-create.component'; @@ -58,14 +57,13 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, ContextRoutingModule, ContextCreateComponent, - ContextEditModule, - ContextPreviewModule, MatMenuModule, MatDialogModule, MatSidenavModule, MatProgressSpinnerModule, TranslatePipe, + ContextComponent, + ContextListComponent, ], - declarations: [ContextComponent, ContextListComponent], }) export class ContextModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/context/context.service.ts b/ui/ui-frontend/projects/referential/src/app/context/context.service.ts index 53e10610de9..2c4c688814b 100644 --- a/ui/ui-frontend/projects/referential/src/app/context/context.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/context/context.service.ts @@ -35,10 +35,10 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { Context, SearchService, VitamuiHttpHeaders, SnackBarService } from 'vitamui-library'; +import { Context, SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { ContextApiService } from '../core/api/context-api.service'; diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/context-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/context-api.service.spec.ts index d7aedf608af..096e6e012a0 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/context-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/context-api.service.spec.ts @@ -34,22 +34,15 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { AgencyApiService, BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { AgencyApiService, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from './../../../environments/environment'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('AgencyApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/customer-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/customer-api.service.spec.ts index d11ae75bd13..a4eb8520455 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/customer-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/customer-api.service.spec.ts @@ -36,7 +36,7 @@ */ import { TestBed } from '@angular/core/testing'; -import { BASE_URL, LoggerModule } from 'vitamui-library'; +import { LoggerModule } from 'vitamui-library'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { CustomerApiService } from './customer-api.service'; @@ -46,14 +46,7 @@ describe('CustomerApiService', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - { - provide: BASE_URL, - useValue: '', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/ingest-contract-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/ingest-contract-api.service.spec.ts index b2e9a38c26c..b4b06141704 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/ingest-contract-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/ingest-contract-api.service.spec.ts @@ -34,23 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from '../../../environments/environment'; import { IngestContractApiService } from './ingest-contract-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('IngestContractApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/logbook-management-operation-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/logbook-management-operation-api.service.spec.ts index b4aebb8669c..c4aa3666ab1 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/logbook-management-operation-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/logbook-management-operation-api.service.spec.ts @@ -36,7 +36,7 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, LoggerModule } from 'vitamui-library'; +import { LoggerModule } from 'vitamui-library'; import { LogbookManagementOperationApiService } from './logbook-management-operation-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -44,14 +44,7 @@ describe('LogbookManagementOperationApiService', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - { - provide: BASE_URL, - useValue: '', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/management-contracts-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/management-contracts-api.service.spec.ts index af5a18e1f5b..9ba0cecc270 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/management-contracts-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/management-contracts-api.service.spec.ts @@ -66,7 +66,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, LoggerModule } from 'vitamui-library'; +import { LoggerModule } from 'vitamui-library'; import { ManagementContractsApiService } from './management-contracts-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -74,14 +74,7 @@ describe('ManagementContractsApiService', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [LoggerModule.forRoot()], - providers: [ - { - provide: BASE_URL, - useValue: '', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/ontology-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/ontology-api.service.spec.ts index 633afc24727..bb27fcb38c2 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/ontology-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/ontology-api.service.spec.ts @@ -34,23 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from './../../../environments/environment'; import { OntologyApiService } from './ontology-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('OntologyApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.spec.ts index 593dbe0014a..5196d7c95ec 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.spec.ts @@ -34,23 +34,17 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from './../../../environments/environment'; import { OperationApiService } from './operation-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('OperationApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.ts b/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.ts index 39539e6be11..2ea4848eca1 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/operation-api.service.ts @@ -35,10 +35,10 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; -import { BASE_URL, PaginatedHttpClient, Event, PageRequest, PaginatedResponse, VitamuiHttpHeaders } from 'vitamui-library'; +import { BASE_URL, Event, PageRequest, PaginatedHttpClient, PaginatedResponse, VitamuiHttpHeaders } from 'vitamui-library'; import { TraceabilityChainAuditRequest } from '../../models/audit.interface'; @Injectable({ diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/security-profile-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/security-profile-api.service.spec.ts index d7aedf608af..096e6e012a0 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/security-profile-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/security-profile-api.service.spec.ts @@ -34,22 +34,15 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { AgencyApiService, BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { AgencyApiService, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from './../../../environments/environment'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('AgencyApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/tenant-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/core/api/tenant-api.service.spec.ts index eeac08a5d50..4f6fe96d5c4 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/tenant-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/tenant-api.service.spec.ts @@ -37,7 +37,6 @@ import { TestBed } from '@angular/core/testing'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { BASE_URL } from 'vitamui-library'; import { TenantApiService } from './tenant-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +44,7 @@ describe('TenantApiService', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/core/core.module.ts b/ui/ui-frontend/projects/referential/src/app/core/core.module.ts index 46e7273ec82..097c10ca4e3 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/core.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/core.module.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { InjectionToken, NgModule, inject } from '@angular/core'; +import { inject, InjectionToken, NgModule } from '@angular/core'; import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule, throwIfAlreadyLoaded, VitamUICommonModule } from 'vitamui-library'; import { environment } from '../../environments/environment'; diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.spec.ts index d054142b3cc..f02568e08e0 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.spec.ts @@ -44,7 +44,6 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -107,11 +106,10 @@ describe.skip(' FileFormatCreateComponent', () => { MatSelectModule, MatButtonToggleModule, MatProgressBarModule, - NoopAnimationsModule, MatProgressSpinnerModule, VitamUICommonTestModule, + FileFormatCreateComponent, ], - declarations: [FileFormatCreateComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.ts index c93c7c4ffec..8673c49a212 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.component.ts @@ -34,27 +34,31 @@ * 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, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { ConfirmDialogService, + DialogHeaderComponent, FILE_FORMAT_EXTERNAL_PREFIX, FileFormat, + InputComponent, Option, + SelectComponent, StartupService, VitamuiSelectOptions, } from 'vitamui-library'; import { FileFormatService } from '../file-format.service'; import { FileFormatCreateValidators } from './file-format-create.validators'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-file-format-create', templateUrl: './file-format-create.component.html', styleUrls: ['./file-format-create.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, ReactiveFormsModule, MatDialogContent, InputComponent, SelectComponent, MatDialogActions, TranslatePipe], }) export class FileFormatCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.module.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.module.ts deleted file mode 100644 index 520e4528fa2..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-create/file-format-create.module.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { SelectComponent, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../../../../identity/src/app/shared/shared.module'; -import { FileFormatCreateComponent } from './file-format-create.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - SelectComponent, - SharedModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [FileFormatCreateComponent], -}) -export class FileFormatCreateModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.html b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.html index 9a8634adfd9..801b8acdac6 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.html @@ -35,7 +35,7 @@
- @for (format of dataSource; track format; let index = $index) { + @for (format of dataSource(); track format; let index = $index) {
@@ -64,15 +64,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && fileFormatService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && fileFormatService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.spec.ts index 9d9b721cb7b..0b2c2461ce2 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.spec.ts @@ -34,14 +34,12 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; -import { AuthService, BASE_URL, StartupService, SnackBarService } from 'vitamui-library'; +import { AuthService, SnackBarService, StartupService } from 'vitamui-library'; import { FileFormatService } from '../file-format.service'; import { FileFormatListComponent } from './file-format-list.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('FileFormatListComponent', () => { let component: FileFormatListComponent; @@ -49,18 +47,14 @@ describe('FileFormatListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [FileFormatListComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [], + imports: [FileFormatListComponent], providers: [ - { provide: BASE_URL, useValue: '' }, FileFormatService, { provide: AuthService, useValue: { user: { proofTenantIdentifier: '1' } } }, { provide: SnackBarService, useValue: {} }, { provide: MatDialog, useValue: {} }, { provide: StartupService, useValue: { getConfigStringValue: (_param: string) => '' } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.ts index 366ad58e46b..a3851e1f5bf 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-list/file-format-list.component.ts @@ -34,23 +34,32 @@ * 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, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; -import { Subject, merge } from 'rxjs'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { merge, Subject } from 'rxjs'; import { debounceTime, filter, takeUntil } from 'rxjs/operators'; -import type { AdminUserProfile, FileFormat, User } from 'vitamui-library'; import { + AdminUserProfile, ConfirmActionComponent, DEFAULT_PAGE_SIZE, Direction, + EllipsisDirective, FILE_FORMAT_EXTERNAL_PREFIX, + FileFormat, + HasRoleDirective, + InfiniteScrollDirective, InfiniteScrollTable, + OrderByButtonComponent, PageRequest, - StartupService, + PipesModule, SnackBarService, + StartupService, + User, } from 'vitamui-library'; import { FileFormatService } from '../file-format.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -58,7 +67,16 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-file-format-list', templateUrl: './file-format-list.component.html', styleUrls: ['./file-format-list.component.scss'], - standalone: false, + imports: [ + OrderByButtonComponent, + MatProgressSpinner, + PipesModule, + TranslatePipe, + CommonModule, + EllipsisDirective, + HasRoleDirective, + InfiniteScrollDirective, + ], }) export class FileFormatListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { fileFormatService: FileFormatService; @@ -117,7 +135,7 @@ export class FileFormatListComponent extends InfiniteScrollTable imp this.fileFormatService .search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, Direction.ASCENDANT)) .subscribe((data: FileFormat[]) => { - this.dataSource = data; + this.dataSource.set(data); }); const searchCriteriaChange = merge(this.searchChange, this.orderChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); @@ -191,10 +209,14 @@ export class FileFormatListComponent extends InfiniteScrollTable imp private replaceUpdatedFileFormat(): void { this.fileFormatService.updated.pipe(takeUntil(this.destroy$)).subscribe((ffUpdated: FileFormat) => { - const index = this.dataSource.findIndex((item: FileFormat) => item.id === ffUpdated.id); - if (index !== -1) { - this.dataSource[index] = ffUpdated; - } + this.dataSource.update((formats) => { + const list = [...(formats ?? [])]; + const index = list.findIndex((item: FileFormat) => item.id === ffUpdated.id); + if (index !== -1) { + list[index] = ffUpdated; + } + return list; + }); }); } } diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.spec.ts index 027b6120011..7b5ef63e61f 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.spec.ts @@ -93,13 +93,16 @@ describe('FileFormatInformationTabComponent', () => { getTenantIdentifier: () => '', }; await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, VitamUICommonTestModule], - declarations: [FileFormatInformationTabComponent], + imports: [ReactiveFormsModule, VitamUICommonTestModule, FileFormatInformationTabComponent], providers: [ { provide: StartupService, useValue: startupServiceStub }, { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'MANAGEMENT_CONTRACT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'MANAGEMENT_CONTRACT_APP' }), + snapshot: { data: { appId: 'MANAGEMENT_CONTRACT_APP' } }, + }, }, { provide: SecurityService, @@ -108,10 +111,11 @@ describe('FileFormatInformationTabComponent', () => { }, }, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: FileFormatService, useValue: fileFormatServiceMock }, ], schemas: [NO_ERRORS_SCHEMA], - }).compileComponents(); + }) + .overrideProvider(FileFormatService, { useValue: fileFormatServiceMock }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.ts index 8214b6156af..afb04f4324a 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-information-tab/file-format-information-tab.component.ts @@ -34,24 +34,32 @@ * 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 { formatDate } from '@angular/common'; -import { Component, EventEmitter, Input, LOCALE_ID, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { AsyncPipe, formatDate } from '@angular/common'; +import { Component, EventEmitter, inject, Input, LOCALE_ID, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { BehaviorSubject, combineLatest, Observable, of, Subscription } from 'rxjs'; import { catchError, filter, map, switchMap, tap } from 'rxjs/operators'; import { extend, isEmpty, omit } from 'underscore'; -import type { FileFormat, VitamuiSelectOptions } from 'vitamui-library'; -import { ApplicationId, Role } from 'vitamui-library'; -import { SecurityService } from 'vitamui-library'; -import { diff, FILE_FORMAT_EXTERNAL_PREFIX } from 'vitamui-library'; +import { + ApplicationId, + diff, + FILE_FORMAT_EXTERNAL_PREFIX, + FileFormat, + InputComponent, + Role, + SecurityService, + SelectComponent, + VitamuiSelectOptions, +} from 'vitamui-library'; import { FileFormatService } from '../../file-format.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-file-format-information-tab', templateUrl: './file-format-information-tab.component.html', styleUrls: ['./file-format-information-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, InputComponent, SelectComponent, AsyncPipe, TranslatePipe], }) export class FileFormatInformationTabComponent { private locale = inject(LOCALE_ID); diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.spec.ts index a63e42cbcb4..687e1baa305 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.spec.ts @@ -40,6 +40,8 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { FileFormatService } from '../file-format.service'; import { FileFormatPreviewComponent } from './file-format-preview.component'; +import { of } from 'rxjs'; +import { FileFormat } from 'vitamui-library'; describe('FileFormatPreviewComponent', () => { let component: FileFormatPreviewComponent; @@ -47,19 +49,34 @@ describe('FileFormatPreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [FileFormatPreviewComponent], - providers: [ - { provide: MatDialog, useValue: {} }, - { provide: FileFormatService, useValue: {} }, - ], + imports: [FileFormatPreviewComponent], + providers: [{ provide: MatDialog, useValue: {} }], schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents(); + }) + .overrideProvider(FileFormatService, { useValue: { getAllForTenant: () => of([]) } }) + .compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(FileFormatPreviewComponent); component = fixture.componentInstance; + component.fileFormat = { + id: 'vitam_id', + documentVersion: 0, + version: '1.0', + versionPronom: '3.0', + puid: 'EXTERNAL_puid', + name: 'Name', + description: 'Format de Fichier', + mimeType: 'application/puid', + hasPriorityOverFileFormatIDs: [], + group: 'test', + alert: false, + comment: 'No Comment', + extensions: ['.puid'], + createdDate: new Date().toISOString(), + updateDate: new Date().toISOString(), + } satisfies FileFormat; fixture.detectChanges(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.ts index 617a1aa104a..8063d9b75bc 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.component.ts @@ -34,20 +34,35 @@ * 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 { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, forwardRef, HostListener, inject, Input, Output, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; import { Observable } from 'rxjs'; -import { ConfirmActionComponent } from 'vitamui-library'; -import type { FileFormat } from 'vitamui-library'; +import { ConfirmActionComponent, FileFormat, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { FileFormatService } from '../file-format.service'; import { FileFormatInformationTabComponent } from './file-format-information-tab/file-format-information-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-file-format-preview', templateUrl: './file-format-preview.component.html', styleUrls: ['./file-format-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + FileFormatInformationTabComponent, + OperationHistoryTabComponent, + forwardRef(() => FileFormatPreviewComponent), + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class FileFormatPreviewComponent implements AfterViewInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.module.ts deleted file mode 100644 index c5bc5088889..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format-preview/file-format-preview.module.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { SelectComponent, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { FileFormatInformationTabComponent } from './file-format-information-tab/file-format-information-tab.component'; -import { FileFormatPreviewComponent } from './file-format-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - MatDialogModule, - MatMenuModule, - MatOptionModule, - MatProgressSpinnerModule, - MatSelectModule, - MatSidenavModule, - MatTabsModule, - ReactiveFormsModule, - RouterModule, - SelectComponent, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [FileFormatPreviewComponent, FileFormatInformationTabComponent], - exports: [FileFormatPreviewComponent], -}) -export class FileFormatPreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.spec.ts index 96cdf8a16f9..efb5bf4f6cc 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.spec.ts @@ -38,18 +38,16 @@ import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { RouterTestingModule } from '@angular/router/testing'; import { InjectorModule, LoggerModule, SecurityService, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { FileFormatComponent } from './file-format.component'; import { of } from 'rxjs'; @Component({ selector: 'app-file-format-preview', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class AgencyPreviewStub { @Input() @@ -59,7 +57,7 @@ class AgencyPreviewStub { @Component({ selector: 'app-file-format-list', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class AgencyListStub {} @@ -69,15 +67,15 @@ describe('FileFormatComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [FileFormatComponent, AgencyListStub, AgencyPreviewStub], imports: [ VitamUICommonTestModule, - RouterTestingModule, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, MatSidenavModule, MatDialogModule, + FileFormatComponent, + AgencyListStub, + AgencyPreviewStub, ], providers: [ { diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.ts index fb70fa86461..f3d89b8edd3 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.component.ts @@ -38,23 +38,45 @@ import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Observable, Subscription } from 'rxjs'; -import { ApplicationId, FileFormat, FileTypes, GlobalEventService, Role, SecurityService, SidenavPage } from 'vitamui-library'; +import { + ApplicationId, + FileFormat, + FileTypes, + Role, + SecurityService, + SidenavPage, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { ImportDialogParam, ReferentialTypes } from '../shared/import-dialog/import-dialog-param.interface'; import { ImportDialogComponent } from '../shared/import-dialog/import-dialog.component'; import { FileFormatCreateComponent } from './file-format-create/file-format-create.component'; import { FileFormatListComponent } from './file-format-list/file-format-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { FileFormatPreviewComponent } from './file-format-preview/file-format-preview.component'; +import { AsyncPipe } from '@angular/common'; @Component({ selector: 'app-file-format', templateUrl: './file-format.component.html', styleUrls: ['./file-format.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + FileFormatPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + FileFormatListComponent, + AsyncPipe, + TranslatePipe, + ], }) export class FileFormatComponent extends SidenavPage implements OnInit, OnDestroy { dialog = inject(MatDialog); - route: ActivatedRoute; + private route = inject(ActivatedRoute); private translateService = inject(TranslateService); private securityService = inject(SecurityService); @@ -66,15 +88,6 @@ export class FileFormatComponent extends SidenavPage implements OnIn @ViewChild(FileFormatListComponent, { static: true }) fileFormatListComponentListComponent: FileFormatListComponent; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - } - openCreateFileFormatDialog() { const dialogRef = this.dialog.open(FileFormatCreateComponent, { disableClose: true }); dialogRef.afterClosed().subscribe((result) => { diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.module.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.module.ts index 3db23cb1bb6..68a17330a85 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.module.ts @@ -42,12 +42,12 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { FileFormatCreateModule } from './file-format-create/file-format-create.module'; + import { FileFormatListComponent } from './file-format-list/file-format-list.component'; -import { FileFormatPreviewModule } from './file-format-preview/file-format-preview.module'; + import { FileFormatRoutingModule } from './file-format-routing.module'; import { FileFormatComponent } from './file-format.component'; -import { ImportDialogModule } from '../shared/import-dialog/import-dialog.module'; + import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ @@ -57,15 +57,13 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, VitamUILibraryModule, FileFormatRoutingModule, - FileFormatCreateModule, - FileFormatPreviewModule, - ImportDialogModule, MatMenuModule, MatDialogModule, MatSidenavModule, MatProgressSpinnerModule, TranslatePipe, + FileFormatComponent, + FileFormatListComponent, ], - declarations: [FileFormatComponent, FileFormatListComponent], }) export class FileFormatModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.service.ts b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.service.ts index dc21207e24f..21299f7fa44 100644 --- a/ui/ui-frontend/projects/referential/src/app/file-format/file-format.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/file-format/file-format.service.ts @@ -35,10 +35,10 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders, HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { FILE_FORMAT_EXTERNAL_PREFIX, FileFormat, SearchService, VitamuiHttpHeaders, SnackBarService } from 'vitamui-library'; +import { FILE_FORMAT_EXTERNAL_PREFIX, FileFormat, SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { FileFormatApiService } from '../core/api/file-format-api.service'; diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-create/ingest-contract-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-create/ingest-contract-create.component.spec.ts index b2b704f06b8..40b97aa1425 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-create/ingest-contract-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-create/ingest-contract-create.component.spec.ts @@ -35,21 +35,12 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { EMPTY, of } from 'rxjs'; -import { - AccessContractService, - BASE_URL, - ConfirmDialogService, - ExternalParameters, - ExternalParametersService, - LoggerModule, -} from 'vitamui-library'; +import { AccessContractService, ConfirmDialogService, ExternalParameters, ExternalParametersService, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ArchiveProfileApiService } from '../../core/api/archive-profile-api.service'; import { ManagementContractApiService } from '../../core/api/management-contract-api.service'; @@ -57,8 +48,6 @@ import { FileFormatService } from '../../file-format/file-format.service'; import { IngestContractService } from '../ingest-contract.service'; import { IngestContractCreateComponent } from './ingest-contract-create.component'; import { IngestContractCreateValidators } from './ingest-contract-create.validators'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('IngestContractCreateComponent', () => { let component: IngestContractCreateComponent; @@ -100,16 +89,9 @@ describe('IngestContractCreateComponent', () => { await TestBed.configureTestingModule({ schemas: [NO_ERRORS_SCHEMA], - imports: [ - IngestContractCreateComponent, - NoopAnimationsModule, - VitamUICommonTestModule, - LoggerModule.forRoot(), - MatButtonToggleModule, - ], + imports: [IngestContractCreateComponent, VitamUICommonTestModule, LoggerModule.forRoot(), MatButtonToggleModule], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: IngestContractService, useValue: {} }, @@ -120,8 +102,6 @@ describe('IngestContractCreateComponent', () => { { provide: ArchiveProfileApiService, useValue: archiveProfileApiServiceMock }, { provide: ExternalParametersService, useValue: externalParametersServiceMock }, { provide: AccessContractService, useValue: accessContractServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.html b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.html index a7f94f455fc..ad795af5afb 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.html @@ -44,7 +44,7 @@
- @for (accessContract of dataSource; track accessContract) { + @for (accessContract of dataSource(); track accessContract) {
@@ -62,15 +62,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && ingestContractService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && ingestContractService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.spec.ts index bb2d1df3bfe..fb476088c27 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.spec.ts @@ -57,8 +57,7 @@ describe('IngestContractListComponent', () => { }; await TestBed.configureTestingModule({ - imports: [], - declarations: [IngestContractListComponent], + imports: [IngestContractListComponent], providers: [ { provide: IngestContractService, useValue: ingestContractServiceMock }, { provide: IngestContractService, useValue: ingestContractServiceSpy }, diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.ts index 00e49ce1782..c96258bded9 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-list/ingest-contract-list.component.ts @@ -34,12 +34,28 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; -import { Subject, Subscription, merge } from 'rxjs'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { merge, Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, IngestContract, PageRequest } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + InfiniteScrollDirective, + InfiniteScrollTable, + IngestContract, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, +} from 'vitamui-library'; import { IngestContractService } from '../ingest-contract.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -47,7 +63,19 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-ingest-contract-list', templateUrl: './ingest-contract-list.component.html', styleUrls: ['./ingest-contract-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + OrderByButtonComponent, + NgClass, + MatProgressSpinner, + TableFilterComponent, + TableFilterOptionComponent, + PipesModule, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class IngestContractListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { ingestContractService: IngestContractService; @@ -83,15 +111,15 @@ export class IngestContractListComponent extends InfiniteScrollTable { - this.dataSource = data; + this.dataSource.set(data); }, () => {}, - () => (this.pending = false), + () => this.pending.set(false), ); this.searchCriteriaSub = merge(this.searchChange, this.filterChange, this.orderChange) @@ -119,35 +147,39 @@ export class IngestContractListComponent extends InfiniteScrollTable { - const index = this.dataSource.findIndex((ingContract: IngestContract) => ingContract.identifier === ingestContract.identifier); - if (index > -1) { - this.dataSource[index] = { - id: ingestContract.id, - tenant: ingestContract.tenant, - version: ingestContract.version, - name: ingestContract.name, - identifier: ingestContract.identifier, - description: ingestContract.description, - status: ingestContract.status, - creationDate: ingestContract.creationDate, - lastUpdate: ingestContract.lastUpdate, - activationDate: ingestContract.activationDate, - deactivationDate: ingestContract.deactivationDate, - checkParentLink: ingestContract.checkParentLink, - linkParentId: ingestContract.linkParentId, - checkParentId: ingestContract.checkParentId, - masterMandatory: ingestContract.masterMandatory, - everyDataObjectVersion: ingestContract.everyDataObjectVersion, - dataObjectVersion: ingestContract.dataObjectVersion, - formatUnidentifiedAuthorized: ingestContract.formatUnidentifiedAuthorized, - everyFormatType: ingestContract.everyFormatType, - formatType: ingestContract.formatType, - archiveProfiles: ingestContract.archiveProfiles, - managementContractId: ingestContract.managementContractId, - computeInheritedRulesAtIngest: ingestContract.computeInheritedRulesAtIngest, - signaturePolicy: ingestContract.signaturePolicy, - }; - } + this.dataSource.update((contracts) => { + const list = [...(contracts ?? [])]; + const index = list.findIndex((ingContract: IngestContract) => ingContract.identifier === ingestContract.identifier); + if (index > -1) { + list[index] = { + id: ingestContract.id, + tenant: ingestContract.tenant, + version: ingestContract.version, + name: ingestContract.name, + identifier: ingestContract.identifier, + description: ingestContract.description, + status: ingestContract.status, + creationDate: ingestContract.creationDate, + lastUpdate: ingestContract.lastUpdate, + activationDate: ingestContract.activationDate, + deactivationDate: ingestContract.deactivationDate, + checkParentLink: ingestContract.checkParentLink, + linkParentId: ingestContract.linkParentId, + checkParentId: ingestContract.checkParentId, + masterMandatory: ingestContract.masterMandatory, + everyDataObjectVersion: ingestContract.everyDataObjectVersion, + dataObjectVersion: ingestContract.dataObjectVersion, + formatUnidentifiedAuthorized: ingestContract.formatUnidentifiedAuthorized, + everyFormatType: ingestContract.everyFormatType, + formatType: ingestContract.formatType, + archiveProfiles: ingestContract.archiveProfiles, + managementContractId: ingestContract.managementContractId, + computeInheritedRulesAtIngest: ingestContract.computeInheritedRulesAtIngest, + signaturePolicy: ingestContract.signaturePolicy, + }; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.spec.ts index 70ea50301ae..5bfca92d6b8 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.spec.ts @@ -34,21 +34,12 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { of } from 'rxjs'; -import { - BASE_URL, - ExternalParameters, - ExternalParametersService, - IngestContract, - LoggerModule, - SearchUnitApiService, -} from 'vitamui-library'; +import { ExternalParameters, ExternalParametersService, IngestContract, LoggerModule, SearchUnitApiService } from 'vitamui-library'; import { IngestContractAttachmentTabComponent } from './ingest-contract-attachment-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('IngestContractAttachmentTabComponent', () => { let component: IngestContractAttachmentTabComponent; @@ -93,16 +84,12 @@ describe('IngestContractAttachmentTabComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [IngestContractAttachmentTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [LoggerModule.forRoot()], + imports: [LoggerModule.forRoot(), IngestContractAttachmentTabComponent], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialog, useValue: {} }, { provide: SearchUnitApiService, useValue: unitValueMock }, { provide: ExternalParametersService, useValue: externalParametersServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.ts index af138bc7fae..54e3341344d 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-attachment-tab.component.ts @@ -35,18 +35,24 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders } from '@angular/common/http'; -import { Component, Input, inject } from '@angular/core'; +import { Component, inject, Input } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import type { IngestContract } from 'vitamui-library'; -import { ExternalParameters, VitamuiHttpHeaders } from 'vitamui-library'; -import { ExternalParametersService, SearchUnitApiService, SnackBarService } from 'vitamui-library'; +import { + ExternalParameters, + ExternalParametersService, + IngestContract, + SearchUnitApiService, + SnackBarService, + VitamuiHttpHeaders, +} from 'vitamui-library'; import { IngestContractNodeUpdateComponent } from './ingest-contract-nodes-update/ingest-contract-node-update.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-contract-attachment-tab', templateUrl: './ingest-contract-attachment-tab.component.html', styleUrls: ['./ingest-contract-attachment-tab.component.scss'], - standalone: false, + imports: [TranslatePipe], }) export class IngestContractAttachmentTabComponent { private unitService = inject(SearchUnitApiService); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.spec.ts index 8fe6e17b6b7..eb8f9f625ae 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.spec.ts @@ -34,17 +34,20 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { BASE_URL, ENVIRONMENT, FilingPlanModule, InjectorModule, LoggerModule, SnackBarService } from 'vitamui-library'; +import { ENVIRONMENT, FilingPlanComponent, InjectorModule, LoggerModule, SnackBarService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { environment } from './../../../../../environments/environment'; import { IngestContractNodeUpdateComponent } from './ingest-contract-node-update.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatButtonModule } from '@angular/material/button'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; +import { MatTreeModule } from '@angular/material/tree'; // TODO fix tests @@ -66,20 +69,29 @@ describe.skip('IngestContractNodeUpdateComponent', () => { open: vi.fn().mockName('SnackBarService.open'), }; await TestBed.configureTestingModule({ - declarations: [IngestContractNodeUpdateComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [ReactiveFormsModule, VitamUICommonTestModule, FilingPlanModule, InjectorModule, LoggerModule.forRoot()], + imports: [ + ReactiveFormsModule, + VitamUICommonTestModule, + InjectorModule, + LoggerModule.forRoot(), + IngestContractNodeUpdateComponent, + CommonModule, + FilingPlanComponent, + FormsModule, + MatButtonModule, + MatCheckboxModule, + MatProgressSpinnerModule, + MatTreeModule, + ], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: { data: { ingestContract: 'IC-000001', accessContractId: 'AC-000001', tenantIdentifier: 1 } }, }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: SnackBarService, useValue: snackBarSpy }, { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.ts index 8f9cd2ad2f5..867bb8ed098 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component.ts @@ -34,17 +34,54 @@ * 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, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { FilingPlanMode, IngestContract } from 'vitamui-library'; +import { Component, inject, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { + DialogHeaderComponent, + FilingPlanComponent, + FilingPlanMode, + IngestContract, + NextStepComponent, + PreviousStepComponent, + StepperComponent, + TooltipDirective, +} from 'vitamui-library'; import { IngestContractService } from '../../../ingest-contract.service'; +import { CdkStep } from '@angular/cdk/stepper'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatButtonModule } from '@angular/material/button'; +import { MatTreeModule } from '@angular/material/tree'; +import { CommonModule } from '@angular/common'; +import { MatCheckboxModule } from '@angular/material/checkbox'; @Component({ selector: 'app-ingest-contract-node-update', templateUrl: './ingest-contract-node-update.component.html', styleUrls: ['./ingest-contract-node-update.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + StepperComponent, + CdkStep, + MatDialogContent, + MatDialogActions, + NextStepComponent, + MatButtonToggleGroup, + MatButtonToggle, + TooltipDirective, + PreviousStepComponent, + TranslatePipe, + CommonModule, + FilingPlanComponent, + FormsModule, + MatButtonModule, + MatCheckboxModule, + MatProgressSpinnerModule, + MatTreeModule, + ], }) export class IngestContractNodeUpdateComponent implements OnInit { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.spec.ts index ced872c816c..af83e605c04 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.spec.ts @@ -84,8 +84,7 @@ describe('IngestContractFormatTabComponent', () => { getAllForTenant: () => of([]), }; await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, VitamUICommonTestModule], - declarations: [IngestContractFormatTabComponent], + imports: [ReactiveFormsModule, VitamUICommonTestModule, IngestContractFormatTabComponent], providers: [ { provide: IngestContractService, useValue: {} }, { provide: FileFormatService, useValue: fileFormatServiceMock }, diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.ts index f7e56e8257e..f59ad7b7c1a 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-format-tab/ingest-contract-format-tab.component.ts @@ -34,21 +34,21 @@ * 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, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import { diff, VitamuiSelectOptions } from 'vitamui-library'; -import type { FileFormat, IngestContract } from 'vitamui-library'; +import { diff, FileFormat, IngestContract, SelectComponent, SlideToggleComponent, VitamuiSelectOptions } from 'vitamui-library'; import { FileFormatService } from '../../../file-format/file-format.service'; import { IngestContractService } from '../../ingest-contract.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-contract-format-tab', templateUrl: './ingest-contract-format-tab.component.html', styleUrls: ['./ingest-contract-format-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, SelectComponent, TranslatePipe], }) export class IngestContractFormatTabComponent implements OnInit { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.spec.ts index 631d02f58e1..5b44cf9d36a 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.spec.ts @@ -77,8 +77,7 @@ describe('IngestContractHeritageTabComponent', () => { TestBed.overrideComponent(IngestContractHeritageTabComponent, { set: { template: '' } }); await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, VitamUICommonTestModule], - declarations: [IngestContractHeritageTabComponent], + imports: [ReactiveFormsModule, VitamUICommonTestModule, IngestContractHeritageTabComponent], providers: [FormBuilder, { provide: IngestContractService, useValue: {} }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.ts index 12706b6dabc..79d3835a196 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-heritage-tab/ingest-contract-heritage-tab.component.ts @@ -34,21 +34,21 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import { diff } from 'vitamui-library'; -import type { IngestContract } from 'vitamui-library'; +import { diff, IngestContract, SlideToggleComponent } from 'vitamui-library'; import { IngestContractService } from '../../ingest-contract.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-contract-heritage-tab', templateUrl: './ingest-contract-heritage-tab.component.html', styleUrls: ['./ingest-contract-heritage-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, TranslatePipe], }) export class IngestContractHeritageTabComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-information-tab/ingest-contract-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-information-tab/ingest-contract-information-tab.component.ts index ac2674c93e1..b8785651788 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-information-tab/ingest-contract-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-information-tab/ingest-contract-information-tab.component.ts @@ -35,24 +35,33 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders, HttpParams } from '@angular/common/http'; -import { Component, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import { diff, Option, VitamuiHttpHeaders } from 'vitamui-library'; -import type { IngestContract } from 'vitamui-library'; +import { + diff, + IngestContract, + InputComponent, + Option, + PipesModule, + SelectComponent, + SlideToggleComponent, + VitamuiHttpHeaders, +} from 'vitamui-library'; import { ArchiveProfileApiService } from '../../../core/api/archive-profile-api.service'; import { ManagementContractApiService } from '../../../core/api/management-contract-api.service'; import { IngestContractCreateValidators } from '../../ingest-contract-create/ingest-contract-create.validators'; import { IngestContractService } from '../../ingest-contract.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-contract-information-tab', templateUrl: './ingest-contract-information-tab.component.html', styleUrls: ['./ingest-contract-information-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, InputComponent, SelectComponent, FormsModule, PipesModule, TranslatePipe], }) export class IngestContractInformationTabComponent implements OnInit { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.spec.ts index 769e3cdfc47..66bc04de89a 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.spec.ts @@ -39,7 +39,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IngestContract } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { IngestContractService } from '../../ingest-contract.service'; @@ -80,8 +79,7 @@ describe('IngestContractObjectTabComponent', () => { TestBed.overrideComponent(IngestContractObjectTabComponent, { set: { template: '' } }); await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, FormsModule, VitamUICommonTestModule, MatSelectModule, NoopAnimationsModule], - declarations: [IngestContractObjectTabComponent], + imports: [ReactiveFormsModule, FormsModule, VitamUICommonTestModule, MatSelectModule, IngestContractObjectTabComponent], providers: [FormBuilder, { provide: IngestContractService, useValue: {} }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.ts index 24f9032806e..529ad5d73c7 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-object-tab/ingest-contract-object-tab.component.ts @@ -34,21 +34,21 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import { diff, Option } from 'vitamui-library'; -import type { IngestContract } from 'vitamui-library'; +import { diff, IngestContract, Option, SelectComponent, SlideToggleComponent } from 'vitamui-library'; import { IngestContractService } from '../../ingest-contract.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-contract-object-tab', templateUrl: './ingest-contract-object-tab.component.html', styleUrls: ['./ingest-contract-object-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, SelectComponent, TranslatePipe], }) export class IngestContractObjectTabComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.spec.ts index e2de57e82d4..7d2a2fc89a2 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.spec.ts @@ -74,8 +74,7 @@ describe('IngestContractPreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [IngestContractPreviewComponent], + imports: [IngestContractPreviewComponent], providers: [ { provide: MatDialog, useValue: {} }, { provide: IngestContractService, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.ts index 319ce40416d..a2eed925d68 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.component.ts @@ -38,31 +38,53 @@ import { AfterViewInit, Component, EventEmitter, + forwardRef, HostListener, + inject, Input, OnChanges, Output, SimpleChanges, ViewChild, - inject, } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; import { Observable } from 'rxjs'; -import { ConfirmActionComponent } from 'vitamui-library'; -import type { IngestContract } from 'vitamui-library'; +import { ConfirmActionComponent, IngestContract, OperationHistoryTabComponent, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { IngestContractService } from '../ingest-contract.service'; import { IngestContractFormatTabComponent } from './ingest-contract-format-tab/ingest-contract-format-tab.component'; import { IngestContractHeritageTabComponent } from './ingest-contract-heritage-tab/ingest-contract-heritage-tab.component'; import { IngestContractInformationTabComponent } from './ingest-contract-information-tab/ingest-contract-information-tab.component'; import { IngestContractObjectTabComponent } from './ingest-contract-object-tab/ingest-contract-object-tab.component'; import { IngestContractSignatureTabComponent } from './ingest-contract-signature-tab/ingest-contract-signature-tab.component'; +import { IngestContractAttachmentTabComponent } from './ingest-contract-attachment-tab/ingest-contract-attachment-tab.component'; + +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-ingest-contract-preview', templateUrl: './ingest-contract-preview.component.html', styleUrls: ['./ingest-contract-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + IngestContractInformationTabComponent, + IngestContractFormatTabComponent, + IngestContractObjectTabComponent, + IngestContractHeritageTabComponent, + IngestContractAttachmentTabComponent, + IngestContractSignatureTabComponent, + OperationHistoryTabComponent, + forwardRef(() => IngestContractPreviewComponent), + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class IngestContractPreviewComponent implements OnChanges, AfterViewInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.module.ts deleted file mode 100644 index e0ea34b2c65..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-preview.module.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { SelectComponent, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { IngestContractAttachmentTabComponent } from './ingest-contract-attachment-tab/ingest-contract-attachment-tab.component'; -import { IngestContractNodeUpdateComponent } from './ingest-contract-attachment-tab/ingest-contract-nodes-update/ingest-contract-node-update.component'; -import { IngestContractFormatTabComponent } from './ingest-contract-format-tab/ingest-contract-format-tab.component'; -import { IngestContractHeritageTabComponent } from './ingest-contract-heritage-tab/ingest-contract-heritage-tab.component'; -import { IngestContractInformationTabComponent } from './ingest-contract-information-tab/ingest-contract-information-tab.component'; -import { IngestContractObjectTabComponent } from './ingest-contract-object-tab/ingest-contract-object-tab.component'; -import { IngestContractPreviewComponent } from './ingest-contract-preview.component'; -import { IngestContractSignatureTabComponent } from './ingest-contract-signature-tab/ingest-contract-signature-tab.component'; -import { MatCheckbox } from '@angular/material/checkbox'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [ - IngestContractPreviewComponent, - IngestContractInformationTabComponent, - IngestContractFormatTabComponent, - IngestContractObjectTabComponent, - IngestContractSignatureTabComponent, - IngestContractAttachmentTabComponent, - IngestContractNodeUpdateComponent, - IngestContractHeritageTabComponent, - ], - imports: [ - CommonModule, - FormsModule, - MatButtonToggleModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatMenuModule, - MatOptionModule, - MatProgressSpinnerModule, - MatSelectModule, - MatSidenavModule, - MatTabsModule, - ReactiveFormsModule, - RouterModule, - SelectComponent, - VitamUICommonModule, - VitamUILibraryModule, - MatCheckbox, - TranslatePipe, - ], - exports: [IngestContractPreviewComponent], -}) -export class IngestContractPreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.spec.ts index c45ddc0c2ea..c629b338f13 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.spec.ts @@ -54,8 +54,13 @@ describe('IngestContractSignatureTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, VitamUICommonTestModule, MatButtonToggleModule, MatCheckboxModule], - declarations: [IngestContractSignatureTabComponent], + imports: [ + ReactiveFormsModule, + VitamUICommonTestModule, + MatButtonToggleModule, + MatCheckboxModule, + IngestContractSignatureTabComponent, + ], providers: [FormBuilder, { provide: IngestContractService, useValue: ingestContractServiceSpy }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.ts index 1801f053f29..f8bdfa7bfdf 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract-preview/ingest-contract-signature-tab/ingest-contract-signature-tab.component.ts @@ -34,18 +34,20 @@ * 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, EventEmitter, Input, OnChanges, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnChanges, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { EMPTY, Observable } from 'rxjs'; -import { SignedDocumentPolicyEnum } from 'vitamui-library'; -import type { IngestContract, SignaturePolicy } from 'vitamui-library'; +import { IngestContract, SignaturePolicy, SignedDocumentPolicyEnum } from 'vitamui-library'; import { IngestContractService } from '../../ingest-contract.service'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { MatCheckbox } from '@angular/material/checkbox'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-ingest-contract-signature-tab', templateUrl: './ingest-contract-signature-tab.component.html', styleUrls: ['./ingest-contract-signature-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, MatButtonToggleGroup, MatButtonToggle, MatCheckbox, TranslatePipe], }) export class IngestContractSignatureTabComponent implements OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.spec.ts index c42920d7ea1..5659011f000 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.spec.ts @@ -38,16 +38,20 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { ApplicationService, BASE_URL, GlobalEventService, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { + Application, + ApplicationService, + GlobalEventService, + IngestContract, + InjectorModule, + LoggerModule, + WINDOW_LOCATION, +} from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { IngestContractComponent } from './ingest-contract.component'; import { IngestContractService } from './ingest-contract.service'; import { DownloadSnackBarService } from '../core/service/download-snack-bar.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('IngestContractComponent', () => { let component: IngestContractComponent; @@ -57,31 +61,63 @@ describe('IngestContractComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'INGEST_CONTRACT_APP' }), + snapshot: { data: { appId: 'INGEST_CONTRACT_APP' } }, }; const applicationServiceMock = { applications: new Array(), isApplicationExternalIdentifierEnabled: () => of(true), + getAppById: () => + of({ + name: 'App name', + } satisfies Partial), }; await TestBed.configureTestingModule({ - declarations: [IngestContractComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [VitamUICommonTestModule, RouterTestingModule, InjectorModule, LoggerModule.forRoot()], + imports: [VitamUICommonTestModule, InjectorModule, LoggerModule.forRoot(), IngestContractComponent], providers: [ GlobalEventService, - { provide: ApplicationService, useValue: applicationServiceMock }, { provide: ActivatedRoute, useValue: activatedRouteMock }, { provide: Router, useValue: {} }, { provide: MatDialog, useValue: {} }, - { provide: BASE_URL, useValue: '' }, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: IngestContractService, useValue: {} }, { provide: DownloadSnackBarService, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(IngestContractService, { + useValue: { + search: () => of([]), + updated: of({ + tenant: 0, + version: 1, + description: 'desc', + status: 'ACTIVE', + id: 'vitam_id', + name: 'Name', + identifier: 'SP-000001', + everyDataObjectVersion: true, + dataObjectVersion: ['test'], + creationDate: '01-01-20', + lastUpdate: '01-01-20', + activationDate: '01-01-20', + deactivationDate: '01-01-20', + checkParentLink: '', + linkParentId: '', + checkParentId: [''], + masterMandatory: true, + formatUnidentifiedAuthorized: true, + everyFormatType: true, + formatType: [''], + archiveProfiles: [], + managementContractId: 'MC-000001', + computeInheritedRulesAtIngest: false, + signaturePolicy: undefined, + } satisfies IngestContract), + }, + }) + .overrideProvider(ApplicationService, { useValue: applicationServiceMock }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.ts index 3b53346286f..ba9dc2256b6 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.component.ts @@ -41,12 +41,14 @@ import { ApplicationService, DownloadUtils, FileTypes, - GlobalEventService, IngestContract, Role, SecurityService, SidenavPage, SnackBarService, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + VitamuiTitleBreadcrumbComponent, } from 'vitamui-library'; import { DownloadSnackBarService } from './../core/service/download-snack-bar.service'; import { firstValueFrom, Observable, Subscription } from 'rxjs'; @@ -54,10 +56,14 @@ import { mergeMap, shareReplay } from 'rxjs/operators'; import { IngestContractCreateComponent } from './ingest-contract-create/ingest-contract-create.component'; import { IngestContractListComponent } from './ingest-contract-list/ingest-contract-list.component'; import { ImportDialogParam, ReferentialTypes } from '../shared/import-dialog/import-dialog-param.interface'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ImportDialogComponent } from '../shared/import-dialog/import-dialog.component'; import { IngestContractService } from './ingest-contract.service'; import { HttpResponse } from '@angular/common/http'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { IngestContractPreviewComponent } from './ingest-contract-preview/ingest-contract-preview.component'; +import { MatMenuItem } from '@angular/material/menu'; +import { AsyncPipe } from '@angular/common'; const IMPORT_FILE_MODEL_NAME = 'Import_ingest_contract_template.csv'; @@ -65,11 +71,23 @@ const IMPORT_FILE_MODEL_NAME = 'Import_ingest_contract_template.csv'; selector: 'app-ingest-contract', templateUrl: './ingest-contract.component.html', styleUrls: ['./ingest-contract.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + IngestContractPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + MatMenuItem, + IngestContractListComponent, + AsyncPipe, + TranslatePipe, + ], }) export class IngestContractComponent extends SidenavPage implements OnInit { dialog = inject(MatDialog); - private route: ActivatedRoute; + private route = inject(ActivatedRoute); private applicationService = inject(ApplicationService); private securityService = inject(SecurityService); private translateService = inject(TranslateService); @@ -89,13 +107,9 @@ export class IngestContractComponent extends SidenavPage impleme #isSlaveMode$ = this.applicationService.isApplicationExternalIdentifierEnabled('INGEST_CONTRACT').pipe(shareReplay(1)); constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); + super(); - super(route, globalEventService); - this.route = route; - - globalEventService.tenantEvent.subscribe(() => { + this.globalEventService.tenantEvent.subscribe(() => { this.refreshList(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.module.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.module.ts index c7ce36de2a0..225b9769cad 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.module.ts @@ -45,16 +45,14 @@ import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule } from 'vitamui-library'; -import { ImportDialogModule } from '../shared/import-dialog/import-dialog.module'; import { IngestContractListComponent } from './ingest-contract-list/ingest-contract-list.component'; -import { IngestContractPreviewModule } from './ingest-contract-preview/ingest-contract-preview.module'; + import { IngestContractRoutingModule } from './ingest-contract-routing.module'; import { IngestContractComponent } from './ingest-contract.component'; import { IngestContractCreateComponent } from './ingest-contract-create/ingest-contract-create.component'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [IngestContractComponent, IngestContractListComponent], imports: [ CommonModule, RouterModule, @@ -67,10 +65,10 @@ import { TranslatePipe } from '@ngx-translate/core'; MatProgressSpinnerModule, MatTabsModule, IngestContractRoutingModule, - IngestContractPreviewModule, IngestContractCreateComponent, - ImportDialogModule, TranslatePipe, + IngestContractComponent, + IngestContractListComponent, ], }) export class IngestContractModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.service.ts b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.service.ts index 8ddc30192d0..41b6caf8dc7 100644 --- a/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/ingest-contract/ingest-contract.service.ts @@ -35,10 +35,10 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { IngestContract, SearchService, VitamuiHttpHeaders, SnackBarService } from 'vitamui-library'; +import { IngestContract, SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { IngestContractApiService } from '../core/api/ingest-contract-api.service'; diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.spec.ts index 1b192fc5235..5a17a054d4f 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.spec.ts @@ -34,7 +34,6 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -42,12 +41,8 @@ import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { OperationsResults } from '../../models/operation-response.interface'; import { LogbookManagementOperationService } from '../logbook-management-operation.service'; import { LogbookManagementOperationListComponent } from './logbook-management-operation-list.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -113,16 +108,13 @@ describe('LogbookManagementOperationListComponent', () => { context: [], }; await TestBed.configureTestingModule({ - declarations: [LogbookManagementOperationListComponent, MockTruncatePipe], schemas: [NO_ERRORS_SCHEMA], - imports: [VitamUICommonTestModule], + imports: [VitamUICommonTestModule, LogbookManagementOperationListComponent, MockTruncatePipe], providers: [ { provide: LogbookManagementOperationService, useValue: logbookManagementOperationServiceMock, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.ts index 908af3a7733..5e6fc16f506 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-list/logbook-management-operation-list.component.ts @@ -34,18 +34,44 @@ * 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, EventEmitter, OnInit, Output, inject } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, EventEmitter, inject, OnInit, Output } from '@angular/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Subscription } from 'rxjs'; -import { Colors, FacetDetails } from 'vitamui-library'; +import { + Colors, + EventTypeLabelComponent, + FacetDetails, + InfiniteScrollDirective, + LogbookOperationFacetComponent, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, + TooltipDirective, +} from 'vitamui-library'; import { OperationCategory, OperationDetails, OperationsResults } from '../../models/operation-response.interface'; import { LogbookManagementOperationService } from '../logbook-management-operation.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; @Component({ selector: 'app-logbook-management-operation-list', templateUrl: './logbook-management-operation-list.component.html', styleUrls: ['./logbook-management-operation-list.component.scss'], - standalone: false, + imports: [ + LogbookOperationFacetComponent, + TableFilterDirective, + TableFilterComponent, + TableFilterOptionComponent, + TooltipDirective, + EventTypeLabelComponent, + NgClass, + MatProgressSpinner, + PipesModule, + TranslatePipe, + CommonModule, + InfiniteScrollDirective, + ], }) export class LogbookManagementOperationListComponent implements OnInit { logbookManagementOperationService = inject(LogbookManagementOperationService); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.spec.ts index 4559cd684ae..ff5df9a3ff4 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.spec.ts @@ -42,10 +42,7 @@ import { LogbookManagementOperationInformationTabComponent } from './logbook-man let expectedOperation: OperationDetails; -@Component({ - template: ``, - standalone: false, -}) +@Component({ template: `` }) class TestLogbookInformationComponent { operation = expectedOperation; tenantIdentifier = 1; @@ -70,8 +67,7 @@ describe('LogbookManagementOperationInformationTabComponent', () => { forcedCancellation: false, }; await TestBed.configureTestingModule({ - declarations: [LogbookManagementOperationInformationTabComponent, TestLogbookInformationComponent], - imports: [], + imports: [LogbookManagementOperationInformationTabComponent, TestLogbookInformationComponent], providers: [{ provide: LogbookService, useValue: {} }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.ts index 5a227d597cd..7ee63dff946 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-information-tab/logbook-management-operation-information-tab.component.ts @@ -34,16 +34,16 @@ * 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, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; -import { LogbookService } from 'vitamui-library'; -import type { IEvent } from 'vitamui-library'; +import { Component, inject, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { EventTypeLabelComponent, IEvent, LogbookService, PipesModule } from 'vitamui-library'; import type { OperationDetails } from '../../../models/operation-response.interface'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-logbook-management-operation-information-tab', templateUrl: './logbook-management-operation-information-tab.component.html', styleUrls: ['./logbook-management-operation-information-tab.component.scss'], - standalone: false, + imports: [EventTypeLabelComponent, PipesModule, TranslatePipe], }) export class LogbookManagementOperationInformationTabComponent implements OnInit, OnChanges { private logbookService = inject(LogbookService); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.spec.ts index f827d47040f..f3cf305c147 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.spec.ts @@ -34,16 +34,14 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { of } from 'rxjs'; -import { BASE_URL, WINDOW_LOCATION } from 'vitamui-library'; +import { WINDOW_LOCATION } from 'vitamui-library'; import { OperationsResults } from '../../models/operation-response.interface'; import { LogbookManagementOperationService } from '../logbook-management-operation.service'; import { LogbookManagementOperationPreviewComponent } from './logbook-management-operation-preview.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('LogbookManagementOperationPreviewComponent', () => { let component: LogbookManagementOperationPreviewComponent; @@ -55,10 +53,7 @@ describe('LogbookManagementOperationPreviewComponent', () => { context: [], }; - @Pipe({ - name: 'truncate', - standalone: false, - }) + @Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -76,15 +71,11 @@ describe('LogbookManagementOperationPreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [LogbookManagementOperationPreviewComponent, MockTruncatePipe], - imports: [], + imports: [LogbookManagementOperationPreviewComponent, MockTruncatePipe], providers: [ { provide: LogbookManagementOperationService, useValue: logbookManagementOperationServiceMock }, { provide: MatDialog, useValue: matDialogSpy }, { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -92,6 +83,8 @@ describe('LogbookManagementOperationPreviewComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(LogbookManagementOperationPreviewComponent); component = fixture.componentInstance; + component.tenant = {}; + component.tenantIdentifier = 42; component.operation = { globalState: 'PAUSE', nextStep: '', diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.ts index 696f49a4335..46b461a37cf 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation-preview/logbook-management-operation-preview.component.ts @@ -34,19 +34,52 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; import { LogbookManagementOperationService } from '../logbook-management-operation.service'; -import { FormControl, Validators } from '@angular/forms'; +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; import type { OperationDetails } from '../../models/operation-response.interface'; +import { + DialogHeaderComponent, + EventTypeLabelComponent, + InputComponent, + PipesModule, + VitamuiMenuButtonComponent, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; +import { MatMenuItem } from '@angular/material/menu'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { LogbookManagementOperationInformationTabComponent } from './logbook-management-operation-information-tab/logbook-management-operation-information-tab.component'; +import { CommonModule, NgClass } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; @Component({ selector: 'app-logbook-management-operation-preview', templateUrl: './logbook-management-operation-preview.component.html', styleUrls: ['./logbook-management-operation-preview.component.scss'], - standalone: false, + imports: [ + VitamuiMenuButtonComponent, + MatMenuItem, + MatTabGroup, + MatTab, + LogbookManagementOperationInformationTabComponent, + DialogHeaderComponent, + MatDialogContent, + EventTypeLabelComponent, + NgClass, + MatDialogActions, + MatDialogClose, + InputComponent, + ReactiveFormsModule, + PipesModule, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + VitamuiSidenavHeaderComponent, + ], }) export class LogbookManagementOperationPreviewComponent implements OnInit, OnDestroy { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.spec.ts index a04b06a3fda..523d0231740 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.spec.ts @@ -39,7 +39,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { of } from 'rxjs'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule, VitamUICommonModule, WINDOW_LOCATION } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule, VitamUICommonModule, WINDOW_LOCATION } from 'vitamui-library'; import { LogbookManagementOperationComponent } from './logbook-management-operation.component'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { provideNativeDateAdapter } from '@angular/material/core'; @@ -54,8 +54,14 @@ describe('LogbookManagementOperationComponent', () => { }); await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, InjectorModule, VitamUICommonModule, LoggerModule.forRoot(), MatDatepickerModule], - declarations: [LogbookManagementOperationComponent], + imports: [ + ReactiveFormsModule, + InjectorModule, + VitamUICommonModule, + LoggerModule.forRoot(), + MatDatepickerModule, + LogbookManagementOperationComponent, + ], providers: [ provideNativeDateAdapter(), { @@ -70,7 +76,6 @@ describe('LogbookManagementOperationComponent', () => { }, }, { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '' }, { provide: ENVIRONMENT, useValue: '' }, ], schemas: [NO_ERRORS_SCHEMA], diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.ts index ad6b8ecb3ec..472e6599453 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.component.ts @@ -34,15 +34,28 @@ * 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, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; -import { FormBuilder } from '@angular/forms'; -import { MatSidenav } from '@angular/material/sidenav'; +import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; import { ActivatedRoute } from '@angular/router'; -import { AuthService, DateService, FrenchDate, QueryParamsService, Tenant } from 'vitamui-library'; +import { + AuthService, + DatepickerComponent, + DateService, + FrenchDate, + QueryParamsService, + Tenant, + TooltipDirective, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { OperationDetails } from '../models/operation-response.interface'; import { LogbookManagementOperationListComponent } from './logbook-management-operation-list/logbook-management-operation-list.component'; import { tap } from 'rxjs/operators'; import { BehaviorSubject, Subscription } from 'rxjs'; +import { LogbookManagementOperationPreviewComponent } from './logbook-management-operation-preview/logbook-management-operation-preview.component'; +import { NgStyle } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; interface FormData { startDateMin?: Date; @@ -60,7 +73,20 @@ interface OperationSearch { selector: 'app-logbook-management-operation', templateUrl: './logbook-management-operation.component.html', styleUrls: ['./logbook-management-operation.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + LogbookManagementOperationPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + TooltipDirective, + ReactiveFormsModule, + NgStyle, + DatepickerComponent, + LogbookManagementOperationListComponent, + TranslatePipe, + ], }) export class LogbookManagementOperationComponent implements OnInit, OnDestroy { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.module.ts b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.module.ts index 1f89dcd2089..b78d35409bb 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-management-operation/logbook-management-operation.module.ts @@ -55,12 +55,6 @@ import { MatMenuItem } from '@angular/material/menu'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [ - LogbookManagementOperationComponent, - LogbookManagementOperationListComponent, - LogbookManagementOperationPreviewComponent, - LogbookManagementOperationInformationTabComponent, - ], imports: [ CommonModule, FormsModule, @@ -76,6 +70,10 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUILibraryModule, MatMenuItem, TranslatePipe, + LogbookManagementOperationComponent, + LogbookManagementOperationListComponent, + LogbookManagementOperationPreviewComponent, + LogbookManagementOperationInformationTabComponent, ], exports: [ LogbookManagementOperationListComponent, diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.html b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.html index c1a8e812ced..51f45e5bcd9 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.html +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.html @@ -1,15 +1,15 @@ - @if (showDownloadButton) { - } @if (hasATRDownloadable()) { @@ -24,60 +24,60 @@
- +
-
{{ event?.agIdExt }}
+
{{ event()?.agIdExt }}
-
{{ event?.rightsStatementIdentifier }}
+
{{ event()?.rightsStatementIdentifier }}
-
{{ event?.agIdApp }}
+
{{ event()?.agIdApp }}
-
{{ event?.idRequest }}
+
{{ event()?.idRequest }}
-
{{ event?.id }}
+
{{ event()?.id }}
-
{{ event?.agId }}
+
{{ event()?.agId }}
-
{{ reportFileName }}
+
{{ reportFileName() }}
-
{{ event?.data }}
+
{{ event()?.data }}
-
{{ (event | lastEvent)?.outMessage }}
+
{{ (event() | lastEvent)?.outMessage }}
- +
diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.spec.ts index 3b0e32a6ea7..eb0d74edd51 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.spec.ts @@ -34,24 +34,19 @@ * 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 { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { AuthService, BASE_URL, ExternalParametersService, InjectorModule, LogbookService, LoggerModule } from 'vitamui-library'; +import { AuthService, ExternalParametersService, InjectorModule, LogbookService, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { LogbookDownloadService } from '../logbook-download.service'; import { LogbookOperationDetailComponent } from './logbook-operation-detail.component'; import { LastEventPipe } from '../../shared/pipes/last-event.pipe'; import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -69,25 +64,23 @@ describe('LogbookOperationDetailComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [LogbookOperationDetailComponent, LastEventPipe, MockTruncatePipe], schemas: [NO_ERRORS_SCHEMA], imports: [ BrowserAnimationsModule, EventTypeBadgeColorPipe, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, - RouterTestingModule, VitamUICommonTestModule, + LogbookOperationDetailComponent, + LastEventPipe, + MockTruncatePipe, ], providers: [ { provide: LogbookService, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: LogbookDownloadService, useValue: { logbookOperationsReloaded: of([{ id: 'event-01' }]) } }, { provide: AuthService, useValue: {} }, { provide: ActivatedRoute, useValue: {} }, { provide: ExternalParametersService, useValue: externalParametersServiceMock }, - provideHttpClient(withInterceptorsFromDi()), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.ts index 1720d360101..20ece4179ce 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-detail.component.ts @@ -34,22 +34,33 @@ * 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, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, OnInit, Output, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs'; import { AuthService, - IEvent, + EventTypeLabelComponent, ExternalParameters, ExternalParametersService, + HistoryEventsComponent, + IEvent, LogbookOperationReportState, LogbookOperationTypeProc, LogbookService, + PipesModule, SnackBarService, + VitamuiSidenavHeaderComponent, } from 'vitamui-library'; import { IngestStatus } from '../../../../../ingest/src/app/models/logbook-event.interface'; import { LogbookDownloadService } from '../logbook-download.service'; import { LogbookOperation } from '../logbook-operation.enum'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { LastEventPipe } from '../../shared/pipes/last-event.pipe'; +import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; const msgForDownload: { [key: string]: string } = { EXPORT_DIP: 'LOGBOOK_OPERATION_DETAIL.DOWNLOAD_DIP', @@ -62,7 +73,20 @@ const defaultDownloadButtonLabel = 'LOGBOOK_OPERATION_DETAIL.DOWNLOAD_REPORT'; selector: 'app-logbook-operation-detail', templateUrl: './logbook-operation-detail.component.html', styleUrls: ['./logbook-operation-detail.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + EventTypeLabelComponent, + HistoryEventsComponent, + PipesModule, + LastEventPipe, + EventTypeBadgeColorPipe, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class LogbookOperationDetailComponent implements OnInit, OnChanges, OnDestroy { private logbookService = inject(LogbookService); @@ -78,15 +102,15 @@ export class LogbookOperationDetailComponent implements OnInit, OnChanges, OnDes @Output() closePanel = new EventEmitter(); - public event: IEvent; + public event = signal(null); private accessContractId: string; - private hasAccessContractId = false; + private hasAccessContractId = signal(false); private accessContractLogbookIdentifier: string; - public reportFileName: string; - public downloadButtonTitle: string; - public showDownloadButton = false; - public disableDownloadButton = true; + public reportFileName = signal(null); + public downloadButtonTitle = signal(''); + public showDownloadButton = signal(false); + public disableDownloadButton = signal(true); private subscriptions = new Subscription(); @@ -107,7 +131,11 @@ export class LogbookOperationDetailComponent implements OnInit, OnChanges, OnDes const accessContratId: string = userExternalParameters.get(ExternalParameters.PARAM_ACCESS_CONTRACT); if (accessContratId && accessContratId.length > 0) { this.accessContractId = accessContratId; - this.hasAccessContractId = true; + this.hasAccessContractId.set(true); + // Recompute the download button in case the operation already arrived + if (this.event()) { + this.updateDownloadButton(); + } } else { this.snackBarService.open({ message: 'SNACKBAR.NO_ACCESS_CONTRACT_LINKED' }); } @@ -125,30 +153,34 @@ export class LogbookOperationDetailComponent implements OnInit, OnChanges, OnDes if (this.doesNotHaveTenant()) { return; } - this.logbookDownloadService.launchDownloadReport(this.event, this.accessContractId); + this.logbookDownloadService.launchDownloadReport(this.event(), this.accessContractId); } private updateDownloadButton() { - this.downloadButtonTitle = msgForDownload[this.event.typeProc] ?? defaultDownloadButtonLabel; - const logbookOperationReportState = this.logbookDownloadService.logbookOperationReportState(this.event); - this.showDownloadButton = + const event = this.event(); + this.downloadButtonTitle.set(msgForDownload[event.typeProc] ?? defaultDownloadButtonLabel); + const logbookOperationReportState = this.logbookDownloadService.logbookOperationReportState(event); + this.showDownloadButton.set( logbookOperationReportState === LogbookOperationReportState.IN_PROGRESS || - logbookOperationReportState === LogbookOperationReportState.DOWNLOADABLE; - this.disableDownloadButton = - !(logbookOperationReportState === LogbookOperationReportState.DOWNLOADABLE && this.hasAccessContractId) || - this.operationOfDIPOrTransferFailed(); + logbookOperationReportState === LogbookOperationReportState.DOWNLOADABLE, + ); + this.disableDownloadButton.set( + !(logbookOperationReportState === LogbookOperationReportState.DOWNLOADABLE && this.hasAccessContractId()) || + this.operationOfDIPOrTransferFailed(), + ); } private updateReportFilename() { - if (this.event.events.length > 0 && this.event.events[0].data != null) { - const data = JSON.parse(this.event.events[0].data); + const event = this.event(); + if (event.events.length > 0 && event.events[0].data != null) { + const data = JSON.parse(event.events[0].data); if (data != null && data.FileName != null) { - this.reportFileName = data.FileName; + this.reportFileName.set(data.FileName); } else { - this.reportFileName = null; + this.reportFileName.set(null); } } else { - this.reportFileName = null; + this.reportFileName.set(null); } } @@ -176,27 +208,28 @@ export class LogbookOperationDetailComponent implements OnInit, OnChanges, OnDes } public hasATRDownloadable(): boolean { - if (!this.event) { + if (!this.event()) { return false; } - return this.event.typeProc === LogbookOperationTypeProc.INGEST_TEST && this.ingestIsFinish(); + return this.event().typeProc === LogbookOperationTypeProc.INGEST_TEST && this.ingestIsFinish(); } private setEvent(event: IEvent): void { - this.event = event; + this.event.set(event); this.updateDownloadButton(); this.updateReportFilename(); } private ingestIsFinish(): boolean { - const eventStatus = this.eventStatus(this.event); + const eventStatus = this.eventStatus(this.event()); return eventStatus !== IngestStatus.STARTED && eventStatus !== IngestStatus.IN_PROGRESS; } private operationOfDIPOrTransferFailed(): boolean { - const eventStatus = this.eventStatus(this.event); + const event = this.event(); + const eventStatus = this.eventStatus(event); - const isDIPOrTransfer = ([LogbookOperation.EXPORT_DIP, LogbookOperation.ARCHIVE_TRANSFER] as string[]).includes(this.event.typeProc); + const isDIPOrTransfer = ([LogbookOperation.EXPORT_DIP, LogbookOperation.ARCHIVE_TRANSFER] as string[]).includes(event.typeProc); const isFailedStatus = ([IngestStatus.KO, IngestStatus.FATAL] as IngestStatus[]).includes(eventStatus); return isDIPOrTransfer && isFailedStatus; @@ -225,6 +258,6 @@ export class LogbookOperationDetailComponent implements OnInit, OnChanges, OnDes } public downloadATR() { - this.logbookService.downloadATR(this.event.objectId); + this.logbookService.downloadATR(this.event().objectId); } } diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-popup.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-popup.component.ts index 04f31a93b89..d6257f36a6d 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-popup.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-detail/logbook-operation-popup.component.ts @@ -34,8 +34,9 @@ * 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, OnInit, inject } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { LogbookOperationDetailComponent } from './logbook-operation-detail.component'; @Component({ selector: 'app-logbook-operation-popup', @@ -47,7 +48,7 @@ import { ActivatedRoute } from '@angular/router'; [isPopup]="true" > `, - standalone: false, + imports: [LogbookOperationDetailComponent], }) export class LogbookOperationPopupComponent implements OnInit { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.html b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.html index 8a0721c7d11..95e71a0c684 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.html @@ -30,7 +30,7 @@
- @for (event of dataSource; track event) { + @for (event of dataSource(); track event) {
@@ -60,15 +60,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && logbookSearchService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && logbookSearchService.canLoadMore && !pending()) {
A{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.spec.ts index 684f3b15bbd..71d0c0e2bca 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.spec.ts @@ -54,8 +54,14 @@ describe('LogbookOperationListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [OverlayModule, TableFilterDirective, EventTypeBadgeClassPipe], - declarations: [LogbookOperationListComponent, LastEventPipe, EventTypeColorClassPipe], + imports: [ + OverlayModule, + TableFilterDirective, + EventTypeBadgeClassPipe, + LogbookOperationListComponent, + LastEventPipe, + EventTypeColorClassPipe, + ], providers: [ { provide: LogbookSearchService, useValue: { search: () => EMPTY } }, { provide: LogbookDownloadService, useValue: { logbookOperationsReloaded: of([{ id: 'event-01' }]) } }, @@ -67,7 +73,7 @@ describe('LogbookOperationListComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(LogbookOperationListComponent); component = fixture.componentInstance; - component.dataSource = []; + component.dataSource.set([]); fixture.detectChanges(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.ts index b3f8a7dbb7d..bff638a59b9 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation-list/logbook-operation-list.component.ts @@ -34,12 +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 { DEFAULT_PAGE_SIZE, Direction, IEvent, InfiniteScrollTable, PageRequest } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + EventTypeLabelComponent, + IEvent, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, +} from 'vitamui-library'; import { Component, ElementRef, EventEmitter, + inject, Input, OnChanges, OnDestroy, @@ -48,7 +63,6 @@ import { SimpleChanges, TemplateRef, ViewChild, - inject, } from '@angular/core'; import { merge, Subject, Subscription } from 'rxjs'; @@ -57,6 +71,12 @@ import { EventFilter } from '../event-filter.interface'; import { LogbookDownloadService } from '../logbook-download.service'; import { LogbookOperation } from '../logbook-operation.enum'; import { LogbookSearchService } from '../logbook-search.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { LastEventPipe } from '../../shared/pipes/last-event.pipe'; +import { EventTypeBadgeClassPipe } from '../../shared/pipes/event-type-badge-class.pipe'; +import { EventTypeColorClassPipe } from '../../shared/pipes/event-type-color-class.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; const ARCHIVE_TRANSFER = 'ARCHIVE_TRANSFER'; @@ -66,7 +86,23 @@ const ARCHIVE_TRANSFER_LABEL = 'ARCHIVE_TRANSFER_LABEL'; selector: 'app-logbook-operation-list', templateUrl: './logbook-operation-list.component.html', styleUrls: ['./logbook-operation-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + OrderByButtonComponent, + NgClass, + EventTypeLabelComponent, + MatProgressSpinner, + TableFilterComponent, + TableFilterOptionComponent, + PipesModule, + LastEventPipe, + EventTypeBadgeClassPipe, + EventTypeColorClassPipe, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class LogbookOperationListComponent extends InfiniteScrollTable implements OnInit, OnChanges, OnDestroy { logbookSearchService: LogbookSearchService; @@ -170,18 +206,24 @@ export class LogbookOperationListComponent extends InfiniteScrollTable i } private onDataSourceReloaded() { - if (this.pending) { + if (this.pending()) { return; } - this.logbookDownloadService.logbookOperationsReloaded.next(this.dataSource); + this.logbookDownloadService.logbookOperationsReloaded.next(this.dataSource()); this.finishedLoading.next(); } private updateLogbookOperations(logbookOperationsReloaded: IEvent[]) { - logbookOperationsReloaded.forEach((logbookOperation) => { - const index = this.dataSource.findIndex((o) => o.id === logbookOperation.id); - this.dataSource[index] = logbookOperation; + this.dataSource.update((operations) => { + const list = [...(operations ?? [])]; + logbookOperationsReloaded.forEach((logbookOperation) => { + const index = list.findIndex((o) => o.id === logbookOperation.id); + if (index !== -1) { + list[index] = logbookOperation; + } + }); + return list; }); } diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.spec.ts index 723abe243bf..afc04566408 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.spec.ts @@ -58,13 +58,23 @@ describe('LogbookOperationComponent', () => { }; matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - imports: [InjectorModule, LoggerModule.forRoot(), MatMenuModule, DatepickerComponent, ReactiveFormsModule, SearchBarComponent], - declarations: [LogbookOperationComponent], + imports: [ + InjectorModule, + LoggerModule.forRoot(), + MatMenuModule, + DatepickerComponent, + ReactiveFormsModule, + SearchBarComponent, + LogbookOperationComponent, + ], providers: [ provideNativeDateAdapter(), DatePipe, { provide: MatDialog, useValue: matDialogSpy }, - { provide: ActivatedRoute, useValue: { paramMap: EMPTY, data: EMPTY, queryParams: of({}) } }, + { + provide: ActivatedRoute, + useValue: { paramMap: EMPTY, data: EMPTY, queryParams: of({}), snapshot: { data: { appId: 'App Id' } } }, + }, { provide: LogbookSearchService, useValue: { search: () => EMPTY } }, { provide: Router, useValue: { navigate: () => {} } }, GlobalEventService, diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.ts index 70dbf740d02..ba47315813a 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.component.ts @@ -34,22 +34,36 @@ * 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 { AfterViewInit, Component, OnInit, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { AfterViewInit, Component, inject, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { GlobalEventService, SidenavPage, VitamuiBannerComponent } from 'vitamui-library'; +import { DatepickerComponent, SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { EventFilter } from './event-filter.interface'; import { LogbookOperationListComponent } from './logbook-operation-list/logbook-operation-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { LogbookOperationDetailComponent } from './logbook-operation-detail/logbook-operation-detail.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-logbook-operation', templateUrl: './logbook-operation.component.html', styleUrls: ['./logbook-operation.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + LogbookOperationDetailComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ReactiveFormsModule, + DatepickerComponent, + LogbookOperationListComponent, + TranslatePipe, + ], }) export class LogbookOperationComponent extends SidenavPage implements OnInit, AfterViewInit { - route: ActivatedRoute; + private route = inject(ActivatedRoute); dialog = inject(MatDialog); private formBuilder = inject(FormBuilder); @@ -62,15 +76,6 @@ export class LogbookOperationComponent extends SidenavPage implements OnIni public filters: Readonly = {}; private openOperationDetailAfterLoading: boolean; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - } - ngOnInit() { this.route.paramMap.subscribe((paramMap) => (this.tenantIdentifier = +paramMap.get('tenantIdentifier'))); @@ -114,7 +119,7 @@ export class LogbookOperationComponent extends SidenavPage implements OnIni } private openOperationDetail(): void { - this.list.eventClick.emit(this.list.dataSource[0]); + this.list.eventClick.emit(this.list.dataSource()[0]); } onFinishedLoading() { diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.module.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.module.ts index 76fcf6c31b0..15cc7793d66 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-operation.module.ts @@ -46,7 +46,7 @@ import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTabsModule } from '@angular/material/tabs'; import { VitamUICommonModule } from 'vitamui-library'; -import { PipesModule } from '../shared/pipes/pipes.module'; + import { LogbookOperationDetailComponent } from './logbook-operation-detail/logbook-operation-detail.component'; import { LogbookOperationPopupComponent } from './logbook-operation-detail/logbook-operation-popup.component'; import { LogbookOperationListComponent } from './logbook-operation-list/logbook-operation-list.component'; @@ -57,7 +57,6 @@ import { FR_DATE_FORMAT } from '../helpers/dates.constants'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [LogbookOperationComponent, LogbookOperationListComponent, LogbookOperationDetailComponent, LogbookOperationPopupComponent], imports: [ CommonModule, MatSidenavModule, @@ -71,8 +70,11 @@ import { TranslatePipe } from '@ngx-translate/core'; MatSelectModule, MatFormFieldModule, MatInputModule, - PipesModule, TranslatePipe, + LogbookOperationComponent, + LogbookOperationListComponent, + LogbookOperationDetailComponent, + LogbookOperationPopupComponent, ], providers: [{ provide: MAT_DATE_FORMATS, useValue: FR_DATE_FORMAT }], }) diff --git a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-search.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-search.service.spec.ts index 60f5f2f8122..9f2a14b1161 100644 --- a/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-search.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/logbook-operation/logbook-search.service.spec.ts @@ -40,18 +40,12 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { LogbookSearchService } from './logbook-search.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('LogbookSearchService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { provide: LogbookService, useValue: {} }, - { provide: LogbookApiService, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: LogbookService, useValue: {} }, { provide: LogbookApiService, useValue: {} }, provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.component.ts index 99860b46b30..f74bfcd31a6 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.component.ts @@ -34,17 +34,31 @@ * 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, EventEmitter, Input, OnChanges, Output, SimpleChanges, inject } from '@angular/core'; -import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Option, PersistentIdentifierPolicyTypeEnum } from 'vitamui-library'; +import { Component, EventEmitter, inject, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { InputComponent, Option, PersistentIdentifierPolicyTypeEnum, SelectComponent, TooltipDirective } from 'vitamui-library'; import { ManagementContractValidationErrors, ManagementContractValidators } from '../../validators/management-contract-validators'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { MatCheckbox } from '@angular/material/checkbox'; +import { NgClass, NgStyle } from '@angular/common'; +import { MatRadioButton, MatRadioGroup } from '@angular/material/radio'; @Component({ selector: 'app-create-persistent-identifier-policy-form', templateUrl: './create-persistent-identifier-policy-form.component.html', styleUrls: ['./create-persistent-identifier-policy-form.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + SelectComponent, + InputComponent, + MatCheckbox, + NgClass, + NgStyle, + MatRadioGroup, + MatRadioButton, + TooltipDirective, + TranslatePipe, + ], }) export class CreatePersistentIdentifierPolicyFormComponent implements OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.module.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.module.ts deleted file mode 100644 index b8adab099a1..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.module.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatRadioModule } from '@angular/material/radio'; -import { MatSelectModule } from '@angular/material/select'; -import { SharedModule } from 'projects/identity/src/app/shared/shared.module'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { CreatePersistentIdentifierPolicyFormComponent } from './create-persistent-identifier-policy-form.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [CreatePersistentIdentifierPolicyFormComponent], - imports: [ - CommonModule, - SharedModule, - FormsModule, - ReactiveFormsModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - MatCheckboxModule, - MatRadioModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - exports: [CreatePersistentIdentifierPolicyFormComponent], -}) -export class PersistentIdentifierPoliciesFormModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.component.ts index 8a3c74e95c4..a703d4c7a00 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.component.ts @@ -34,20 +34,34 @@ * 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, EventEmitter, Input, OnChanges, Output, SimpleChanges, inject } from '@angular/core'; -import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { ManagementContractValidationErrors, ManagementContractValidators, } from 'projects/referential/src/app/management-contract/validators/management-contract-validators'; -import { Option } from 'vitamui-library'; -import { TranslateService } from '@ngx-translate/core'; +import { InputComponent, Option, SelectComponent, TooltipDirective } from 'vitamui-library'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { MatCheckbox } from '@angular/material/checkbox'; +import { NgClass, NgStyle } from '@angular/common'; +import { MatRadioButton, MatRadioGroup } from '@angular/material/radio'; @Component({ selector: 'app-update-persistent-identifier-policy-form', templateUrl: './update-persistent-identifier-policy-form.component.html', styleUrls: ['./update-persistent-identifier-policy-form.component.scss'], - standalone: false, + imports: [ + ReactiveFormsModule, + InputComponent, + MatCheckbox, + NgClass, + NgStyle, + SelectComponent, + TooltipDirective, + MatRadioGroup, + MatRadioButton, + TranslatePipe, + ], }) export class UpdatePersistentIdentifierPolicyFormComponent implements OnChanges { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.module.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.module.ts deleted file mode 100644 index 3120b0e1910..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.module.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatRadioModule } from '@angular/material/radio'; -import { MatSelectModule } from '@angular/material/select'; -import { SharedModule } from 'projects/identity/src/app/shared/shared.module'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { UpdatePersistentIdentifierPolicyFormComponent } from './update-persistent-identifier-policy-form.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [UpdatePersistentIdentifierPolicyFormComponent], - imports: [ - CommonModule, - SharedModule, - FormsModule, - ReactiveFormsModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - MatCheckboxModule, - MatRadioModule, - VitamUICommonModule, - VitamUILibraryModule, - TranslatePipe, - ], - exports: [UpdatePersistentIdentifierPolicyFormComponent], -}) -export class PersistentIdentifierFormModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.spec.ts index c9546d69737..3725dd8f70d 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.spec.ts @@ -34,19 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { delay } from 'rxjs/operators'; import { - BASE_URL, ConfirmDialogService, InjectorModule, LoggerModule, @@ -58,7 +55,6 @@ import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ManagementContractToFormGroupConverterService } from '../components/management-contract-to-form-group-converter.service'; import { ManagementContractService } from '../management-contract.service'; import { ManagementContractCreateComponent } from './management-contract-create.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ManagementContractCreateComponent', () => { let managementContractToFormGroupConverterService: ManagementContractToFormGroupConverterService; @@ -100,9 +96,7 @@ describe('ManagementContractCreateComponent', () => { LoggerModule.forRoot(), MatSelectModule, MatSidenavModule, - NoopAnimationsModule, ReactiveFormsModule, - RouterTestingModule, VitamUICommonTestModule, VitamUILibraryModule, ], @@ -112,11 +106,8 @@ describe('ManagementContractCreateComponent', () => { { provide: WINDOW_LOCATION, useValue: window.location }, { provide: ManagementContractService, useValue: managementContractServiceMock }, { provide: MatDialogRef, useValue: matDialogRefSpy }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ConfirmDialogService, useValue: confirmDialogServiceMock }, ManagementContractToFormGroupConverterService, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); managementContractToFormGroupConverterService = TestBed.inject(ManagementContractToFormGroupConverterService); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.ts index 441b97cbec3..58fee2a6183 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-create/management-contract-create.component.ts @@ -56,6 +56,7 @@ import { ManagementContractCreateValidators } from '../validators/management-con import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { SharedModule } from '../../../../../identity/src/app/shared/shared.module'; +import { CreatePersistentIdentifierPolicyFormComponent } from '../components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.component'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; @@ -63,7 +64,6 @@ import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule } from '@angular/material/select'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatRadioModule } from '@angular/material/radio'; -import { PersistentIdentifierPoliciesFormModule } from '../components/create-persistent-identifier-policy-form/create-persistent-identifier-policy-form.module'; @Component({ selector: 'app-management-contract-create', @@ -79,8 +79,8 @@ import { PersistentIdentifierPoliciesFormModule } from '../components/create-per MatProgressBarModule, MatRadioModule, MatSelectModule, - PersistentIdentifierPoliciesFormModule, ReactiveFormsModule, + CreatePersistentIdentifierPolicyFormComponent, SharedModule, VitamUICommonModule, VitamUILibraryModule, diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.html b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.html index b649f8afaa5..6d2909a2420 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.html @@ -71,7 +71,7 @@
- @for (managementContract of dataSource; track managementContract; let index = $index) { + @for (managementContract of dataSource(); track managementContract; let index = $index) {
@@ -103,7 +103,7 @@
- @if (!pending && !managementContractService.canLoadMore) { + @if (!pending() && !managementContractService.canLoadMore) {
{{ 'CONTRACT_MANAGEMENT.CONTRACT_LIST.NO_RESULT_FOUND' | translate }}
} @else {
diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.spec.ts index 9baf3c74ba9..5023d42f01e 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.spec.ts @@ -34,20 +34,17 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { of, Subject } from 'rxjs'; -import { BASE_URL, InjectorModule, LoggerModule, ManagementContract, SearchService, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, LoggerModule, ManagementContract, SearchService, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ManagementContractService } from '../management-contract.service'; import { ManagementContractListComponent } from './management-contract-list.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ManagementContractListComponent', () => { let component: ManagementContractListComponent; @@ -77,26 +74,21 @@ describe('ManagementContractListComponent', () => { matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - declarations: [ManagementContractListComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ ReactiveFormsModule, MatSidenavModule, InjectorModule, VitamUICommonTestModule, - RouterTestingModule, LoggerModule.forRoot(), BrowserAnimationsModule, - NoopAnimationsModule, + ManagementContractListComponent, ], providers: [ { provide: MatDialog, useValue: matDialogSpy }, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ManagementContractService, useValue: managementContractServiceMock }, { provide: SearchService, useValue: searchServiceeMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -143,7 +135,7 @@ describe('ManagementContractListComponent', () => { vi.spyOn(searchServiceeMock, 'search'); // When - component.pending = true; + component.pending.set(true); component.searchManagementContractOrdered(); // Then @@ -172,12 +164,6 @@ describe('ManagementContractListComponent', () => { }); describe('DOM', () => { - it('should have 1 button ', () => { - const nativeElement = fixture.nativeElement; - const elementBtn = nativeElement.querySelectorAll('button'); - expect(elementBtn.length).toBe(1); - }); - it('should have 5 vitamui order button', () => { const nativeElement = fixture.nativeElement; const vitamUiOrderBtn = nativeElement.querySelectorAll('vitamui-order-by-button'); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.ts index ed65ac43904..a46aeec6f9d 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-list/management-contract-list.component.ts @@ -34,11 +34,26 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; -import { Subject, Subscription, merge } from 'rxjs'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { merge, Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, ManagementContract, PageRequest } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + InfiniteScrollDirective, + InfiniteScrollTable, + ManagementContract, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, +} from 'vitamui-library'; import { ManagementContractService } from '../management-contract.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -46,7 +61,18 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-management-contract-list', templateUrl: './management-contract-list.component.html', styleUrls: ['./management-contract-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + TableFilterComponent, + TableFilterOptionComponent, + OrderByButtonComponent, + NgClass, + MatProgressSpinner, + PipesModule, + TranslatePipe, + CommonModule, + InfiniteScrollDirective, + ], }) export class ManagementContractListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { managementContractService: ManagementContractService; @@ -82,15 +108,15 @@ export class ManagementContractListComponent extends InfiniteScrollTable { - this.dataSource = data; + this.dataSource.set(data); }, () => {}, - () => (this.pending = false), + () => this.pending.set(false), ); this.searchCriteriaSub = merge(this.searchChange, this.filterChange, this.orderChange) @@ -118,12 +144,14 @@ export class ManagementContractListComponent extends InfiniteScrollTable { - const index = this.dataSource.findIndex( - (mngContract: ManagementContract) => mngContract.identifier === managementContract.identifier, - ); - if (index > -1) { - this.dataSource[index] = { ...managementContract }; - } + this.dataSource.update((contracts) => { + const list = [...(contracts ?? [])]; + const index = list.findIndex((mngContract: ManagementContract) => mngContract.identifier === managementContract.identifier); + if (index > -1) { + list[index] = { ...managementContract }; + } + return list; + }); }); } diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-identification-tab/management-contract-identification-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-identification-tab/management-contract-identification-tab.component.ts index d556ab11f0f..e63a2213413 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-identification-tab/management-contract-identification-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-identification-tab/management-contract-identification-tab.component.ts @@ -34,23 +34,31 @@ * 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, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, inject } from '@angular/core'; -import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnChanges, OnDestroy, Output, SimpleChanges } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of, Subscription } from 'rxjs'; import { mergeMap, tap } from 'rxjs/operators'; -import { PersistentIdentifierPolicyTypeEnum } from 'vitamui-library'; -import type { ManagementContract, Option } from 'vitamui-library'; +import { ManagementContract, Option, PersistentIdentifierPolicyTypeEnum, SelectComponent, TooltipDirective } from 'vitamui-library'; import { FormGroupToManagementContractConverterService } from '../../components/form-group-to-management-contract-converter.service'; import { ManagementContractToFormGroupConverterService } from '../../components/management-contract-to-form-group-converter.service'; import { ManagementContractService } from '../../management-contract.service'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { UpdatePersistentIdentifierPolicyFormComponent } from '../../components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; @Component({ selector: 'app-management-contract-identification-tab', templateUrl: './management-contract-identification-tab.component.html', styleUrls: ['./management-contract-identification-tab.component.scss'], providers: [ManagementContractToFormGroupConverterService], - standalone: false, + imports: [ + ReactiveFormsModule, + SelectComponent, + UpdatePersistentIdentifierPolicyFormComponent, + TooltipDirective, + MatProgressSpinner, + TranslatePipe, + ], }) export class ManagementContractIdentificationTabComponent implements OnChanges, OnDestroy { private managementContractToFormGroupConverterService = inject(ManagementContractToFormGroupConverterService); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.spec.ts index acffde38a43..a691bfd03da 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.spec.ts @@ -34,29 +34,23 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { BASE_URL, InjectorModule, IntermediaryVersionEnum, LoggerModule, ManagementContract, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, IntermediaryVersionEnum, LoggerModule, ManagementContract, WINDOW_LOCATION } from 'vitamui-library'; import { InputStubComponent, VitamUICommonTestModule } from 'vitamui-library/testing'; import { ManagementContractService } from '../../management-contract.service'; import { ManagementContractInformationTabComponent } from './management-contract-information-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { By } from '@angular/platform-browser'; describe('ManagementContractInformationTabComponent', () => { let component: ManagementContractInformationTabComponent; let fixture: ComponentFixture; - @Pipe({ - name: 'dateTime', - standalone: false, - }) + @Pipe({ name: 'dateTime' }) class DateTimeStubPipe implements PipeTransform { transform(value: string = ''): string { return value; @@ -108,18 +102,21 @@ describe('ManagementContractInformationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ManagementContractInformationTabComponent, DateTimeStubPipe], schemas: [NO_ERRORS_SCHEMA], - imports: [MatSidenavModule, InjectorModule, VitamUICommonTestModule, RouterTestingModule, LoggerModule.forRoot()], + imports: [ + MatSidenavModule, + InjectorModule, + VitamUICommonTestModule, + LoggerModule.forRoot(), + ManagementContractInformationTabComponent, + DateTimeStubPipe, + ], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: MatDialog, useValue: matDialogSpy }, { provide: ManagementContractService, useValue: managementContractServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.ts index 4145d9d39a5..ca9253536b2 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-information-tab/management-contract-information-tab.component.ts @@ -34,20 +34,21 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import { diff } from 'vitamui-library'; -import type { ManagementContract } from 'vitamui-library'; +import { diff, InputComponent, ManagementContract, PipesModule, SlideToggleComponent } from 'vitamui-library'; import { ManagementContractService } from '../../management-contract.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-management-contract-information-tab', templateUrl: './management-contract-information-tab.component.html', styleUrls: ['./management-contract-information-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SlideToggleComponent, InputComponent, MatProgressSpinner, PipesModule, TranslatePipe], }) export class ManagementContractInformationTabComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.spec.ts index 0ccdd8bce99..2eaa1a738f9 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.spec.ts @@ -34,25 +34,19 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA, Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { RouterTestingModule } from '@angular/router/testing'; -import { InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, IntermediaryVersionEnum, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ManagementContractPreviewComponent } from './management-contract-preview.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ManagementContractPreviewComponent', () => { let component: ManagementContractPreviewComponent; let fixture: ComponentFixture; - @Pipe({ - name: 'truncate', - standalone: false, - }) + @Pipe({ name: 'truncate' }) class TruncateStubPipe implements PipeTransform { transform(value: string = ''): string { return value; @@ -61,16 +55,21 @@ describe('ManagementContractPreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ManagementContractPreviewComponent, TruncateStubPipe], schemas: [NO_ERRORS_SCHEMA], - imports: [MatSidenavModule, InjectorModule, VitamUICommonTestModule, RouterTestingModule, LoggerModule.forRoot(), MatDialogModule], + imports: [ + MatSidenavModule, + InjectorModule, + VitamUICommonTestModule, + LoggerModule.forRoot(), + MatDialogModule, + ManagementContractPreviewComponent, + TruncateStubPipe, + ], providers: [ { provide: WINDOW_LOCATION, useValue: window.location, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); @@ -78,6 +77,29 @@ describe('ManagementContractPreviewComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ManagementContractPreviewComponent); component = fixture.componentInstance; + component.inputManagementContract = { + id: 'contractId', + name: 'Contrat de gestion avec stockage', + identifier: 'MCDefaultStorageAll', + description: 'Contrat de gestion valide déclarant pas de surcharge pour le stockage avec la stratégie par défaut', + status: 'ACTIVE', + lastUpdate: '10/12/2016', + creationDate: '10/12/2016', + activationDate: '10/12/2016', + deactivationDate: '10/12/2016', + tenant: 10, + version: 2, + storage: { + unitStrategy: 'default', + objectGroupStrategy: 'default', + objectStrategy: 'default', + }, + versionRetentionPolicy: { + usages: null, + initialVersion: true, + intermediaryVersionEnum: IntermediaryVersionEnum.ALL, + }, + }; fixture.detectChanges(); }); @@ -97,12 +119,4 @@ describe('ManagementContractPreviewComponent', () => { expect(component.tabUpdated.length).toEqual(2); expect(component.tabUpdated).toEqual(expectedArray); }); - - describe('DOM', () => { - it('should have 4 angular mat tab', () => { - const nativeElement = fixture.nativeElement; - const elementMatTab = nativeElement.querySelectorAll('mat-tab'); - expect(elementMatTab.length).toBe(4); - }); - }); }); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.ts index b5386634dc6..a674bb3b88d 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.component.ts @@ -39,28 +39,53 @@ import { Component, EventEmitter, HostListener, + inject, Input, OnChanges, Output, SimpleChanges, ViewChild, - inject, } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; import { Subscription } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { ConfirmActionComponent } from 'vitamui-library'; -import type { ManagementContract } from 'vitamui-library'; +import { + ConfirmActionComponent, + ManagementContract, + OperationHistoryTabComponent, + PipesModule, + VitamuiMenuButtonComponent, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; import { ManagementContractIdentificationTabComponent } from './management-contract-identification-tab/management-contract-identification-tab.component'; import { ManagementContractInformationTabComponent } from './management-contract-information-tab/management-contract-information-tab.component'; import { ManagementContractStorageTabComponent } from './management-contract-storage-tab/management-contract-storage-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-management-contract-preview', templateUrl: './management-contract-preview.component.html', styleUrls: ['./management-contract-preview.component.scss'], - standalone: false, + imports: [ + VitamuiMenuButtonComponent, + MatTabGroup, + MatTab, + ManagementContractInformationTabComponent, + ManagementContractStorageTabComponent, + ManagementContractIdentificationTabComponent, + OperationHistoryTabComponent, + PipesModule, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ManagementContractPreviewComponent implements OnChanges, AfterViewInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.module.ts deleted file mode 100644 index a1c8b2a1c4e..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-preview.module.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { PersistentIdentifierFormModule } from '../components/update-persistent-identifier-policy-form/update-persistent-identifier-policy-form.module'; -import { ManagementContractIdentificationTabComponent } from './management-contract-identification-tab/management-contract-identification-tab.component'; -import { ManagementContractInformationTabComponent } from './management-contract-information-tab/management-contract-information-tab.component'; -import { ManagementContractPreviewComponent } from './management-contract-preview.component'; -import { ManagementContractStorageTabComponent } from './management-contract-storage-tab/management-contract-storage-tab.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - RouterModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatSidenavModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - PersistentIdentifierFormModule, - TranslatePipe, - ], - declarations: [ - ManagementContractPreviewComponent, - ManagementContractInformationTabComponent, - ManagementContractStorageTabComponent, - ManagementContractIdentificationTabComponent, - ], - exports: [ManagementContractPreviewComponent], -}) -export class ManagementContractPreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.spec.ts index b8ec3385452..72cfe0d6756 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.spec.ts @@ -34,19 +34,16 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { BASE_URL, InjectorModule, IntermediaryVersionEnum, LoggerModule, ManagementContract, WINDOW_LOCATION } from 'vitamui-library'; +import { InjectorModule, IntermediaryVersionEnum, LoggerModule, ManagementContract, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ManagementContractService } from '../../management-contract.service'; import { ManagementContractStorageTabComponent } from './management-contract-storage-tab.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ManagementContractStorageTabComponent', () => { let component: ManagementContractStorageTabComponent; @@ -97,18 +94,14 @@ describe('ManagementContractStorageTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ManagementContractStorageTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [MatSidenavModule, InjectorModule, VitamUICommonTestModule, RouterTestingModule, LoggerModule.forRoot()], + imports: [MatSidenavModule, InjectorModule, VitamUICommonTestModule, LoggerModule.forRoot(), ManagementContractStorageTabComponent], providers: [ FormBuilder, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: WINDOW_LOCATION, useValue: window.location }, { provide: MatDialog, useValue: matDialogSpy }, { provide: ManagementContractService, useValue: managementContractServiceMock }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.ts index 89a5ca7fb65..7ccbda55303 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract-preview/management-contract-storage-tab/management-contract-storage-tab.component.ts @@ -34,20 +34,21 @@ * 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, EventEmitter, Input, OnDestroy, Output, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Observable, Subscription, of } from 'rxjs'; +import { Component, EventEmitter, inject, Input, OnDestroy, Output } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { Observable, of, Subscription } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { ManagementContract, StorageStrategy } from 'vitamui-library'; -import { diff } from 'vitamui-library'; +import { diff, InputComponent, ManagementContract, StorageStrategy } from 'vitamui-library'; import { ManagementContractService } from '../../management-contract.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-management-contract-storage-tab', templateUrl: './management-contract-storage-tab.component.html', styleUrls: ['./management-contract-storage-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, InputComponent, MatProgressSpinner, TranslatePipe], }) export class ManagementContractStorageTabComponent implements OnDestroy { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.spec.ts index 118beddc53c..b9fe5a7b5f4 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.spec.ts @@ -34,20 +34,17 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { ApplicationService, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; +import { Application, ApplicationService, InjectorModule, LoggerModule, WINDOW_LOCATION } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ManagementContractComponent } from './management-contract.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ManagementContractComponent', () => { let component: ManagementContractComponent; @@ -55,6 +52,10 @@ describe('ManagementContractComponent', () => { const applicationServiceSpy = { isApplicationExternalIdentifierEnabled: vi.fn().mockName('ApplicationService.isApplicationExternalIdentifierEnabled'), + getAppById: () => + of({ + name: 'App name', + } satisfies Partial), }; applicationServiceSpy.isApplicationExternalIdentifierEnabled.mockReturnValue(of(true)); @@ -66,30 +67,31 @@ describe('ManagementContractComponent', () => { matDialogSpy.open.mockReturnValue({ afterClosed: () => of(true) }); await TestBed.configureTestingModule({ - declarations: [ManagementContractComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ ReactiveFormsModule, MatSidenavModule, InjectorModule, VitamUICommonTestModule, - RouterTestingModule, LoggerModule.forRoot(), BrowserAnimationsModule, - NoopAnimationsModule, + ManagementContractComponent, ], providers: [ { provide: ActivatedRoute, - useValue: { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'MANAGEMENT_CONTRACT_APP' }) }, + useValue: { + params: of({ tenantIdentifier: 1 }), + data: of({ appId: 'MANAGEMENT_CONTRACT_APP' }), + snapshot: { data: { appId: 'MANAGEMENT_CONTRACT_APP' } }, + }, }, { provide: MatDialog, useValue: matDialogSpy }, { provide: WINDOW_LOCATION, useValue: window.location }, - { provide: ApplicationService, useValue: applicationServiceSpy }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], - }).compileComponents(); + }) + .overrideProvider(ApplicationService, { useValue: applicationServiceSpy }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.ts index 689d2a9f778..069c3fa39a5 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.component.ts @@ -34,24 +34,44 @@ * 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, ViewChild, inject } from '@angular/core'; +import { Component, inject, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { firstValueFrom } from 'rxjs'; -import { ApplicationService, GlobalEventService, ManagementContract, SidenavPage } from 'vitamui-library'; +import { + ApplicationService, + ManagementContract, + SidenavPage, + TooltipDirective, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { ManagementContractCreateComponent } from './management-contract-create/management-contract-create.component'; import { ManagementContractListComponent } from './management-contract-list/management-contract-list.component'; import { shareReplay } from 'rxjs/operators'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { ManagementContractPreviewComponent } from './management-contract-preview/management-contract-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-management-contract', templateUrl: './management-contract.component.html', styleUrls: ['./management-contract.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + ManagementContractPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + TooltipDirective, + ManagementContractListComponent, + TranslatePipe, + ], }) export class ManagementContractComponent extends SidenavPage { dialog = inject(MatDialog); - private route: ActivatedRoute; + private route = inject(ActivatedRoute); private applicationService = inject(ApplicationService); @ViewChild(ManagementContractListComponent, { static: true }) managementContractListComponent: ManagementContractListComponent; @@ -63,13 +83,9 @@ export class ManagementContractComponent extends SidenavPage #isSlaveMode$ = this.applicationService.isApplicationExternalIdentifierEnabled('MANAGEMENT_CONTRACT').pipe(shareReplay(1)); constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); + super(); - super(route, globalEventService); - this.route = route; - - globalEventService.tenantEvent.subscribe(() => { + this.globalEventService.tenantEvent.subscribe(() => { this.refreshList(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.module.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.module.ts index 6c12b2fff20..3a33ad14e8d 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.module.ts @@ -45,14 +45,13 @@ import { MatTabsModule } from '@angular/material/tabs'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule } from 'vitamui-library'; import { ManagementContractListComponent } from './management-contract-list/management-contract-list.component'; -import { ManagementContractPreviewModule } from './management-contract-preview/management-contract-preview.module'; + import { ManagementContractRoutingModule } from './management-contract-routing.module'; import { ManagementContractComponent } from './management-contract.component'; import { ManagementContractCreateComponent } from './management-contract-create/management-contract-create.component'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [ManagementContractComponent, ManagementContractListComponent], imports: [ CommonModule, RouterModule, @@ -65,9 +64,10 @@ import { TranslatePipe } from '@ngx-translate/core'; MatProgressSpinnerModule, MatTabsModule, ManagementContractRoutingModule, - ManagementContractPreviewModule, ManagementContractCreateComponent, TranslatePipe, + ManagementContractComponent, + ManagementContractListComponent, ], }) export class ManagementContractModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.service.ts b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.service.ts index 79ca68f358b..17cdc9cc57f 100644 --- a/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/management-contract/management-contract.service.ts @@ -35,11 +35,11 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders, HttpParams } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Observable, Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; -import { ManagementContract, SearchService, VitamuiHttpHeaders, SnackBarService } from 'vitamui-library'; +import { ManagementContract, SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { ManagementContractsApiService } from '../core/api/management-contracts-api.service'; diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-create/ontology-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-create/ontology-create.component.spec.ts index 6a3105025cd..824f4f45e91 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-create/ontology-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-create/ontology-create.component.spec.ts @@ -43,7 +43,6 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService, VitamUILibraryModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -105,7 +104,6 @@ describe('OntologyCreateComponent', () => { MatProgressBarModule, MatProgressSpinnerModule, MatSelectModule, - NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule, VitamUILibraryModule, diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.html b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.html index b4870a54128..5c9b2c4b248 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.html @@ -48,7 +48,7 @@ - @for (ontology of dataSource; track ontology) { + @for (ontology of dataSource(); track ontology) { {{ ontology.shortName }} @@ -74,13 +74,13 @@ } - @if (!dataSource || pending) { + @if (!dataSource() || pending()) { } - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) { } - @if (infiniteScrollDisabled && ontologyService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && ontologyService.canLoadMore && !pending()) { }
diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.spec.ts index 505a8ed3b7f..b90c7809dc1 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.spec.ts @@ -38,20 +38,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { TranslateLoader } from '@ngx-translate/core'; -import { EMPTY, Observable, of } from 'rxjs'; -import { AuthService, BASE_URL, Ontology, TenantSelectionService } from 'vitamui-library'; +import { EMPTY, of } from 'rxjs'; +import { AuthService, Ontology, TenantSelectionService } from 'vitamui-library'; import { OntologyListComponent } from './ontology-list.component'; import { OntologyService } from '../../ontology.service'; -const translations: any = { TEST: 'Mock translate test' }; - -class FakeLoader implements TranslateLoader { - getTranslation(): Observable { - return of(translations); - } -} - describe('OntologyListComponent', () => { let component: OntologyListComponent; let fixture: ComponentFixture; @@ -73,7 +64,6 @@ describe('OntologyListComponent', () => { declarations: [], imports: [OntologyListComponent], providers: [ - { provide: BASE_URL, useValue: '' }, { provide: MatDialog, useValue: {} }, { provide: OntologyService, useValue: ontologyServiceMock }, { provide: AuthService, useValue: { user: { proofTenantIdentifier: '1' } } }, diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.ts index 8ee3913d3d3..67e71042448 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/ontology-list/ontology-list.component.ts @@ -102,13 +102,13 @@ export class OntologyListComponent extends InfiniteScrollTable impleme } ngOnInit() { - this.pending = true; + this.pending.set(true); this.ontologyService .search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.shortName, Direction.ASCENDANT)) - .pipe(finalize(() => (this.pending = false))) + .pipe(finalize(() => this.pending.set(false))) .subscribe({ next: (data: Ontology[]) => { - this.dataSource = data; + this.dataSource.set(data); }, error: (e) => console.error(e), }); @@ -170,10 +170,14 @@ export class OntologyListComponent extends InfiniteScrollTable impleme private replaceUpdatedOntology(): void { this.subscriptions.add( this.ontologyService.updated.pipe(takeUntil(this.destroy$)).subscribe((updatedOntology: Ontology) => { - const index = this.dataSource.findIndex((item: Ontology) => item.id === updatedOntology.id); - if (index !== -1) { - this.dataSource[index] = updatedOntology; - } + this.dataSource.update((ontologies) => { + const list = [...(ontologies ?? [])]; + const index = list.findIndex((item: Ontology) => item.id === updatedOntology.id); + if (index !== -1) { + list[index] = updatedOntology; + } + return list; + }); }), ); } diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-delete-dialog/schema-delete-dialog.component.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-delete-dialog/schema-delete-dialog.component.ts index b1a2139ecf8..64e19b2672f 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-delete-dialog/schema-delete-dialog.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-delete-dialog/schema-delete-dialog.component.ts @@ -38,7 +38,7 @@ import { Component, inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { I18nPluralPipe } from '@angular/common'; -import { SchemaService, StartupService, SnackBarService, VitamUILibraryModule } from 'vitamui-library'; +import { SchemaService, SnackBarService, StartupService, VitamUILibraryModule } from 'vitamui-library'; import { finalize } from 'rxjs'; export type SchemaDeleteDialogComponentData = string[]; diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.spec.ts index e2395e0908f..0866f1bea19 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.spec.ts @@ -39,7 +39,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { of } from 'rxjs'; -import { AuthService, BASE_URL, SchemaService, TenantSelectionService } from 'vitamui-library'; +import { AuthService, SchemaService, TenantSelectionService } from 'vitamui-library'; import { SchemaListComponent } from './schema-list.component'; describe('SchemaListComponent', () => { @@ -61,7 +61,6 @@ describe('SchemaListComponent', () => { declarations: [], imports: [SchemaListComponent], providers: [ - { provide: BASE_URL, useValue: '' }, { provide: MatDialog, useValue: {} }, { provide: SchemaService, useValue: schemaServiceMock }, { provide: TenantSelectionService, useValue: tenantSelectionServiceMock }, diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.ts index 147969df8ce..8b642bedd98 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-group/schema-list/schema-list.component.ts @@ -34,11 +34,10 @@ * 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, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, QueryList, ViewChildren, inject } from '@angular/core'; +import { Component, ElementRef, EventEmitter, inject, Input, OnDestroy, OnInit, Output, QueryList, ViewChildren } from '@angular/core'; import { finalize, Subscription } from 'rxjs'; import { ClickOutsideDirective, - CommonTooltipModule, ItemFlatNode, ItemNode, ItemNodeUtils, @@ -46,6 +45,7 @@ import { SchemaElement, SchemaService, TenantSelectionService, + TooltipDirective, VitamUICommonModule, } from 'vitamui-library'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; @@ -68,7 +68,7 @@ import { SchemaDeleteDialogComponent, SchemaDeleteDialogComponentData } from './ MatButtonToggleModule, MatButtonModule, MatProgressSpinnerModule, - CommonTooltipModule, + TooltipDirective, ClickOutsideDirective, ], selector: 'app-schema-list', diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.spec.ts index cd14856b323..b41fa5b4baf 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.spec.ts @@ -40,7 +40,6 @@ import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; import { Ontology, SecurityService, VitamUILibraryModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -75,15 +74,7 @@ describe('OntologyInformationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ - MatFormFieldModule, - MatInputModule, - MatSelectModule, - NoopAnimationsModule, - ReactiveFormsModule, - VitamUICommonTestModule, - VitamUILibraryModule, - ], + imports: [MatFormFieldModule, MatInputModule, MatSelectModule, ReactiveFormsModule, VitamUICommonTestModule, VitamUILibraryModule], providers: [ FormBuilder, { provide: OntologyService, useValue: ontologyServiceMock }, diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.ts index 04bde3cad06..c8fed9d466b 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/ontology-information-tab/ontology-information-tab.component.ts @@ -38,10 +38,11 @@ import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, switchMap } from 'rxjs/operators'; -import type { Ontology, Option } from 'vitamui-library'; import { ApplicationId, diff, + Ontology, + Option, Role, SecurityService, setTypeDetailAndStringSize, diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.spec.ts index 5a2736abc49..860e2b02085 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.spec.ts @@ -43,7 +43,6 @@ import { of } from 'rxjs'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { NO_ERRORS_SCHEMA } from '@angular/core'; @@ -80,15 +79,7 @@ describe('SchemaInformationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ - MatFormFieldModule, - MatInputModule, - MatSelectModule, - NoopAnimationsModule, - ReactiveFormsModule, - VitamUICommonTestModule, - VitamUILibraryModule, - ], + imports: [MatFormFieldModule, MatInputModule, MatSelectModule, ReactiveFormsModule, VitamUICommonTestModule, VitamUILibraryModule], providers: [FormBuilder, { provide: SchemaService, useValue: schemaServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.ts index 05c44e94735..73737605d86 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology-preview/schema-information-tab/schema-information-tab.component.ts @@ -36,8 +36,7 @@ */ import { Component, inject, Input } from '@angular/core'; import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; -import type { Option, SchemaElement } from 'vitamui-library'; -import { SchemaService, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; +import { Option, SchemaElement, SchemaService, VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; import { sizes, types } from '../../ontology-form-options'; import { TranslatePipe } from '@ngx-translate/core'; diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.spec.ts index 3d6bcb3ad30..759ec2b9531 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.spec.ts @@ -38,18 +38,17 @@ import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { InjectorModule, LoggerModule, SchemaService, SecurityService, StartupService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { OntologyComponent } from './ontology.component'; import { OntologyService } from './ontology.service'; +import { EMPTY } from 'rxjs'; @Component({ selector: 'app-ontology-preview', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class OntologyPreviewStub { @Input() @@ -59,7 +58,7 @@ class OntologyPreviewStub { @Component({ selector: 'app-ontology-list', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class OntologyListStub {} @@ -69,20 +68,20 @@ describe('OntologyComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [OntologyComponent, OntologyListStub, OntologyPreviewStub], imports: [ VitamUICommonTestModule, - RouterTestingModule, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, MatSidenavModule, MatDialogModule, + OntologyComponent, + OntologyListStub, + OntologyPreviewStub, ], schemas: [NO_ERRORS_SCHEMA], providers: [ - { provide: OntologyService, useValue: {} }, - { provide: SchemaService, useValue: {} }, + { provide: OntologyService, useValue: { search: () => EMPTY, updated: EMPTY } }, + { provide: SchemaService, useValue: { getSchemaTreeByCategory: () => EMPTY } }, { provide: StartupService, useValue: { getConfigStringValue: (_param: string) => '' } }, { provide: SecurityService, diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.ts index cdb8adae6ed..7b316358596 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology.component.ts @@ -38,11 +38,11 @@ import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ApplicationId, + ClickOutsideDirective, FileTypes, - GlobalEventService, Ontology, Role, SchemaElement, @@ -50,6 +50,9 @@ import { SecurityService, SidenavPage, StartupService, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + VitamuiTitleBreadcrumbComponent, } from 'vitamui-library'; import { ImportDialogParam, ReferentialTypes } from '../shared/import-dialog/import-dialog-param.interface'; import { ImportDialogComponent } from '../shared/import-dialog/import-dialog.component'; @@ -57,16 +60,32 @@ import { OntologyCreateComponent } from './ontology-create/ontology-create.compo import { OntologyListComponent } from './ontology-group/ontology-list/ontology-list.component'; import { Subscription } from 'rxjs'; import { OntologyService } from './ontology.service'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { OntologyPreviewComponent } from './ontology-preview/ontology-preview.component'; +import { MatMenuItem } from '@angular/material/menu'; +import { OntologyGroupComponent } from './ontology-group/ontology-group.component'; @Component({ selector: 'app-ontology', templateUrl: './ontology.component.html', styleUrls: ['./ontology.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + ClickOutsideDirective, + OntologyPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + MatMenuItem, + OntologyGroupComponent, + TranslatePipe, + ], }) export class OntologyComponent extends SidenavPage implements OnInit, OnDestroy { dialog = inject(MatDialog); - route: ActivatedRoute; + private route = inject(ActivatedRoute); private translateService = inject(TranslateService); private securityService = inject(SecurityService); private ontologyService = inject(OntologyService); @@ -84,15 +103,6 @@ export class OntologyComponent extends SidenavPage imp canImportSchema: boolean; canCreateVocabulary: boolean; - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - - this.route = route; - } - ngOnInit(): void { this.vitamAdminTenant = +this.startupService.getConfigStringValue('VITAM_ADMIN_TENANT'); this.initializeTenantId(); diff --git a/ui/ui-frontend/projects/referential/src/app/ontology/ontology.module.ts b/ui/ui-frontend/projects/referential/src/app/ontology/ontology.module.ts index 531d5e7eac2..9b6c5017e54 100644 --- a/ui/ui-frontend/projects/referential/src/app/ontology/ontology.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/ontology/ontology.module.ts @@ -44,7 +44,7 @@ import { RouterModule } from '@angular/router'; import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; import { OntologyRoutingModule } from './ontology-routing.module'; import { OntologyComponent } from './ontology.component'; -import { ImportDialogModule } from '../shared/import-dialog/import-dialog.module'; + import { OntologyGroupComponent } from './ontology-group/ontology-group.component'; import { OntologyPreviewComponent } from './ontology-preview/ontology-preview.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -52,7 +52,6 @@ import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ imports: [ CommonModule, - ImportDialogModule, MatDialogModule, MatMenuModule, MatProgressSpinnerModule, @@ -64,7 +63,7 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, VitamUILibraryModule, TranslatePipe, + OntologyComponent, ], - declarations: [OntologyComponent], }) export class OntologyModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/griffin-list/griffin-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/griffin-list/griffin-list.component.spec.ts index 058b4f42a53..8361c237ebb 100644 --- a/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/griffin-list/griffin-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/griffin-list/griffin-list.component.spec.ts @@ -35,14 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { HttpErrorResponse, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpErrorResponse } from '@angular/common/http'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { MatDialog } from '@angular/material/dialog'; import { EMPTY, of, throwError } from 'rxjs'; import type { Mock, MockInstance } from 'vitest'; -import { BASE_URL, Griffin, GriffinsService, LoggerModule, SnackBarService, StartupService, TenantSelectionService } from 'vitamui-library'; +import { Griffin, GriffinsService, LoggerModule, SnackBarService, StartupService, TenantSelectionService } from 'vitamui-library'; import { GriffinListComponent } from './griffin-list.component'; @@ -106,9 +105,6 @@ describe('GriffinListComponent', () => { await TestBed.configureTestingModule({ imports: [GriffinListComponent, LoggerModule.forRoot()], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), { provide: GriffinsService, useValue: griffinsService }, { provide: SnackBarService, useValue: snackBarService }, { provide: StartupService, useValue: startupService }, diff --git a/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/preservation-scenario-list/preservation-scenario-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/preservation-scenario-list/preservation-scenario-list.component.spec.ts index baa91827816..12f17f40d60 100644 --- a/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/preservation-scenario-list/preservation-scenario-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/preservation/preservation-group/preservation-scenario-list/preservation-scenario-list.component.spec.ts @@ -35,14 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import { HttpErrorResponse, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpErrorResponse } from '@angular/common/http'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { MatDialog } from '@angular/material/dialog'; import { EMPTY, of, throwError } from 'rxjs'; import type { Mock, MockInstance } from 'vitest'; -import { BASE_URL, LoggerModule, PreservationScenario, PreservationScenariosService, SnackBarService } from 'vitamui-library'; +import { LoggerModule, PreservationScenario, PreservationScenariosService, SnackBarService } from 'vitamui-library'; import { PreservationScenarioListComponent } from './preservation-scenario-list.component'; @@ -84,9 +83,6 @@ describe('PreservationScenarioListComponent', () => { await TestBed.configureTestingModule({ imports: [PreservationScenarioListComponent, LoggerModule.forRoot()], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), { provide: PreservationScenariosService, useValue: preservationScenariosService }, { provide: SnackBarService, useValue: snackBarService }, ], diff --git a/ui/ui-frontend/projects/referential/src/app/preservation/preservation.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/preservation/preservation.component.spec.ts index 7596d7d919c..3bd77b26c59 100644 --- a/ui/ui-frontend/projects/referential/src/app/preservation/preservation.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/preservation/preservation.component.spec.ts @@ -38,9 +38,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PreservationComponent } from './preservation.component'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { BASE_URL, InjectorModule, LoggerModule, SecurityService, VitamUICommonModule } from 'vitamui-library'; +import { InjectorModule, LoggerModule, SecurityService, VitamUICommonModule } from 'vitamui-library'; import { ActivatedRoute } from '@angular/router'; import { of } from 'rxjs'; @@ -56,9 +54,6 @@ describe('PreservationComponent', () => { await TestBed.configureTestingModule({ imports: [PreservationComponent, LoggerModule.forRoot(), VitamUICommonModule, InjectorModule], providers: [ - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ActivatedRoute, useValue: { diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.spec.ts index fa13f0b2a72..92f2a014911 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.spec.ts @@ -40,7 +40,6 @@ import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService, @@ -74,12 +73,11 @@ describe('ProbativeValueCreateComponent', () => { ReactiveFormsModule, MatSelectModule, MatButtonToggleModule, - NoopAnimationsModule, MatProgressBarModule, VitamUICommonTestModule, VitamUILibraryModule, + ProbativeValueCreateComponent, ], - declarations: [ProbativeValueCreateComponent], providers: [ FormBuilder, { provide: MatDialogRef, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.ts index 48cb174b3dc..61f4e10443e 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.component.ts @@ -35,30 +35,45 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders } from '@angular/common/http'; -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ConfirmDialogService, + DialogHeaderComponent, ExternalParameters, ExternalParametersService, + InputComponent, Option, SearchResponse, SearchUnitApiService, + SelectComponent, SigningRoleType, SnackBarService, VitamuiHttpHeaders, } from 'vitamui-library'; import { ProbativeValueService } from '../probative-value.service'; import { sizes } from '../../ontology/ontology-form-options'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-probative-value-create', templateUrl: './probative-value-create.component.html', styleUrls: ['./probative-value-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + MatDialogContent, + InputComponent, + SelectComponent, + MatButtonToggleGroup, + MatButtonToggle, + MatDialogActions, + TranslatePipe, + ], }) export class ProbativeValueCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.module.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.module.ts deleted file mode 100644 index 6a6c353a152..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-create/probative-value-create.module.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { ProbativeValueCreateComponent } from './probative-value-create.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [ProbativeValueCreateComponent], - imports: [ - CommonModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - VitamUILibraryModule, - MatDialogModule, - TranslatePipe, - ], -}) -export class ProbativeValueCreateModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.html b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.html index 2319c399e1c..93362c4ddfd 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.html @@ -35,7 +35,7 @@
- @for (value of dataSource; track value) { + @for (value of dataSource(); track value) {
@@ -52,15 +52,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && probativeValueService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && probativeValueService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.spec.ts index 1a7f1962e00..789f5441ae4 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.spec.ts @@ -49,8 +49,7 @@ describe('ProbativeValueListComponent', () => { search: () => of(null), }; await TestBed.configureTestingModule({ - imports: [], - declarations: [ProbativeValueListComponent], + imports: [ProbativeValueListComponent], providers: [{ provide: ProbativeValueService, useValue: probativeValueServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.ts index 3dd14c0ed86..baec12334f9 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-list/probative-value-list.component.ts @@ -34,12 +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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { merge, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, PageRequest } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, +} from 'vitamui-library'; import { ProbativeValueService } from '../probative-value.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { LastEventPipe } from '../../shared/pipes/last-event.pipe'; +import { EventTypeBadgeClassPipe } from '../../shared/pipes/event-type-badge-class.pipe'; +import { EventTypeColorClassPipe } from '../../shared/pipes/event-type-color-class.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -52,7 +67,19 @@ export class ProbativeValueFilters { selector: 'app-probative-value-list', templateUrl: './probative-value-list.component.html', styleUrls: ['./probative-value-list.component.scss'], - standalone: false, + imports: [ + OrderByButtonComponent, + NgClass, + MatProgressSpinner, + PipesModule, + LastEventPipe, + EventTypeBadgeClassPipe, + EventTypeColorClassPipe, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class ProbativeValueListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { probativeValueService: ProbativeValueService; @@ -104,7 +131,7 @@ export class ProbativeValueListComponent extends InfiniteScrollTable implem JSON.stringify(this.buildProbativeValueCriteriaFromSearch()), ), ) - .subscribe((data: any[]) => (this.dataSource = data)); + .subscribe((data: any[]) => this.dataSource.set(data)); const searchCriteriaChange = merge(this.searchChange, this.orderChange, this.filterChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.spec.ts index e0570962d97..7f254bb65fe 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.spec.ts @@ -43,10 +43,7 @@ import { ProbativeValueService } from '../probative-value.service'; import { ProbativeValuePreviewComponent } from './probative-value-preview.component'; import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -68,8 +65,7 @@ describe('ProbativeValuePreviewComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [ProbativeValuePreviewComponent, MockTruncatePipe], - imports: [EventTypeBadgeColorPipe], + imports: [EventTypeBadgeColorPipe, ProbativeValuePreviewComponent, MockTruncatePipe], providers: [ { provide: ExternalParametersService, useValue: externalParametersServiceMock }, { provide: ProbativeValueService, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.ts index 77f2238697e..6bfd672572c 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.component.ts @@ -34,18 +34,37 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { finalize, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import { ExternalParameters, ExternalParametersService, SnackBarService } from 'vitamui-library'; +import { + ExternalParameters, + ExternalParametersService, + PipesModule, + SnackBarService, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; import { ProbativeValueService } from '../probative-value.service'; +import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-probative-value-preview', templateUrl: './probative-value-preview.component.html', styleUrls: ['./probative-value-preview.component.scss'], - standalone: false, + imports: [ + PipesModule, + EventTypeBadgeColorPipe, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class ProbativeValuePreviewComponent implements OnInit, OnDestroy { private probativeValueService = inject(ProbativeValueService); diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.module.ts deleted file mode 100644 index e931d409885..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value-preview/probative-value-preview.module.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { PipesModule } from '../../shared/pipes/pipes.module'; -import { ProbativeValuePreviewComponent } from './probative-value-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [ProbativeValuePreviewComponent], - imports: [ - CommonModule, - RouterModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatSidenavModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - PipesModule, - TranslatePipe, - ], - exports: [ProbativeValuePreviewComponent], -}) -export class ProbativeValuePreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.spec.ts index 72a0428617c..77ccde17402 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.spec.ts @@ -41,14 +41,12 @@ import { MatDialog } from '@angular/material/dialog'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Router } from '@angular/router'; import { of } from 'rxjs'; -import { BASE_URL, DatepickerComponent, InjectorModule, LoggerModule } from 'vitamui-library'; +import { DatepickerComponent, InjectorModule, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { ProbativeValueComponent } from './probative-value.component'; -import { PipesModule } from '../shared/pipes/pipes.module'; import { DatePipe } from '@angular/common'; import { provideNativeDateAdapter } from '@angular/material/core'; @@ -60,6 +58,7 @@ describe('ProbativeValueComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'PROBATIVE_VALUE_APP' }), + snapshot: { data: { appId: 'PROBATIVE_VALUE_APP' } }, }; await TestBed.configureTestingModule({ imports: [ @@ -69,15 +68,12 @@ describe('ProbativeValueComponent', () => { MatSelectModule, MatSidenavModule, DatepickerComponent, - NoopAnimationsModule, - PipesModule, ReactiveFormsModule, VitamUICommonTestModule, + ProbativeValueComponent, ], - declarations: [ProbativeValueComponent], providers: [ provideNativeDateAdapter(), - { provide: BASE_URL, useValue: '/pastis-api' }, DatePipe, FormBuilder, { provide: MatDialog, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.ts index 3ee6a2e960f..8e50dedc116 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.component.ts @@ -34,25 +34,46 @@ * 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, OnDestroy, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { Component, inject, OnDestroy, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { Event, GlobalEventService, SearchBarComponent, SidenavPage } from 'vitamui-library'; +import { + DatepickerComponent, + Event, + SearchBarComponent, + SidenavPage, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { ProbativeValueCreateComponent } from './probative-value-create/probative-value-create.component'; import { ProbativeValueListComponent } from './probative-value-list/probative-value-list.component'; import { DateTime } from 'luxon'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { ProbativeValuePreviewComponent } from './probative-value-preview/probative-value-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-probative-value', templateUrl: './probative-value.component.html', styleUrls: ['./probative-value.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + ProbativeValuePreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ReactiveFormsModule, + DatepickerComponent, + ProbativeValueListComponent, + TranslatePipe, + ], }) export class ProbativeValueComponent extends SidenavPage implements OnDestroy { dialog = inject(MatDialog); private router = inject(Router); - private route: ActivatedRoute; + private route = inject(ActivatedRoute); private formBuilder = inject(FormBuilder); search: string; @@ -65,11 +86,7 @@ export class ProbativeValueComponent extends SidenavPage implements OnDes @ViewChild(ProbativeValueListComponent, { static: true }) probativeValueListComponent: ProbativeValueListComponent; constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - this.route = route; + super(); this.dateRangeFilterForm = this.formBuilder.group({ startDate: null, diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.module.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.module.ts index 235117dda2f..6aad485e398 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.module.ts @@ -46,20 +46,17 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule } from 'vitamui-library'; -import { ProbativeValueCreateModule } from './probative-value-create/probative-value-create.module'; -import { ProbativeValuePreviewModule } from './probative-value-preview/probative-value-preview.module'; import { ProbativeValueRoutingModule } from './probative-value-routing.module'; import { ProbativeValueComponent } from './probative-value.component'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; -import { PipesModule } from '../shared/pipes/pipes.module'; + import { ProbativeValueListComponent } from './probative-value-list/probative-value-list.component'; import { MAT_DATE_FORMATS } from '@angular/material/core'; import { FR_DATE_FORMAT } from '../helpers/dates.constants'; import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ - declarations: [ProbativeValueComponent, ProbativeValueListComponent], imports: [ CommonModule, RouterModule, @@ -67,8 +64,6 @@ import { TranslatePipe } from '@ngx-translate/core'; ReactiveFormsModule, VitamUICommonModule, ProbativeValueRoutingModule, - ProbativeValueCreateModule, - ProbativeValuePreviewModule, MatMenuModule, MatDialogModule, MatSidenavModule, @@ -77,8 +72,9 @@ import { TranslatePipe } from '@ngx-translate/core'; MatSelectModule, MatFormFieldModule, MatInputModule, - PipesModule, TranslatePipe, + ProbativeValueComponent, + ProbativeValueListComponent, ], providers: [{ provide: MAT_DATE_FORMATS, useValue: FR_DATE_FORMAT }], }) diff --git a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.service.ts b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.service.ts index ca2502b4767..0f59d3a69f6 100644 --- a/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/probative-value/probative-value.service.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { tap } from 'rxjs/operators'; import { Event, SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { OperationApiService } from '../core/api/operation-api.service'; diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts index ec370bba828..ba6bbc5defd 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts @@ -44,7 +44,6 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService, ManagementRuleValidators, RuleService, VitamUILibraryModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -103,7 +102,6 @@ describe('RuleCreateComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [RuleCreateComponent], imports: [ MatButtonToggleModule, MatDialogModule, @@ -111,10 +109,10 @@ describe('RuleCreateComponent', () => { MatProgressBarModule, MatProgressSpinnerModule, MatSelectModule, - NoopAnimationsModule, ReactiveFormsModule, VitamUICommonTestModule, VitamUILibraryModule, + RuleCreateComponent, ], providers: [ { provide: RuleService, useValue: ruleServiceSpy }, diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts index f31d9fe6e23..c4d5304bc90 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts @@ -34,20 +34,39 @@ * 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, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; import { Subscription } from 'rxjs'; -import { ConfirmDialogService, ManagementRuleValidators, Rule, RuleService } from 'vitamui-library'; +import { + ConfirmDialogService, + DialogHeaderComponent, + InputComponent, + ManagementRuleValidators, + Rule, + RuleService, + SelectComponent, + TooltipDirective, +} from 'vitamui-library'; import { RULE_MEASUREMENTS, RULE_TYPES } from '../rules.constants'; import { RuleCreateValidators } from './rule-create.validators'; import { sizes } from '../../ontology/ontology-form-options'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-rule-create', templateUrl: './rule-create.component.html', styleUrls: ['./rule-create.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + ReactiveFormsModule, + MatDialogContent, + InputComponent, + TooltipDirective, + SelectComponent, + MatDialogActions, + TranslatePipe, + ], }) export class RuleCreateComponent implements OnInit, OnDestroy { dialogRef = inject>(MatDialogRef); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.module.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.module.ts deleted file mode 100644 index 93533388c7a..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.module.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SharedModule } from '../../../../../identity/src/app/shared/shared.module'; -import { RuleCreateComponent } from './rule-create.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - SharedModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - MatDialogModule, - VitamUILibraryModule, - TranslatePipe, - ], - declarations: [RuleCreateComponent], -}) -export class RuleCreateModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.html b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.html index aa8afe1f30e..99aba81daf1 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.html @@ -42,7 +42,7 @@
- @for (rule of dataSource; track rule; let index = $index) { + @for (rule of dataSource(); track rule; let index = $index) {
@@ -71,15 +71,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && ruleService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && ruleService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts index da495313dcc..6b8b9dc1815 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts @@ -38,7 +38,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; import { of } from 'rxjs'; -import { AuthService, BASE_URL, Rule, RuleService, SnackBarService } from 'vitamui-library'; +import { AuthService, Rule, RuleService, SnackBarService } from 'vitamui-library'; import { RuleListComponent } from './rule-list.component'; describe('RuleListComponent', () => { @@ -52,10 +52,8 @@ describe('RuleListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [RuleListComponent], + imports: [RuleListComponent], providers: [ - { provide: BASE_URL, useValue: '' }, { provide: RuleService, useValue: ruleServiceMock }, { provide: AuthService, useValue: { user: { proofTenantIdentifier: '1' } } }, { provide: SnackBarService, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts index e7a715ef558..eaab68228d1 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts @@ -34,25 +34,35 @@ * 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, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { TranslateService } from '@ngx-translate/core'; -import { Subject, merge } from 'rxjs'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { merge, Subject } from 'rxjs'; import { debounceTime, filter } from 'rxjs/operators'; -import type { AdminUserProfile, Rule } from 'vitamui-library'; import { + AdminUserProfile, ApplicationId, AuthService, ConfirmActionComponent, DEFAULT_PAGE_SIZE, Direction, + EllipsisDirective, + HasRoleDirective, + InfiniteScrollDirective, InfiniteScrollTable, + OrderByButtonComponent, PageRequest, Role, + Rule, RuleService, SnackBarService, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, } from 'vitamui-library'; import { RULE_MEASUREMENTS, RULE_TYPES } from '../rules.constants'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -60,7 +70,18 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-rule-list', templateUrl: './rule-list.component.html', styleUrls: ['./rule-list.component.scss'], - standalone: false, + imports: [ + OrderByButtonComponent, + TableFilterDirective, + MatProgressSpinner, + TableFilterComponent, + TableFilterOptionComponent, + TranslatePipe, + CommonModule, + EllipsisDirective, + HasRoleDirective, + InfiniteScrollDirective, + ], }) export class RuleListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { ruleService: RuleService; @@ -126,7 +147,7 @@ export class RuleListComponent extends InfiniteScrollTable implements OnDe ngOnInit() { this.ruleService.search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, Direction.ASCENDANT)).subscribe((data: Rule[]) => { - this.dataSource = data; + this.dataSource.set(data); }); const searchCriteriaChange = merge(this.searchChange, this.orderChange, this.filterChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts index 916e4f78d54..2e1ca1db880 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts @@ -83,10 +83,10 @@ describe('RuleInformationTabComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'RULES_APP' }), + snapshot: { data: { appId: 'RULES_APP' } }, }; await TestBed.configureTestingModule({ - imports: [], - declarations: [RuleInformationTabComponent], + imports: [RuleInformationTabComponent], providers: [ FormBuilder, { provide: ActivatedRoute, useValue: activatedRouteMock }, diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts index 92c40b5cb42..008e1a888dc 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts @@ -34,15 +34,16 @@ * 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, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, mergeMap, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { Rule } from 'vitamui-library'; -import { RuleService, SecurityService, VitamuiRoles, diff } from 'vitamui-library'; +import { diff, InputComponent, Rule, RuleService, SecurityService, SelectComponent, VitamuiRoles } from 'vitamui-library'; import { RULE_MEASUREMENTS, RULE_TYPES } from '../../rules.constants'; +import { AsyncPipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; const RULES_APP = 'RULES_APP'; @@ -50,7 +51,7 @@ const RULES_APP = 'RULES_APP'; selector: 'app-rule-information-tab', templateUrl: './rule-information-tab.component.html', styleUrls: ['./rule-information-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SelectComponent, InputComponent, AsyncPipe, TranslatePipe], }) export class RuleInformationTabComponent implements OnInit { private route = inject(ActivatedRoute); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts index effdc0dbce4..6307b62f643 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts @@ -46,8 +46,7 @@ describe('RulePreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [RulePreviewComponent], + imports: [RulePreviewComponent], providers: [ { provide: MatDialog, useValue: {} }, { provide: RuleService, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts index 05faa72dd49..ea6171efb3f 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts @@ -34,19 +34,34 @@ * 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 { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, forwardRef, HostListener, inject, Input, Output, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; -import type { Rule } from 'vitamui-library'; -import { ConfirmActionComponent, RuleService } from 'vitamui-library'; +import { ConfirmActionComponent, OperationHistoryTabComponent, Rule, RuleService, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { RuleInformationTabComponent } from './rule-information-tab/rule-information-tab.component'; import { switchMap } from 'rxjs/operators'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-rule-preview', templateUrl: './rule-preview.component.html', styleUrls: ['./rule-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + RuleInformationTabComponent, + OperationHistoryTabComponent, + forwardRef(() => RulePreviewComponent), + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class RulePreviewComponent implements AfterViewInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.module.ts deleted file mode 100644 index 8c3a27568e0..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.module.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { RuleInformationTabComponent } from './rule-information-tab/rule-information-tab.component'; -import { RulePreviewComponent } from './rule-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - RouterModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatSidenavModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - TranslatePipe, - ], - declarations: [RulePreviewComponent, RuleInformationTabComponent], - exports: [RulePreviewComponent], -}) -export class RulePreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule.component.spec.ts index 20f387eac8f..3c0c1b9d665 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule.component.spec.ts @@ -35,8 +35,6 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { Component, Input } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { MatOptionModule } from '@angular/material/core'; @@ -45,30 +43,36 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; import { EMPTY, of } from 'rxjs'; -import type { Rule } from 'vitamui-library'; import { AuthService, - BASE_URL, ENVIRONMENT, GlobalEventService, InjectorModule, LoggerModule, + Rule, SecurityService, SnackBarService, } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { environment } from '../../environments/environment'; import { RuleComponent } from './rule.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'app-rule-preview', template: '', - standalone: false, + imports: [ + VitamUICommonTestModule, + ReactiveFormsModule, + MatMenuModule, + MatTabsModule, + MatOptionModule, + MatSelectModule, + MatSidenavModule, + MatDialogModule, + InjectorModule, + ], }) class RulePreviewStubComponent { @Input() @@ -78,7 +82,17 @@ class RulePreviewStubComponent { @Component({ selector: 'app-rule-list', template: '', - standalone: false, + imports: [ + VitamUICommonTestModule, + ReactiveFormsModule, + MatMenuModule, + MatTabsModule, + MatOptionModule, + MatSelectModule, + MatSidenavModule, + MatDialogModule, + InjectorModule, + ], }) class RuleListStubComponent { @Input() @@ -113,6 +127,7 @@ describe('RuleComponent', () => { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'RULE_APP' }), paramMap: EMPTY, + snapshot: { data: { appId: 'RULE_APP' } }, }; const securityServiceMock = { @@ -120,10 +135,7 @@ describe('RuleComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [RuleComponent, RuleListStubComponent, RulePreviewStubComponent], imports: [ - NoopAnimationsModule, - RouterTestingModule, VitamUICommonTestModule, ReactiveFormsModule, MatMenuModule, @@ -134,6 +146,9 @@ describe('RuleComponent', () => { MatDialogModule, InjectorModule, LoggerModule.forRoot(), + RuleComponent, + RuleListStubComponent, + RulePreviewStubComponent, ], providers: [ GlobalEventService, @@ -143,9 +158,6 @@ describe('RuleComponent', () => { { provide: AuthService, useValue: authServiceMock }, { provide: ENVIRONMENT, useValue: environment }, { provide: SecurityService, useValue: securityServiceMock }, - { provide: BASE_URL, useValue: '/fake-api' }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts index 72b7eb2360d..b6f7cedd0f6 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts @@ -37,24 +37,51 @@ import { Component, inject, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Observable } from 'rxjs'; -import { ApplicationId, FileTypes, GlobalEventService, Role, Rule, RuleService, SecurityService, SidenavPage } from 'vitamui-library'; +import { + ApplicationId, + FileTypes, + Role, + Rule, + RuleService, + SecurityService, + SidenavPage, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { ImportDialogParam, ReferentialTypes } from '../shared/import-dialog/import-dialog-param.interface'; import { ImportDialogComponent } from '../shared/import-dialog/import-dialog.component'; import { RuleCreateComponent } from './rule-create/rule-create.component'; import { RuleListComponent } from './rule-list/rule-list.component'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { RulePreviewComponent } from './rule-preview/rule-preview.component'; +import { MatMenuItem } from '@angular/material/menu'; +import { AsyncPipe } from '@angular/common'; @Component({ selector: 'app-rules', templateUrl: './rule.component.html', styleUrls: ['./rule.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + RulePreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + VitamuiMenuButtonComponent, + MatMenuItem, + RuleListComponent, + AsyncPipe, + TranslatePipe, + ], }) export class RuleComponent extends SidenavPage implements OnInit { ruleService = inject(RuleService); dialog = inject(MatDialog); - private route: ActivatedRoute; + private route = inject(ActivatedRoute); private router = inject(Router); private translateService = inject(TranslateService); private securityService = inject(SecurityService); @@ -71,13 +98,9 @@ export class RuleComponent extends SidenavPage implements OnInit { checkExportRole = new Observable(); constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); + super(); - super(route, globalEventService); - this.route = route; - - globalEventService.tenantEvent.subscribe(() => { + this.globalEventService.tenantEvent.subscribe(() => { this.refreshList(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule.module.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule.module.ts index 876aa0f38fd..89d54766fc8 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule.module.ts @@ -45,12 +45,12 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { RuleCreateModule } from './rule-create/rule-create.module'; + import { RuleListComponent } from './rule-list/rule-list.component'; -import { RulePreviewModule } from './rule-preview/rule-preview.module'; + import { RuleRoutingModule } from './rule-routing.module'; import { RuleComponent } from './rule.component'; -import { ImportDialogModule } from '../shared/import-dialog/import-dialog.module'; + import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ @@ -62,16 +62,14 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, VitamUILibraryModule, RuleRoutingModule, - RuleCreateModule, - RulePreviewModule, - ImportDialogModule, MatMenuModule, MatDialogModule, MatSidenavModule, MatProgressSpinnerModule, MatSelectModule, TranslatePipe, + RuleComponent, + RuleListComponent, ], - declarations: [RuleComponent, RuleListComponent], }) export class RuleModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.html b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.html index 7f40ae43da3..731caa167c0 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.html @@ -29,7 +29,7 @@
- @for (secu of dataSource; track secu) { + @for (secu of dataSource(); track secu) {
@@ -52,15 +52,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && securisationService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && securisationService.canLoadMore && !pending()) {
A{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.spec.ts index 62fefb2ce65..8f994a87cb6 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.spec.ts @@ -58,8 +58,7 @@ describe('SecurisationListComponent', () => { }); await TestBed.configureTestingModule({ - imports: [VitamUICommonTestModule, ReactiveFormsModule], - declarations: [SecurisationListComponent], + imports: [VitamUICommonTestModule, ReactiveFormsModule, SecurisationListComponent], providers: [ { provide: MatDialog, useValue: {} }, { provide: SecurisationService, useValue: securisationServiceMock }, diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.ts index 2b7a21aa0ce..04e5174d9ef 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.component.ts @@ -34,11 +34,29 @@ * 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, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; -import { Subject, merge } from 'rxjs'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { merge, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, PageRequest } from 'vitamui-library'; +import { + DEFAULT_PAGE_SIZE, + Direction, + EllipsisDirective, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + PipesModule, + TableFilterComponent, + TableFilterDirective, + TableFilterOptionComponent, +} from 'vitamui-library'; import { SecurisationService } from '../securisation.service'; +import { CommonModule, NgClass } from '@angular/common'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { LastEventPipe } from '../../shared/pipes/last-event.pipe'; +import { EventTypeBadgeClassPipe } from '../../shared/pipes/event-type-badge-class.pipe'; +import { EventTypeColorClassPipe } from '../../shared/pipes/event-type-color-class.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -52,7 +70,22 @@ export class TraceabilityFilter { selector: 'app-securisation-list', templateUrl: './securisation-list.component.html', styleUrls: ['./securisation-list.component.scss'], - standalone: false, + imports: [ + TableFilterDirective, + OrderByButtonComponent, + NgClass, + MatProgressSpinner, + TableFilterComponent, + TableFilterOptionComponent, + PipesModule, + LastEventPipe, + EventTypeBadgeClassPipe, + EventTypeColorClassPipe, + TranslatePipe, + CommonModule, + EllipsisDirective, + InfiniteScrollDirective, + ], }) export class SecurisationListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { securisationService: SecurisationService; @@ -98,7 +131,7 @@ export class SecurisationListComponent extends InfiniteScrollTable implemen .search( new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, this.direction, JSON.stringify(this.buildSecurisationCriteriaFromSearch())), ) - .subscribe((data: any[]) => (this.dataSource = data)); + .subscribe((data: any[]) => this.dataSource.set(data)); const searchCriteriaChange = merge(this.searchChange, this.filterChange, this.orderChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.module.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.module.ts deleted file mode 100644 index 8632d6b291c..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-list/securisation-list.module.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { VitamUICommonModule } from 'vitamui-library'; -import { PipesModule } from '../../shared/pipes/pipes.module'; -import { SecurisationListComponent } from './securisation-list.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [SecurisationListComponent], - imports: [CommonModule, MatProgressSpinnerModule, VitamUICommonModule, PipesModule, TranslatePipe], - exports: [SecurisationListComponent], -}) -export class SecurisationListModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.spec.ts index 9239f3c18f4..3a6d48ca4a5 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.spec.ts @@ -37,11 +37,9 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; -import { AccessContractService, BASE_URL, ExternalParameters, ExternalParametersService, SnackBarService } from 'vitamui-library'; +import { AccessContractService, ExternalParameters, ExternalParametersService, SnackBarService } from 'vitamui-library'; import { SecurisationService } from '../../securisation.service'; import { SecurisationCheckTabComponent } from './securisation-check-tab.component'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('SecurisationCheckTabComponent', () => { let component: SecurisationCheckTabComponent; @@ -106,11 +104,9 @@ describe('SecurisationCheckTabComponent', () => { }; await TestBed.configureTestingModule({ - declarations: [SecurisationCheckTabComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [], + imports: [SecurisationCheckTabComponent], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: AccessContractService, useValue: accessContractServiceMock }, { provide: SecurisationService, useValue: {} }, { @@ -120,8 +116,6 @@ describe('SecurisationCheckTabComponent', () => { }, }, { provide: SnackBarService, useValue: snackBarSpy }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.ts index d5e00cb44d6..1caefadbc40 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-check-tab/securisation-check-tab.component.ts @@ -34,16 +34,28 @@ * 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, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; -import type { ApiEvent, Event, IEvent } from 'vitamui-library'; -import { ApplicationId, ExternalParameters, ExternalParametersService, LogbookApiService, SnackBarService } from 'vitamui-library'; +import { Component, inject, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { + ApiEvent, + ApplicationId, + CollapseComponent, + Event, + ExternalParameters, + ExternalParametersService, + HistoryEventsComponent, + IEvent, + LogbookApiService, + SnackBarService, +} from 'vitamui-library'; import { SecurisationService } from '../../securisation.service'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-securisation-check-tab', templateUrl: './securisation-check-tab.component.html', styleUrls: ['./securisation-check-tab.component.scss'], - standalone: false, + imports: [HistoryEventsComponent, TranslatePipe, CollapseComponent, CommonModule], }) export class SecurisationCheckTabComponent implements OnChanges, OnInit { private readonly securingService = inject(SecurisationService); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.spec.ts index 1c906f8fb70..bcf934996f4 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.spec.ts @@ -108,8 +108,7 @@ describe.skip('SecurisationInformationTabComponent', () => { }; await TestBed.configureTestingModule({ - imports: [NgxFilesizeModule], - declarations: [SecurisationInformationTabComponent], + imports: [NgxFilesizeModule, SecurisationInformationTabComponent], providers: [{ provide: SecurisationService, useValue: securisationServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.ts index 392b9bac68e..64614fd80f6 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-information-tab/securisation-information-tab.component.ts @@ -34,15 +34,16 @@ * 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, Input, OnInit, inject } from '@angular/core'; -import type { Event } from 'vitamui-library'; +import { Component, inject, Input, OnInit } from '@angular/core'; +import { Event, PipesModule } from 'vitamui-library'; import { SecurisationService } from '../../securisation.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-securisation-information-tab', templateUrl: './securisation-information-tab.component.html', styleUrls: ['./securisation-information-tab.component.scss'], - standalone: false, + imports: [PipesModule, TranslatePipe], }) export class SecurisationInformationTabComponent implements OnInit { private securisationService = inject(SecurisationService); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.spec.ts index b5f563226c0..e5acc832545 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.spec.ts @@ -43,10 +43,7 @@ import { SecurisationService } from '../securisation.service'; import { SecurisationPreviewComponent } from './securisation-preview.component'; import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; -@Pipe({ - name: 'truncate', - standalone: false, -}) +@Pipe({ name: 'truncate' }) class MockTruncatePipe implements PipeTransform { transform(value: number): number { return value; @@ -116,15 +113,15 @@ describe('SecurisationPreviewComponent', () => { }; await TestBed.configureTestingModule({ - imports: [BrowserAnimationsModule, EventTypeBadgeColorPipe], - declarations: [SecurisationPreviewComponent, MockTruncatePipe], + imports: [BrowserAnimationsModule, EventTypeBadgeColorPipe, SecurisationPreviewComponent, MockTruncatePipe], providers: [ - { provide: SecurisationService, useValue: {} }, { provide: ExternalParametersService, useValue: externalParametersServiceMock }, { provide: SnackBarService, useValue: snackBarSpy }, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents(); + }) + .overrideProvider(SecurisationService, { useValue: { getInfoFromTimestamp: () => of({}) } }) + .compileComponents(); }); beforeEach(() => { diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.ts index 89a1dbb27f2..b9605a5d36a 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.component.ts @@ -34,16 +34,44 @@ * 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, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; -import type { Event } from 'vitamui-library'; -import { ExternalParameters, ExternalParametersService, SnackBarService } from 'vitamui-library'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; +import { + Event, + ExternalParameters, + ExternalParametersService, + OperationHistoryTabComponent, + PipesModule, + SnackBarService, + VitamuiSidenavHeaderComponent, +} from 'vitamui-library'; import { SecurisationService } from '../securisation.service'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { SecurisationInformationTabComponent } from './securisation-information-tab/securisation-information-tab.component'; +import { SecurisationCheckTabComponent } from './securisation-check-tab/securisation-check-tab.component'; +import { EventTypeBadgeColorPipe } from '../../shared/pipes/event-type-badge-color.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'app-securisation-preview', templateUrl: './securisation-preview.component.html', styleUrls: ['./securisation-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + SecurisationInformationTabComponent, + SecurisationCheckTabComponent, + OperationHistoryTabComponent, + PipesModule, + EventTypeBadgeColorPipe, + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class SecurisationPreviewComponent implements OnInit { private securisationService = inject(SecurisationService); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.module.ts deleted file mode 100644 index d9b8e932230..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation-preview/securisation-preview.module.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { SecurisationCheckTabComponent } from './securisation-check-tab/securisation-check-tab.component'; -import { SecurisationInformationTabComponent } from './securisation-information-tab/securisation-information-tab.component'; -import { SecurisationPreviewComponent } from './securisation-preview.component'; -import { PipesModule } from '../../shared/pipes/pipes.module'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [SecurisationPreviewComponent, SecurisationInformationTabComponent, SecurisationCheckTabComponent], - imports: [ - CommonModule, - RouterModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatSidenavModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - PipesModule, - TranslatePipe, - ], - exports: [SecurisationPreviewComponent], -}) -export class SecurisationPreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.spec.ts index 19e2715d2d3..3dcb10291c0 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.spec.ts @@ -34,14 +34,12 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormBuilder } from '@angular/forms'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatDialog } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Router } from '@angular/router'; import { of } from 'rxjs'; import { DatepickerComponent, GlobalEventService, InjectorModule, LoggerModule } from 'vitamui-library'; @@ -49,7 +47,6 @@ import { DatepickerComponent, GlobalEventService, InjectorModule, LoggerModule } import { VitamUICommonTestModule } from 'vitamui-library/testing'; import { SecurisationComponent } from './securisation.component'; import { DatePipe } from '@angular/common'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { provideNativeDateAdapter } from '@angular/material/core'; describe('SecurisationComponent', () => { @@ -60,10 +57,10 @@ describe('SecurisationComponent', () => { const activatedRouteMock = { params: of({ tenantIdentifier: 1 }), data: of({ appId: 'SECURISATION_APP' }), + snapshot: { data: { appId: 'SECURISATION_APP' } }, }; await TestBed.configureTestingModule({ - declarations: [SecurisationComponent], schemas: [NO_ERRORS_SCHEMA], imports: [ InjectorModule, @@ -71,8 +68,8 @@ describe('SecurisationComponent', () => { MatDatepickerModule, MatSidenavModule, DatepickerComponent, - NoopAnimationsModule, VitamUICommonTestModule, + SecurisationComponent, ], providers: [ provideNativeDateAdapter(), @@ -87,8 +84,6 @@ describe('SecurisationComponent', () => { navigate: () => {}, }, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.ts index 6a0265fe8f4..66e42710153 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.component.ts @@ -34,24 +34,42 @@ * 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, ViewChild, inject } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { Component, inject, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; -import { Event, GlobalEventService, SearchBarComponent, SidenavPage } from 'vitamui-library'; +import { + DatepickerComponent, + Event, + SearchBarComponent, + SidenavPage, + VitamuiBannerComponent, + VitamuiTitleBreadcrumbComponent, +} from 'vitamui-library'; import { SecurisationListComponent } from './securisation-list/securisation-list.component'; import { DateTime } from 'luxon'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { SecurisationPreviewComponent } from './securisation-preview/securisation-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-securisation', templateUrl: './securisation.component.html', styleUrls: ['./securisation.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + SecurisationPreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + ReactiveFormsModule, + DatepickerComponent, + SecurisationListComponent, + TranslatePipe, + ], }) export class SecurisationComponent extends SidenavPage { dialog = inject(MatDialog); - route: ActivatedRoute; - override globalEventService: GlobalEventService; private formBuilder = inject(FormBuilder); search: string; @@ -62,12 +80,7 @@ export class SecurisationComponent extends SidenavPage { @ViewChild(SecurisationListComponent, { static: true }) securisationListComponent: SecurisationListComponent; constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - this.route = route; - this.globalEventService = globalEventService; + super(); this.dateRangeFilterForm = this.formBuilder.group({ startDate: null, diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.module.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.module.ts index 5b52c444b96..66804e5c66c 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.module.ts @@ -50,8 +50,7 @@ import { VitamUICommonModule } from 'vitamui-library'; import { MAT_DATE_FORMATS } from '@angular/material/core'; import { FR_DATE_FORMAT } from '../helpers/dates.constants'; -import { SecurisationListModule } from './securisation-list/securisation-list.module'; -import { SecurisationPreviewModule } from './securisation-preview/securisation-preview.module'; + import { SecurisationRoutingModule } from './securisation-routing.module'; import { SecurisationComponent } from './securisation.component'; import { TranslatePipe } from '@ngx-translate/core'; @@ -64,8 +63,6 @@ import { TranslatePipe } from '@ngx-translate/core'; ReactiveFormsModule, VitamUICommonModule, SecurisationRoutingModule, - SecurisationPreviewModule, - SecurisationListModule, MatMenuModule, MatDialogModule, MatSidenavModule, @@ -75,8 +72,8 @@ import { TranslatePipe } from '@ngx-translate/core'; MatFormFieldModule, MatInputModule, TranslatePipe, + SecurisationComponent, ], - declarations: [SecurisationComponent], providers: [{ provide: MAT_DATE_FORMATS, useValue: FR_DATE_FORMAT }], }) export class SecurisationModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.service.ts b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.service.ts index 8556245ec61..4ff51bdd201 100644 --- a/ui/ui-frontend/projects/referential/src/app/securisation/securisation.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/securisation/securisation.service.ts @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpHeaders } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Event, SearchService, SnackBarService, VitamuiHttpHeaders } from 'vitamui-library'; import { OperationApiService } from '../core/api/operation-api.service'; diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.spec.ts index 3f759a6572f..2b3623db9bb 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.spec.ts @@ -43,7 +43,6 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EMPTY, of } from 'rxjs'; import { ConfirmDialogService } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -61,7 +60,15 @@ import { SecurityProfileCreateValidators } from './security-profile-create.valid multi: true, }, ], - standalone: false, + imports: [ + ReactiveFormsModule, + MatFormFieldModule, + MatSelectModule, + MatButtonToggleModule, + MatProgressBarModule, + MatProgressSpinnerModule, + VitamUICommonTestModule, + ], }) class DomainInputStubComponent implements ControlValueAccessor { @Input() @@ -89,7 +96,15 @@ class DomainInputStubComponent implements ControlValueAccessor { multi: true, }, ], - standalone: false, + imports: [ + ReactiveFormsModule, + MatFormFieldModule, + MatSelectModule, + MatButtonToggleModule, + MatProgressBarModule, + MatProgressSpinnerModule, + VitamUICommonTestModule, + ], }) class SecurityProfileEditPermissionStubComponent implements ControlValueAccessor { writeValue() {} @@ -148,11 +163,11 @@ describe('SecurityProfileCreateComponent', () => { MatSelectModule, MatButtonToggleModule, MatProgressBarModule, - NoopAnimationsModule, MatProgressSpinnerModule, VitamUICommonTestModule, + SecurityProfileEditPermissionStubComponent, + DomainInputStubComponent, ], - declarations: [SecurityProfileEditPermissionStubComponent, DomainInputStubComponent], providers: [ { provide: MatDialogRef, useValue: matDialogRefSpy }, { provide: MAT_DIALOG_DATA, useValue: {} }, diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.ts index 328bafede98..50beb4529ee 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-create.component.ts @@ -48,7 +48,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule } from '@angular/material/select'; -import { SecurityProfileEditPermissionModule } from './security-profile-edit-permission/security-profile-edit-permission.module'; + import { TranslatePipe } from '@ngx-translate/core'; @Component({ @@ -63,7 +63,6 @@ import { TranslatePipe } from '@ngx-translate/core'; MatProgressBarModule, MatSelectModule, ReactiveFormsModule, - SecurityProfileEditPermissionModule, SharedModule, VitamUICommonModule, VitamUILibraryModule, diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.component.ts index 4b20a00343e..c3643738274 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.component.ts @@ -34,9 +34,11 @@ * 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, forwardRef, Input, inject } from '@angular/core'; -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, forwardRef, inject, Input } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { PermissionStructure, PermissionUtils } from '../permission.utils'; +import { SlideToggleComponent, TooltipDirective } from 'vitamui-library'; +import { TranslatePipe } from '@ngx-translate/core'; export const PERMISSION_SELECT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -49,7 +51,7 @@ export const PERMISSION_SELECT_VALUE_ACCESSOR: any = { templateUrl: './security-profile-edit-permission.component.html', styleUrls: ['./security-profile-edit-permission.component.scss'], providers: [PERMISSION_SELECT_VALUE_ACCESSOR], - standalone: false, + imports: [ReactiveFormsModule, TooltipDirective, SlideToggleComponent, TranslatePipe], }) export class SecurityProfileEditPermissionComponent implements ControlValueAccessor { private permissionUtils = inject(PermissionUtils); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.module.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.module.ts deleted file mode 100644 index 1c665899f6e..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-create/security-profile-edit-permission/security-profile-edit-permission.module.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatSelectModule } from '@angular/material/select'; - -import { VitamUICommonModule } from 'vitamui-library'; -import { SecurityProfileEditPermissionComponent } from './security-profile-edit-permission.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - MatButtonToggleModule, - MatFormFieldModule, - MatInputModule, - MatProgressBarModule, - MatSelectModule, - ReactiveFormsModule, - VitamUICommonModule, - TranslatePipe, - ], - declarations: [SecurityProfileEditPermissionComponent], - exports: [SecurityProfileEditPermissionComponent], -}) -export class SecurityProfileEditPermissionModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.html b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.html index f75572ef3c1..418fec65a72 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.html +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.html @@ -25,7 +25,7 @@
- @for (profile of dataSource; track profile; let index = $index) { + @for (profile of dataSource(); track profile; let index = $index) {
@@ -36,15 +36,15 @@ }
- @if (!dataSource || pending) { + @if (!dataSource() || pending()) {
} - @if (!pending && dataSource?.length === 0) { + @if (!pending() && dataSource()?.length === 0) {
{{ 'COMMON.NO_RESULT' | translate }}
} - @if (infiniteScrollDisabled && securityProfileService.canLoadMore && !pending) { + @if (infiniteScrollDisabled() && securityProfileService.canLoadMore && !pending()) {
{{ 'COMMON.SHOW_MORE_RESULTS' | translate }}
diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.spec.ts index 3f4d6aedde7..c367a256f49 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.spec.ts @@ -37,7 +37,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; -import { AuthService, BASE_URL, SecurityProfile } from 'vitamui-library'; +import { AuthService, SecurityProfile } from 'vitamui-library'; import { SecurityProfileService } from '../security-profile.service'; import { SecurityProfileListComponent } from './security-profile-list.component'; @@ -52,10 +52,8 @@ describe('SecurityProfileListComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [SecurityProfileListComponent], - imports: [], + imports: [SecurityProfileListComponent], providers: [ - { provide: BASE_URL, useValue: '' }, { provide: SecurityProfileService, useValue: securityProfileServiceMock }, { provide: AuthService, useValue: { user: { proofTenantIdentifier: '1' } } }, ], diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.ts index 49a6d6f5a7d..9b7de4637be 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-list/security-profile-list.component.ts @@ -34,12 +34,23 @@ * 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, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, EventEmitter, inject, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; import { merge, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import type { AdminUserProfile, SecurityProfile } from 'vitamui-library'; -import { DEFAULT_PAGE_SIZE, Direction, InfiniteScrollTable, PageRequest } from 'vitamui-library'; +import { + AdminUserProfile, + DEFAULT_PAGE_SIZE, + Direction, + InfiniteScrollDirective, + InfiniteScrollTable, + OrderByButtonComponent, + PageRequest, + SecurityProfile, +} from 'vitamui-library'; import { SecurityProfileService } from '../security-profile.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; +import { CommonModule } from '@angular/common'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -47,7 +58,7 @@ const FILTER_DEBOUNCE_TIME_MS = 400; selector: 'app-security-profile-list', templateUrl: './security-profile-list.component.html', styleUrls: ['./security-profile-list.component.scss'], - standalone: false, + imports: [OrderByButtonComponent, MatProgressSpinner, TranslatePipe, CommonModule, InfiniteScrollDirective], }) export class SecurityProfileListComponent extends InfiniteScrollTable implements OnDestroy, OnInit { securityProfileService: SecurityProfileService; @@ -102,7 +113,7 @@ export class SecurityProfileListComponent extends InfiniteScrollTable { - this.dataSource = data; + this.dataSource.set(data); }); const searchCriteriaChange = merge(this.searchChange, this.filterChange, this.orderChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.spec.ts index 6bf19ea92e2..1e5572184ea 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.spec.ts @@ -66,8 +66,7 @@ describe('SecurityProfileInformationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [SecurityProfileInformationTabComponent], + imports: [SecurityProfileInformationTabComponent], providers: [FormBuilder, { provide: SecurityProfileService, useValue: securityProfileServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.ts index ad64f1536e4..32f6ee838a0 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-information-tab/security-profile-information-tab.component.ts @@ -34,20 +34,20 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { Option, SecurityProfile } from 'vitamui-library'; -import { diff } from 'vitamui-library'; +import { diff, InputComponent, Option, SecurityProfile, SlideToggleComponent } from 'vitamui-library'; import { SecurityProfileService } from '../../security-profile.service'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-security-profile-information-tab', templateUrl: './security-profile-information-tab.component.html', styleUrls: ['./security-profile-information-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, InputComponent, SlideToggleComponent, TranslatePipe], }) export class SecurityProfileInformationTabComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.spec.ts index 7fdac976a29..a45982f8999 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.spec.ts @@ -65,8 +65,7 @@ describe('SecurityProfilePermissionsTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [SecurityProfilePermissionsTabComponent], + imports: [SecurityProfilePermissionsTabComponent], providers: [FormBuilder, { provide: SecurityProfileService, useValue: securityProfileServiceMock }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.ts index cbd66e86a6e..3e527748ad3 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-permissions-tab/security-profile-permissions-tab.component.ts @@ -34,20 +34,21 @@ * 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, EventEmitter, Input, Output, inject } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; +import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, filter, map, switchMap } from 'rxjs/operators'; import { extend, isEmpty } from 'underscore'; -import type { Option, SecurityProfile } from 'vitamui-library'; -import { diff } from 'vitamui-library'; +import { diff, Option, SecurityProfile } from 'vitamui-library'; import { SecurityProfileService } from '../../security-profile.service'; +import { SecurityProfileEditPermissionComponent } from '../../security-profile-create/security-profile-edit-permission/security-profile-edit-permission.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-security-profile-permissions-tab', templateUrl: './security-profile-permissions-tab.component.html', styleUrls: ['./security-profile-permissions-tab.component.scss'], - standalone: false, + imports: [ReactiveFormsModule, SecurityProfileEditPermissionComponent, TranslatePipe], }) export class SecurityProfilePermissionsTabComponent { private formBuilder = inject(FormBuilder); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.spec.ts index 27fdb51e3fa..fedbb8e183d 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.spec.ts @@ -47,19 +47,24 @@ describe('SecurityProfilePreviewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [], - declarations: [SecurityProfilePreviewComponent], - providers: [ - { provide: MatDialog, useValue: {} }, - { provide: SecurityProfileService, useValue: {} }, - ], + imports: [SecurityProfilePreviewComponent], + providers: [{ provide: MatDialog, useValue: {} }], schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents(); + }) + .overrideProvider(SecurityProfileService, { useValue: {} }) + .compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(SecurityProfilePreviewComponent); component = fixture.componentInstance; + component.securityProfile = { + id: 'vitam_id', + name: 'Name', + identifier: 'SP-000001', + fullAccess: true, + permissions: [], + }; fixture.detectChanges(); }); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.ts index 6ddbed4017b..e700ee9ca5e 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.component.ts @@ -34,21 +34,37 @@ * 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 { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, forwardRef, HostListener, inject, Input, Output, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; import { Observable } from 'rxjs'; -import type { SecurityProfile } from 'vitamui-library'; -import { ConfirmActionComponent } from 'vitamui-library'; +import { ConfirmActionComponent, OperationHistoryTabComponent, SecurityProfile, VitamuiSidenavHeaderComponent } from 'vitamui-library'; import { SecurityProfileService } from '../security-profile.service'; import { SecurityProfileInformationTabComponent } from './security-profile-information-tab/security-profile-information-tab.component'; import { SecurityProfilePermissionsTabComponent } from './security-profile-permissions-tab/security-profile-permissions-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-security-profile-preview', templateUrl: './security-profile-preview.component.html', styleUrls: ['./security-profile-preview.component.scss'], - standalone: false, + imports: [ + MatTabGroup, + MatTab, + SecurityProfileInformationTabComponent, + SecurityProfilePermissionsTabComponent, + OperationHistoryTabComponent, + forwardRef(() => SecurityProfilePreviewComponent), + TranslatePipe, + CommonModule, + MatProgressSpinnerModule, + ReactiveFormsModule, + VitamuiSidenavHeaderComponent, + ], }) export class SecurityProfilePreviewComponent implements AfterViewInit { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.module.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.module.ts deleted file mode 100644 index c510bdbd16f..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile-preview/security-profile-preview.module.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatOptionModule } from '@angular/material/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { MatTabsModule } from '@angular/material/tabs'; -import { RouterModule } from '@angular/router'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; - -import { SecurityProfileEditPermissionModule } from '../security-profile-create/security-profile-edit-permission/security-profile-edit-permission.module'; -import { SecurityProfileInformationTabComponent } from './security-profile-information-tab/security-profile-information-tab.component'; -import { SecurityProfilePermissionsTabComponent } from './security-profile-permissions-tab/security-profile-permissions-tab.component'; -import { SecurityProfilePreviewComponent } from './security-profile-preview.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - RouterModule, - VitamUICommonModule, - VitamUILibraryModule, - FormsModule, - ReactiveFormsModule, - MatMenuModule, - MatDialogModule, - MatSidenavModule, - MatProgressSpinnerModule, - MatSelectModule, - MatOptionModule, - MatTabsModule, - SecurityProfileEditPermissionModule, - TranslatePipe, - ], - declarations: [SecurityProfilePreviewComponent, SecurityProfileInformationTabComponent, SecurityProfilePermissionsTabComponent], - exports: [SecurityProfilePreviewComponent], -}) -export class SecurityProfilePreviewModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.spec.ts index 79c21f5dc79..443516c6eef 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.spec.ts @@ -39,8 +39,6 @@ import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatSidenavModule } from '@angular/material/sidenav'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ApplicationService, InjectorModule, LoggerModule } from 'vitamui-library'; import { VitamUICommonTestModule } from 'vitamui-library/testing'; @@ -50,7 +48,7 @@ import { SecurityProfileComponent } from './security-profile.component'; @Component({ selector: 'app-SecurityProfile-preview', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class SecurityProfilePreviewStub { @Input() @@ -60,7 +58,7 @@ class SecurityProfilePreviewStub { @Component({ selector: 'app-SecurityProfile-list', template: '', - standalone: false, + imports: [VitamUICommonTestModule, InjectorModule, MatSidenavModule, MatDialogModule], }) class SecurityProfileListStub {} @@ -75,15 +73,15 @@ describe('SecurityProfileComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [SecurityProfileComponent, SecurityProfileListStub, SecurityProfilePreviewStub], imports: [ VitamUICommonTestModule, - RouterTestingModule, InjectorModule, LoggerModule.forRoot(), - NoopAnimationsModule, MatSidenavModule, MatDialogModule, + SecurityProfileComponent, + SecurityProfileListStub, + SecurityProfilePreviewStub, ], providers: [{ provide: ApplicationService, useValue: applicationServiceMock }], schemas: [NO_ERRORS_SCHEMA], diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.ts index 67dd04177cf..6cad2412108 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.component.ts @@ -34,20 +34,31 @@ * 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, ViewChild, inject } from '@angular/core'; +import { Component, inject, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute } from '@angular/router'; -import { ApplicationService, GlobalEventService, SecurityProfile, SidenavPage } from 'vitamui-library'; +import { ApplicationService, SecurityProfile, SidenavPage, VitamuiBannerComponent, VitamuiTitleBreadcrumbComponent } from 'vitamui-library'; import { SecurityProfileCreateComponent } from './security-profile-create/security-profile-create.component'; import { SecurityProfileListComponent } from './security-profile-list/security-profile-list.component'; import { shareReplay } from 'rxjs/operators'; import { firstValueFrom } from 'rxjs'; +import { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; +import { SecurityProfilePreviewComponent } from './security-profile-preview/security-profile-preview.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'app-security-profile', templateUrl: './security-profile.component.html', styleUrls: ['./security-profile.component.scss'], - standalone: false, + imports: [ + MatSidenavContainer, + MatSidenav, + SecurityProfilePreviewComponent, + MatSidenavContent, + VitamuiTitleBreadcrumbComponent, + VitamuiBannerComponent, + SecurityProfileListComponent, + TranslatePipe, + ], }) export class SecurityProfileComponent extends SidenavPage { dialog = inject(MatDialog); @@ -59,13 +70,6 @@ export class SecurityProfileComponent extends SidenavPage { #isSlaveMode$ = this.applicationService.isApplicationExternalIdentifierEnabled('SECURITY_PROFILE').pipe(shareReplay(1)); - constructor() { - const route = inject(ActivatedRoute); - const globalEventService = inject(GlobalEventService); - - super(route, globalEventService); - } - async openCreateSecurityProfileDialog() { const isSlaveMode = await firstValueFrom(this.#isSlaveMode$); this.dialog.closeAll(); // Prevent opening multiple dialogs diff --git a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.module.ts b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.module.ts index 088ca1de0f6..8badbef3ff5 100644 --- a/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.module.ts +++ b/ui/ui-frontend/projects/referential/src/app/security-profile/security-profile.module.ts @@ -43,7 +43,7 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { RouterModule } from '@angular/router'; import { VitamUICommonModule } from 'vitamui-library'; import { SecurityProfileListComponent } from './security-profile-list/security-profile-list.component'; -import { SecurityProfilePreviewModule } from './security-profile-preview/security-profile-preview.module'; + import { SecurityProfileRoutingModule } from './security-profile-routing.module'; import { SecurityProfileComponent } from './security-profile.component'; import { SecurityProfileCreateComponent } from './security-profile-create/security-profile-create.component'; @@ -56,13 +56,13 @@ import { TranslatePipe } from '@ngx-translate/core'; VitamUICommonModule, SecurityProfileRoutingModule, SecurityProfileCreateComponent, - SecurityProfilePreviewModule, MatMenuModule, MatDialogModule, MatSidenavModule, MatProgressSpinnerModule, TranslatePipe, + SecurityProfileComponent, + SecurityProfileListComponent, ], - declarations: [SecurityProfileComponent, SecurityProfileListComponent], }) export class SecurityProfileModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.component.ts b/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.component.ts index cb89d069c6c..0665fb1d4bf 100644 --- a/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.component.ts @@ -35,20 +35,37 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, inject, OnDestroy } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { ApplicationId, FileTypes, FileValidationErrors, FileValidatorFunction, SnackBarService } from 'vitamui-library'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { + ApplicationId, + DialogHeaderComponent, + FileSelectorComponent, + FileTypes, + FileValidationErrors, + FileValidatorFunction, + SnackBarService, +} from 'vitamui-library'; import { firstValueFrom, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ImportDialogParam, ReferentialImportInvalidFileError, ReferentialTypes } from './import-dialog-param.interface'; -import { FormControl, Validators } from '@angular/forms'; -import { TranslateService } from '@ngx-translate/core'; +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ReferentialImportService } from './referential-import.service'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; @Component({ selector: 'app-import-dialog', templateUrl: './import-dialog.component.html', styleUrls: ['./import-dialog.component.scss'], - standalone: false, + imports: [ + DialogHeaderComponent, + MatDialogContent, + FileSelectorComponent, + ReactiveFormsModule, + MatDialogActions, + MatProgressSpinner, + TranslatePipe, + ], }) export class ImportDialogComponent implements OnDestroy { dialogParams = inject(MAT_DIALOG_DATA); diff --git a/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.module.ts b/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.module.ts deleted file mode 100644 index d1ec940ad8a..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/import-dialog.module.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { VitamUICommonModule, VitamUILibraryModule } from 'vitamui-library'; -import { ImportDialogComponent } from './import-dialog.component'; -import { MatDialogModule } from '@angular/material/dialog'; -import { TranslatePipe } from '@ngx-translate/core'; -import { ReactiveFormsModule } from '@angular/forms'; - -@NgModule({ - imports: [ - CommonModule, - VitamUICommonModule, - MatProgressSpinnerModule, - MatDialogModule, - VitamUILibraryModule, - TranslatePipe, - ReactiveFormsModule, - ], - declarations: [ImportDialogComponent], -}) -export class ImportDialogModule {} diff --git a/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/referential-import-api.service.spec.ts b/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/referential-import-api.service.spec.ts index 7632cc9fa01..8a986e26bd1 100644 --- a/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/referential-import-api.service.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/shared/import-dialog/referential-import-api.service.spec.ts @@ -34,25 +34,19 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL, ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; +import { ENVIRONMENT, InjectorModule, LoggerModule } from 'vitamui-library'; import { environment } from '../../../environments/environment'; import { ReferentialImportService } from './referential-import.service'; import { ReferentialImportInvalidFileError, ReferentialTypes } from './import-dialog-param.interface'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { firstValueFrom } from 'rxjs'; describe('ReferentialImportService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/referential/src/app/shared/pipes/event-type-color-class.pipe.ts b/ui/ui-frontend/projects/referential/src/app/shared/pipes/event-type-color-class.pipe.ts index a0a4fece543..bf65a365488 100644 --- a/ui/ui-frontend/projects/referential/src/app/shared/pipes/event-type-color-class.pipe.ts +++ b/ui/ui-frontend/projects/referential/src/app/shared/pipes/event-type-color-class.pipe.ts @@ -44,10 +44,7 @@ const colorClassMap: { [key: string]: string } = { FATAL: 'text danger', }; -@Pipe({ - name: 'eventTypeColorClass', - standalone: false, -}) +@Pipe({ name: 'eventTypeColorClass' }) export class EventTypeColorClassPipe implements PipeTransform { transform(event: IEvent): string { if (!event.events || event.events.length <= 0) { diff --git a/ui/ui-frontend/projects/referential/src/app/shared/pipes/last-event.pipe.ts b/ui/ui-frontend/projects/referential/src/app/shared/pipes/last-event.pipe.ts index c94ddb95545..ab5aae020cb 100644 --- a/ui/ui-frontend/projects/referential/src/app/shared/pipes/last-event.pipe.ts +++ b/ui/ui-frontend/projects/referential/src/app/shared/pipes/last-event.pipe.ts @@ -38,10 +38,7 @@ import { IEvent } from 'vitamui-library'; import { Pipe, PipeTransform } from '@angular/core'; -@Pipe({ - name: 'lastEvent', - standalone: false, -}) +@Pipe({ name: 'lastEvent' }) export class LastEventPipe implements PipeTransform { transform(event: IEvent): IEvent { return event?.events?.length > 0 ? event.events[event.events.length - 1] : null; diff --git a/ui/ui-frontend/projects/referential/src/app/shared/pipes/pipes.module.ts b/ui/ui-frontend/projects/referential/src/app/shared/pipes/pipes.module.ts deleted file mode 100644 index 6a4b99c9882..00000000000 --- a/ui/ui-frontend/projects/referential/src/app/shared/pipes/pipes.module.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { NgModule } from '@angular/core'; -import { EventTypeBadgeClassPipe } from './event-type-badge-class.pipe'; -import { EventTypeColorClassPipe } from './event-type-color-class.pipe'; -import { LastEventPipe } from './last-event.pipe'; -import { EventTypeBadgeColorPipe } from './event-type-badge-color.pipe'; - -@NgModule({ - declarations: [LastEventPipe, EventTypeColorClassPipe], - imports: [EventTypeBadgeClassPipe, EventTypeBadgeColorPipe], - exports: [LastEventPipe, EventTypeBadgeClassPipe, EventTypeBadgeColorPipe, EventTypeColorClassPipe], -}) -export class PipesModule {} diff --git a/ui/ui-frontend/projects/referential/src/main.ts b/ui/ui-frontend/projects/referential/src/main.ts index c0ee6e23c2c..9ccaae45807 100644 --- a/ui/ui-frontend/projects/referential/src/main.ts +++ b/ui/ui-frontend/projects/referential/src/main.ts @@ -34,16 +34,59 @@ * 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 { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowser } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom, LOCALE_ID } from '@angular/core'; +import { bootstrapApplication, BrowserModule, Title } from '@angular/platform-browser'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import { + AuthenticationModule, + BASE_URL, + BytesPipe, + ENVIRONMENT, + InjectorModule, + provideI18n, + VitamUICommonModule, + VitamUILibraryModule, + WINDOW_LOCATION, +} from 'vitamui-library'; +import { provideNativeDateAdapter } from '@angular/material/core'; +import { DatePipe } from '@angular/common'; +import { CoreModule } from './app/core/core.module'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { AppRoutingModule } from './app/app-routing.module'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { AppComponent } from './app/app.component'; if (environment.production) { enableProdMode(); } -platformBrowser() - .bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }) - .catch((err) => console.error(err)); +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom( + CoreModule, + AuthenticationModule.forRoot(), + InjectorModule, + BrowserAnimationsModule, + BrowserModule, + VitamUICommonModule.forRoot(), + AppRoutingModule, + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: environment.production, + // Register the ServiceWorker as soon as the application is stable + // or after 30 seconds (whichever comes first). + registrationStrategy: 'registerWhenStable:30000', + }), + VitamUILibraryModule, // For Material tokens + ), + provideI18n(), + provideNativeDateAdapter(), + Title, + { provide: LOCALE_ID, useValue: 'fr' }, + { provide: BASE_URL, useValue: './referential-api' }, + { provide: ENVIRONMENT, useValue: environment }, + { provide: WINDOW_LOCATION, useValue: window.location }, + BytesPipe, + DatePipe, + ], +}).catch((err) => console.error(err)); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.spec.ts index 3a82185c0a6..537d61f61a2 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.spec.ts @@ -44,7 +44,7 @@ describe('AccountApplicationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AccountApplicationTabComponent], + imports: [AccountApplicationTabComponent], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.ts index 195f54d8588..9b59021495a 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-application-tab/account-application-tab.component.ts @@ -40,6 +40,5 @@ import { Component } from '@angular/core'; selector: 'vitamui-common-account-application-tab', templateUrl: './account-application-tab.component.html', styleUrls: ['./account-application-tab.component.scss'], - standalone: false, }) export class AccountApplicationTabComponent {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.spec.ts index eab80c5e964..c08c67e1a57 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.spec.ts @@ -36,11 +36,9 @@ */ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { of } from 'rxjs'; import { VitamUIFieldErrorStubComponent } from '../../../../../testing/src/public_api'; -import { EditableFieldModule } from '../../components/editable-field/editable-field.module'; import { WINDOW_LOCATION } from '../../injection-tokens'; import { AccountService } from '../account.service'; import { AccountInformationTabComponent } from './account-information-tab.component'; @@ -56,8 +54,7 @@ describe('AccountInformationTabComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, EditableFieldModule, SlideToggleComponent, NoopAnimationsModule], - declarations: [AccountInformationTabComponent, VitamUIFieldErrorStubComponent], + imports: [ReactiveFormsModule, SlideToggleComponent, AccountInformationTabComponent, VitamUIFieldErrorStubComponent], providers: [ { provide: WINDOW_LOCATION, useValue: {} }, { provide: AccountService, useValue: accountServiceSpy }, diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.ts index ab058e93858..4e7f74eeac8 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account-information-tab/account-information-tab.component.ts @@ -34,16 +34,18 @@ * 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, Input, inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, effect, inject, input } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import type { Account } from '../../models/account/account.interface'; +import { SlideToggleComponent } from '../../../../lib/components/slide-toggle/slide-toggle.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-account-information-tab', templateUrl: './account-information-tab.component.html', styleUrls: ['./account-information-tab.component.scss'], - standalone: false, + imports: [FormsModule, ReactiveFormsModule, SlideToggleComponent, TranslatePipe], }) export class AccountInformationTabComponent { private formBuilder = inject(FormBuilder); @@ -52,18 +54,7 @@ export class AccountInformationTabComponent { public language: string; - @Input() - set account(account: Account) { - this._account = account; - if (this.account?.userInfo) { - this.language = this.account.userInfo.language; - } - this.resetForm(this.account); - } - get account(): Account { - return this._account; - } - private _account: Account; + public account = input(null); constructor() { this.form = this.formBuilder.group({ @@ -79,6 +70,16 @@ export class AccountInformationTabComponent { type: [{ value: null, disabled: true }], profileGroup: [{ value: null, disabled: true }], }); + + effect(() => { + const acc = this.account(); + if (acc?.userInfo) { + this.language = acc.userInfo.language; + } + if (acc) { + this.resetForm(acc); + } + }); } private resetForm(account: Account) { diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.html b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.html index b018cf1b118..6f70cf509d9 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.html +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.html @@ -1,7 +1,7 @@
- + {{ 'ACCOUNT.TITLE' | translate }}
@@ -19,7 +19,9 @@
- + @if (account(); as acc) { + + }
diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.spec.ts index 68b7178d8b1..3fc4f993b79 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.spec.ts @@ -37,7 +37,6 @@ import { Component, Input, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MatTabsModule } from '@angular/material/tabs'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; import { EMPTY, of } from 'rxjs'; @@ -46,15 +45,15 @@ import { environment } from '../../../environments/environment'; import { BaseUserInfoApiService } from '../api/base-user-info-api.service'; import { InjectorModule } from '../helper/injector.module'; import { LoggerModule } from '../logger/logger.module'; +import { ENVIRONMENT, WINDOW_LOCATION } from '../injection-tokens'; import type { Account } from '../models/account/account.interface'; -import { ENVIRONMENT } from './../injection-tokens'; import { AccountComponent } from './account.component'; import { AccountService } from './account.service'; @Component({ selector: 'vitamui-common-account-information-tab', template: '', - standalone: false, + imports: [InjectorModule, MatTabsModule, VitamUICommonTestModule], }) class InformationTabStubComponent { @Input() account: Account; @@ -74,13 +73,20 @@ describe('AccountComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [InjectorModule, MatTabsModule, NoopAnimationsModule, LoggerModule.forRoot(), VitamUICommonTestModule], - declarations: [AccountComponent, InformationTabStubComponent], + imports: [ + InjectorModule, + MatTabsModule, + LoggerModule.forRoot(), + VitamUICommonTestModule, + AccountComponent, + InformationTabStubComponent, + ], providers: [ { provide: AccountService, useValue: accountServiceSpy }, { provide: BaseUserInfoApiService, useValue: userInfoApiServiceSpy }, - { provide: ActivatedRoute, useValue: { data: EMPTY } }, + { provide: ActivatedRoute, useValue: { data: { appId: 'SomeAppId' }, snapshot: { data: { appId: 'SomeAppId' } } } }, { provide: ENVIRONMENT, useValue: environment }, + { provide: WINDOW_LOCATION, useValue: location }, ], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.ts index 18f11010439..f0a8c783612 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.component.ts @@ -34,54 +34,37 @@ * 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, OnDestroy, OnInit, inject } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs'; +import { Component, inject } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { map, switchMap } from 'rxjs/operators'; import { BaseUserInfoApiService } from '../api/base-user-info-api.service'; -import { AppRootComponent } from '../app-root-component.class'; import { ApplicationId } from '../application-id.enum'; import { Account } from '../models/account/account.interface'; import { BreadCrumbData } from '../models/breadcrumb/breadcrumb.interface'; import { AccountService } from './account.service'; +import { VitamuiTitleBreadcrumbComponent } from '../components/vitamui-title-breadcrumb/vitamui-title-breadcrumb.component'; +import { UserPhotoComponent } from '../components/header/user-photo/user-photo.component'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { AccountInformationTabComponent } from './account-information-tab/account-information-tab.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-account', templateUrl: './account.component.html', styleUrls: ['./account.component.scss'], - standalone: false, + imports: [VitamuiTitleBreadcrumbComponent, UserPhotoComponent, MatTabGroup, MatTab, AccountInformationTabComponent, TranslatePipe], }) -export class AccountComponent extends AppRootComponent implements OnInit, OnDestroy { +export class AccountComponent { private accountService = inject(AccountService); private userInfoApiService = inject(BaseUserInfoApiService); - route: ActivatedRoute; public displayAppTab = false; - public displayEditionAndAdminContact = false; - public account: Account; - public dataBreadcrumb: BreadCrumbData[]; + public dataBreadcrumb: BreadCrumbData[] = [{ identifier: ApplicationId.PORTAL_APP }, { identifier: ApplicationId.ACCOUNTS_APP }]; - private sub: Subscription; - - constructor() { - const route = inject(ActivatedRoute); - - super(route); - - this.route = route; - } - - ngOnInit() { - this.sub = this.accountService.getMyAccount().subscribe((account) => { - this.userInfoApiService.getMyUserInfo().subscribe((userInfo) => { - const accountWithUserInfos = account; - accountWithUserInfos.userInfo = userInfo; - this.account = accountWithUserInfos; - }); - }); - this.dataBreadcrumb = [{ identifier: ApplicationId.PORTAL_APP }, { identifier: ApplicationId.ACCOUNTS_APP }]; - } - - ngOnDestroy() { - this.sub.unsubscribe(); - } + public account = toSignal( + this.accountService + .getMyAccount() + .pipe(switchMap((account) => this.userInfoApiService.getMyUserInfo().pipe(map((userInfo) => ({ ...account, userInfo }) as Account)))), + { initialValue: null as Account | null }, + ); } diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.module.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.module.spec.ts deleted file mode 100644 index d8a2144cb02..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.module.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { AccountModule } from './account.module'; - -describe('AccountModule', () => { - let accountModule: AccountModule; - - beforeEach(() => { - accountModule = new AccountModule(); - }); - - it('should create an instance', () => { - expect(accountModule).toBeTruthy(); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.module.ts deleted file mode 100644 index eb02f9a71b0..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.module.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatSlideToggleModule } from '@angular/material/slide-toggle'; -import { MatTabsModule } from '@angular/material/tabs'; - -import { EditableFieldModule } from '../components/editable-field/editable-field.module'; -import { UserPhotoModule } from '../components/header/user-photo/user-photo.module'; -import { AccountApplicationTabComponent } from './account-application-tab/account-application-tab.component'; -import { AccountInformationTabComponent } from './account-information-tab/account-information-tab.component'; -import { AccountComponent } from './account.component'; -import { SlideToggleComponent } from '../../../lib/components/slide-toggle/slide-toggle.component'; -import { VitamuiTitleBreadcrumbComponent } from '../components/vitamui-title-breadcrumb/vitamui-title-breadcrumb.component'; -import { VitamUIFieldErrorComponent } from '../components/vitamui-field-error/vitamui-field-error.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - ReactiveFormsModule, - EditableFieldModule, - MatSlideToggleModule, - SlideToggleComponent, - MatTabsModule, - VitamUIFieldErrorComponent, - VitamuiTitleBreadcrumbComponent, - UserPhotoModule, - TranslatePipe, - ], - declarations: [AccountComponent, AccountInformationTabComponent, AccountApplicationTabComponent], -}) -export class AccountModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.service.spec.ts index ad64fb4da60..4564d1635c6 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/account/account.service.spec.ts @@ -34,26 +34,17 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { EMPTY } from 'rxjs'; import { SnackBarService } from '../components/snack-bar/snack-bar.service'; -import { BASE_URL } from '../injection-tokens'; import { AccountService } from './account.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('AccountService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - AccountService, - { provide: BASE_URL, useValue: {} }, - { provide: SnackBarService, useValue: { instant: () => EMPTY } }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [AccountService, { provide: SnackBarService, useValue: { instant: () => EMPTY } }], }); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/agencies/agency-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/agencies/agency-api.service.spec.ts index 654f8718d0b..84d730a2a86 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/agencies/agency-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/agencies/agency-api.service.spec.ts @@ -34,25 +34,18 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { AgencyApiService } from './agency-api.service'; import { InjectorModule } from '../helper/injector.module'; import { LoggerModule } from '../logger/logger.module'; -import { BASE_URL, ENVIRONMENT } from '../injection-tokens'; +import { ENVIRONMENT } from '../injection-tokens'; import { environment } from '../../../environments/environment'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('AgencyApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], - providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, - { provide: ENVIRONMENT, useValue: environment }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [{ provide: ENVIRONMENT, useValue: environment }], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/analytics-resolver.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/analytics-resolver.service.spec.ts index 6fc88c6b876..bc7d7cdd072 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/analytics-resolver.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/analytics-resolver.service.spec.ts @@ -34,16 +34,14 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { UserApiService } from './api/user-api.service'; import { Router, RouterModule } from '@angular/router'; import { AnalyticsResolver } from './analytics-resolver.service'; -import { BASE_URL, WINDOW_LOCATION } from './injection-tokens'; +import { WINDOW_LOCATION } from './injection-tokens'; import { LoggerModule } from './logger/logger.module'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const expectedUser = { id: 10 }; @@ -54,7 +52,6 @@ describe('AnalyticsResolver', () => { providers: [ { provide: Router, useValue: {} }, { provide: WINDOW_LOCATION, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: UserApiService, useValue: { @@ -63,8 +60,6 @@ describe('AnalyticsResolver', () => { }, }, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/access-contract-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/access-contract-api.service.spec.ts index 49d594bf5f1..bfb532ae437 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/access-contract-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/access-contract-api.service.spec.ts @@ -34,13 +34,13 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { LoggerModule } from '../logger/logger.module'; import { InjectorModule } from '../helper/injector.module'; import { BASE_URL, ENVIRONMENT } from '../injection-tokens'; import { environment } from '../../../environments/environment'; import { AccessContractApiService } from './access-contract-api.service'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('AccessContractApiService', () => { @@ -49,10 +49,10 @@ describe('AccessContractApiService', () => { TestBed.configureTestingModule({ imports: [InjectorModule, LoggerModule.forRoot()], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ENVIRONMENT, useValue: environment }, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting(), + { provide: BASE_URL, useValue: '/fake-api' }, ], }); service = TestBed.inject(AccessContractApiService); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/application-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/application-api.service.spec.ts index 7052f2af853..364472a9a80 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/application-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/application-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from '../injection-tokens'; import { ApplicationApiService } from './application-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('ApplicationApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/logbook-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/logbook-api.service.spec.ts index b1603e33bc6..437bc989d94 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/logbook-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/logbook-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from '../injection-tokens'; import { LogbookApiService } from './logbook-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('LogbookApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/ontology-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/ontology-api.service.spec.ts index 26fc1c71ef1..b3f6d5e990b 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/ontology-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/ontology-api.service.spec.ts @@ -36,7 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL } from '../injection-tokens'; import { OntologyApiService } from './ontology-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -46,14 +45,7 @@ describe('OntologyApiService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }); service = TestBed.inject(OntologyApiService); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/profile-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/profile-api.service.spec.ts index cf58beab1b5..80462e95a2d 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/profile-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/profile-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from '../injection-tokens'; import { ProfileApiService } from './profile-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('ProfileApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/security-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/security-api.service.spec.ts index 5e62d46047a..18d96eaa2dc 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/security-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/security-api.service.spec.ts @@ -36,8 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; - -import { BASE_URL } from '../injection-tokens'; import { SecurityApiService } from './security-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -45,14 +43,7 @@ describe('SecurityApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/site-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/site-api.service.spec.ts index 9364bf68fc1..2634bad1f8f 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/site-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/site-api.service.spec.ts @@ -36,7 +36,6 @@ */ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { BASE_URL } from '../injection-tokens'; import { SiteApiService } from './site-api.service'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -47,14 +46,7 @@ describe(SiteApiService.name, () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }); service = TestBed.inject(SiteApiService); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/subrogation-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/subrogation-api.service.spec.ts index 935e31d0e01..7bcc87e58cb 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/subrogation-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/subrogation-api.service.spec.ts @@ -34,24 +34,19 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { AuthService } from '../auth.service'; -import { BASE_URL, WINDOW_LOCATION } from '../injection-tokens'; +import { WINDOW_LOCATION } from '../injection-tokens'; import { SubrogationApiService } from './subrogation-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('SubrogationApiService', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [], providers: [ - { provide: BASE_URL, useValue: '/fake-api' }, { provide: WINDOW_LOCATION, useValue: {} }, { provide: AuthService, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/user-api.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/user-api.service.spec.ts index 31cd9ac7353..91b1c5c63d9 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/user-api.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/api/user-api.service.spec.ts @@ -34,13 +34,11 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { AuthService } from '../auth.service'; -import { BASE_URL, WINDOW_LOCATION } from './../injection-tokens'; +import { WINDOW_LOCATION } from './../injection-tokens'; import { UserApiService } from './user-api.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('UserApiService', () => { beforeEach(() => @@ -48,10 +46,7 @@ describe('UserApiService', () => { imports: [], providers: [ { provide: AuthService, useValue: {} }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: WINDOW_LOCATION, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }), ); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/app-root-component.class.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/app-root-component.class.ts deleted file mode 100644 index 864b22bfc11..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/app-root-component.class.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { ActivatedRoute } from '@angular/router'; -import { InjectorHelper } from './helper/injector-helper'; -import { Logger } from './logger/logger'; - -export class AppRootComponent { - private _appId: string; - - public logger: Logger; - - constructor(route: ActivatedRoute) { - if (InjectorHelper.injector === undefined) { - throw new Error('Injector not Found'); - } - this.logger = InjectorHelper.injector.get(Logger); - route.data.subscribe((data) => { - if (!data.hasOwnProperty('appId')) { - this.logger.error(this, 'Error: Missing "appId" property in route data.'); - } else { - this._appId = data['appId']; - } - }); - } - - get appId(): string { - return this._appId; - } -} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/app.guard.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/app.guard.spec.ts index 6d7c9c6c627..13d1b6d7ed7 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/app.guard.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/app.guard.spec.ts @@ -34,7 +34,6 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; import { ActivatedRouteSnapshot } from '@angular/router'; @@ -43,7 +42,6 @@ import { ApplicationService } from './application.service'; import { AuthService } from './auth.service'; import { WINDOW_LOCATION } from './injection-tokens'; import { StartupService } from './startup.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const expectedApp = [ { @@ -91,8 +89,6 @@ describe('AppGuard', () => { }, { provide: ApplicationService, useValue: { applications: expectedApp } }, { provide: WINDOW_LOCATION, useValue: {} }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/application.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/application.service.spec.ts index 9524806e97c..41618b2c3cc 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/application.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/application.service.spec.ts @@ -34,7 +34,7 @@ * 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 { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { HttpTestingController } from '@angular/common/http/testing'; import { LOCALE_ID, Type } from '@angular/core'; import { inject, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; @@ -42,10 +42,8 @@ import { ApplicationId } from './application-id.enum'; import { ApplicationService } from './application.service'; import { AuthService } from './auth.service'; import { ConfigService } from './config.service'; -import { BASE_URL } from './injection-tokens'; import { Application } from './models/application/application.interface'; import { StartupService } from './startup.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { Category } from './models/application/category.interface'; describe('ApplicationService', () => { @@ -75,10 +73,7 @@ describe('ApplicationService', () => { { provide: AuthService, useValue: authStubService }, { provide: LOCALE_ID, useValue: 'fr' }, { provide: StartupService, useValue: startupServiceStub }, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: ConfigService, useValue: configServiceStub }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/archive-unit.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/archive-unit.module.ts index 5395be92caf..fc708bac34d 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/archive-unit.module.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/archive-unit.module.ts @@ -48,7 +48,7 @@ import { ArchiveUnitEditorService } from './components/archive-unit-editor/archi import { EditorBannerComponent } from './components/archive-unit-editor/components/editor-banner/editor-banner.component'; import { ArchiveUnitViewerComponent } from './components/archive-unit-viewer/archive-unit-viewer.component'; import { PhysicalArchiveViewerComponent } from './components/physical-archive-viewer/physical-archive-viewer.component'; -import { CommonTooltipModule } from '../components/common-tooltip/common-tooltip.module'; + import { TranslatePipe } from '@ngx-translate/core'; @NgModule({ @@ -60,17 +60,14 @@ import { TranslatePipe } from '@ngx-translate/core'; MatProgressSpinnerModule, ObjectViewerModule, ObjectEditorModule, - CommonTooltipModule, TranslatePipe, - ], - providers: [ArchiveUnitEditorService], - declarations: [ PhysicalArchiveViewerComponent, ArchiveUnitCountComponent, ArchiveUnitViewerComponent, ArchiveUnitEditorComponent, EditorBannerComponent, ], + providers: [ArchiveUnitEditorService], exports: [ PhysicalArchiveViewerComponent, ArchiveUnitCountComponent, diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.spec.ts index 99375195845..42e0467dbf8 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.spec.ts @@ -74,9 +74,8 @@ describe('ArchiveUnitCountComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitCountComponent, PluralPipe], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], - imports: [LoggerModule.forRoot(), MatProgressSpinnerModule, LoggerModule.forRoot()], + imports: [LoggerModule.forRoot(), MatProgressSpinnerModule, LoggerModule.forRoot(), ArchiveUnitCountComponent, PluralPipe], providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.ts index 2fe22c7d476..bc4d27dba2b 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-count/archive-unit-count.component.ts @@ -35,16 +35,20 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpErrorResponse } from '@angular/common/http'; -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, inject } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { tap } from 'rxjs/operators'; import { Logger } from '../../../logger/logger'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TooltipDirective } from '../../../components/common-tooltip/tooltip.directive'; +import { PluralPipe } from '../../../pipes/plural.pipe'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-archive-unit-count', templateUrl: './archive-unit-count.component.html', styleUrls: ['./archive-unit-count.component.scss'], - standalone: false, + imports: [MatProgressSpinner, TooltipDirective, PluralPipe, TranslatePipe], }) export class ArchiveUnitCountComponent implements OnChanges { private logger = inject(Logger); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/archive-unit-editor.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/archive-unit-editor.component.ts index 06d63011d7d..ee087c3a4fd 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/archive-unit-editor.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/archive-unit-editor.component.ts @@ -43,13 +43,15 @@ import { customTemplate } from '../../archive-unit-template'; import type { ArchiveUnit } from '../../models/archive-unit'; import { JsonPatchDto } from '../../models/json-patch'; import { ArchiveUnitEditorService } from './archive-unit-editor.service'; +import { ObjectEditorComponent } from '../../../object-editor/object-editor.component'; +import { AsyncPipe } from '@angular/common'; @Component({ selector: 'vitamui-common-archive-unit-editor', templateUrl: './archive-unit-editor.component.html', styleUrls: ['./archive-unit-editor.component.scss'], providers: [ArchiveUnitEditorService], - standalone: false, + imports: [ObjectEditorComponent, AsyncPipe], }) export class ArchiveUnitEditorComponent implements OnInit, OnChanges, OnDestroy { private archiveUnitEditorService = inject(ArchiveUnitEditorService); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/components/editor-banner/editor-banner.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/components/editor-banner/editor-banner.component.ts index 9a59c30f87f..6443d7aca94 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/components/editor-banner/editor-banner.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-editor/components/editor-banner/editor-banner.component.ts @@ -35,12 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input } from '@angular/core'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-editor-banner', templateUrl: './editor-banner.component.html', styleUrls: ['./editor-banner.component.scss'], - standalone: false, + imports: [TranslatePipe], }) export class EditorBannerComponent { @Input() title: string; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.spec.ts index 9ce5b06f311..198e96cc48a 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.spec.ts @@ -38,7 +38,6 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; -import { BASE_URL } from '../../../injection-tokens'; import { LoggerModule } from '../../../logger/logger.module'; import { UnitType } from '../../../models/units/unit-type.enum'; import { Unit } from '../../../models/units/unit.interface'; @@ -97,17 +96,9 @@ describe('ArchiveUnitViewerComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ArchiveUnitViewerComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [ObjectViewerModule, ObjectEditorModule, ReactiveFormsModule, LoggerModule.forRoot()], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + imports: [ObjectViewerModule, ObjectEditorModule, ReactiveFormsModule, LoggerModule.forRoot(), ArchiveUnitViewerComponent], + providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.ts index ddeb87f7a1d..bfd4ce62c22 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.component.ts @@ -39,13 +39,14 @@ import { DisplayObjectService } from '../../../object-viewer/models/display-obje import { DisplayRule } from '../../../object-viewer/models/display-rule.model'; import { customTemplate } from '../../archive-unit-template'; import { ArchiveUnitViewerService, AUMode } from './archive-unit-viewer.service'; +import { ObjectViewerComponent } from '../../../object-viewer/object-viewer.component'; @Component({ selector: 'vitamui-common-archive-unit-viewer', templateUrl: './archive-unit-viewer.component.html', styleUrls: ['./archive-unit-viewer.component.scss'], providers: [{ provide: DisplayObjectService, useClass: ArchiveUnitViewerService }], - standalone: false, + imports: [ObjectViewerComponent], }) export class ArchiveUnitViewerComponent implements OnInit, OnChanges { private displayObjectService = inject(DisplayObjectService); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.service.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.service.spec.ts index 544441c4e47..fe86bda403c 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.service.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/archive-unit-viewer/archive-unit-viewer.service.spec.ts @@ -34,10 +34,8 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; -import { BASE_URL } from '../../../injection-tokens'; import { LoggerModule } from '../../../logger/logger.module'; import { DisplayObject } from '../../../object-viewer/models/display-object.model'; import { DisplayRule } from '../../../object-viewer/models/display-rule.model'; @@ -50,7 +48,6 @@ import { SchemaService } from '../../../schema/schema.service'; import { MockSchemaService } from '../../../schema/mock-schema.service'; import { ArchiveUnitViewerService } from './archive-unit-viewer.service'; import { ObjectEditorModule } from '../../../object-editor/object-editor.module'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('ArchiveUnitViewerService', () => { let service: ArchiveUnitViewerService; @@ -65,10 +62,7 @@ describe('ArchiveUnitViewerService', () => { DisplayObjectHelperService, DisplayRuleHelperService, SchemaElementToDisplayRuleService, - { provide: BASE_URL, useValue: '/fake-api' }, { provide: SchemaService, useClass: MockSchemaService }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }); service = TestBed.inject(ArchiveUnitViewerService); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/physical-archive-viewer/physical-archive-viewer.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/physical-archive-viewer/physical-archive-viewer.component.ts index 055da0b9c3d..d4f06410f03 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/physical-archive-viewer/physical-archive-viewer.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/archive-unit/components/physical-archive-viewer/physical-archive-viewer.component.ts @@ -35,10 +35,12 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, inject, Input, OnInit } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ObjectQualifierType } from '../../../models/units/object-qualifier.enums'; import { ValidationError } from '../../../models/units/unit.interface'; import type { VersionWithQualifierDto } from '../../../models/units/object-group.interface'; +import { NgClass, UpperCasePipe } from '@angular/common'; +import { BytesPipe } from '../../../pipes/bytes.pipe'; interface Measurement { name: string; @@ -66,7 +68,7 @@ type MeasurementDisplayMode = 'SYMBOL' | 'NAME'; selector: 'vitamui-common-physical-archive-viewer', templateUrl: './physical-archive-viewer.component.html', styleUrls: ['./physical-archive-viewer.component.scss'], - standalone: false, + imports: [NgClass, UpperCasePipe, BytesPipe, TranslatePipe], }) export class PhysicalArchiveViewerComponent implements OnInit { private translateService = inject(TranslateService); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/chip/chip.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/chip/chip.component.ts index c42c8ac4f80..2257533b1ac 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/chip/chip.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/chip/chip.component.ts @@ -40,7 +40,6 @@ import { Component, Input } from '@angular/core'; selector: 'vitamui-chip', template: ` {{ text }} `, styleUrls: ['chip.component.scss'], - standalone: true, }) export class ChipComponent { @Input() text = ''; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.scss b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.scss index aa494ea8177..8340c1fdc66 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.scss +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.scss @@ -7,5 +7,40 @@ .collapse-content { overflow: hidden; + display: grid; + transition: + grid-template-rows 150ms cubic-bezier(0.4, 0, 0.2, 1), + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1); + grid-template-rows: 1fr; + opacity: 1; + + &.collapsed { + grid-template-rows: 0fr; + opacity: 0; + visibility: hidden; + } + + &.expanded { + grid-template-rows: 1fr; + opacity: 1; + visibility: visible; + } + + & > * { + min-height: 0; + } + } + + .collapse-icon { + display: inline-block; + transition: transform 200ms ease-out; + + &.collapsed { + transform: rotate(-90deg); + } + + &:not(.collapsed) { + transform: rotate(0deg); + } } } diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.spec.ts deleted file mode 100644 index f25cc69e53d..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.spec.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; - -import { CollapseComponent } from './collapse.component'; - -@Component({ - template: ` Test Collapse Content `, - standalone: false, -}) -class TesthostComponent { - @ViewChild(CollapseComponent) component: CollapseComponent; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('CollapseComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [NoopAnimationsModule], - declarations: [CollapseComponent, TesthostComponent], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - it('should have a title', () => { - const elTitle = fixture.nativeElement.querySelector('.collapse-title'); - expect(elTitle).toBeTruthy(); - expect(elTitle.textContent).toContain('Test Collapse Title'); - }); - - it('should display the content', () => { - const elContent = fixture.nativeElement.querySelector('.collapse-content'); - expect(elContent).toBeTruthy(); - expect(elContent.textContent).toContain('Test Collapse Content'); - }); - - it('should toggle the content on click on the title', () => { - expect(testhost.component.collapseState).toBe('expanded'); - const elTitle = fixture.nativeElement.querySelector('.collapse-title'); - - elTitle.click(); - fixture.detectChanges(); - expect(testhost.component.collapseState).toBe('collapsed'); - - elTitle.click(); - fixture.detectChanges(); - expect(testhost.component.collapseState).toBe('expanded'); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.ts index ef480e14aa4..134bed62ccb 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.component.ts @@ -34,14 +34,14 @@ * 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, HostBinding, Input } from '@angular/core'; +import { Component, forwardRef, HostBinding, Input } from '@angular/core'; @Component({ selector: 'vitamui-common-collapse', templateUrl: './collapse.component.html', styleUrls: ['./collapse.component.scss'], exportAs: 'vitamuiCommonCollapse', - standalone: false, + imports: [forwardRef(() => CollapseComponent)], }) export class CollapseComponent { @HostBinding('class.collapse-container') classCollapseContainer = true; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.module.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.module.spec.ts deleted file mode 100644 index 689182f9162..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.module.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CollapseModule } from './collapse.module'; - -describe('CollapseModule', () => { - let collapseModule: CollapseModule; - - beforeEach(() => { - collapseModule = new CollapseModule(); - }); - - it('should create an instance', () => { - expect(collapseModule).toBeTruthy(); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.module.ts deleted file mode 100644 index 65808229189..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/collapse/collapse.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { CollapseComponent } from './collapse.component'; - -@NgModule({ - imports: [CommonModule], - declarations: [CollapseComponent], - exports: [CollapseComponent], -}) -export class CollapseModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.spec.ts index fbcebc3eb4f..a0e97bde54f 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.spec.ts @@ -46,8 +46,7 @@ describe('ClosePopupDialogComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [VitamUICommonTestModule], - declarations: [ClosePopupDialogComponent], + imports: [VitamUICommonTestModule, ClosePopupDialogComponent], schemas: [NO_ERRORS_SCHEMA], providers: [{ provide: MAT_DIALOG_DATA, useValue: {} }], }).compileComponents(); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.ts index 21721002392..d60cec0420b 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/close-popup-dialog.component.ts @@ -37,12 +37,14 @@ import { Component, inject } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { DialogInputData } from './dialog-input-data.interface'; +import { CommonConfirmDialogComponent } from './common-confirm-dialog.component'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-close-popup-dialog', templateUrl: './close-popup-dialog.component.html', styleUrls: ['./close-popup-dialog.component.scss'], - standalone: false, + imports: [CommonConfirmDialogComponent, TranslatePipe], }) export class ClosePopupDialogComponent { data? = inject(MAT_DIALOG_DATA); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.spec.ts index afedeaeaebf..f3a138fcba5 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.spec.ts @@ -47,8 +47,7 @@ describe('CommonConfirmDialogComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [MatDialogModule, VitamUICommonTestModule], - declarations: [CommonConfirmDialogComponent], + imports: [MatDialogModule, VitamUICommonTestModule, CommonConfirmDialogComponent], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.ts index 394d480d04a..436e88add33 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/common-confirm-dialog.component.ts @@ -35,12 +35,15 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component, Input } from '@angular/core'; +import { DialogHeaderComponent } from '../../../../lib/components/dialog/dialog-header/dialog-header.component'; +import { MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-confirm-dialog', templateUrl: './common-confirm-dialog.component.html', styleUrls: ['./common-confirm-dialog.component.scss'], - standalone: false, + imports: [DialogHeaderComponent, MatDialogContent, MatDialogActions, MatDialogClose, TranslatePipe], }) export class CommonConfirmDialogComponent { @Input() dialogTitle: string; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/confirm-dialog.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/confirm-dialog.module.ts deleted file mode 100644 index f2a55ff3441..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-confirm-dialog/confirm-dialog.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatDialogModule } from '@angular/material/dialog'; - -import { ClosePopupDialogComponent } from './close-popup-dialog.component'; -import { CommonConfirmDialogComponent } from './common-confirm-dialog.component'; -import { DialogHeaderComponent } from '../../../../lib/components/dialog/dialog-header/dialog-header.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - declarations: [CommonConfirmDialogComponent, ClosePopupDialogComponent], - imports: [CommonModule, MatDialogModule, DialogHeaderComponent, TranslatePipe], - exports: [CommonConfirmDialogComponent, ClosePopupDialogComponent], -}) -export class ConfirmDialogModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.component.ts index ca14bb719dc..4fb4e22e3be 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.component.ts @@ -35,12 +35,13 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { Component } from '@angular/core'; +import { NgClass } from '@angular/common'; @Component({ selector: 'vitamui-common-tooltip', templateUrl: './common-tooltip.component.html', styleUrls: ['./common-tooltip.component.scss'], - standalone: false, + imports: [NgClass], }) export class CommonTooltipComponent { public text = ''; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.module.ts deleted file mode 100644 index 9c834a6b14c..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/common-tooltip.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { CommonTooltipComponent } from './common-tooltip.component'; -import { TooltipDirective } from './tooltip.directive'; - -@NgModule({ - imports: [CommonModule], - declarations: [CommonTooltipComponent, TooltipDirective], - exports: [CommonTooltipComponent, TooltipDirective], -}) -export class CommonTooltipModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/tooltip.directive.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/tooltip.directive.ts index 4780d1ed480..bb3fcfb2f58 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/tooltip.directive.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/common-tooltip/tooltip.directive.ts @@ -42,12 +42,12 @@ import { Directive, ElementRef, HostListener, + inject, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, - inject, } from '@angular/core'; import type { TooltipPosition } from './TooltipPosition.enum'; import { CommonTooltipComponent } from './common-tooltip.component'; @@ -81,10 +81,7 @@ const VITAMUI_TOOL_TIP_POSITIONS: { [key: string]: ConnectedPosition } = { const TOOLTIP_TRIGGER_CLASS = 'tooltip-trigger'; -@Directive({ - selector: '[vitamuiTooltip]', - standalone: false, -}) +@Directive({ selector: '[vitamuiTooltip]' }) export class TooltipDirective implements OnInit, OnDestroy, OnChanges { private overlay = inject(Overlay); private overlayPositionBuilder = inject(OverlayPositionBuilder); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/data/data.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/data/data.component.ts index cc46828396b..e4a3b8a2ca1 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/data/data.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/data/data.component.ts @@ -34,18 +34,20 @@ * 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, ContentChild, Input, TemplateRef, inject } from '@angular/core'; +import { Component, ContentChild, inject, Input, TemplateRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PipesModule } from '../../pipes/pipes.module'; -import { CommonTooltipModule } from '../common-tooltip/common-tooltip.module'; + import { Clipboard } from '@angular/cdk/clipboard'; import { TranslatePipe } from '@ngx-translate/core'; +import { TooltipDirective } from '../common-tooltip/tooltip.directive'; @Component({ selector: 'vitamui-common-data', templateUrl: './data.component.html', styleUrls: ['./data.component.scss'], - imports: [CommonModule, PipesModule, CommonTooltipModule, TranslatePipe], + imports: [CommonModule, PipesModule, TooltipDirective, TranslatePipe], + hostDirectives: [{ directive: TooltipDirective, inputs: ['vitamuiTooltipShowDelay'] }], }) export class DataComponent { private clipboard = inject(Clipboard); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.spec.ts index 184b7078800..3546359a10b 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.spec.ts @@ -47,8 +47,7 @@ describe('DownloadSnackBarComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [DownloadSnackBarComponent], - imports: [MatDialogModule, MatProgressBarModule], + imports: [MatDialogModule, MatProgressBarModule, DownloadSnackBarComponent], providers: [ { provide: MatDialog, @@ -70,38 +69,3 @@ describe('DownloadSnackBarComponent', () => { expect(component).toBeTruthy(); }); }); - -// import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -// import { MatDialog } from '@angular/material/dialog'; -// import { MatProgressBarModule } from '@angular/material/progress-bar'; -// import { empty } from 'rxjs'; - -// import { DownloadService } from '../download.service'; -// import { DownloadSnackBarComponent } from './download-snack-bar.component'; - -// describe('DownloadSnackBarComponent', () => { -// let component: DownloadSnackBarComponent; -// let fixture: ComponentFixture; - -// beforeEach(async(() => { -// await TestBed.configureTestingModule({ -// imports: [MatProgressBarModule], -// declarations: [ DownloadSnackBarComponent ], -// providers: [ -// { provide: MatDialog, useValue: {} }, -// { provide: DownloadService, useValue: { downloadReady: empty(), startRefreshLoop: () => {}, stopRefreshLoop: () => {} } }, -// ] -// }) -// .compileComponents(); -// })); - -// beforeEach(() => { -// fixture = TestBed.createComponent(DownloadSnackBarComponent); -// component = fixture.componentInstance; -// fixture.detectChanges(); -// }); - -// it('should create', () => { -// expect(component).toBeTruthy(); -// }); -// }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.ts index 18e47104d5d..8137a633570 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.component.ts @@ -34,16 +34,19 @@ * 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, TemplateRef, ViewChild, inject } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; +import { Component, inject, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog'; import { Observable, Subject } from 'rxjs'; import { filter } from 'rxjs/operators'; +import { MatProgressBar } from '@angular/material/progress-bar'; +import { I18nPluralPipe, PercentPipe } from '@angular/common'; +import { TranslatePipe } from '@ngx-translate/core'; @Component({ selector: 'vitamui-common-download-snack-bar', templateUrl: './download-snack-bar.component.html', styleUrls: ['./download-snack-bar.component.scss'], - standalone: false, + imports: [MatProgressBar, MatDialogContent, MatDialogActions, MatDialogClose, PercentPipe, I18nPluralPipe, TranslatePipe], }) export class DownloadSnackBarComponent { private matDialog = inject(MatDialog); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.module.ts deleted file mode 100644 index d502dc9ccaa..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/download-snack-bar/download-snack-bar.module.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { DownloadSnackBarComponent } from '../download-snack-bar/download-snack-bar.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, MatDialogModule, MatProgressBarModule, TranslatePipe], - declarations: [DownloadSnackBarComponent], - exports: [DownloadSnackBarComponent], -}) -export class DownloadSnackBarModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.spec.ts index e02c732969a..b5f4612e75a 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.spec.ts @@ -34,9 +34,9 @@ * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing'; +// import {async, ComponentFixture, TestBed} from '@angular/core/testing'; -// import { EditableEmailInputComponent } from './editable-email-input.component'; +// import {EditableEmailInputComponent} from './editable-email-input.component'; // describe('EditableEmailInputComponent', () => { // let component: EditableEmailInputComponent; @@ -65,7 +65,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MatSelectModule } from '@angular/material/select'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EditableEmailInputComponent } from './editable-email-input.component'; @@ -75,8 +74,7 @@ describe('EditableEmailInputComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [EditableEmailInputComponent], - imports: [OverlayModule, ReactiveFormsModule, MatSelectModule, NoopAnimationsModule], + imports: [OverlayModule, ReactiveFormsModule, MatSelectModule, EditableEmailInputComponent], providers: [{ provide: DOCUMENT, useValue: document }], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.ts index 415722e6875..78d424c8142 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-email-input/editable-email-input.component.ts @@ -34,12 +34,15 @@ * 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, ElementRef, forwardRef, Input, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, forwardRef, inject, Input, ViewChild } from '@angular/core'; import { DOCUMENT } from '@angular/common'; -import { FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { MatSelect } from '@angular/material/select'; +import { FormBuilder, FormGroup, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; +import { MatOption, MatSelect } from '@angular/material/select'; import { EditableFieldComponent } from '../editable-field.component'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { MatFormField } from '@angular/material/form-field'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; export const EDITABLE_EMAIL_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -52,7 +55,16 @@ export const EDITABLE_EMAIL_INPUT_VALUE_ACCESSOR: any = { templateUrl: './editable-email-input.component.html', styleUrls: ['./editable-email-input.component.scss'], providers: [EDITABLE_EMAIL_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [ + CdkOverlayOrigin, + FormsModule, + ReactiveFormsModule, + MatFormField, + MatSelect, + MatOption, + MatProgressSpinner, + CdkConnectedOverlay, + ], }) export class EditableEmailInputComponent extends EditableFieldComponent { private document = inject(DOCUMENT); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.spec.ts index f635c00fe05..ffab183189a 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.spec.ts @@ -38,10 +38,8 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { Validators } from '@angular/forms'; import { VitamUICommonTestModule } from '../../../../../testing/src/vitamui-common-test.module'; -import { BASE_URL } from '../../injection-tokens'; import { EditableFieldComponent } from './editable-field.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('EditableFieldComponent', () => { let component: EditableFieldComponent; @@ -49,14 +47,7 @@ describe('EditableFieldComponent', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [VitamUICommonTestModule], - providers: [ - { - provide: BASE_URL, - useValue: '/fake-api', - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], + providers: [provideHttpClientTesting()], }), ); beforeEach(() => { diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.ts index 8dd261a58a3..ce72af8a313 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.component.ts @@ -43,14 +43,14 @@ import { EventEmitter, HostBinding, HostListener, + inject, Input, Output, QueryList, ViewChild, - inject, } from '@angular/core'; -import { ControlValueAccessor, FormControl } from '@angular/forms'; import type { AsyncValidatorFn, ValidatorFn } from '@angular/forms'; +import { ControlValueAccessor, FormControl } from '@angular/forms'; import { VitamUIFieldErrorComponent } from '../vitamui-field-error/vitamui-field-error.component'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; @@ -58,7 +58,6 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion'; @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector selector: 'editable-field-component', - standalone: false, }) export class EditableFieldComponent implements AfterContentInit, ControlValueAccessor { protected elementRef: ElementRef; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.module.ts deleted file mode 100644 index 042a8f77b38..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-field.module.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayModule } from '@angular/cdk/overlay'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSelectModule } from '@angular/material/select'; -import { EllipsisDirectiveModule } from '../../directives/ellipsis/ellipsis.directive.module'; -import { ConfirmDialogModule } from '../common-confirm-dialog/confirm-dialog.module'; -import { EditableEmailInputComponent } from './editable-email-input/editable-email-input.component'; -import { EditableFieldComponent } from './editable-field.component'; -import { EditableFileComponent } from './editable-file/editable-file.component'; -import { EditableInputComponent } from './editable-input/editable-input.component'; -import { EditableLevelInputComponent } from './editable-level-input/editable-level-input.component'; -import { SubLevelPipe } from './editable-level-input/sub-level.pipe'; -import { EditableTextareaComponent } from './editable-textarea/editable-textarea.component'; -import { EditableButtonToggleComponent } from './editable-toggle-group/editable-button-toggle.component'; -import { EditableToggleGroupComponent } from './editable-toggle-group/editable-toggle-group.component'; -import { LevelInputModule } from './level-input/level-input.module'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - ReactiveFormsModule, - OverlayModule, - MatSelectModule, - MatProgressSpinnerModule, - MatButtonToggleModule, - MatDialogModule, - ConfirmDialogModule, - LevelInputModule, - MatInputModule, - MatFormFieldModule, - EllipsisDirectiveModule, - TranslatePipe, - ], - declarations: [ - EditableFieldComponent, - EditableButtonToggleComponent, - EditableEmailInputComponent, - EditableFileComponent, - EditableInputComponent, - EditableLevelInputComponent, - EditableTextareaComponent, - EditableToggleGroupComponent, - SubLevelPipe, - ], - exports: [ - EditableFieldComponent, - EditableInputComponent, - EditableTextareaComponent, - EditableToggleGroupComponent, - EditableButtonToggleComponent, - EditableFileComponent, - EditableEmailInputComponent, - EditableLevelInputComponent, - SubLevelPipe, - LevelInputModule, - ], -}) -export class EditableFieldModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.spec.ts deleted file mode 100644 index 9b2dcf5f1cb..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.spec.ts +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { AbstractControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { By } from '@angular/platform-browser'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of } from 'rxjs'; - -import { WINDOW_LOCATION } from '../../../injection-tokens'; -import { newFile } from '../../../models/customer/identity-provider.interface'; -import { VitamUIFieldErrorComponent } from '../../vitamui-field-error/vitamui-field-error.component'; -import { EditableFileComponent } from './editable-file.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - -@Component({ - template: ` - - Expected required error message - Expected async error message - - `, - standalone: false, -}) -class TesthostComponent { - value: File; - label = 'Test label'; - accept = '.txt'; - @ViewChild(EditableFileComponent) - component: EditableFileComponent; - - validator = Validators.required; - asyncValidator = (control: AbstractControl) => { - return of(control.value !== 'invalid value' ? null : { async: true }); - }; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditableFileComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [TesthostComponent, EditableFileComponent], - imports: [ - FormsModule, - MatProgressSpinnerModule, - NoopAnimationsModule, - OverlayModule, - ReactiveFormsModule, - VitamUIFieldErrorComponent, - ], - providers: [ - { - provide: WINDOW_LOCATION, - useValue: {}, - }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), - ], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should display the label', () => { - const elLabel = fixture.nativeElement.querySelector('label'); - expect(elLabel.textContent).toContain('Test label'); - }); - - it('should display the value', waitForAsync(() => { - testhost.value = newFile([''], 'test-file.txt'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elValue = fixture.nativeElement.querySelector('.editable-field .editable-field-content .editable-field-text-content'); - expect(elValue.textContent).toContain('test-file.txt'); - }); - })); - - it('should have an input', () => { - const elInput = fixture.nativeElement.querySelector('input[type=file]'); - expect(elInput).toBeTruthy(); - fixture.detectChanges(); - expect(elInput.attributes.accept.value).toBe('.txt'); - }); - - it('should set the file', () => { - const dbInput = fixture.debugElement.query(By.css('input[type=file]')); - const expectedFile = newFile([''], 'test.txt'); - dbInput.triggerEventHandler('change', { target: { files: { item: () => expectedFile } } }); - expect(testhost.component.file).toBe(expectedFile); - }); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeTruthy(); - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.control.setValue('valid value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-cancel') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have a spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(true); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeTruthy(); - }); - - it('should hide the spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(false); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeFalsy(); - }); - - it('should display the error message', () => { - testhost.component.control.setValue(''); - fixture.detectChanges(); - const elErrors = fixture.nativeElement.querySelectorAll('.vitamui-input-errors vitamui-common-field-error'); - expect(elErrors.length).toBe(2); - expect(elErrors[0].textContent).toContain('Expected required error message'); - }); - - it('should display the async error message', () => { - testhost.component.control.setValue('invalid value'); - fixture.detectChanges(); - const elErrors = fixture.nativeElement.querySelectorAll('.vitamui-input-errors vitamui-common-field-error'); - expect(elErrors.length).toBe(2); - expect(elErrors[1].textContent).toContain('Expected async error message'); - }); - }); - - describe('Class', () => { - it('should set the control value', waitForAsync(() => { - testhost.value = newFile([''], 'test-file.txt'); - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toBe(testhost.value); - }); - })); - - describe('canConfirm', () => { - it('should return true when the edit mode is active, the value has changed and is valid', () => { - testhost.component.editMode = true; - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue(newFile([''], 'test-file.txt')); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - it('should emit a new value', waitForAsync(() => { - const originFile = newFile([''], 'origin-file.txt'); - const newFileTmp = newFile([''], 'new-file.txt'); - testhost.value = originFile; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue(newFileTmp); - testhost.component.control.markAsDirty(); - fixture.detectChanges(false); - expect(testhost.value).toEqual(originFile); - testhost.component.confirm(); - expect(testhost.value).toEqual(newFileTmp); - }); - })); - - it('should reverse the changes', waitForAsync(() => { - const originFile = newFile([''], 'origin-file.txt'); - const newFileTmp = newFile([''], 'new-file.txt'); - testhost.value = originFile; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue(newFileTmp); - testhost.component.control.markAsDirty(); - fixture.detectChanges(false); - expect(testhost.value).toEqual(originFile); - testhost.component.cancel(); - fixture.detectChanges(false); - expect(testhost.value).toEqual(originFile); - expect(testhost.component.control.value).toEqual(originFile); - }); - })); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.ts index 5f1c749c45e..3480e7a8008 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-file/editable-file.component.ts @@ -34,10 +34,13 @@ * 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, ElementRef, forwardRef, Input, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, forwardRef, inject, Input, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { EditableFieldComponent } from '../editable-field.component'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { TranslatePipe } from '@ngx-translate/core'; export const EDITABLE_FILE_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -49,7 +52,7 @@ export const EDITABLE_FILE_VALUE_ACCESSOR: any = { selector: 'vitamui-common-editable-file', templateUrl: './editable-file.component.html', providers: [EDITABLE_FILE_VALUE_ACCESSOR], - standalone: false, + imports: [CdkOverlayOrigin, MatProgressSpinner, CdkConnectedOverlay, TranslatePipe], }) export class EditableFileComponent extends EditableFieldComponent { @Input() accept: string; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.spec.ts deleted file mode 100644 index 04c8cba6c9a..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.spec.ts +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { Component, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { AbstractControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of } from 'rxjs'; - -import { input } from '../../../../../../testing/src/helpers'; -import { VitamUIFieldErrorComponent } from '../../vitamui-field-error/vitamui-field-error.component'; -import { EditableInputComponent } from './editable-input.component'; - -@Component({ - template: ` - - Expected required error message - Expected async error message - - `, - standalone: false, -}) -class TesthostComponent { - value: string; - label = 'Test label'; - maxlength = 42; - @ViewChild(EditableInputComponent) - component: EditableInputComponent; - - validator = Validators.required; - asyncValidator = (control: AbstractControl) => { - return of(control.value !== 'invalid value' ? null : { async: true }); - }; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditableInputComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - FormsModule, - MatProgressSpinnerModule, - NoopAnimationsModule, - OverlayModule, - ReactiveFormsModule, - VitamUIFieldErrorComponent, - ], - declarations: [EditableInputComponent, TesthostComponent], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should display the label', () => { - const elLabel = fixture.nativeElement.querySelector('label'); - expect(elLabel.textContent).toContain('Test label'); - }); - - it('should display the value', waitForAsync(() => { - testhost.value = 'test value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elValue = fixture.nativeElement.querySelector('.editable-field .editable-field-content .editable-field-text-content'); - expect(elValue.textContent).toContain('test value'); - }); - })); - - it('should have an input', () => { - const elInput = fixture.nativeElement.querySelector('.editable-field-control > input'); - expect(elInput).toBeTruthy(); - input(elInput, 'input value'); - fixture.detectChanges(); - expect(testhost.component.control.value).toBe('input value'); - expect(elInput.attributes.maxlength.value).toBe('42'); - }); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeTruthy(); - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.control.setValue('valid value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-cancel') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have a spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(true); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeTruthy(); - }); - - it('should hide the spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(false); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeFalsy(); - }); - - it('should display the error message', () => { - testhost.component.control.setValue(''); - fixture.detectChanges(); - const elErrors = fixture.nativeElement.querySelectorAll('.vitamui-input-errors vitamui-common-field-error'); - expect(elErrors.length).toBe(2); - expect(elErrors[0].textContent).toContain('Expected required error message'); - }); - - it('should display the async error message', () => { - testhost.component.control.setValue('invalid value'); - fixture.detectChanges(); - const elErrors = fixture.nativeElement.querySelectorAll('.vitamui-input-errors vitamui-common-field-error'); - expect(elErrors.length).toBe(2); - expect(elErrors[1].textContent).toContain('Expected async error message'); - }); - }); - - describe('Class', () => { - it('should set the control value', waitForAsync(() => { - testhost.value = 'test value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toBe(testhost.value); - }); - })); - - describe('canConfirm', () => { - it('should return true when the edit mode is active, the value has changed and is valid', () => { - testhost.component.editMode = true; - testhost.component.control.setValue(['test1.com', 'test2.com']); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue('test value'); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue('test value'); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue('test value'); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - it('should emit a new value', waitForAsync(() => { - testhost.value = 'origin value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue('new value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual('origin value'); - testhost.component.confirm(); - expect(testhost.value).toEqual('new value'); - }); - })); - - it('should reverse the changes', waitForAsync(() => { - testhost.value = 'origin value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue('new value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual('origin value'); - testhost.component.cancel(); - fixture.detectChanges(); - expect(testhost.value).toEqual('origin value'); - expect(testhost.component.control.value).toEqual('origin value'); - }); - })); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.ts index fef298f40c7..1ee21175173 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-input/editable-input.component.ts @@ -34,11 +34,14 @@ * 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, ElementRef, forwardRef, Input, ViewChild, inject } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, ElementRef, forwardRef, inject, Input, ViewChild } from '@angular/core'; +import { FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent } from '../editable-field.component'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { EllipsisDirective } from '../../../directives/ellipsis/ellipsis.directive'; export const EDITABLE_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -51,7 +54,7 @@ export const EDITABLE_INPUT_VALUE_ACCESSOR: any = { templateUrl: './editable-input.component.html', styleUrls: ['./editable-input.component.scss'], providers: [EDITABLE_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [CdkOverlayOrigin, FormsModule, ReactiveFormsModule, MatProgressSpinner, CdkConnectedOverlay, EllipsisDirective], }) export class EditableInputComponent extends EditableFieldComponent { @Input() maxlength: number; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.spec.ts index 507d2352ee0..822646fc812 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.spec.ts @@ -35,14 +35,12 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { OverlayModule } from '@angular/cdk/overlay'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { Component, forwardRef, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { WINDOW_LOCATION } from '../../../injection-tokens'; import { EditableLevelInputComponent } from './editable-level-input.component'; import { SubLevelPipe } from './sub-level.pipe'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @Component({ selector: 'vitamui-common-level-input', @@ -54,7 +52,7 @@ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http' multi: true, }, ], - standalone: false, + imports: [ReactiveFormsModule, OverlayModule], }) class LevelInputStubComponent implements ControlValueAccessor { @Input() prefix: string; @@ -71,15 +69,12 @@ describe('EditableLevelInputComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [EditableLevelInputComponent, LevelInputStubComponent, SubLevelPipe], - imports: [ReactiveFormsModule, OverlayModule], + imports: [ReactiveFormsModule, OverlayModule, EditableLevelInputComponent, LevelInputStubComponent, SubLevelPipe], providers: [ { provide: WINDOW_LOCATION, useValue: {}, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.ts index 9adf44c2401..959f7e42a1b 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/editable-level-input.component.ts @@ -34,9 +34,13 @@ * 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, ElementRef, forwardRef, Input, inject } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, ElementRef, forwardRef, inject, Input } from '@angular/core'; +import { FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent } from '../editable-field.component'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { LevelInputComponent } from '../level-input/level-input.component'; +import { TranslatePipe } from '@ngx-translate/core'; +import { SubLevelPipe } from './sub-level.pipe'; export const EDITABLE_LEVEL_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -49,7 +53,7 @@ export const EDITABLE_LEVEL_INPUT_VALUE_ACCESSOR: any = { templateUrl: './editable-level-input.component.html', styleUrls: ['./editable-level-input.component.scss'], providers: [EDITABLE_LEVEL_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [CdkOverlayOrigin, LevelInputComponent, FormsModule, ReactiveFormsModule, CdkConnectedOverlay, TranslatePipe, SubLevelPipe], }) export class EditableLevelInputComponent extends EditableFieldComponent { @Input() prefix: string; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/sub-level.pipe.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/sub-level.pipe.ts index ad3b4b9ddee..c1188a57141 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/sub-level.pipe.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-level-input/sub-level.pipe.ts @@ -37,10 +37,7 @@ import { Pipe, PipeTransform } from '@angular/core'; import { extractSubLevel } from '../../../utils/level.util'; -@Pipe({ - name: 'subLevel', - standalone: false, -}) +@Pipe({ name: 'subLevel' }) export class SubLevelPipe implements PipeTransform { transform(level: any, userLevel: string): any { return extractSubLevel(userLevel, level); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.spec.ts deleted file mode 100644 index 5863c83411e..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.spec.ts +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { Component, NgModule, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { AbstractControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of } from 'rxjs'; - -import { input } from '../../../../../../testing/src/helpers'; -import { VitamUIFieldErrorStubComponent } from '../../../../../../testing/src/vitamui-common-test.module'; -import { EditableTextareaComponent } from './editable-textarea.component'; - -@Component({ - template: ` - - Expected required error message - Expected async error message - - `, - standalone: false, -}) -class TesthostComponent { - value: string; - label = 'Test label'; - maxlength = 42; - @ViewChild(EditableTextareaComponent) - component: EditableTextareaComponent; - - validator = Validators.required; - asyncValidator = (control: AbstractControl) => { - return of(control.value !== 'invalid value' ? null : { async: true }); - }; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditableTextareaComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [OverlayModule, FormsModule, ReactiveFormsModule, MatProgressSpinnerModule, NoopAnimationsModule], - declarations: [TesthostComponent, EditableTextareaComponent, VitamUIFieldErrorStubComponent], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should display the label', () => { - const elLabel = fixture.nativeElement.querySelector('label'); - expect(elLabel.textContent).toContain('Test label'); - }); - - it('should display the value', waitForAsync(() => { - testhost.value = 'test value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elValue = fixture.nativeElement.querySelector('.editable-field .editable-field-content .editable-field-text-content'); - expect(elValue.textContent).toContain('test value'); - }); - })); - - it('should have a textarea', () => { - const elInput = fixture.nativeElement.querySelector('.editable-field-control > textarea'); - expect(elInput).toBeTruthy(); - input(elInput, 'input value'); - fixture.detectChanges(); - expect(testhost.component.control.value).toBe('input value'); - expect(elInput.attributes.maxlength.value).toBe('42'); - }); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeTruthy(); - testhost.component.cancel(); - expect(testhost.component.editMode).toBe(false); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.control.setValue('valid value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-cancel') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have a spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(true); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeTruthy(); - }); - - it('should hide the spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(false); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeFalsy(); - }); - - it('should display the error message', () => { - testhost.component.control.setValue(''); - fixture.detectChanges(); - const elErrors = fixture.nativeElement.querySelectorAll('.vitamui-input-errors vitamui-common-field-error'); - expect(elErrors.length).toBe(2); - expect(elErrors[0].textContent).toContain('Expected required error message'); - }); - - it('should display the async error message', () => { - testhost.component.control.setValue('invalid value'); - fixture.detectChanges(); - const elErrors = fixture.nativeElement.querySelectorAll('.vitamui-input-errors vitamui-common-field-error'); - expect(elErrors.length).toBe(2); - expect(elErrors[1].textContent).toContain('Expected async error message'); - }); - }); - - describe('Class', () => { - it('should set the control value', waitForAsync(() => { - testhost.value = 'test value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toBe(testhost.value); - }); - })); - - describe('canConfirm', () => { - it('should return true when the edit mode is active, the value has changed and is valid', () => { - testhost.component.editMode = true; - testhost.component.control.setValue(['test1.com', 'test2.com']); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue('test value'); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue('test value'); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue('test value'); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - it('should emit a new value', waitForAsync(() => { - testhost.value = 'origin value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue('new value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual('origin value'); - testhost.component.confirm(); - expect(testhost.value).toEqual('new value'); - }); - })); - - it('should reverse the changes', waitForAsync(() => { - testhost.value = 'origin value'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue('new value'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual('origin value'); - testhost.component.cancel(); - fixture.detectChanges(); - expect(testhost.value).toEqual('origin value'); - expect(testhost.component.control.value).toEqual('origin value'); - }); - })); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.ts index b026c9a2202..6522104501d 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-textarea/editable-textarea.component.ts @@ -34,11 +34,13 @@ * 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, ElementRef, forwardRef, Input, ViewChild, inject } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, ElementRef, forwardRef, inject, Input, ViewChild } from '@angular/core'; +import { FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent } from '../editable-field.component'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; export const EDITABLE_TEXTAREA_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -51,7 +53,7 @@ export const EDITABLE_TEXTAREA_VALUE_ACCESSOR: any = { templateUrl: './editable-textarea.component.html', styleUrls: ['./editable-textarea.component.scss'], providers: [EDITABLE_TEXTAREA_VALUE_ACCESSOR], - standalone: false, + imports: [CdkOverlayOrigin, FormsModule, ReactiveFormsModule, MatProgressSpinner, CdkConnectedOverlay], }) export class EditableTextareaComponent extends EditableFieldComponent { @Input() maxlength: number; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-button-toggle.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-button-toggle.component.ts index ba1b0b5b706..73820af959b 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-button-toggle.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-button-toggle.component.ts @@ -39,7 +39,6 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'vitamui-common-editable-button-toggle', template: '', - standalone: false, }) export class EditableButtonToggleComponent { @Input() value: any; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.spec.ts deleted file mode 100644 index 6d69be119e1..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.spec.ts +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; -import { Component, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; -import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; -import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; - -import { EditableButtonToggleComponent } from './editable-button-toggle.component'; -import { EditableToggleGroupComponent } from './editable-toggle-group.component'; - -@Component({ - template: ` - - - - - - `, - standalone: false, -}) -class TesthostComponent { - value: string; - label = 'Test label'; - maxlength = 42; - - @ViewChild(EditableToggleGroupComponent) - component: EditableToggleGroupComponent; -} - -@NgModule({ declarations: [TesthostComponent], schemas: [NO_ERRORS_SCHEMA] }) -class TestHostModule {} - -describe('EditableToggleGroupComponent', () => { - let testhost: TesthostComponent; - let fixture: ComponentFixture; - let overlayContainerElement: HTMLElement; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [OverlayModule, FormsModule, ReactiveFormsModule, MatProgressSpinnerModule, MatButtonToggleModule], - declarations: [TesthostComponent, EditableToggleGroupComponent, EditableButtonToggleComponent], - }).compileComponents(); - - inject([OverlayContainer], (oc: OverlayContainer) => { - overlayContainerElement = oc.getContainerElement(); - })(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TesthostComponent); - testhost = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(testhost).toBeTruthy(); - }); - - describe('DOM', () => { - it('should call enterEditMode() on click', () => { - vi.spyOn(testhost.component, 'enterEditMode'); - const element = fixture.nativeElement.querySelector('.editable-field'); - element.click(); - expect(testhost.component.enterEditMode).toHaveBeenCalled(); - }); - - it('should display the label', () => { - const elLabel = fixture.nativeElement.querySelector('label'); - expect(elLabel.textContent).toContain('Test label'); - }); - - it('should display the value', waitForAsync(() => { - testhost.value = 'value2'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - const elValue = fixture.nativeElement.querySelector('.editable-field .editable-field-content .editable-field-text-content'); - expect(elValue.textContent).toContain('Content 2'); - }); - })); - - it('should have a mat-button-toggle-group', () => { - const elToggleGroup = fixture.nativeElement.querySelector('.editable-field-control > mat-button-toggle-group'); - expect(elToggleGroup).toBeTruthy(); - }); - - it('should open then close the action buttons', () => { - testhost.component.enterEditMode(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeTruthy(); - testhost.component.cancel(); - fixture.detectChanges(false); - expect(overlayContainerElement.querySelector('.editable-field-actions')).toBeFalsy(); - }); - - it('should have a confirm button', () => { - vi.spyOn(testhost.component, 'confirm'); - testhost.component.enterEditMode(); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-confirm') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.confirm).toHaveBeenCalled(); - }); - - it('should have a cancel button', () => { - vi.spyOn(testhost.component, 'cancel'); - testhost.component.enterEditMode(); - fixture.detectChanges(); - const elButton = overlayContainerElement.querySelector('.editable-field-actions button.editable-field-cancel') as HTMLButtonElement; - expect(elButton).toBeTruthy(); - elButton.click(); - expect(testhost.component.cancel).toHaveBeenCalled(); - }); - - it('should have a spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(true); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeTruthy(); - }); - - it('should hide the spinner', () => { - vi.spyOn(testhost.component as any, 'showSpinner', 'get').mockReturnValue(false); - fixture.detectChanges(); - const elSpinner = fixture.nativeElement.querySelector('.editable-field mat-spinner'); - expect(elSpinner).toBeFalsy(); - }); - }); - - describe('Class', () => { - it('should set the control value', waitForAsync(() => { - testhost.value = 'value1'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toBe(testhost.value); - }); - })); - - describe('canConfirm', () => { - it('should return true when the edit mode is active, the value has changed and is valid', () => { - testhost.component.editMode = true; - testhost.component.control.setValue('value1'); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(true); - }); - - it('should return false if editMode is not active', () => { - testhost.component.editMode = false; - testhost.component.control.setValue('value1'); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pristine', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue('value1'); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is invalid', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValidators(Validators.required); - testhost.component.control.setValue(null); - testhost.component.control.markAsDirty(); - expect(testhost.component.canConfirm).toBe(false); - }); - - it('should return false if control is pending', () => { - testhost.component.enterEditMode(); - testhost.component.control.setValue('value1'); - testhost.component.control.markAsDirty(); - testhost.component.control.markAsPending(); - expect(testhost.component.canConfirm).toBe(false); - }); - }); - - it('should emit a new value', waitForAsync(() => { - testhost.value = 'value1'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue('value2'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual('value1'); - testhost.component.confirm(); - expect(testhost.value).toEqual('value2'); - }); - })); - - it('should reverse the changes', waitForAsync(() => { - testhost.value = 'value1'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(testhost.component.control.value).toEqual(testhost.value); - testhost.component.enterEditMode(); - testhost.component.control.setValue('value2'); - testhost.component.control.markAsDirty(); - fixture.detectChanges(); - expect(testhost.value).toEqual('value1'); - testhost.component.cancel(); - fixture.detectChanges(); - expect(testhost.value).toEqual('value1'); - expect(testhost.component.control.value).toEqual('value1'); - }); - })); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.ts index d4efa0687a6..1c57229b755 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/editable-toggle-group/editable-toggle-group.component.ts @@ -34,11 +34,14 @@ * 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, ContentChildren, ElementRef, forwardRef, QueryList, inject } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Component, ContentChildren, ElementRef, forwardRef, inject, QueryList } from '@angular/core'; +import { FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { EditableFieldComponent } from '../editable-field.component'; import { EditableButtonToggleComponent } from './editable-button-toggle.component'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; export const EDITABLE_TOGGLE_GROUP_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -51,7 +54,15 @@ export const EDITABLE_TOGGLE_GROUP_VALUE_ACCESSOR: any = { templateUrl: './editable-toggle-group.component.html', styleUrls: ['./editable-toggle-group.component.scss'], providers: [EDITABLE_TOGGLE_GROUP_VALUE_ACCESSOR], - standalone: false, + imports: [ + CdkOverlayOrigin, + MatButtonToggleGroup, + FormsModule, + ReactiveFormsModule, + MatButtonToggle, + MatProgressSpinner, + CdkConnectedOverlay, + ], }) export class EditableToggleGroupComponent extends EditableFieldComponent { @ContentChildren(EditableButtonToggleComponent) buttons: QueryList; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.spec.ts index 68a6bea5478..cf3b01491d8 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.spec.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.spec.ts @@ -34,12 +34,10 @@ * 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 { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { WINDOW_LOCATION } from '../../../injection-tokens'; import { LevelInputComponent } from './level-input.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; describe('LevelInputComponent', () => { let component: LevelInputComponent; @@ -47,15 +45,12 @@ describe('LevelInputComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [LevelInputComponent], - imports: [FormsModule], + imports: [FormsModule, LevelInputComponent], providers: [ { provide: WINDOW_LOCATION, useValue: {}, }, - provideHttpClient(withInterceptorsFromDi()), - provideHttpClientTesting(), ], }).compileComponents(); }); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.ts index e0111d834d0..ae2432b0d41 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.component.ts @@ -36,9 +36,11 @@ */ import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { Component, ElementRef, forwardRef, HostBinding, HostListener, Input, OnInit, ViewChild } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { extractSubLevel } from '../../../utils/level.util'; +import { TranslatePipe } from '@ngx-translate/core'; + export const LEVEL_INPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => LevelInputComponent), @@ -50,7 +52,7 @@ export const LEVEL_INPUT_VALUE_ACCESSOR: any = { templateUrl: './level-input.component.html', styleUrls: ['./level-input.component.scss'], providers: [LEVEL_INPUT_VALUE_ACCESSOR], - standalone: false, + imports: [FormsModule, forwardRef(() => LevelInputComponent), TranslatePipe], }) export class LevelInputComponent implements OnInit, ControlValueAccessor { @Input() prefix: string; diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.module.spec.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.module.spec.ts deleted file mode 100644 index 2a774521d2d..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.module.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { LevelInputModule } from './level-input.module'; - -describe('LevelInputComponent', () => { - let levelInputModule: LevelInputModule; - - beforeEach(() => { - levelInputModule = new LevelInputModule(); - }); - - it('should create', () => { - expect(levelInputModule).toBeTruthy(); - }); -}); diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.module.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.module.ts deleted file mode 100644 index aaa0c519422..00000000000 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/editable-field/level-input/level-input.module.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) - * and the signatories of the "VITAM - Accord du Contributeur" agreement. - * - * contact@programmevitam.fr - * - * This software is a computer program whose purpose is to implement - * implement a digital archiving front-office system for the secure and - * efficient high volumetry VITAM solution. - * - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * 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 { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { LevelInputComponent } from './level-input.component'; -import { TranslatePipe } from '@ngx-translate/core'; - -@NgModule({ - imports: [CommonModule, FormsModule, TranslatePipe], - declarations: [LevelInputComponent], - exports: [LevelInputComponent], -}) -export class LevelInputModule {} diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/elements/elements.component.ts b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/elements/elements.component.ts index 7849b01ac52..43e47d28ef1 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/elements/elements.component.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/elements/elements.component.ts @@ -36,15 +36,15 @@ */ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { MatMenuModule } from '@angular/material/menu'; -import { CommonTooltipModule } from '../common-tooltip/common-tooltip.module'; + import { PipesModule } from '../../pipes/pipes.module'; +import { TooltipDirective } from '../common-tooltip/tooltip.directive'; @Component({ selector: 'vitamui-elements', templateUrl: './elements.component.html', styleUrls: ['elements.component.scss'], - standalone: true, - imports: [CommonTooltipModule, MatMenuModule, PipesModule], + imports: [TooltipDirective, MatMenuModule, PipesModule], }) export class ElementsComponent { @Input() icon = ''; 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 120fccd6942..d86e79276bc 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 @@ -38,11 +38,12 @@ import { Component, input, output } from '@angular/core'; import type { DisplayFile } from './display-file.interface'; import { FormErrorComponent } from '../../../../../lib/components/form-errors/form-error/form-error.component'; import { PipesModule } from '../../../pipes/pipes.module'; -import { CommonTooltipModule } from '../../common-tooltip/common-tooltip.module'; + +import { TooltipDirective } from '../../common-tooltip/tooltip.directive'; @Component({ selector: 'vitamui-display-file', - imports: [FormErrorComponent, PipesModule, CommonTooltipModule], + imports: [FormErrorComponent, PipesModule, TooltipDirective], templateUrl: './display-file.component.html', styleUrl: './display-file.component.scss', }) diff --git a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/header/header.component.html b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/header/header.component.html index daafcdb5487..f542c33864e 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/header/header.component.html +++ b/ui/ui-frontend/projects/vitamui-library/src/app/modules/components/header/header.component.html @@ -1,7 +1,7 @@ @@ -20,9 +20,9 @@
} -
+
- @if (hasTenantSelection) { + @if (hasTenantSelection()) { - @if (hasCustomerSelection) { + @if (hasCustomerSelection()) {