diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts deleted file mode 100644 index 7e988659..00000000 --- a/src/app/app-routing.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -@NgModule({ - imports: [RouterModule.forRoot([], { useHash: true })], - exports: [RouterModule] -}) -export class AppRoutingModule {} diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 33cba79f..43e72b0f 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,13 +1,12 @@ +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { ModalModule } from 'ngx-bootstrap/modal'; -import { PopoverModule } from 'ngx-bootstrap/popover'; import { of } from 'rxjs'; -import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; -import { ConfigService, CoreModule } from './core/core.module'; -import { SiteModule } from './site/site.module'; +import { ConfigService } from './core/config.service'; describe('AppComponent', () => { let configServiceSpy: any; @@ -17,15 +16,12 @@ describe('AppComponent', () => { configServiceSpy.getConfig.and.returnValue(of({})); TestBed.configureTestingModule({ - declarations: [AppComponent], - imports: [ - AppRoutingModule, - CoreModule, - SiteModule, - PopoverModule, - ModalModule.forRoot() - ], - providers: [{ provide: ConfigService, useValue: configServiceSpy }] + imports: [ModalModule.forRoot(), AppComponent], + providers: [ + { provide: ConfigService, useValue: configServiceSpy }, + provideHttpClient(), + provideHttpClientTesting() + ] }).compileComponents(); })); it('should create the app', waitForAsync(() => { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 4d6ffd04..a3f94af3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,12 @@ import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +import { SiteContainerComponent } from './core/site-container/site-container.component'; @Component({ selector: 'app-root', - templateUrl: './app.component.html' + templateUrl: './app.component.html', + standalone: true, + imports: [SiteContainerComponent, RouterOutlet] }) export class AppComponent {} diff --git a/src/app/app.module.ts b/src/app/app.module.ts deleted file mode 100644 index aa5eb6d1..00000000 --- a/src/app/app.module.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -import { AlertModule } from 'ngx-bootstrap/alert'; -import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; -import { ModalModule } from 'ngx-bootstrap/modal'; -import { PopoverModule } from 'ngx-bootstrap/popover'; -import { TabsModule } from 'ngx-bootstrap/tabs'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; -import { TypeaheadModule } from 'ngx-bootstrap/typeahead'; - -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { CoreModule } from './core/core.module'; -import { SiteModule } from './site/site.module'; - -@NgModule({ - declarations: [AppComponent], - imports: [ - BrowserModule, - BrowserAnimationsModule, - HttpClientModule, - - AlertModule.forRoot(), - BsDatepickerModule.forRoot(), - BsDropdownModule.forRoot(), - ModalModule.forRoot(), - PopoverModule.forRoot(), - TabsModule.forRoot(), - TooltipModule.forRoot(), - TypeaheadModule.forRoot(), - - AppRoutingModule, - CoreModule, - SiteModule - ], - bootstrap: [AppComponent] -}) -export class AppModule {} diff --git a/src/app/common/admin.module.ts b/src/app/common/admin.module.ts deleted file mode 100644 index 24a65bf4..00000000 --- a/src/app/common/admin.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { AdminComponent } from './admin/admin.component'; - -@NgModule({ - imports: [CommonModule, RouterModule], - exports: [AdminComponent], - declarations: [AdminComponent] -}) -export class AdminModule {} diff --git a/src/app/common/admin/admin.component.ts b/src/app/common/admin/admin.component.ts index 8dfce572..e1508113 100644 --- a/src/app/common/admin/admin.component.ts +++ b/src/app/common/admin/admin.component.ts @@ -1,10 +1,14 @@ +import { NgFor } from '@angular/common'; import { Component } from '@angular/core'; +import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router'; import { AdminTopic, AdminTopics } from './admin-topic.model'; @Component({ templateUrl: 'admin.component.html', - styleUrls: ['admin.component.scss'] + styleUrls: ['admin.component.scss'], + standalone: true, + imports: [NgFor, RouterLinkActive, RouterLink, RouterOutlet] }) export class AdminComponent { helpTopics: AdminTopic[] = []; diff --git a/src/app/common/breadcrumb.module.ts b/src/app/common/breadcrumb.module.ts deleted file mode 100644 index 9e2af4b6..00000000 --- a/src/app/common/breadcrumb.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component'; - -@NgModule({ - imports: [CommonModule, RouterModule], - exports: [BreadcrumbComponent], - declarations: [BreadcrumbComponent] -}) -export class BreadcrumbModule {} diff --git a/src/app/common/breadcrumb/breadcrumb.component.ts b/src/app/common/breadcrumb/breadcrumb.component.ts index 19049c69..e53fcc0c 100644 --- a/src/app/common/breadcrumb/breadcrumb.component.ts +++ b/src/app/common/breadcrumb/breadcrumb.component.ts @@ -1,5 +1,6 @@ +import { NgFor, NgIf } from '@angular/common'; import { Component, Input } from '@angular/core'; -import { ActivatedRoute, Event, NavigationEnd, Router } from '@angular/router'; +import { ActivatedRoute, Event, NavigationEnd, Router, RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { BehaviorSubject, Observable, merge } from 'rxjs'; @@ -11,7 +12,9 @@ import { Breadcrumb, BreadcrumbService } from './breadcrumb.service'; @Component({ selector: 'breadcrumb', templateUrl: 'breadcrumb.component.html', - styleUrls: ['breadcrumb.component.scss'] + styleUrls: ['breadcrumb.component.scss'], + standalone: true, + imports: [NgFor, NgIf, RouterLink] }) export class BreadcrumbComponent { @Input() diff --git a/src/app/common/directives.module.ts b/src/app/common/directives.module.ts deleted file mode 100644 index e4e70cf4..00000000 --- a/src/app/common/directives.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { LinkAccessibilityDirective } from './directives/link-accessibility.directive'; -import { SkipToDirective } from './directives/skip-to.directive'; - -@NgModule({ - imports: [], - exports: [SkipToDirective, LinkAccessibilityDirective], - declarations: [SkipToDirective, LinkAccessibilityDirective] -}) -export class DirectivesModule {} diff --git a/src/app/common/directives/link-accessibility.directive.ts b/src/app/common/directives/link-accessibility.directive.ts index 643db982..7e5fe5a6 100644 --- a/src/app/common/directives/link-accessibility.directive.ts +++ b/src/app/common/directives/link-accessibility.directive.ts @@ -7,7 +7,8 @@ import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core'; * the tabbing structure. */ @Directive({ - selector: '[linkAccessibility]' + selector: '[linkAccessibility]', + standalone: true }) export class LinkAccessibilityDirective { constructor(private elRef: ElementRef, private renderer: Renderer2) { diff --git a/src/app/common/directives/skip-to.directive.ts b/src/app/common/directives/skip-to.directive.ts index 4fa54ba9..95c6074e 100644 --- a/src/app/common/directives/skip-to.directive.ts +++ b/src/app/common/directives/skip-to.directive.ts @@ -6,7 +6,8 @@ import { Directive, ElementRef, Renderer2 } from '@angular/core'; * the h1 element. This directive should only be used once per page */ @Directive({ - selector: '[skipTo]' + selector: '[skipTo]', + standalone: true }) export class SkipToDirective { constructor(private elRef: ElementRef, private renderer: Renderer2) { diff --git a/src/app/common/flyout.module.ts b/src/app/common/flyout.module.ts deleted file mode 100644 index 754f10f6..00000000 --- a/src/app/common/flyout.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { FlyoutComponent } from './flyout/flyout.component'; - -@NgModule({ - imports: [CommonModule], - exports: [FlyoutComponent], - declarations: [FlyoutComponent] -}) -export class FlyoutModule {} diff --git a/src/app/common/flyout/flyout.component.ts b/src/app/common/flyout/flyout.component.ts index f7a32eed..af43fe69 100644 --- a/src/app/common/flyout/flyout.component.ts +++ b/src/app/common/flyout/flyout.component.ts @@ -1,9 +1,12 @@ +import { NgClass } from '@angular/common'; import { Component, ContentChild, ElementRef, Input, Renderer2, ViewChild } from '@angular/core'; @Component({ selector: 'app-flyout', templateUrl: './flyout.component.html', - styleUrls: ['./flyout.component.scss'] + styleUrls: ['./flyout.component.scss'], + standalone: true, + imports: [NgClass] }) export class FlyoutComponent { @ViewChild('flyoutContentContainer') container?: ElementRef; diff --git a/src/app/common/loading-overlay.module.ts b/src/app/common/loading-overlay.module.ts deleted file mode 100644 index 604d762f..00000000 --- a/src/app/common/loading-overlay.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { LoadingOverlayComponent } from './loading-overlay/loading-overlay.component'; -import { LoadingSpinnerModule } from './loading-spinner.module'; -import { NotificationModule } from './notification.module'; - -@NgModule({ - imports: [NotificationModule, LoadingSpinnerModule, CommonModule], - exports: [LoadingOverlayComponent], - declarations: [LoadingOverlayComponent] -}) -export class LoadingOverlayModule {} diff --git a/src/app/common/loading-overlay/loading-overlay.component.spec.ts b/src/app/common/loading-overlay/loading-overlay.component.spec.ts index bb519efc..c63fc556 100644 --- a/src/app/common/loading-overlay/loading-overlay.component.spec.ts +++ b/src/app/common/loading-overlay/loading-overlay.component.spec.ts @@ -1,6 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { LoadingOverlayModule } from '../loading-overlay.module'; import { LoadingOverlayComponent } from './loading-overlay.component'; describe('LoadingOverlayComponent', () => { @@ -10,8 +9,7 @@ describe('LoadingOverlayComponent', () => { beforeEach(() => { const testbed = TestBed.configureTestingModule({ - imports: [LoadingOverlayModule], - declarations: [LoadingOverlayComponent] + imports: [LoadingOverlayComponent] }); fixture = testbed.createComponent(LoadingOverlayComponent); diff --git a/src/app/common/loading-overlay/loading-overlay.component.ts b/src/app/common/loading-overlay/loading-overlay.component.ts index 4a12b9a4..202cf865 100644 --- a/src/app/common/loading-overlay/loading-overlay.component.ts +++ b/src/app/common/loading-overlay/loading-overlay.component.ts @@ -1,9 +1,15 @@ +import { NgIf } from '@angular/common'; import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { LoadingSpinnerComponent } from '../loading-spinner/loading-spinner.component'; +import { NotificationComponent } from '../notification/notification.component'; + @Component({ selector: 'loading-overlay', templateUrl: 'loading-overlay.component.html', - styleUrls: ['loading-overlay.component.scss'] + styleUrls: ['loading-overlay.component.scss'], + standalone: true, + imports: [NgIf, NotificationComponent, LoadingSpinnerComponent] }) export class LoadingOverlayComponent { @Input() message = 'Loading...'; diff --git a/src/app/common/loading-spinner.module.ts b/src/app/common/loading-spinner.module.ts deleted file mode 100644 index a16de87c..00000000 --- a/src/app/common/loading-spinner.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { LoadingSpinnerComponent } from './loading-spinner/loading-spinner.component'; - -@NgModule({ - imports: [], - exports: [LoadingSpinnerComponent], - declarations: [LoadingSpinnerComponent] -}) -export class LoadingSpinnerModule {} diff --git a/src/app/common/loading-spinner/loading-spinner.component.spec.ts b/src/app/common/loading-spinner/loading-spinner.component.spec.ts index 14a59f96..a84258f8 100644 --- a/src/app/common/loading-spinner/loading-spinner.component.spec.ts +++ b/src/app/common/loading-spinner/loading-spinner.component.spec.ts @@ -4,12 +4,16 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { LoadingSpinnerComponent } from './loading-spinner.component'; @Component({ - template: '' + template: '', + standalone: true, + imports: [LoadingSpinnerComponent] }) export class LoadingSpinnerDefaultTestHostComponent {} @Component({ - template: '' + template: '', + standalone: true, + imports: [LoadingSpinnerComponent] }) export class LoadingSpinnerProvidedTestHostComponent { message = 'Bootstrapping...'; @@ -25,8 +29,7 @@ describe('LoadingSpinnerComponent', () => { beforeEach(() => { const testbed = TestBed.configureTestingModule({ - imports: [], - declarations: [ + imports: [ LoadingSpinnerDefaultTestHostComponent, LoadingSpinnerProvidedTestHostComponent, LoadingSpinnerComponent diff --git a/src/app/common/loading-spinner/loading-spinner.component.ts b/src/app/common/loading-spinner/loading-spinner.component.ts index 1c88a5ca..c9eca5b3 100644 --- a/src/app/common/loading-spinner/loading-spinner.component.ts +++ b/src/app/common/loading-spinner/loading-spinner.component.ts @@ -3,7 +3,8 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'loading-spinner', templateUrl: 'loading-spinner.component.html', - styleUrls: ['loading-spinner.component.scss'] + styleUrls: ['loading-spinner.component.scss'], + standalone: true }) export class LoadingSpinnerComponent { @Input() diff --git a/src/app/common/modal.module.ts b/src/app/common/modal.module.ts deleted file mode 100644 index 19ab008a..00000000 --- a/src/app/common/modal.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { A11yModule } from '@angular/cdk/a11y'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { ModalModule as BsModalModule } from 'ngx-bootstrap/modal'; - -import { ConfigurableModalComponent } from './modal/configurable-modal/configurable-modal.component'; -import { ContainerModalComponent } from './modal/container-modal/container-modal.component'; -import { ModalComponent } from './modal/modal/modal.component'; - -@NgModule({ - imports: [BsModalModule, CommonModule, FormsModule, A11yModule], - exports: [ConfigurableModalComponent, ModalComponent], - declarations: [ConfigurableModalComponent, ContainerModalComponent, ModalComponent] -}) -export class ModalModule {} diff --git a/src/app/common/modal/abstract-modal.directive.spec.ts b/src/app/common/modal/abstract-modal.directive.spec.ts index 56177069..9c3117d2 100644 --- a/src/app/common/modal/abstract-modal.directive.spec.ts +++ b/src/app/common/modal/abstract-modal.directive.spec.ts @@ -11,7 +11,9 @@ import { ModalAction } from './modal.model'; @UntilDestroy() @Component({ selector: 'test-modal-component', - template: `` + template: ``, + standalone: true, + imports: [A11yModule] }) class ConcreteModalComponent extends AbstractModalDirective {} @@ -21,8 +23,7 @@ describe('Abstract Modal Directive', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [A11yModule], - declarations: [ConcreteModalComponent], + imports: [A11yModule, ConcreteModalComponent], providers: [{ provide: BsModalRef, useValue: {} }] }); diff --git a/src/app/common/modal/abstract-modalizable.directive.spec.ts b/src/app/common/modal/abstract-modalizable.directive.spec.ts index 4b12a985..aabeaf4e 100644 --- a/src/app/common/modal/abstract-modalizable.directive.spec.ts +++ b/src/app/common/modal/abstract-modalizable.directive.spec.ts @@ -8,7 +8,8 @@ import { AbstractModalizableDirective } from './abstract-modalizable.directive'; @UntilDestroy() @Component({ selector: 'test-modalized-component', - template: `` + template: ``, + standalone: true }) class ConcreteModalizedComponent extends AbstractModalizableDirective { onCancel() {} @@ -21,8 +22,7 @@ describe('Abstract Modalized Directive', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [], - declarations: [ConcreteModalizedComponent] + imports: [ConcreteModalizedComponent] }); fixture = TestBed.createComponent(ConcreteModalizedComponent); diff --git a/src/app/common/modal/configurable-modal/configurable-modal.component.spec.ts b/src/app/common/modal/configurable-modal/configurable-modal.component.spec.ts index e8b6f8e5..d8c170d6 100644 --- a/src/app/common/modal/configurable-modal/configurable-modal.component.spec.ts +++ b/src/app/common/modal/configurable-modal/configurable-modal.component.spec.ts @@ -13,8 +13,7 @@ describe('Modal Component', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [FormsModule], - declarations: [ConfigurableModalComponent, ModalComponent], + imports: [FormsModule, ConfigurableModalComponent, ModalComponent], providers: [{ provide: BsModalRef, useValue: {} }] }); diff --git a/src/app/common/modal/configurable-modal/configurable-modal.component.ts b/src/app/common/modal/configurable-modal/configurable-modal.component.ts index 04e95250..0ebde99b 100644 --- a/src/app/common/modal/configurable-modal/configurable-modal.component.ts +++ b/src/app/common/modal/configurable-modal/configurable-modal.component.ts @@ -1,11 +1,16 @@ +import { LowerCasePipe, NgFor, NgIf } from '@angular/common'; import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { AbstractModalDirective } from '../abstract-modal.directive'; import { ModalAction, ModalCloseEvent, ModalInput } from '../modal.model'; +import { ModalComponent } from '../modal/modal.component'; @Component({ templateUrl: 'configurable-modal.component.html', - styleUrls: ['configurable-modal.component.scss'] + styleUrls: ['configurable-modal.component.scss'], + standalone: true, + imports: [ModalComponent, NgIf, FormsModule, NgFor, LowerCasePipe] }) export class ConfigurableModalComponent extends AbstractModalDirective { message = ''; diff --git a/src/app/common/modal/container-modal/container-modal.component.spec.ts b/src/app/common/modal/container-modal/container-modal.component.spec.ts index 10550d99..791a500a 100644 --- a/src/app/common/modal/container-modal/container-modal.component.spec.ts +++ b/src/app/common/modal/container-modal/container-modal.component.spec.ts @@ -25,8 +25,7 @@ describe('Container Modal Component', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [A11yModule], - declarations: [ContainerModalComponent, ModalComponent], + imports: [A11yModule, ContainerModalComponent, ModalComponent], providers: [{ provide: BsModalRef, useValue: {} }] }); diff --git a/src/app/common/modal/container-modal/container-modal.component.ts b/src/app/common/modal/container-modal/container-modal.component.ts index 2b69d584..32ce495d 100644 --- a/src/app/common/modal/container-modal/container-modal.component.ts +++ b/src/app/common/modal/container-modal/container-modal.component.ts @@ -12,11 +12,14 @@ import { Subject } from 'rxjs'; import { AbstractModalDirective } from '../abstract-modal.directive'; import { AbstractModalizableDirective } from '../abstract-modalizable.directive'; +import { ModalComponent } from '../modal/modal.component'; @UntilDestroy() @Component({ templateUrl: 'container-modal.component.html', - styleUrls: ['container-modal.component.scss'] + styleUrls: ['container-modal.component.scss'], + standalone: true, + imports: [ModalComponent] }) export class ContainerModalComponent extends AbstractModalDirective diff --git a/src/app/common/modal/modal/modal.component.spec.ts b/src/app/common/modal/modal/modal.component.spec.ts index db56af59..432d0751 100644 --- a/src/app/common/modal/modal/modal.component.spec.ts +++ b/src/app/common/modal/modal/modal.component.spec.ts @@ -9,8 +9,7 @@ describe('ModalComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [A11yModule], - declarations: [ModalComponent] + imports: [A11yModule, ModalComponent] }).compileComponents(); })); diff --git a/src/app/common/modal/modal/modal.component.ts b/src/app/common/modal/modal/modal.component.ts index 2da3ca32..ab7c0940 100644 --- a/src/app/common/modal/modal/modal.component.ts +++ b/src/app/common/modal/modal/modal.component.ts @@ -1,10 +1,14 @@ +import { A11yModule } from '@angular/cdk/a11y'; +import { NgIf } from '@angular/common'; import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'asy-modal', templateUrl: './modal.component.html', styleUrls: ['./modal.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [A11yModule, NgIf] }) export class ModalComponent { /** diff --git a/src/app/common/multi-select-input.module.ts b/src/app/common/multi-select-input.module.ts deleted file mode 100644 index 3cc2a0bd..00000000 --- a/src/app/common/multi-select-input.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; - -import { MultiSelectInputComponent } from './multi-select-input/multi-select-input.component'; - -@NgModule({ - imports: [CommonModule, FormsModule, NgSelectModule], - exports: [MultiSelectInputComponent], - declarations: [MultiSelectInputComponent] -}) -export class MultiSelectInputModule {} diff --git a/src/app/common/multi-select-input/multi-select-input.component.ts b/src/app/common/multi-select-input/multi-select-input.component.ts index 65868545..6fe241bf 100644 --- a/src/app/common/multi-select-input/multi-select-input.component.ts +++ b/src/app/common/multi-select-input/multi-select-input.component.ts @@ -1,5 +1,7 @@ import { Component, Input, ViewChild } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, NgModel } from '@angular/forms'; +import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, NgModel } from '@angular/forms'; + +import { NgSelectModule } from '@ng-select/ng-select'; @Component({ selector: 'asy-multi-select-input', @@ -10,7 +12,9 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR, NgModel } from '@angular/forms useExisting: MultiSelectInputComponent, multi: true } - ] + ], + standalone: true, + imports: [NgSelectModule, FormsModule] }) export class MultiSelectInputComponent implements ControlValueAccessor { @Input() placeholder = ''; diff --git a/src/app/common/notification.module.ts b/src/app/common/notification.module.ts deleted file mode 100644 index f857096c..00000000 --- a/src/app/common/notification.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { NotificationComponent } from './notification/notification.component'; - -@NgModule({ - imports: [CommonModule], - exports: [NotificationComponent], - declarations: [NotificationComponent] -}) -export class NotificationModule {} diff --git a/src/app/common/notification/notification.component.spec.ts b/src/app/common/notification/notification.component.spec.ts index a66b5337..3d7e1a4e 100644 --- a/src/app/common/notification/notification.component.spec.ts +++ b/src/app/common/notification/notification.component.spec.ts @@ -6,7 +6,9 @@ import { NotificationComponent } from './notification.component'; @Component({ template: '' + - '' + '', + standalone: true, + imports: [NotificationComponent] }) export class NotificationDefaultTestHostComponent { message = 'foo'; @@ -16,7 +18,9 @@ export class NotificationDefaultTestHostComponent { template: '' + '' + - '' + '', + standalone: true, + imports: [NotificationComponent] }) export class NotificationProvidedTestHostComponent { message = 'foo'; @@ -31,8 +35,7 @@ describe('NotificationComponent', () => { beforeEach(() => { const testbed = TestBed.configureTestingModule({ - imports: [], - declarations: [ + imports: [ NotificationDefaultTestHostComponent, NotificationProvidedTestHostComponent, NotificationComponent diff --git a/src/app/common/notification/notification.component.ts b/src/app/common/notification/notification.component.ts index 9af31300..91d82fbe 100644 --- a/src/app/common/notification/notification.component.ts +++ b/src/app/common/notification/notification.component.ts @@ -1,9 +1,12 @@ +import { NgIf, NgTemplateOutlet } from '@angular/common'; import { Component, ContentChild, Input, TemplateRef } from '@angular/core'; @Component({ selector: 'notification', templateUrl: 'notification.component.html', - styleUrls: ['notification.component.scss'] + styleUrls: ['notification.component.scss'], + standalone: true, + imports: [NgIf, NgTemplateOutlet] }) export class NotificationComponent { @Input() notificationType: 'info' | 'success' | 'warning' | 'danger' = 'info'; diff --git a/src/app/common/pipes.module.ts b/src/app/common/pipes.module.ts deleted file mode 100644 index f62551c6..00000000 --- a/src/app/common/pipes.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { AgoDatePipe } from './pipes/ago-date.pipe'; -import { JoinPipe } from './pipes/join.pipe'; -import { KeysPipe } from './pipes/keys.pipe'; -import { SortObjectKeysPipe } from './pipes/sort-object-keys.pipe'; -import { UtcDatePipe } from './pipes/utc-date-pipe/utc-date.pipe'; - -@NgModule({ - imports: [], - exports: [AgoDatePipe, JoinPipe, KeysPipe, SortObjectKeysPipe, UtcDatePipe], - declarations: [AgoDatePipe, JoinPipe, KeysPipe, SortObjectKeysPipe, UtcDatePipe] -}) -export class PipesModule {} diff --git a/src/app/common/pipes/ago-date.pipe.ts b/src/app/common/pipes/ago-date.pipe.ts index 5ca68d19..96738454 100644 --- a/src/app/common/pipes/ago-date.pipe.ts +++ b/src/app/common/pipes/ago-date.pipe.ts @@ -2,7 +2,10 @@ import { Pipe, PipeTransform } from '@angular/core'; import { DateTime } from 'luxon'; -@Pipe({ name: 'agoDate' }) +@Pipe({ + name: 'agoDate', + standalone: true +}) export class AgoDatePipe implements PipeTransform { transform(date: Date | string | number | null | undefined, hideAgo?: boolean): string { if (null != date) { diff --git a/src/app/common/pipes/join.pipe.ts b/src/app/common/pipes/join.pipe.ts index c5e2dea2..5752d1a4 100644 --- a/src/app/common/pipes/join.pipe.ts +++ b/src/app/common/pipes/join.pipe.ts @@ -1,7 +1,8 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ - name: 'join' + name: 'join', + standalone: true }) export class JoinPipe implements PipeTransform { transform(input: any, separator: string): any { diff --git a/src/app/common/pipes/keys.pipe.ts b/src/app/common/pipes/keys.pipe.ts index b6dbfc0c..a2a7dd02 100644 --- a/src/app/common/pipes/keys.pipe.ts +++ b/src/app/common/pipes/keys.pipe.ts @@ -2,7 +2,10 @@ import { Pipe, PipeTransform } from '@angular/core'; import forOwn from 'lodash/forOwn'; -@Pipe({ name: 'keys' }) +@Pipe({ + name: 'keys', + standalone: true +}) export class KeysPipe implements PipeTransform { transform(obj: any): any { const values: any[] = []; diff --git a/src/app/common/pipes/sort-object-keys.pipe.ts b/src/app/common/pipes/sort-object-keys.pipe.ts index 0da8f7f6..d7e1eac6 100644 --- a/src/app/common/pipes/sort-object-keys.pipe.ts +++ b/src/app/common/pipes/sort-object-keys.pipe.ts @@ -2,7 +2,10 @@ import { Pipe, PipeTransform } from '@angular/core'; import _isObject from 'lodash/isObject'; -@Pipe({ name: 'sortObjectKeys' }) +@Pipe({ + name: 'sortObjectKeys', + standalone: true +}) export class SortObjectKeysPipe implements PipeTransform { // Derived from http://stackoverflow.com/a/1359808 and http://stackoverflow.com/a/23124958 transform(obj: any): any { diff --git a/src/app/common/pipes/utc-date-pipe/utc-date.pipe.ts b/src/app/common/pipes/utc-date-pipe/utc-date.pipe.ts index 088e24b8..59dcd0d5 100644 --- a/src/app/common/pipes/utc-date-pipe/utc-date.pipe.ts +++ b/src/app/common/pipes/utc-date-pipe/utc-date.pipe.ts @@ -3,7 +3,8 @@ import { Pipe, PipeTransform } from '@angular/core'; import { UtcDateUtils } from './utc-date-utils.service'; @Pipe({ - name: 'utcDate' + name: 'utcDate', + standalone: true }) export class UtcDatePipe implements PipeTransform { transform(value: Date | string | number | null | undefined, format?: string): string { diff --git a/src/app/common/search-input.module.ts b/src/app/common/search-input.module.ts deleted file mode 100644 index b4b20110..00000000 --- a/src/app/common/search-input.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; - -import { SearchInputComponent } from './search-input/search-input.component'; - -@NgModule({ - imports: [CommonModule, FormsModule, NgSelectModule], - exports: [SearchInputComponent], - declarations: [SearchInputComponent] -}) -export class SearchInputModule {} diff --git a/src/app/common/search-input/search-input.component.spec.ts b/src/app/common/search-input/search-input.component.spec.ts index 24000fdd..64008e64 100644 --- a/src/app/common/search-input/search-input.component.spec.ts +++ b/src/app/common/search-input/search-input.component.spec.ts @@ -13,8 +13,7 @@ describe('SearchInputComponent', () => { beforeEach(() => { fixture = TestBed.configureTestingModule({ - declarations: [SearchInputComponent], - imports: [FormsModule, NoopAnimationsModule] + imports: [FormsModule, NoopAnimationsModule, SearchInputComponent] }).createComponent(SearchInputComponent); componentInstance = fixture.componentInstance; diff --git a/src/app/common/search-input/search-input.component.ts b/src/app/common/search-input/search-input.component.ts index 1970d125..cc06d601 100644 --- a/src/app/common/search-input/search-input.component.ts +++ b/src/app/common/search-input/search-input.component.ts @@ -1,5 +1,7 @@ import { animate, style, transition, trigger } from '@angular/animations'; +import { NgIf } from '@angular/common'; import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Subject } from 'rxjs'; @@ -21,7 +23,9 @@ import { debounceTime } from 'rxjs/operators'; animate('200ms ease', style({ opacity: 0, height: 0 })) ]) ]) - ] + ], + standalone: true, + imports: [FormsModule, NgIf] }) export class SearchInputComponent { @Input() placeholder = 'Search...'; diff --git a/src/app/common/system-alert.module.ts b/src/app/common/system-alert.module.ts deleted file mode 100644 index b3c84925..00000000 --- a/src/app/common/system-alert.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { AlertModule } from 'ngx-bootstrap/alert'; - -import { SystemAlertIconComponent } from './system-alert/system-alert-icon.component'; -import { SystemAlertComponent } from './system-alert/system-alert.component'; - -@NgModule({ - imports: [CommonModule, FormsModule, AlertModule], - exports: [SystemAlertComponent], - declarations: [SystemAlertComponent, SystemAlertIconComponent] -}) -export class SystemAlertModule {} diff --git a/src/app/common/system-alert/system-alert-icon.component.ts b/src/app/common/system-alert/system-alert-icon.component.ts index a1884f68..2002ed83 100644 --- a/src/app/common/system-alert/system-alert-icon.component.ts +++ b/src/app/common/system-alert/system-alert-icon.component.ts @@ -1,8 +1,11 @@ +import { NgSwitch, NgSwitchCase } from '@angular/common'; import { Component, Input } from '@angular/core'; @Component({ selector: 'system-alert-icon', - templateUrl: 'system-alert-icon.component.html' + templateUrl: 'system-alert-icon.component.html', + standalone: true, + imports: [NgSwitch, NgSwitchCase] }) export class SystemAlertIconComponent { @Input() icon = 'info'; diff --git a/src/app/common/system-alert/system-alert.component.ts b/src/app/common/system-alert/system-alert.component.ts index d5d56943..028dcce6 100644 --- a/src/app/common/system-alert/system-alert.component.ts +++ b/src/app/common/system-alert/system-alert.component.ts @@ -1,11 +1,17 @@ +import { AsyncPipe, NgFor, NgIf } from '@angular/common'; import { Component } from '@angular/core'; +import { AlertModule } from 'ngx-bootstrap/alert'; + +import { SystemAlertIconComponent } from './system-alert-icon.component'; import { SystemAlertService } from './system-alert.service'; @Component({ selector: 'system-alert', templateUrl: 'system-alert.component.html', - styleUrls: ['system-alert.component.scss'] + styleUrls: ['system-alert.component.scss'], + standalone: true, + imports: [NgFor, AlertModule, SystemAlertIconComponent, NgIf, AsyncPipe] }) export class SystemAlertComponent { constructor(public alertService: SystemAlertService) {} diff --git a/src/app/common/table.module.ts b/src/app/common/table.module.ts deleted file mode 100644 index 7bf5cbee..00000000 --- a/src/app/common/table.module.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { DragDropModule } from '@angular/cdk/drag-drop'; -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule, TitleCasePipe } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; -import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; - -import { SearchInputModule } from './search-input.module'; -import { ColumnChooserComponent } from './table/column-chooser/column-chooser.component'; -import { AsyExpanderColumnComponent } from './table/expander/asy-expander-column.component'; -import { AsyFilterDirective } from './table/filter/asy-filter.directive'; -import { AsyHeaderDateFilterComponent } from './table/filter/asy-header-date-filter/asy-header-date-filter.component'; -import { AsyHeaderListFilterComponent } from './table/filter/asy-header-list-filter/asy-header-list-filter.component'; -import { AsyHeaderTextFilterComponent } from './table/filter/asy-header-text-filter/asy-header-text-filter.component'; -import { AsyHeaderTypeaheadFilterComponent } from './table/filter/asy-header-typeahead-filter/asy-header-typeahead-filter.component'; -import { PaginatorComponent } from './table/paginator/paginator.component'; -import { AsySelectionColumnComponent } from './table/selection/asy-selection-column.component'; -import { SidebarComponent } from './table/sidebar/sidebar.component'; -import { AsySkeletonRowsComponent } from './table/skeleton-rows/asy-skeleton-rows.component'; -import { AsySortHeaderComponent } from './table/sort/asy-sort-header/asy-sort-header.component'; -import { AsySortDirective } from './table/sort/asy-sort.directive'; -import { AsyTableEmptyStateComponent } from './table/table-empty-state/asy-table-empty-state.component'; - -@NgModule({ - imports: [ - CdkTableModule, - CommonModule, - FormsModule, - SearchInputModule, - NgSelectModule, - BsDropdownModule, - BsDatepickerModule, - DragDropModule - ], - declarations: [ - AsyFilterDirective, - AsySortDirective, - AsySortHeaderComponent, - AsyHeaderDateFilterComponent, - AsyHeaderListFilterComponent, - AsyHeaderTextFilterComponent, - AsyHeaderTypeaheadFilterComponent, - AsySelectionColumnComponent, - AsyExpanderColumnComponent, - AsySkeletonRowsComponent, - AsyTableEmptyStateComponent, - ColumnChooserComponent, - SidebarComponent, - PaginatorComponent - ], - exports: [ - AsyFilterDirective, - AsySortDirective, - AsySortHeaderComponent, - AsyHeaderDateFilterComponent, - AsyHeaderListFilterComponent, - AsyHeaderTextFilterComponent, - AsyHeaderTypeaheadFilterComponent, - AsySelectionColumnComponent, - AsyExpanderColumnComponent, - AsySkeletonRowsComponent, - AsyTableEmptyStateComponent, - ColumnChooserComponent, - SidebarComponent, - PaginatorComponent - ], - providers: [TitleCasePipe] -}) -export class TableModule {} diff --git a/src/app/common/table/column-chooser/column-chooser.component.ts b/src/app/common/table/column-chooser/column-chooser.component.ts index 1f1620f5..6575f008 100644 --- a/src/app/common/table/column-chooser/column-chooser.component.ts +++ b/src/app/common/table/column-chooser/column-chooser.component.ts @@ -1,5 +1,13 @@ -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { + CdkDrag, + CdkDragDrop, + CdkDragHandle, + CdkDropList, + moveItemInArray +} from '@angular/cdk/drag-drop'; +import { NgFor, NgIf, TitleCasePipe } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { LocalStorageService } from '../../storage/local-storage.service'; @@ -12,7 +20,9 @@ export type ColumnDefinition = { @Component({ selector: 'asy-column-chooser', templateUrl: './column-chooser.component.html', - styleUrls: ['./column-chooser.component.scss'] + styleUrls: ['./column-chooser.component.scss'], + standalone: true, + imports: [CdkDropList, NgFor, CdkDrag, NgIf, CdkDragHandle, FormsModule, TitleCasePipe] }) export class ColumnChooserComponent implements OnInit { @Input() diff --git a/src/app/common/table/expander/asy-expander-column.component.ts b/src/app/common/table/expander/asy-expander-column.component.ts index bf8d97d7..0c7ac523 100644 --- a/src/app/common/table/expander/asy-expander-column.component.ts +++ b/src/app/common/table/expander/asy-expander-column.component.ts @@ -1,4 +1,6 @@ import { SelectionModel } from '@angular/cdk/collections'; +import { CdkTableModule } from '@angular/cdk/table'; +import { NgIf } from '@angular/common'; import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { AsyAbstractColumnComponent } from '../asy-abstract-column.component'; @@ -7,7 +9,9 @@ import { AsyAbstractColumnComponent } from '../asy-abstract-column.component'; selector: 'asy-expander-column', templateUrl: './asy-expander-column.component.html', styleUrls: ['./asy-expander-column.component.scss'], - changeDetection: ChangeDetectionStrategy.Default + changeDetection: ChangeDetectionStrategy.Default, + standalone: true, + imports: [CdkTableModule, NgIf] }) export class AsyExpanderColumnComponent extends AsyAbstractColumnComponent diff --git a/src/app/common/table/filter/asy-filter.directive.ts b/src/app/common/table/filter/asy-filter.directive.ts index f1321666..5550c98e 100644 --- a/src/app/common/table/filter/asy-filter.directive.ts +++ b/src/app/common/table/filter/asy-filter.directive.ts @@ -15,7 +15,8 @@ export interface AsyFilterable { selector: '[asyFilter]', exportAs: 'asyFilter', // eslint-disable-next-line @angular-eslint/no-host-metadata-property - host: { class: 'asy-filter' } + host: { class: 'asy-filter' }, + standalone: true }) export class AsyFilterDirective { /** Collection of all registered filterables that this directive manages. */ diff --git a/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.spec.ts b/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.spec.ts index 2f09606e..16c34044 100644 --- a/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.spec.ts +++ b/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.spec.ts @@ -36,8 +36,7 @@ describe('AsyHeaderDateFilter', () => { filterSpy.deregister.and.callFake(() => {}); await TestBed.configureTestingModule({ - declarations: [AsyHeaderDateFilterComponent], - imports: [BrowserAnimationsModule, BsDropdownModule], + imports: [BrowserAnimationsModule, BsDropdownModule, AsyHeaderDateFilterComponent], providers: [{ provide: AsyFilterDirective, useValue: filterSpy as AsyFilterDirective }] }).compileComponents(); diff --git a/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.ts b/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.ts index dcf4f851..e1e52f51 100644 --- a/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.ts +++ b/src/app/common/table/filter/asy-header-date-filter/asy-header-date-filter.component.ts @@ -1,6 +1,11 @@ +import { TitleCasePipe } from '@angular/common'; import { ChangeDetectionStrategy, Component, Inject, Optional } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { NgSelectModule } from '@ng-select/ng-select'; import { DateTime } from 'luxon'; +import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { AsyAbstractHeaderFilterComponent, @@ -11,7 +16,9 @@ import { selector: 'asy-header-filter[date-filter]', templateUrl: './asy-header-date-filter.component.html', styleUrls: ['./asy-header-date-filter.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [BsDropdownModule, FormsModule, NgSelectModule, BsDatepickerModule, TitleCasePipe] }) export class AsyHeaderDateFilterComponent extends AsyAbstractHeaderFilterComponent { enabled = false; diff --git a/src/app/common/table/filter/asy-header-list-filter/asy-header-list-filter.component.ts b/src/app/common/table/filter/asy-header-list-filter/asy-header-list-filter.component.ts index 862957d3..afa403db 100644 --- a/src/app/common/table/filter/asy-header-list-filter/asy-header-list-filter.component.ts +++ b/src/app/common/table/filter/asy-header-list-filter/asy-header-list-filter.component.ts @@ -1,6 +1,10 @@ -import { TitleCasePipe } from '@angular/common'; +import { NgClass, NgFor, NgIf, TitleCasePipe } from '@angular/common'; import { ChangeDetectionStrategy, Component, Inject, Input, Optional, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; + +import { SearchInputComponent } from '../../../search-input/search-input.component'; import { AsyAbstractHeaderFilterComponent, AsyFilterHeaderColumnDef @@ -19,7 +23,18 @@ export type ListFilterOption = { selector: 'asy-header-filter[list-filter]', templateUrl: './asy-header-list-filter.component.html', styleUrls: ['./asy-header-list-filter.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [ + BsDropdownModule, + NgClass, + NgIf, + SearchInputComponent, + NgFor, + FormsModule, + TitleCasePipe + ], + providers: [TitleCasePipe] }) export class AsyHeaderListFilterComponent extends AsyAbstractHeaderFilterComponent { _options: ListFilterOption[]; diff --git a/src/app/common/table/filter/asy-header-text-filter/asy-header-text-filter.component.ts b/src/app/common/table/filter/asy-header-text-filter/asy-header-text-filter.component.ts index 81dc9dcc..72040431 100644 --- a/src/app/common/table/filter/asy-header-text-filter/asy-header-text-filter.component.ts +++ b/src/app/common/table/filter/asy-header-text-filter/asy-header-text-filter.component.ts @@ -1,7 +1,12 @@ +import { NgClass } from '@angular/common'; import { ChangeDetectionStrategy, Component, Inject, Input, Optional } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { NgSelectModule } from '@ng-select/ng-select'; import escapeRegExp from 'lodash/escapeRegExp'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; +import { SearchInputComponent } from '../../../search-input/search-input.component'; import { AsyAbstractHeaderFilterComponent, AsyFilterHeaderColumnDef @@ -15,7 +20,9 @@ type BuildFilterFunction = (search: string, option: TextFilterOption) => any; selector: 'asy-header-filter[text-filter]', templateUrl: './asy-header-text-filter.component.html', styleUrls: ['./asy-header-text-filter.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [BsDropdownModule, NgClass, NgSelectModule, FormsModule, SearchInputComponent] }) export class AsyHeaderTextFilterComponent extends AsyAbstractHeaderFilterComponent { @Input() diff --git a/src/app/common/table/filter/asy-header-typeahead-filter/asy-header-typeahead-filter.component.ts b/src/app/common/table/filter/asy-header-typeahead-filter/asy-header-typeahead-filter.component.ts index de2bb2c5..9c182e50 100644 --- a/src/app/common/table/filter/asy-header-typeahead-filter/asy-header-typeahead-filter.component.ts +++ b/src/app/common/table/filter/asy-header-typeahead-filter/asy-header-typeahead-filter.component.ts @@ -1,6 +1,10 @@ +import { AsyncPipe, NgClass } from '@angular/common'; import { Component, Inject, Input, OnInit, Optional } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { Observable, Subject, concat, of } from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap, tap } from 'rxjs/operators'; @@ -16,7 +20,9 @@ type BuildFilterFunction = (selectedValue: any | null) => any; @Component({ selector: 'asy-header-filter[typeahead-filter]', templateUrl: './asy-header-typeahead-filter.component.html', - styleUrls: ['./asy-header-typeahead-filter.component.scss'] + styleUrls: ['./asy-header-typeahead-filter.component.scss'], + standalone: true, + imports: [BsDropdownModule, NgClass, NgSelectModule, FormsModule, AsyncPipe] }) export class AsyHeaderTypeaheadFilterComponent extends AsyAbstractHeaderFilterComponent diff --git a/src/app/common/table/paginator/paginator.component.ts b/src/app/common/table/paginator/paginator.component.ts index e3230f05..b766643f 100644 --- a/src/app/common/table/paginator/paginator.component.ts +++ b/src/app/common/table/paginator/paginator.component.ts @@ -1,4 +1,8 @@ +import { AsyncPipe, DecimalPipe, NgIf } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { NgSelectModule } from '@ng-select/ng-select'; import { PageChange } from '../../paging.model'; import { AsyTableDataSource } from '../asy-table-data-source'; @@ -6,7 +10,9 @@ import { AsyTableDataSource } from '../asy-table-data-source'; @Component({ selector: 'asy-paginator', templateUrl: './paginator.component.html', - styleUrls: ['./paginator.component.scss'] + styleUrls: ['./paginator.component.scss'], + standalone: true, + imports: [NgIf, NgSelectModule, FormsModule, AsyncPipe, DecimalPipe] }) export class PaginatorComponent implements OnInit { @Input() diff --git a/src/app/common/table/selection/asy-selection-column.component.ts b/src/app/common/table/selection/asy-selection-column.component.ts index 82ec8dca..118ee5ee 100644 --- a/src/app/common/table/selection/asy-selection-column.component.ts +++ b/src/app/common/table/selection/asy-selection-column.component.ts @@ -1,4 +1,6 @@ import { DataSource, SelectionModel } from '@angular/cdk/collections'; +import { CdkTableModule } from '@angular/cdk/table'; +import { AsyncPipe, NgIf } from '@angular/common'; import { AfterViewInit, ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; @@ -13,7 +15,9 @@ import { AsyTableDataSource } from '../asy-table-data-source'; selector: 'asy-selection-column', templateUrl: './asy-selection-column.component.html', styleUrls: ['./asy-selection-column.component.scss'], - changeDetection: ChangeDetectionStrategy.Default + changeDetection: ChangeDetectionStrategy.Default, + standalone: true, + imports: [CdkTableModule, NgIf, AsyncPipe] }) export class AsySelectionColumnComponent extends AsyAbstractColumnComponent diff --git a/src/app/common/table/sidebar/sidebar.component.spec.ts b/src/app/common/table/sidebar/sidebar.component.spec.ts index b2411478..d59191e2 100644 --- a/src/app/common/table/sidebar/sidebar.component.spec.ts +++ b/src/app/common/table/sidebar/sidebar.component.spec.ts @@ -8,7 +8,7 @@ describe('SidebarComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [SidebarComponent] + imports: [SidebarComponent] }).compileComponents(); }); diff --git a/src/app/common/table/sidebar/sidebar.component.ts b/src/app/common/table/sidebar/sidebar.component.ts index c3e24b6f..d1397475 100644 --- a/src/app/common/table/sidebar/sidebar.component.ts +++ b/src/app/common/table/sidebar/sidebar.component.ts @@ -8,7 +8,8 @@ import { Component, HostBinding, Input } from '@angular/core'; host: { class: 'sidebar', '[class.sidebar-left]': 'placement === "left"' - } + }, + standalone: true }) export class SidebarComponent { @Input() diff --git a/src/app/common/table/skeleton-rows/asy-skeleton-rows.component.ts b/src/app/common/table/skeleton-rows/asy-skeleton-rows.component.ts index bd387a64..c024c5e8 100644 --- a/src/app/common/table/skeleton-rows/asy-skeleton-rows.component.ts +++ b/src/app/common/table/skeleton-rows/asy-skeleton-rows.component.ts @@ -1,10 +1,13 @@ +import { NgFor } from '@angular/common'; import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; @Component({ selector: 'asy-skeleton-rows', templateUrl: './asy-skeleton-rows.component.html', styleUrls: ['./asy-skeleton-rows.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [NgFor] }) export class AsySkeletonRowsComponent { _rows: Array = []; diff --git a/src/app/common/table/sort/asy-sort-header/asy-sort-header.component.ts b/src/app/common/table/sort/asy-sort-header/asy-sort-header.component.ts index 8593d8e3..436947fa 100644 --- a/src/app/common/table/sort/asy-sort-header/asy-sort-header.component.ts +++ b/src/app/common/table/sort/asy-sort-header/asy-sort-header.component.ts @@ -1,3 +1,4 @@ +import { NgIf } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -31,7 +32,9 @@ interface AsySortHeaderColumnDef { '[class.asy-sort-header-sorted]': 'isSorted', '[attr.aria-sort]': '_getAriaSortAttribute()' }, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [NgIf] }) export class AsySortHeaderComponent implements AsySortable, OnDestroy, OnInit { /** The direction the arrow should be facing according to the current state. */ diff --git a/src/app/common/table/sort/asy-sort.directive.ts b/src/app/common/table/sort/asy-sort.directive.ts index d04fbc44..44681d21 100644 --- a/src/app/common/table/sort/asy-sort.directive.ts +++ b/src/app/common/table/sort/asy-sort.directive.ts @@ -13,7 +13,8 @@ export interface AsySortable { selector: '[asySort]', exportAs: 'asySort', // eslint-disable-next-line @angular-eslint/no-host-metadata-property - host: { class: 'asy-sort' } + host: { class: 'asy-sort' }, + standalone: true }) export class AsySortDirective { /** Collection of all registered sortables that this directive manages. */ diff --git a/src/app/common/table/table-empty-state/asy-table-empty-state.component.ts b/src/app/common/table/table-empty-state/asy-table-empty-state.component.ts index 3b425448..2c5a136c 100644 --- a/src/app/common/table/table-empty-state/asy-table-empty-state.component.ts +++ b/src/app/common/table/table-empty-state/asy-table-empty-state.component.ts @@ -1,11 +1,15 @@ +import { NgIf } from '@angular/common'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { AsyTableDataSource } from '../asy-table-data-source'; +import { AsySkeletonRowsComponent } from '../skeleton-rows/asy-skeleton-rows.component'; @Component({ selector: 'asy-table-empty-state', templateUrl: './asy-table-empty-state.component.html', - styleUrls: ['./asy-table-empty-state.component.scss'] + styleUrls: ['./asy-table-empty-state.component.scss'], + standalone: true, + imports: [NgIf, AsySkeletonRowsComponent] }) export class AsyTableEmptyStateComponent { @Input() diff --git a/src/app/core/about.component.ts b/src/app/core/about.component.ts index 27258c08..f412ee3d 100644 --- a/src/app/core/about.component.ts +++ b/src/app/core/about.component.ts @@ -16,7 +16,8 @@ import { ConfigService } from './config.service'; - ` + `, + standalone: true }) export class AboutComponent implements OnInit { appTitle?: string; diff --git a/src/app/core/access.component.spec.ts b/src/app/core/access.component.spec.ts index a832078d..fed20442 100644 --- a/src/app/core/access.component.spec.ts +++ b/src/app/core/access.component.spec.ts @@ -13,8 +13,7 @@ describe('AccessComponent', () => { } as Navigation; await TestBed.configureTestingModule({ - declarations: [AccessComponent], - imports: [BrowserModule], + imports: [BrowserModule, AccessComponent], providers: [ { provide: Router, diff --git a/src/app/core/access.component.ts b/src/app/core/access.component.ts index 95a7388d..1ec13800 100644 --- a/src/app/core/access.component.ts +++ b/src/app/core/access.component.ts @@ -12,7 +12,8 @@ import { Router } from '@angular/router'; - ` + `, + standalone: true }) export class AccessComponent { status = '403'; diff --git a/src/app/core/admin/admin-routes.ts b/src/app/core/admin/admin-routes.ts new file mode 100644 index 00000000..8f7cfdd2 --- /dev/null +++ b/src/app/core/admin/admin-routes.ts @@ -0,0 +1,37 @@ +import { Routes } from '@angular/router'; + +import { AdminComponent } from '../../common/admin/admin.component'; +import { authGuard } from '../auth/auth.guard'; +import { ADMIN_CACHE_ENTRIES_ROUTES } from './cache-entries/admin-cache-entries-routes'; +import { CacheEntriesService } from './cache-entries/cache-entries.service'; +import { ADMIN_EUA_ROUTES } from './end-user-agreement/admin-eua-routes'; +import { EuaService } from './end-user-agreement/eua.service'; +import { ADMIN_FEEDBACK_ROUTES } from './feedback/admin-feedback-routes'; +import { ADMIN_MESSAGES_ROUTES } from './messages/admin-messages-routes'; +import { ADMIN_USER_ROUTES } from './user-management/admin-user-routes'; +import { AdminUsersService } from './user-management/admin-users.service'; + +export const ADMIN_ROUTES: Routes = [ + { + path: '', + component: AdminComponent, + canActivate: [authGuard], + data: { roles: ['admin'] }, + providers: [AdminUsersService, CacheEntriesService, EuaService], + children: [ + /** + * Default Route + */ + { + path: '', + redirectTo: '/admin/users', + pathMatch: 'full' + }, + ...ADMIN_USER_ROUTES, + ...ADMIN_CACHE_ENTRIES_ROUTES, + ...ADMIN_EUA_ROUTES, + ...ADMIN_MESSAGES_ROUTES, + ...ADMIN_FEEDBACK_ROUTES + ] + } +]; diff --git a/src/app/core/admin/admin-routing.module.ts b/src/app/core/admin/admin-routing.module.ts deleted file mode 100644 index 9e802363..00000000 --- a/src/app/core/admin/admin-routing.module.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { AdminComponent } from '../../common/admin/admin.component'; -import { authGuard } from '../auth/auth.guard'; -import { CacheEntriesComponent } from './cache-entries/cache-entries.component'; -import { AdminCreateEuaComponent } from './end-user-agreement/admin-create-eua.component'; -import { AdminUpdateEuaComponent } from './end-user-agreement/admin-edit-eua.component'; -import { AdminListEuasComponent } from './end-user-agreement/list-euas/admin-list-euas.component'; -import { AdminListFeedbackComponent } from './feedback/list-feedback/admin-list-feedback.component'; -import { CreateMessageComponent } from './messages/create-message.component'; -import { UpdateMessageComponent } from './messages/edit-message.component'; -import { ListMessagesComponent } from './messages/list-messages/list-messages.component'; -import { AdminCreateUserComponent } from './user-management/admin-create-user.component'; -import { AdminEditUserComponent } from './user-management/admin-edit-user.component'; -import { AdminListUsersComponent } from './user-management/list-users/admin-list-users.component'; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: '', - component: AdminComponent, - canActivate: [authGuard], - data: { roles: ['admin'] }, - children: [ - /** - * Default Route - */ - { - path: '', - redirectTo: '/admin/users', - pathMatch: 'full' - }, - - /** - * Admin User Routes - */ - { - path: 'users', - component: AdminListUsersComponent - }, - { - path: 'user', - component: AdminCreateUserComponent - }, - { - path: 'user/:id', - component: AdminEditUserComponent - }, - - /** - * Admin Access Checker Cache Entries Route - */ - { - path: 'cacheEntries', - component: CacheEntriesComponent - }, - - /** - * Admin EUA Routes - */ - { - path: 'euas', - component: AdminListEuasComponent - }, - { - path: 'eua', - component: AdminCreateEuaComponent - }, - { - path: 'eua/:id', - component: AdminUpdateEuaComponent - }, - - /** - * Admin Access Checker Cache Entries Route - */ - { - path: 'messages', - component: ListMessagesComponent - }, - { - path: 'message', - component: CreateMessageComponent - }, - { - path: 'message/:id', - component: UpdateMessageComponent - }, - - /** - * Admin Feedback Routes - */ - { - path: 'feedback', - component: AdminListFeedbackComponent - } - ] - } - ]) - ], - exports: [RouterModule] -}) -export class AdminRoutingModule {} diff --git a/src/app/core/admin/admin.module.ts b/src/app/core/admin/admin.module.ts deleted file mode 100644 index 2f520dd7..00000000 --- a/src/app/core/admin/admin.module.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { AdminModule as CommonAdminModule } from '../../common/admin.module'; -import { AdminRoutingModule } from './admin-routing.module'; -import { CacheEntriesModule } from './cache-entries/cache-entries.module'; -import { AdminEuaModule } from './end-user-agreement/admin-eua.module'; -import { AdminFeedbackModule } from './feedback/admin-feedback.module'; -import { AdminMessagesModule } from './messages/admin-messages.module'; -import { AdminUserModule } from './user-management/admin-user.module'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - - CommonAdminModule, - - // App Admin Modules - AdminUserModule, - AdminEuaModule, - AdminFeedbackModule, - CacheEntriesModule, - AdminMessagesModule, - AdminRoutingModule - ], - exports: [] -}) -export class AdminModule {} diff --git a/src/app/core/admin/cache-entries/admin-cache-entries-routes.ts b/src/app/core/admin/cache-entries/admin-cache-entries-routes.ts new file mode 100644 index 00000000..c180e0ce --- /dev/null +++ b/src/app/core/admin/cache-entries/admin-cache-entries-routes.ts @@ -0,0 +1,10 @@ +import { Routes } from '@angular/router'; + +import { CacheEntriesComponent } from './cache-entries.component'; + +export const ADMIN_CACHE_ENTRIES_ROUTES: Routes = [ + { + path: 'cacheEntries', + component: CacheEntriesComponent + } +]; diff --git a/src/app/core/admin/cache-entries/cache-entries.component.ts b/src/app/core/admin/cache-entries/cache-entries.component.ts index 8bbc5415..20cadc2c 100644 --- a/src/app/core/admin/cache-entries/cache-entries.component.ts +++ b/src/app/core/admin/cache-entries/cache-entries.component.ts @@ -1,17 +1,31 @@ +import { CdkTableModule } from '@angular/cdk/table'; +import { JsonPipe } from '@angular/common'; import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable } from 'rxjs'; import { filter, first, switchMap } from 'rxjs/operators'; +import { SkipToDirective } from '../../../common/directives/skip-to.directive'; import { ModalAction } from '../../../common/modal/modal.model'; import { ModalService } from '../../../common/modal/modal.service'; import { PagingOptions, PagingResults } from '../../../common/paging.model'; +import { AgoDatePipe } from '../../../common/pipes/ago-date.pipe'; +import { UtcDatePipe } from '../../../common/pipes/utc-date-pipe/utc-date.pipe'; +import { SearchInputComponent } from '../../../common/search-input/search-input.component'; import { SortDirection } from '../../../common/sorting.model'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../../common/system-alert/system-alert.service'; import { AsyTableDataSource } from '../../../common/table/asy-table-data-source'; +import { AsyFilterDirective } from '../../../common/table/filter/asy-filter.directive'; +import { PaginatorComponent } from '../../../common/table/paginator/paginator.component'; +import { AsySortHeaderComponent } from '../../../common/table/sort/asy-sort-header/asy-sort-header.component'; +import { AsySortDirective } from '../../../common/table/sort/asy-sort.directive'; +import { AsyTableEmptyStateComponent } from '../../../common/table/table-empty-state/asy-table-empty-state.component'; import { CacheEntriesService } from './cache-entries.service'; import { CacheEntryModalComponent } from './cache-entry-modal.component'; import { CacheEntry } from './cache-entry.model'; @@ -19,7 +33,24 @@ import { CacheEntry } from './cache-entry.model'; @UntilDestroy() @Component({ selector: 'cache-entries', - templateUrl: './cache-entries.component.html' + templateUrl: './cache-entries.component.html', + standalone: true, + imports: [ + SkipToDirective, + SystemAlertComponent, + SearchInputComponent, + CdkTableModule, + AsySortDirective, + AsyFilterDirective, + AsySortHeaderComponent, + TooltipModule, + BsDropdownModule, + AsyTableEmptyStateComponent, + PaginatorComponent, + JsonPipe, + AgoDatePipe, + UtcDatePipe + ] }) export class CacheEntriesComponent implements OnDestroy, OnInit { displayedColumns = ['key', 'value', 'ts', 'actionsMenu']; diff --git a/src/app/core/admin/cache-entries/cache-entries.module.ts b/src/app/core/admin/cache-entries/cache-entries.module.ts deleted file mode 100644 index a633a778..00000000 --- a/src/app/core/admin/cache-entries/cache-entries.module.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; -import { ModalModule as BsModalModule } from 'ngx-bootstrap/modal'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; - -import { DirectivesModule } from '../../../common/directives.module'; -import { ModalModule } from '../../../common/modal.module'; -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; -import { TableModule } from '../../../common/table.module'; -import { CacheEntriesComponent } from './cache-entries.component'; -import { CacheEntriesService } from './cache-entries.service'; -import { CacheEntryModalComponent } from './cache-entry-modal.component'; - -@NgModule({ - imports: [ - BsDropdownModule, - BsModalModule, - CommonModule, - DirectivesModule, - FormsModule, - PipesModule, - SystemAlertModule, - SearchInputModule, - TooltipModule, - ModalModule, - CdkTableModule, - TableModule - ], - declarations: [CacheEntriesComponent, CacheEntryModalComponent], - exports: [CacheEntriesComponent], - providers: [CacheEntriesService] -}) -export class CacheEntriesModule {} diff --git a/src/app/core/admin/cache-entries/cache-entry-modal.component.ts b/src/app/core/admin/cache-entries/cache-entry-modal.component.ts index 40c3d333..fd7072b7 100644 --- a/src/app/core/admin/cache-entries/cache-entry-modal.component.ts +++ b/src/app/core/admin/cache-entries/cache-entry-modal.component.ts @@ -1,7 +1,11 @@ +import { JsonPipe } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { BsModalRef } from 'ngx-bootstrap/modal'; +import { ModalComponent } from '../../../common/modal/modal/modal.component'; +import { AgoDatePipe } from '../../../common/pipes/ago-date.pipe'; +import { UtcDatePipe } from '../../../common/pipes/utc-date-pipe/utc-date.pipe'; import { CacheEntry } from './cache-entry.model'; @Component({ @@ -12,7 +16,9 @@ import { CacheEntry } from './cache-entry.model'; display: contents; } ` - ] + ], + standalone: true, + imports: [ModalComponent, JsonPipe, AgoDatePipe, UtcDatePipe] }) export class CacheEntryModalComponent implements OnInit { @Input() diff --git a/src/app/core/admin/end-user-agreement/admin-create-eua.component.ts b/src/app/core/admin/end-user-agreement/admin-create-eua.component.ts index b47e4f08..9806a926 100644 --- a/src/app/core/admin/end-user-agreement/admin-create-eua.component.ts +++ b/src/app/core/admin/end-user-agreement/admin-create-eua.component.ts @@ -1,14 +1,20 @@ +import { NgIf } from '@angular/common'; import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { EuaService } from './eua.service'; import { ManageEuaComponent } from './manage-eua.component'; @UntilDestroy() @Component({ selector: 'admin-create-eua', - templateUrl: './manage-eua.component.html' + templateUrl: './manage-eua.component.html', + standalone: true, + imports: [RouterLink, SystemAlertComponent, FormsModule, NgIf] }) export class AdminCreateEuaComponent extends ManageEuaComponent { constructor(protected euaService: EuaService) { diff --git a/src/app/core/admin/end-user-agreement/admin-edit-eua.component.ts b/src/app/core/admin/end-user-agreement/admin-edit-eua.component.ts index f485fb19..8170b5b8 100644 --- a/src/app/core/admin/end-user-agreement/admin-edit-eua.component.ts +++ b/src/app/core/admin/end-user-agreement/admin-edit-eua.component.ts @@ -1,10 +1,13 @@ +import { NgIf } from '@angular/common'; import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Params, RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { switchMap } from 'rxjs'; import { isNotNullOrUndefined } from '../../../common/rxjs-utils'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { EndUserAgreement } from './eua.model'; import { EuaService } from './eua.service'; import { ManageEuaComponent } from './manage-eua.component'; @@ -12,7 +15,9 @@ import { ManageEuaComponent } from './manage-eua.component'; @UntilDestroy() @Component({ selector: 'admin-update-eua', - templateUrl: './manage-eua.component.html' + templateUrl: './manage-eua.component.html', + standalone: true, + imports: [RouterLink, SystemAlertComponent, FormsModule, NgIf] }) export class AdminUpdateEuaComponent extends ManageEuaComponent implements OnInit { constructor(protected euaService: EuaService, protected route: ActivatedRoute) { diff --git a/src/app/core/admin/end-user-agreement/admin-eua-routes.ts b/src/app/core/admin/end-user-agreement/admin-eua-routes.ts new file mode 100644 index 00000000..6b792f96 --- /dev/null +++ b/src/app/core/admin/end-user-agreement/admin-eua-routes.ts @@ -0,0 +1,20 @@ +import { Routes } from '@angular/router'; + +import { AdminCreateEuaComponent } from './admin-create-eua.component'; +import { AdminUpdateEuaComponent } from './admin-edit-eua.component'; +import { AdminListEuasComponent } from './list-euas/admin-list-euas.component'; + +export const ADMIN_EUA_ROUTES: Routes = [ + { + path: 'euas', + component: AdminListEuasComponent + }, + { + path: 'eua', + component: AdminCreateEuaComponent + }, + { + path: 'eua/:id', + component: AdminUpdateEuaComponent + } +]; diff --git a/src/app/core/admin/end-user-agreement/admin-eua.module.ts b/src/app/core/admin/end-user-agreement/admin-eua.module.ts deleted file mode 100644 index cd81faf1..00000000 --- a/src/app/core/admin/end-user-agreement/admin-eua.module.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; - -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; - -import { DirectivesModule } from '../../../common/directives.module'; -import { ModalModule } from '../../../common/modal.module'; -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; -import { TableModule } from '../../../common/table.module'; -import { AdminUsersService } from '../user-management/admin-users.service'; -import { AdminCreateEuaComponent } from './admin-create-eua.component'; -import { AdminUpdateEuaComponent } from './admin-edit-eua.component'; -import { EuaService } from './eua.service'; -import { AdminListEuasComponent } from './list-euas/admin-list-euas.component'; - -@NgModule({ - imports: [ - BsDropdownModule, - CommonModule, - DirectivesModule, - FormsModule, - ModalModule, - PipesModule, - RouterModule, - SystemAlertModule, - SearchInputModule, - CdkTableModule, - TableModule - ], - exports: [], - declarations: [AdminListEuasComponent, AdminCreateEuaComponent, AdminUpdateEuaComponent], - providers: [AdminUsersService, EuaService] -}) -export class AdminEuaModule {} diff --git a/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.spec.ts b/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.spec.ts index 5be9dc02..5564bdc4 100644 --- a/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.spec.ts +++ b/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.spec.ts @@ -1,16 +1,10 @@ -import { CdkTableModule } from '@angular/cdk/table'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { of } from 'rxjs'; import { ModalService } from '../../../../common/modal/modal.service'; -import { SearchInputModule } from '../../../../common/search-input.module'; -import { SystemAlertModule } from '../../../../common/system-alert.module'; import { SystemAlertService } from '../../../../common/system-alert/system-alert.service'; -import { TableModule } from '../../../../common/table.module'; import { EuaService } from '../eua.service'; import { AdminListEuasComponent } from './admin-list-euas.component'; @@ -37,15 +31,7 @@ describe('Admin List End User Agreements Component', () => { return of(void 0); }); const testBed = TestBed.configureTestingModule({ - declarations: [AdminListEuasComponent], - imports: [ - ModalModule.forRoot(), - RouterTestingModule, - SystemAlertModule, - SearchInputModule, - CdkTableModule, - TableModule - ], + imports: [AdminListEuasComponent], providers: [ { provide: ActivatedRoute, useValue: activatedRoute }, { provide: EuaService, useValue: endUserAgreementServiceSpy }, diff --git a/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.ts b/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.ts index bdd96752..dbe098b1 100644 --- a/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.ts +++ b/src/app/core/admin/end-user-agreement/list-euas/admin-list-euas.component.ts @@ -1,23 +1,53 @@ +import { CdkTableModule } from '@angular/cdk/table'; import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { Observable } from 'rxjs'; import { filter, first, switchMap } from 'rxjs/operators'; +import { SkipToDirective } from '../../../../common/directives/skip-to.directive'; import { ModalAction } from '../../../../common/modal/modal.model'; import { ModalService } from '../../../../common/modal/modal.service'; import { PagingOptions, PagingResults } from '../../../../common/paging.model'; +import { UtcDatePipe } from '../../../../common/pipes/utc-date-pipe/utc-date.pipe'; +import { SearchInputComponent } from '../../../../common/search-input/search-input.component'; import { SortDirection } from '../../../../common/sorting.model'; +import { SystemAlertComponent } from '../../../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../../../common/system-alert/system-alert.service'; import { AsyTableDataSource } from '../../../../common/table/asy-table-data-source'; +import { ColumnChooserComponent } from '../../../../common/table/column-chooser/column-chooser.component'; +import { AsyFilterDirective } from '../../../../common/table/filter/asy-filter.directive'; +import { PaginatorComponent } from '../../../../common/table/paginator/paginator.component'; +import { SidebarComponent } from '../../../../common/table/sidebar/sidebar.component'; +import { AsySortHeaderComponent } from '../../../../common/table/sort/asy-sort-header/asy-sort-header.component'; +import { AsySortDirective } from '../../../../common/table/sort/asy-sort.directive'; +import { AsyTableEmptyStateComponent } from '../../../../common/table/table-empty-state/asy-table-empty-state.component'; import { EndUserAgreement } from '../eua.model'; import { EuaService } from '../eua.service'; @UntilDestroy() @Component({ templateUrl: './admin-list-euas.component.html', - styleUrls: ['./admin-list-euas.component.scss'] + styleUrls: ['./admin-list-euas.component.scss'], + standalone: true, + imports: [ + SkipToDirective, + SystemAlertComponent, + SearchInputComponent, + RouterLink, + CdkTableModule, + AsySortDirective, + AsyFilterDirective, + AsySortHeaderComponent, + BsDropdownModule, + AsyTableEmptyStateComponent, + SidebarComponent, + ColumnChooserComponent, + PaginatorComponent, + UtcDatePipe + ] }) export class AdminListEuasComponent implements OnDestroy, OnInit { columns = [ diff --git a/src/app/core/admin/feedback/admin-feedback-routes.ts b/src/app/core/admin/feedback/admin-feedback-routes.ts new file mode 100644 index 00000000..2aacd0e7 --- /dev/null +++ b/src/app/core/admin/feedback/admin-feedback-routes.ts @@ -0,0 +1,10 @@ +import { Routes } from '@angular/router'; + +import { AdminListFeedbackComponent } from './list-feedback/admin-list-feedback.component'; + +export const ADMIN_FEEDBACK_ROUTES: Routes = [ + { + path: 'feedback', + component: AdminListFeedbackComponent + } +]; diff --git a/src/app/core/admin/feedback/admin-feedback.module.ts b/src/app/core/admin/feedback/admin-feedback.module.ts deleted file mode 100644 index f0cb06f1..00000000 --- a/src/app/core/admin/feedback/admin-feedback.module.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; - -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; -import { TableModule } from '../../../common/table.module'; -import { AdminListFeedbackComponent } from './list-feedback/admin-list-feedback.component'; - -@NgModule({ - imports: [ - CommonModule, - - TooltipModule, - - PipesModule, - SearchInputModule, - SystemAlertModule, - BsDropdownModule, - CdkTableModule, - TableModule - ], - exports: [AdminListFeedbackComponent], - declarations: [AdminListFeedbackComponent] -}) -export class AdminFeedbackModule {} diff --git a/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.spec.ts b/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.spec.ts index 6beeec2a..b026d4b6 100644 --- a/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.spec.ts +++ b/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.spec.ts @@ -1,18 +1,9 @@ -import { CdkTableModule } from '@angular/cdk/table'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { of } from 'rxjs'; import { PagingResults } from '../../../../common/paging.model'; -import { PipesModule } from '../../../../common/pipes.module'; -import { SearchInputModule } from '../../../../common/search-input.module'; -import { SystemAlertModule } from '../../../../common/system-alert.module'; -import { TableModule } from '../../../../common/table.module'; import { User } from '../../../auth/user.model'; import { ConfigService } from '../../../config.service'; import { ExportConfigService } from '../../../export-config.service'; @@ -69,19 +60,7 @@ describe('Admin List Feedback Component Spec', () => { adminUsersServiceSpy.getAll.and.returnValue(of(['mockUser'])); TestBed.configureTestingModule({ - declarations: [AdminListFeedbackComponent], - imports: [ - FormsModule, - RouterTestingModule, - PipesModule, - SearchInputModule, - SystemAlertModule, - NgSelectModule, - TooltipModule, - CdkTableModule, - TableModule, - BrowserAnimationsModule - ], + imports: [BrowserAnimationsModule, AdminListFeedbackComponent], providers: [ { provide: FeedbackService, useValue: feedbackServiceSpy }, { provide: ConfigService, useValue: configServiceSpy }, diff --git a/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.ts b/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.ts index 6bab0d41..015fd6cd 100644 --- a/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.ts +++ b/src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.ts @@ -1,13 +1,30 @@ +import { CdkTableModule } from '@angular/cdk/table'; +import { NgFor, NgIf, TitleCasePipe } from '@angular/common'; import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable } from 'rxjs'; +import { SkipToDirective } from '../../../../common/directives/skip-to.directive'; import { PagingOptions, PagingResults } from '../../../../common/paging.model'; +import { AgoDatePipe } from '../../../../common/pipes/ago-date.pipe'; +import { UtcDatePipe } from '../../../../common/pipes/utc-date-pipe/utc-date.pipe'; +import { SearchInputComponent } from '../../../../common/search-input/search-input.component'; import { SortDirection } from '../../../../common/sorting.model'; +import { SystemAlertComponent } from '../../../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../../../common/system-alert/system-alert.service'; import { AsyTableDataSource } from '../../../../common/table/asy-table-data-source'; +import { ColumnChooserComponent } from '../../../../common/table/column-chooser/column-chooser.component'; +import { AsyFilterDirective } from '../../../../common/table/filter/asy-filter.directive'; +import { AsyHeaderListFilterComponent } from '../../../../common/table/filter/asy-header-list-filter/asy-header-list-filter.component'; +import { PaginatorComponent } from '../../../../common/table/paginator/paginator.component'; +import { SidebarComponent } from '../../../../common/table/sidebar/sidebar.component'; +import { AsySortHeaderComponent } from '../../../../common/table/sort/asy-sort-header/asy-sort-header.component'; +import { AsySortDirective } from '../../../../common/table/sort/asy-sort.directive'; +import { AsyTableEmptyStateComponent } from '../../../../common/table/table-empty-state/asy-table-empty-state.component'; import { ExportConfigService } from '../../../export-config.service'; import { Feedback, FeedbackStatusOption } from '../../../feedback/feedback.model'; import { FeedbackService } from '../../../feedback/feedback.service'; @@ -16,7 +33,29 @@ import { AdminUsersService } from '../../user-management/admin-users.service'; @UntilDestroy() @Component({ templateUrl: 'admin-list-feedback.component.html', - styleUrls: ['admin-list-feedback.component.scss'] + styleUrls: ['admin-list-feedback.component.scss'], + standalone: true, + imports: [ + SystemAlertComponent, + SearchInputComponent, + TooltipModule, + CdkTableModule, + AsySortDirective, + AsyFilterDirective, + AsySortHeaderComponent, + AsyHeaderListFilterComponent, + BsDropdownModule, + NgIf, + NgFor, + AsyTableEmptyStateComponent, + SidebarComponent, + ColumnChooserComponent, + PaginatorComponent, + TitleCasePipe, + AgoDatePipe, + UtcDatePipe, + SkipToDirective + ] }) export class AdminListFeedbackComponent implements OnDestroy, OnInit { feedbackStatusOptions = FeedbackStatusOption; diff --git a/src/app/core/admin/messages/admin-messages-routes.ts b/src/app/core/admin/messages/admin-messages-routes.ts new file mode 100644 index 00000000..ae2392d6 --- /dev/null +++ b/src/app/core/admin/messages/admin-messages-routes.ts @@ -0,0 +1,20 @@ +import { Routes } from '@angular/router'; + +import { CreateMessageComponent } from './create-message.component'; +import { UpdateMessageComponent } from './edit-message.component'; +import { ListMessagesComponent } from './list-messages/list-messages.component'; + +export const ADMIN_MESSAGES_ROUTES: Routes = [ + { + path: 'messages', + component: ListMessagesComponent + }, + { + path: 'message', + component: CreateMessageComponent + }, + { + path: 'message/:id', + component: UpdateMessageComponent + } +]; diff --git a/src/app/core/admin/messages/admin-messages.module.ts b/src/app/core/admin/messages/admin-messages.module.ts deleted file mode 100644 index aa5bbcbb..00000000 --- a/src/app/core/admin/messages/admin-messages.module.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; - -import { NgSelectModule } from '@ng-select/ng-select'; -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; - -import { DirectivesModule } from '../../../common/directives.module'; -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; -import { TableModule } from '../../../common/table.module'; -import { CreateMessageComponent } from './create-message.component'; -import { UpdateMessageComponent } from './edit-message.component'; -import { ListMessagesComponent } from './list-messages/list-messages.component'; - -@NgModule({ - imports: [ - BsDropdownModule, - CommonModule, - FormsModule, - RouterModule, - PipesModule, - DirectivesModule, - SystemAlertModule, - SearchInputModule, - NgSelectModule, - CdkTableModule, - TableModule - ], - exports: [], - declarations: [UpdateMessageComponent, CreateMessageComponent, ListMessagesComponent] -}) -export class AdminMessagesModule {} diff --git a/src/app/core/admin/messages/create-message.component.spec.ts b/src/app/core/admin/messages/create-message.component.spec.ts index e95d2158..67a3c2d7 100644 --- a/src/app/core/admin/messages/create-message.component.spec.ts +++ b/src/app/core/admin/messages/create-message.component.spec.ts @@ -1,13 +1,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { of } from 'rxjs'; import { ModalService } from '../../../common/modal/modal.service'; -import { SystemAlertModule } from '../../../common/system-alert.module'; import { SystemAlertService } from '../../../common/system-alert/system-alert.service'; import { ConfigService } from '../../config.service'; import { Message, MessageType } from '../../messages/message.model'; @@ -48,14 +44,7 @@ describe('Create Message Component', () => { return of(); }); const testBed = TestBed.configureTestingModule({ - declarations: [CreateMessageComponent], - imports: [ - ModalModule.forRoot(), - NgSelectModule, - FormsModule, - RouterTestingModule, - SystemAlertModule - ], + imports: [RouterTestingModule, CreateMessageComponent], providers: [ { provide: ConfigService, useValue: configServiceSpy }, { provide: MessageService, useValue: messageServiceSpy }, diff --git a/src/app/core/admin/messages/create-message.component.ts b/src/app/core/admin/messages/create-message.component.ts index 8f815c9f..bf4dfe15 100644 --- a/src/app/core/admin/messages/create-message.component.ts +++ b/src/app/core/admin/messages/create-message.component.ts @@ -1,14 +1,21 @@ +import { NgIf } from '@angular/common'; import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { RouterLink } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy } from '@ngneat/until-destroy'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { Message, MessageType } from '../../messages/message.model'; import { MessageService } from '../../messages/message.service'; import { ManageMessageComponent } from './manage-message.component'; @UntilDestroy() @Component({ - templateUrl: './manage-message.component.html' + templateUrl: './manage-message.component.html', + standalone: true, + imports: [NgIf, RouterLink, SystemAlertComponent, FormsModule, NgSelectModule] }) export class CreateMessageComponent extends ManageMessageComponent { mode = 'admin-create'; diff --git a/src/app/core/admin/messages/edit-message.component.spec.ts b/src/app/core/admin/messages/edit-message.component.spec.ts index 35f5b2e6..7d48ca6d 100644 --- a/src/app/core/admin/messages/edit-message.component.spec.ts +++ b/src/app/core/admin/messages/edit-message.component.spec.ts @@ -1,13 +1,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { of } from 'rxjs'; import { ModalService } from '../../../common/modal/modal.service'; -import { SystemAlertModule } from '../../../common/system-alert.module'; import { SystemAlertService } from '../../../common/system-alert/system-alert.service'; import { ConfigService } from '../../config.service'; import { Message, MessageType } from '../../messages/message.model'; @@ -51,14 +47,7 @@ describe('Update Message Component', () => { return of(); }); const testBed = TestBed.configureTestingModule({ - declarations: [UpdateMessageComponent], - imports: [ - ModalModule.forRoot(), - NgSelectModule, - FormsModule, - RouterTestingModule, - SystemAlertModule - ], + imports: [RouterTestingModule, UpdateMessageComponent], providers: [ { provide: ConfigService, useValue: configServiceSpy }, { provide: MessageService, useValue: messageServiceSpy }, diff --git a/src/app/core/admin/messages/edit-message.component.ts b/src/app/core/admin/messages/edit-message.component.ts index 2432d5b3..9ceaa7c9 100644 --- a/src/app/core/admin/messages/edit-message.component.ts +++ b/src/app/core/admin/messages/edit-message.component.ts @@ -1,17 +1,23 @@ +import { NgIf } from '@angular/common'; import { Component } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Params, RouterLink } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { switchMap } from 'rxjs'; import { isNotNullOrUndefined } from '../../../common/rxjs-utils'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { Message } from '../../messages/message.model'; import { MessageService } from '../../messages/message.service'; import { ManageMessageComponent } from './manage-message.component'; @UntilDestroy() @Component({ - templateUrl: './manage-message.component.html' + templateUrl: './manage-message.component.html', + standalone: true, + imports: [NgIf, RouterLink, SystemAlertComponent, FormsModule, NgSelectModule] }) export class UpdateMessageComponent extends ManageMessageComponent { mode = 'admin-edit'; diff --git a/src/app/core/admin/messages/list-messages/list-messages.component.ts b/src/app/core/admin/messages/list-messages/list-messages.component.ts index aff2dbed..33422740 100644 --- a/src/app/core/admin/messages/list-messages/list-messages.component.ts +++ b/src/app/core/admin/messages/list-messages/list-messages.component.ts @@ -1,22 +1,49 @@ +import { CdkTableModule } from '@angular/cdk/table'; import { Component, OnDestroy, OnInit } from '@angular/core'; +import { RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { Observable } from 'rxjs'; import { filter, first, switchMap } from 'rxjs/operators'; +import { SkipToDirective } from '../../../../common/directives/skip-to.directive'; import { ModalAction } from '../../../../common/modal/modal.model'; import { ModalService } from '../../../../common/modal/modal.service'; import { PagingOptions, PagingResults } from '../../../../common/paging.model'; +import { UtcDatePipe } from '../../../../common/pipes/utc-date-pipe/utc-date.pipe'; +import { SearchInputComponent } from '../../../../common/search-input/search-input.component'; import { SortDirection } from '../../../../common/sorting.model'; +import { SystemAlertComponent } from '../../../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../../../common/system-alert/system-alert.service'; import { AsyTableDataSource } from '../../../../common/table/asy-table-data-source'; +import { AsyFilterDirective } from '../../../../common/table/filter/asy-filter.directive'; +import { PaginatorComponent } from '../../../../common/table/paginator/paginator.component'; +import { AsySortHeaderComponent } from '../../../../common/table/sort/asy-sort-header/asy-sort-header.component'; +import { AsySortDirective } from '../../../../common/table/sort/asy-sort.directive'; +import { AsyTableEmptyStateComponent } from '../../../../common/table/table-empty-state/asy-table-empty-state.component'; import { Message } from '../../../messages/message.model'; import { MessageService } from '../../../messages/message.service'; @UntilDestroy() @Component({ templateUrl: './list-messages.component.html', - styleUrls: ['./list-messages.component.scss'] + styleUrls: ['./list-messages.component.scss'], + standalone: true, + imports: [ + SkipToDirective, + SystemAlertComponent, + SearchInputComponent, + RouterLink, + CdkTableModule, + AsySortDirective, + AsyFilterDirective, + AsySortHeaderComponent, + BsDropdownModule, + AsyTableEmptyStateComponent, + PaginatorComponent, + UtcDatePipe + ] }) export class ListMessagesComponent implements OnDestroy, OnInit { displayedColumns = ['title', 'type', 'created', 'updated', 'actionsMenu']; diff --git a/src/app/core/admin/user-management/admin-create-user.component.ts b/src/app/core/admin/user-management/admin-create-user.component.ts index 309ff35c..b0b223d7 100644 --- a/src/app/core/admin/user-management/admin-create-user.component.ts +++ b/src/app/core/admin/user-management/admin-create-user.component.ts @@ -1,8 +1,13 @@ +import { NgFor, NgIf } from '@angular/common'; import { Component, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { RouterLink } from '@angular/router'; import { UntilDestroy } from '@ngneat/until-destroy'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable } from 'rxjs'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { User } from '../../auth/user.model'; import { AdminUsersService } from './admin-users.service'; import { ManageUserComponent } from './manage-user.component'; @@ -10,7 +15,9 @@ import { ManageUserComponent } from './manage-user.component'; @UntilDestroy() @Component({ selector: 'admin-create-user', - templateUrl: 'manage-user.component.html' + templateUrl: 'manage-user.component.html', + standalone: true, + imports: [NgIf, RouterLink, SystemAlertComponent, FormsModule, NgFor, TooltipModule] }) export class AdminCreateUserComponent extends ManageUserComponent { mode = 'admin-create'; diff --git a/src/app/core/admin/user-management/admin-edit-user.component.ts b/src/app/core/admin/user-management/admin-edit-user.component.ts index 5363fa45..62a8f2ca 100644 --- a/src/app/core/admin/user-management/admin-edit-user.component.ts +++ b/src/app/core/admin/user-management/admin-edit-user.component.ts @@ -1,10 +1,14 @@ +import { NgFor, NgIf } from '@angular/common'; import { Component, inject } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Params, RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable, switchMap } from 'rxjs'; import { map } from 'rxjs/operators'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { User } from '../../auth/user.model'; import { AdminUsersService } from './admin-users.service'; import { ManageUserComponent } from './manage-user.component'; @@ -12,7 +16,9 @@ import { ManageUserComponent } from './manage-user.component'; @UntilDestroy() @Component({ selector: 'admin-edit-user', - templateUrl: './manage-user.component.html' + templateUrl: './manage-user.component.html', + standalone: true, + imports: [NgIf, RouterLink, SystemAlertComponent, FormsModule, NgFor, TooltipModule] }) export class AdminEditUserComponent extends ManageUserComponent { mode = 'admin-edit'; diff --git a/src/app/core/admin/user-management/admin-user-routes.ts b/src/app/core/admin/user-management/admin-user-routes.ts new file mode 100644 index 00000000..88338c5a --- /dev/null +++ b/src/app/core/admin/user-management/admin-user-routes.ts @@ -0,0 +1,20 @@ +import { Routes } from '@angular/router'; + +import { AdminCreateUserComponent } from './admin-create-user.component'; +import { AdminEditUserComponent } from './admin-edit-user.component'; +import { AdminListUsersComponent } from './list-users/admin-list-users.component'; + +export const ADMIN_USER_ROUTES: Routes = [ + { + path: 'users', + component: AdminListUsersComponent + }, + { + path: 'user', + component: AdminCreateUserComponent + }, + { + path: 'user/:id', + component: AdminEditUserComponent + } +]; diff --git a/src/app/core/admin/user-management/admin-user.module.ts b/src/app/core/admin/user-management/admin-user.module.ts deleted file mode 100644 index a95571eb..00000000 --- a/src/app/core/admin/user-management/admin-user.module.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; - -import { AlertModule } from 'ngx-bootstrap/alert'; -import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; - -import { DirectivesModule } from '../../../common/directives.module'; -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; -import { TableModule } from '../../../common/table.module'; -import { AdminCreateUserComponent } from './admin-create-user.component'; -import { AdminEditUserComponent } from './admin-edit-user.component'; -import { AdminListUsersComponent } from './list-users/admin-list-users.component'; -import { UserRoleFilterDirective } from './list-users/user-role-filter.directive'; - -@NgModule({ - imports: [ - AlertModule, - BsDropdownModule, - TooltipModule, - - CommonModule, - DirectivesModule, - FormsModule, - PipesModule, - RouterModule, - SystemAlertModule, - SearchInputModule, - CdkTableModule, - TableModule - ], - exports: [], - declarations: [ - AdminCreateUserComponent, - AdminListUsersComponent, - AdminEditUserComponent, - UserRoleFilterDirective - ] -}) -export class AdminUserModule {} diff --git a/src/app/core/admin/user-management/list-users/admin-list-users.component.spec.ts b/src/app/core/admin/user-management/list-users/admin-list-users.component.spec.ts index 0d38ff9c..8152ebcd 100644 --- a/src/app/core/admin/user-management/list-users/admin-list-users.component.spec.ts +++ b/src/app/core/admin/user-management/list-users/admin-list-users.component.spec.ts @@ -1,20 +1,12 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; import { ModalModule } from 'ngx-bootstrap/modal'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { of } from 'rxjs'; import { ModalService } from '../../../../common/modal/modal.service'; import { PagingResults } from '../../../../common/paging.model'; -import { PipesModule } from '../../../../common/pipes.module'; -import { SearchInputModule } from '../../../../common/search-input.module'; -import { SystemAlertModule } from '../../../../common/system-alert.module'; -import { TableModule } from '../../../../common/table.module'; import { Role } from '../../../auth/role.model'; import { User } from '../../../auth/user.model'; import { ConfigService } from '../../../config.service'; @@ -67,19 +59,11 @@ describe('Admin List Users Component Spec', () => { ); TestBed.configureTestingModule({ - declarations: [AdminListUsersComponent], imports: [ - CommonModule, - FormsModule, RouterTestingModule, - PipesModule, - SearchInputModule, - SystemAlertModule, - TooltipModule, - CdkTableModule, - TableModule, BrowserAnimationsModule, - ModalModule.forRoot() + ModalModule.forRoot(), + AdminListUsersComponent ], providers: [ { provide: AdminUsersService, useValue: adminUsersServiceSpy }, diff --git a/src/app/core/admin/user-management/list-users/admin-list-users.component.ts b/src/app/core/admin/user-management/list-users/admin-list-users.component.ts index e9fda9db..f98da452 100644 --- a/src/app/core/admin/user-management/list-users/admin-list-users.component.ts +++ b/src/app/core/admin/user-management/list-users/admin-list-users.component.ts @@ -1,28 +1,72 @@ +import { CdkTableModule } from '@angular/cdk/table'; +import { AsyncPipe, NgClass, NgFor, NgIf } from '@angular/common'; import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable, of } from 'rxjs'; import { catchError, filter, first, map, switchMap } from 'rxjs/operators'; +import { SkipToDirective } from '../../../../common/directives/skip-to.directive'; import { ModalAction } from '../../../../common/modal/modal.model'; import { ModalService } from '../../../../common/modal/modal.service'; import { PagingOptions, PagingResults } from '../../../../common/paging.model'; +import { AgoDatePipe } from '../../../../common/pipes/ago-date.pipe'; +import { JoinPipe } from '../../../../common/pipes/join.pipe'; +import { UtcDatePipe } from '../../../../common/pipes/utc-date-pipe/utc-date.pipe'; +import { SearchInputComponent } from '../../../../common/search-input/search-input.component'; import { SortDirection } from '../../../../common/sorting.model'; +import { SystemAlertComponent } from '../../../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../../../common/system-alert/system-alert.service'; import { AsyTableDataSource } from '../../../../common/table/asy-table-data-source'; +import { ColumnChooserComponent } from '../../../../common/table/column-chooser/column-chooser.component'; import { AsyFilterDirective } from '../../../../common/table/filter/asy-filter.directive'; +import { AsyHeaderListFilterComponent } from '../../../../common/table/filter/asy-header-list-filter/asy-header-list-filter.component'; +import { PaginatorComponent } from '../../../../common/table/paginator/paginator.component'; +import { SidebarComponent } from '../../../../common/table/sidebar/sidebar.component'; +import { AsySortHeaderComponent } from '../../../../common/table/sort/asy-sort-header/asy-sort-header.component'; +import { AsySortDirective } from '../../../../common/table/sort/asy-sort.directive'; +import { AsyTableEmptyStateComponent } from '../../../../common/table/table-empty-state/asy-table-empty-state.component'; import { Role } from '../../../auth/role.model'; import { User } from '../../../auth/user.model'; import { ConfigService } from '../../../config.service'; import { ExportConfigService } from '../../../export-config.service'; import { AdminUsersService } from '../admin-users.service'; +import { UserRoleFilterDirective } from './user-role-filter.directive'; @UntilDestroy() @Component({ templateUrl: './admin-list-users.component.html', - styleUrls: ['./admin-list-users.component.scss'] + styleUrls: ['./admin-list-users.component.scss'], + standalone: true, + imports: [ + SkipToDirective, + SystemAlertComponent, + SearchInputComponent, + RouterLink, + TooltipModule, + CdkTableModule, + AsySortDirective, + AsyFilterDirective, + AsySortHeaderComponent, + AsyHeaderListFilterComponent, + UserRoleFilterDirective, + NgFor, + NgIf, + NgClass, + BsDropdownModule, + AsyTableEmptyStateComponent, + SidebarComponent, + ColumnChooserComponent, + PaginatorComponent, + AsyncPipe, + AgoDatePipe, + JoinPipe, + UtcDatePipe + ] }) export class AdminListUsersComponent implements OnDestroy, OnInit { @ViewChild(AsyFilterDirective) diff --git a/src/app/core/admin/user-management/list-users/user-role-filter.directive.ts b/src/app/core/admin/user-management/list-users/user-role-filter.directive.ts index 0ec05256..56c2eb9f 100644 --- a/src/app/core/admin/user-management/list-users/user-role-filter.directive.ts +++ b/src/app/core/admin/user-management/list-users/user-role-filter.directive.ts @@ -12,7 +12,8 @@ import { ConfigService } from '../../../config.service'; @UntilDestroy() @Directive({ - selector: 'asy-header-filter[list-filter][user-role-filter]' + selector: 'asy-header-filter[list-filter][user-role-filter]', + standalone: true }) export class UserRoleFilterDirective implements OnInit { private requiredExternalRoles: string[] = []; diff --git a/src/app/core/audit/audit-object.component.ts b/src/app/core/audit/audit-object.component.ts index 56813614..5a97badb 100644 --- a/src/app/core/audit/audit-object.component.ts +++ b/src/app/core/audit/audit-object.component.ts @@ -1,10 +1,13 @@ +import { JsonPipe, NgIf } from '@angular/common'; import { Component, ComponentRef, Input, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; import { AuditObjectTypes } from './audit.classes'; @Component({ selector: 'default', - template: '{{ auditObject | json }}' + template: '{{ auditObject | json }}', + standalone: true, + imports: [JsonPipe] }) export class DefaultAuditObjectComponent { @Input() auditObject: any = {}; @@ -13,21 +16,24 @@ AuditObjectTypes.registerType('default', DefaultAuditObjectComponent); @Component({ selector: 'url', - template: '{{ auditObject.url }}' + template: '{{ auditObject.url }}', + standalone: true }) export class UrlAuditObjectComponent extends DefaultAuditObjectComponent {} AuditObjectTypes.registerType('url', UrlAuditObjectComponent); @Component({ selector: 'user', - template: '{{ auditObject?.username }}' + template: '{{ auditObject?.username }}', + standalone: true }) export class UserAuditObjectComponent extends DefaultAuditObjectComponent {} AuditObjectTypes.registerType('user', UserAuditObjectComponent); @Component({ selector: 'user-authentication', - template: '' + template: '', + standalone: true }) export class UserAuthenticationObjectComponent extends DefaultAuditObjectComponent {} AuditObjectTypes.registerType('user-authentication', UserAuthenticationObjectComponent); @@ -36,14 +42,17 @@ AuditObjectTypes.registerType('user-authentication', UserAuthenticationObjectCom selector: 'export-audit', template: ` Export config - ` + `, + standalone: true, + imports: [NgIf] }) export class ExportAuditObjectComponent extends DefaultAuditObjectComponent {} AuditObjectTypes.registerType('export', ExportAuditObjectComponent); @Component({ selector: 'asy-audit-component', - template: '
' + template: '
', + standalone: true }) export class AuditObjectComponent implements OnInit { @ViewChild('content', { read: ViewContainerRef, static: true }) content?: ViewContainerRef; diff --git a/src/app/core/audit/audit-routes.ts b/src/app/core/audit/audit-routes.ts new file mode 100644 index 00000000..e3a92d9e --- /dev/null +++ b/src/app/core/audit/audit-routes.ts @@ -0,0 +1,13 @@ +import { authGuard } from '../auth/auth.guard'; +import { AuditService } from './audit.service'; +import { ListAuditEntriesComponent } from './list-audit-entries/list-audit-entries.component'; + +export const AUDIT_ROUTES = [ + { + path: '', + component: ListAuditEntriesComponent, + canActivate: [authGuard], + data: { roles: ['auditor'] }, + providers: [AuditService] + } +]; diff --git a/src/app/core/audit/audit-routing.module.ts b/src/app/core/audit/audit-routing.module.ts deleted file mode 100644 index 7aaed5ba..00000000 --- a/src/app/core/audit/audit-routing.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { authGuard } from '../auth/auth.guard'; -import { ListAuditEntriesComponent } from './list-audit-entries/list-audit-entries.component'; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: '', - component: ListAuditEntriesComponent, - canActivate: [authGuard], - data: { roles: ['auditor'] } - } - ]) - ], - exports: [RouterModule] -}) -export class AuditRoutingModule {} diff --git a/src/app/core/audit/audit-view-change-modal/audit-view-change-modal.component.ts b/src/app/core/audit/audit-view-change-modal/audit-view-change-modal.component.ts index 7aa5f9bc..fde4abe0 100644 --- a/src/app/core/audit/audit-view-change-modal/audit-view-change-modal.component.ts +++ b/src/app/core/audit/audit-view-change-modal/audit-view-change-modal.component.ts @@ -1,5 +1,9 @@ +import { JsonPipe } from '@angular/common'; import { Component } from '@angular/core'; +import { ModalComponent } from '../../../common/modal/modal/modal.component'; +import { SortObjectKeysPipe } from '../../../common/pipes/sort-object-keys.pipe'; +import { UtcDatePipe } from '../../../common/pipes/utc-date-pipe/utc-date.pipe'; import { AuditViewDetailsModalComponent } from '../audit-view-details-modal/audit-view-details-modal.component'; @Component({ @@ -10,6 +14,8 @@ import { AuditViewDetailsModalComponent } from '../audit-view-details-modal/audi display: contents; } ` - ] + ], + standalone: true, + imports: [ModalComponent, JsonPipe, SortObjectKeysPipe, UtcDatePipe] }) export class AuditViewChangeModalComponent extends AuditViewDetailsModalComponent {} diff --git a/src/app/core/audit/audit-view-details-modal/audit-view-details-modal.component.ts b/src/app/core/audit/audit-view-details-modal/audit-view-details-modal.component.ts index 744abd1f..27a5f6c4 100644 --- a/src/app/core/audit/audit-view-details-modal/audit-view-details-modal.component.ts +++ b/src/app/core/audit/audit-view-details-modal/audit-view-details-modal.component.ts @@ -1,7 +1,11 @@ +import { JsonPipe, NgIf, TitleCasePipe } from '@angular/common'; import { Component } from '@angular/core'; import { BsModalRef } from 'ngx-bootstrap/modal'; +import { ModalComponent } from '../../../common/modal/modal/modal.component'; +import { UtcDatePipe } from '../../../common/pipes/utc-date-pipe/utc-date.pipe'; + @Component({ templateUrl: './audit-view-details-modal.component.html', styles: [ @@ -10,7 +14,9 @@ import { BsModalRef } from 'ngx-bootstrap/modal'; display: contents; } ` - ] + ], + standalone: true, + imports: [ModalComponent, NgIf, JsonPipe, TitleCasePipe, UtcDatePipe] }) export class AuditViewDetailsModalComponent { auditEntry: any; diff --git a/src/app/core/audit/audit.module.ts b/src/app/core/audit/audit.module.ts deleted file mode 100644 index 50b943d8..00000000 --- a/src/app/core/audit/audit.module.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CdkTableModule } from '@angular/cdk/table'; -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; -import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; -import { ModalModule as BsModalModule } from 'ngx-bootstrap/modal'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; -import { TypeaheadModule } from 'ngx-bootstrap/typeahead'; - -import { DirectivesModule } from '../../common/directives.module'; -import { ModalModule } from '../../common/modal.module'; -import { PipesModule } from '../../common/pipes.module'; -import { SystemAlertModule } from '../../common/system-alert.module'; -import { TableModule } from '../../common/table.module'; -import { - AuditObjectComponent, - DefaultAuditObjectComponent, - ExportAuditObjectComponent, - UrlAuditObjectComponent, - UserAuditObjectComponent, - UserAuthenticationObjectComponent -} from './audit-object.component'; -import { AuditRoutingModule } from './audit-routing.module'; -import { AuditViewChangeModalComponent } from './audit-view-change-modal/audit-view-change-modal.component'; -import { AuditViewDetailsModalComponent } from './audit-view-details-modal/audit-view-details-modal.component'; -import { AuditService } from './audit.service'; -import { AuditActorFilterDirective } from './list-audit-entries/audit-actor-filter.directive'; -import { AuditDistinctValueFilterDirective } from './list-audit-entries/audit-distinct-value-filter.directive'; -import { ListAuditEntriesComponent } from './list-audit-entries/list-audit-entries.component'; - -@NgModule({ - imports: [ - BsDatepickerModule, - BsModalModule, - TypeaheadModule, - TooltipModule, - NgSelectModule, - - AuditRoutingModule, - CommonModule, - DirectivesModule, - FormsModule, - PipesModule, - SystemAlertModule, - CdkTableModule, - TableModule, - ModalModule - ], - exports: [], - declarations: [ - ListAuditEntriesComponent, - AuditViewChangeModalComponent, - AuditViewDetailsModalComponent, - AuditDistinctValueFilterDirective, - AuditActorFilterDirective, - AuditObjectComponent, - UrlAuditObjectComponent, - DefaultAuditObjectComponent, - ExportAuditObjectComponent, - UrlAuditObjectComponent, - UserAuditObjectComponent, - UserAuthenticationObjectComponent - ], - providers: [AuditService] -}) -export class AuditModule {} diff --git a/src/app/core/audit/audit.service.spec.ts b/src/app/core/audit/audit.service.spec.ts index 0b676e4a..5d335f2f 100644 --- a/src/app/core/audit/audit.service.spec.ts +++ b/src/app/core/audit/audit.service.spec.ts @@ -4,7 +4,6 @@ import { TestBed, getTestBed } from '@angular/core/testing'; import _cloneDeep from 'lodash/cloneDeep'; import { PagingOptions, PagingResults } from '../../common/paging.model'; -import { SystemAlertModule } from '../../common/system-alert.module'; import { SystemAlertService } from '../../common/system-alert/system-alert.service'; import { User } from '../auth/user.model'; import { AuditService } from './audit.service'; @@ -16,7 +15,7 @@ describe('Audit Service', () => { beforeEach(async () => { TestBed.configureTestingModule({ - imports: [HttpClientTestingModule, SystemAlertModule], + imports: [HttpClientTestingModule], providers: [AuditService, SystemAlertService] }); diff --git a/src/app/core/audit/list-audit-entries/audit-actor-filter.directive.ts b/src/app/core/audit/list-audit-entries/audit-actor-filter.directive.ts index f8e3fa40..4d7659ea 100644 --- a/src/app/core/audit/list-audit-entries/audit-actor-filter.directive.ts +++ b/src/app/core/audit/list-audit-entries/audit-actor-filter.directive.ts @@ -8,7 +8,8 @@ import { AsyHeaderTypeaheadFilterComponent } from '../../../common/table/filter/ import { AuditService } from '../audit.service'; @Directive({ - selector: 'asy-header-filter[typeahead-filter][audit-actor-filter]' + selector: 'asy-header-filter[typeahead-filter][audit-actor-filter]', + standalone: true }) export class AuditActorFilterDirective implements OnInit { constructor( diff --git a/src/app/core/audit/list-audit-entries/audit-distinct-value-filter.directive.ts b/src/app/core/audit/list-audit-entries/audit-distinct-value-filter.directive.ts index 3d4ba786..21b23bb2 100644 --- a/src/app/core/audit/list-audit-entries/audit-distinct-value-filter.directive.ts +++ b/src/app/core/audit/list-audit-entries/audit-distinct-value-filter.directive.ts @@ -11,7 +11,8 @@ import { AuditService } from '../audit.service'; @UntilDestroy() @Directive({ - selector: 'asy-header-filter[list-filter][audit-distinct-value-filter]' + selector: 'asy-header-filter[list-filter][audit-distinct-value-filter]', + standalone: true }) export class AuditDistinctValueFilterDirective implements OnInit { constructor( diff --git a/src/app/core/audit/list-audit-entries/list-audit-entries.component.spec.ts b/src/app/core/audit/list-audit-entries/list-audit-entries.component.spec.ts index 1512b46a..88209c97 100644 --- a/src/app/core/audit/list-audit-entries/list-audit-entries.component.spec.ts +++ b/src/app/core/audit/list-audit-entries/list-audit-entries.component.spec.ts @@ -1,23 +1,13 @@ -import { CdkTableModule } from '@angular/cdk/table'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; import { ModalModule } from 'ngx-bootstrap/modal'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; -import { TypeaheadModule } from 'ngx-bootstrap/typeahead'; import { of } from 'rxjs'; -import { DirectivesModule } from '../../../common/directives.module'; import { PagingResults } from '../../../common/paging.model'; -import { PipesModule } from '../../../common/pipes.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; import { SystemAlertService } from '../../../common/system-alert/system-alert.service'; -import { TableModule } from '../../../common/table.module'; -import { ConfigService } from '../../core.module'; +import { ConfigService } from '../../config.service'; import { AuditObjectComponent, DefaultAuditObjectComponent, @@ -112,7 +102,9 @@ describe('Audit Component Spec', () => { configServiceSpy.getConfig.and.returnValue(of({})); TestBed.configureTestingModule({ - declarations: [ + imports: [ + ModalModule.forRoot(), + BrowserAnimationsModule, ListAuditEntriesComponent, AuditObjectComponent, UrlAuditObjectComponent, @@ -121,21 +113,6 @@ describe('Audit Component Spec', () => { UserAuditObjectComponent, UserAuthenticationObjectComponent ], - imports: [ - BsDatepickerModule, - ModalModule.forRoot(), - TypeaheadModule, - TooltipModule, - NgSelectModule, - DirectivesModule, - FormsModule, - PipesModule, - SystemAlertModule, - CdkTableModule, - TableModule, - BrowserAnimationsModule, - ModalModule - ], providers: [ { provide: AuditService, useValue: auditServiceSpy }, { provide: ConfigService, useValue: configServiceSpy }, diff --git a/src/app/core/audit/list-audit-entries/list-audit-entries.component.ts b/src/app/core/audit/list-audit-entries/list-audit-entries.component.ts index d226b300..3c4a9b3c 100644 --- a/src/app/core/audit/list-audit-entries/list-audit-entries.component.ts +++ b/src/app/core/audit/list-audit-entries/list-audit-entries.component.ts @@ -1,22 +1,58 @@ +import { CdkTableModule } from '@angular/cdk/table'; +import { NgIf } from '@angular/common'; import { Component, OnDestroy, ViewChild } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable } from 'rxjs'; import { first } from 'rxjs/operators'; +import { SkipToDirective } from '../../../common/directives/skip-to.directive'; import { PagingOptions, PagingResults } from '../../../common/paging.model'; +import { UtcDatePipe } from '../../../common/pipes/utc-date-pipe/utc-date.pipe'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { AsyTableDataSource } from '../../../common/table/asy-table-data-source'; import { AsyFilterDirective } from '../../../common/table/filter/asy-filter.directive'; +import { AsyHeaderDateFilterComponent } from '../../../common/table/filter/asy-header-date-filter/asy-header-date-filter.component'; +import { AsyHeaderListFilterComponent } from '../../../common/table/filter/asy-header-list-filter/asy-header-list-filter.component'; +import { AsyHeaderTypeaheadFilterComponent } from '../../../common/table/filter/asy-header-typeahead-filter/asy-header-typeahead-filter.component'; +import { PaginatorComponent } from '../../../common/table/paginator/paginator.component'; +import { AsySortHeaderComponent } from '../../../common/table/sort/asy-sort-header/asy-sort-header.component'; +import { AsySortDirective } from '../../../common/table/sort/asy-sort.directive'; +import { AsyTableEmptyStateComponent } from '../../../common/table/table-empty-state/asy-table-empty-state.component'; import { ConfigService } from '../../config.service'; +import { AuditObjectComponent } from '../audit-object.component'; import { AuditViewChangeModalComponent } from '../audit-view-change-modal/audit-view-change-modal.component'; import { AuditViewDetailsModalComponent } from '../audit-view-details-modal/audit-view-details-modal.component'; import { AuditService } from '../audit.service'; +import { AuditActorFilterDirective } from './audit-actor-filter.directive'; +import { AuditDistinctValueFilterDirective } from './audit-distinct-value-filter.directive'; @UntilDestroy() @Component({ templateUrl: './list-audit-entries.component.html', - styleUrls: ['./list-audit-entries.component.scss'] + styleUrls: ['./list-audit-entries.component.scss'], + standalone: true, + imports: [ + SkipToDirective, + SystemAlertComponent, + CdkTableModule, + AsySortDirective, + AsyFilterDirective, + AsySortHeaderComponent, + AsyHeaderTypeaheadFilterComponent, + AuditActorFilterDirective, + AuditObjectComponent, + AsyHeaderDateFilterComponent, + AsyHeaderListFilterComponent, + AuditDistinctValueFilterDirective, + NgIf, + TooltipModule, + AsyTableEmptyStateComponent, + PaginatorComponent, + UtcDatePipe + ] }) export class ListAuditEntriesComponent implements OnDestroy { @ViewChild(AsyFilterDirective) diff --git a/src/app/core/auth/abstract.interceptor.ts b/src/app/core/auth/abstract.interceptor.ts index be750c03..3dc17462 100644 --- a/src/app/core/auth/abstract.interceptor.ts +++ b/src/app/core/auth/abstract.interceptor.ts @@ -7,6 +7,8 @@ import { catchError } from 'rxjs/operators'; /** * Abstract HTTP Interceptor + * + * @deprecated Moving towards functional interceptors. Migrate to using errorInterceptor. */ @Injectable() export abstract class AbstractHttpInterceptor implements HttpInterceptor { diff --git a/src/app/core/auth/auth.interceptor.ts b/src/app/core/auth/auth.interceptor.ts index 1afcabb6..322bbf2a 100644 --- a/src/app/core/auth/auth.interceptor.ts +++ b/src/app/core/auth/auth.interceptor.ts @@ -1,19 +1,24 @@ -import { HttpRequest } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http'; +import { inject } from '@angular/core'; +import { Router } from '@angular/router'; -import { AbstractHttpInterceptor } from './abstract.interceptor'; +import { Observable } from 'rxjs'; + +import { errorInterceptor } from './error.interceptor'; /** * HTTP Interceptor that will interpret authentication related HTTP calls */ -@Injectable() -export class AuthInterceptor extends AbstractHttpInterceptor { - handleError(err: unknown, req: HttpRequest): void { - if (!req.headers.has('bypass-auth-interceptor')) { - const { status, type, message, url } = this.parseError(err); - if (status === 403) { - this.router.navigate(['/access'], { state: { status, type, message, url } }); - } +// eslint-disable-next-line rxjs/finnish +export function authInterceptor( + req: HttpRequest, + next: HttpHandlerFn +): Observable> { + const router = inject(Router); + + return errorInterceptor(req, next, (error, req) => { + if (!req.headers.has('bypass-auth-interceptor') && error.status === 403) { + router.navigate(['/access'], { state: error }); } - } + }); } diff --git a/src/app/core/auth/authorization.service.spec.ts b/src/app/core/auth/authorization.service.spec.ts index ff2fdd50..8be14d08 100644 --- a/src/app/core/auth/authorization.service.spec.ts +++ b/src/app/core/auth/authorization.service.spec.ts @@ -8,9 +8,9 @@ import { Session } from './session.model'; import { SessionService } from './session.service'; class MockSessionService { - sessionSubject$ = new BehaviorSubject(null); + sessionSubject$ = new BehaviorSubject(null); - getSession(): Observable { + getSession(): Observable { return this.sessionSubject$; } } diff --git a/src/app/core/auth/directives/has-every-role.directive.ts b/src/app/core/auth/directives/has-every-role.directive.ts index ff893cb7..447089a0 100644 --- a/src/app/core/auth/directives/has-every-role.directive.ts +++ b/src/app/core/auth/directives/has-every-role.directive.ts @@ -15,7 +15,8 @@ import { SessionService } from '../session.service'; directive: NgIf, inputs: ['ngIfElse: hasEveryRoleElse', 'ngIfThen: hasEveryRoleThen'] } - ] + ], + standalone: true }) export class HasEveryRoleDirective implements OnInit { roles: Array; diff --git a/src/app/core/auth/directives/has-role.directive.ts b/src/app/core/auth/directives/has-role.directive.ts index b319a92d..dbfae393 100644 --- a/src/app/core/auth/directives/has-role.directive.ts +++ b/src/app/core/auth/directives/has-role.directive.ts @@ -15,7 +15,8 @@ import { SessionService } from '../session.service'; directive: NgIf, inputs: ['ngIfElse: hasRoleElse', 'ngIfThen: hasRoleThen'] } - ] + ], + standalone: true }) export class HasRoleDirective implements OnInit { role: string | Role; diff --git a/src/app/core/auth/directives/has-some-roles.directive.ts b/src/app/core/auth/directives/has-some-roles.directive.ts index a61ccc6b..72e15fb1 100644 --- a/src/app/core/auth/directives/has-some-roles.directive.ts +++ b/src/app/core/auth/directives/has-some-roles.directive.ts @@ -15,7 +15,8 @@ import { SessionService } from '../session.service'; directive: NgIf, inputs: ['ngIfElse: hasSomeRolesElse', 'ngIfThen: hasSomeRolesThen'] } - ] + ], + standalone: true }) export class HasSomeRolesDirective implements OnInit { roles: Array; diff --git a/src/app/core/auth/directives/is-authenticated.directive.ts b/src/app/core/auth/directives/is-authenticated.directive.ts index 9f592ee8..9765893c 100644 --- a/src/app/core/auth/directives/is-authenticated.directive.ts +++ b/src/app/core/auth/directives/is-authenticated.directive.ts @@ -15,7 +15,8 @@ import { SessionService } from '../session.service'; directive: NgIf, inputs: ['ngIfElse: isAuthenticatedElse', 'ngIfThen: isAuthenticatedThen'] } - ] + ], + standalone: true }) export class IsAuthenticatedDirective implements OnInit { private _isAuthenticated = true; diff --git a/src/app/core/auth/error.interceptor.ts b/src/app/core/auth/error.interceptor.ts new file mode 100644 index 00000000..4b8fe6f6 --- /dev/null +++ b/src/app/core/auth/error.interceptor.ts @@ -0,0 +1,31 @@ +import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http'; + +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +type HttpError = { status: number; type: string; url: string; message: string }; + +export type HttpErrorHandlerFn = (err: HttpError, req: HttpRequest) => void; + +// eslint-disable-next-line rxjs/finnish +export function errorInterceptor( + req: HttpRequest, + next: HttpHandlerFn, + errorHandler: HttpErrorHandlerFn +): Observable> { + return next(req).pipe( + catchError((err: unknown) => { + errorHandler(parseError(err), req); + return throwError(() => err); + }) + ); +} + +function parseError(err: any): HttpError { + const status = err?.status ?? 200; + const type = err?.error?.type ?? ''; + const url = err?.url ?? ''; + const message = err?.error?.message ?? ''; + + return { status, type, message, url }; +} diff --git a/src/app/core/auth/eua.interceptor.ts b/src/app/core/auth/eua.interceptor.ts index 690778c8..c92b2b62 100644 --- a/src/app/core/auth/eua.interceptor.ts +++ b/src/app/core/auth/eua.interceptor.ts @@ -1,16 +1,24 @@ -import { Injectable } from '@angular/core'; +import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http'; +import { inject } from '@angular/core'; +import { Router } from '@angular/router'; -import { AbstractHttpInterceptor } from './abstract.interceptor'; +import { Observable } from 'rxjs'; + +import { errorInterceptor } from './error.interceptor'; /** * HTTP Interceptor that will interpret EUA related HTTP calls */ -@Injectable() -export class EuaInterceptor extends AbstractHttpInterceptor { - handleError(err: unknown): void { - const { status, type } = this.parseError(err); +// eslint-disable-next-line rxjs/finnish +export function euaInterceptor( + req: HttpRequest, + next: HttpHandlerFn +): Observable> { + const router = inject(Router); + + return errorInterceptor(req, next, ({ status, type }) => { if (status === 403 && type === 'eua') { - this.router.navigate(['/eua']); + router.navigate(['/eua']); } - } + }); } diff --git a/src/app/core/auth/signin.interceptor.ts b/src/app/core/auth/signin.interceptor.ts index b9f01558..03497b51 100644 --- a/src/app/core/auth/signin.interceptor.ts +++ b/src/app/core/auth/signin.interceptor.ts @@ -1,16 +1,24 @@ -import { Injectable } from '@angular/core'; +import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http'; +import { inject } from '@angular/core'; +import { Router } from '@angular/router'; -import { AbstractHttpInterceptor } from './abstract.interceptor'; +import { Observable } from 'rxjs'; + +import { errorInterceptor } from './error.interceptor'; /** - * HTTP Interceptor that will interpret Sign In related HTTP calls + * HTTP Interceptor that will interpret Sign In related HTTP errors */ -@Injectable() -export class SigninInterceptor extends AbstractHttpInterceptor { - handleError(err: unknown): void { - const { status, url } = this.parseError(err); +// eslint-disable-next-line rxjs/finnish +export function signinInterceptor( + req: HttpRequest, + next: HttpHandlerFn +): Observable> { + const router = inject(Router); + + return errorInterceptor(req, next, ({ status, url }) => { if (status === 401 && !url.endsWith('auth/signin')) { - this.router.navigate(['/signin']); + router.navigate(['/signin']); } - } + }); } diff --git a/src/app/core/core-routes.ts b/src/app/core/core-routes.ts new file mode 100644 index 00000000..32400a22 --- /dev/null +++ b/src/app/core/core-routes.ts @@ -0,0 +1,78 @@ +import { Routes } from '@angular/router'; + +import { AboutComponent } from './about.component'; +import { AccessComponent } from './access.component'; +import { authGuard } from './auth/auth.guard'; +import { UserEuaComponent } from './eua/user-eua.component'; +import { MasqueradeComponent } from './masquerade/masquerade/masquerade.component'; +import { ViewAllMessagesComponent } from './messages/view-all-messages/view-all-messages.component'; +import { SigninComponent } from './signin/signin.component'; +import { SignedUpComponent } from './signup/signed-up.component'; +import { SignupComponent } from './signup/signup.component'; +import { UnauthorizedComponent } from './unauthorized.component'; + +export const CORE_ROUTES: Routes = [ + { + path: 'about', + component: AboutComponent + }, + { + path: 'access', + component: AccessComponent + }, + { + path: 'eua', + component: UserEuaComponent, + canActivate: [authGuard], + data: { + requiresEua: false + } + }, + { + path: 'signin', + component: SigninComponent + }, + { + path: 'signup', + component: SignupComponent + }, + { + path: 'signed-up', + component: SignedUpComponent + }, + { + path: 'unauthorized', + component: UnauthorizedComponent, + canActivate: [authGuard], + data: { + roles: [], // no roles are needed to get to the "unauthorized" page + requiresEua: false + } + }, + { + path: 'messages', + component: ViewAllMessagesComponent, + canActivate: [authGuard], + data: { roles: ['user'] } + }, + { + path: 'masquerade', + component: MasqueradeComponent + }, + { + path: 'team', + loadChildren: () => import('./teams/teams-routes').then((m) => m.TEAMS_ROUTES) + }, + { + path: 'help', + loadChildren: () => import('./help/help-routes').then((m) => m.HELP_ROUTES) + }, + { + path: 'admin', + loadChildren: () => import('./admin/admin-routes').then((m) => m.ADMIN_ROUTES) + }, + { + path: 'audit', + loadChildren: () => import('./audit/audit-routes').then((m) => m.AUDIT_ROUTES) + } +]; diff --git a/src/app/core/core-routing.module.ts b/src/app/core/core-routing.module.ts deleted file mode 100644 index 6397c73c..00000000 --- a/src/app/core/core-routing.module.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { AboutComponent } from './about.component'; -import { AccessComponent } from './access.component'; -import { authGuard } from './auth/auth.guard'; -import { UserEuaComponent } from './eua/user-eua.component'; -import { SigninComponent } from './signin/signin.component'; -import { SignedUpComponent } from './signup/signed-up.component'; -import { SignupComponent } from './signup/signup.component'; -import { UnauthorizedComponent } from './unauthorized.component'; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: 'about', - component: AboutComponent - }, - { - path: 'access', - component: AccessComponent - }, - { - path: 'eua', - component: UserEuaComponent, - canActivate: [authGuard], - data: { - requiresEua: false - } - }, - { - path: 'signin', - component: SigninComponent - }, - { - path: 'signup', - component: SignupComponent - }, - { - path: 'signed-up', - component: SignedUpComponent - }, - { - path: 'unauthorized', - component: UnauthorizedComponent, - canActivate: [authGuard], - data: { - roles: [], // no roles are needed to get to the "unauthorized" page - requiresEua: false - } - }, - { - path: 'admin', - loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule) - }, - { - path: 'audit', - loadChildren: () => import('./audit/audit.module').then((m) => m.AuditModule) - } - ]) - ], - exports: [RouterModule] -}) -export class CoreRoutingModule {} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts deleted file mode 100644 index 922589c4..00000000 --- a/src/app/core/core.module.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { RouterModule, TitleStrategy } from '@angular/router'; - -import { ModalModule } from 'ngx-bootstrap/modal'; -import { PopoverModule } from 'ngx-bootstrap/popover'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; -import { firstValueFrom } from 'rxjs'; -import { tap } from 'rxjs/operators'; - -import { AdminTopics } from '../common/admin/admin-topic.model'; -import { DirectivesModule } from '../common/directives.module'; -import { LoadingSpinnerModule } from '../common/loading-spinner.module'; -import { SystemAlertModule } from '../common/system-alert.module'; -import { AboutComponent } from './about.component'; -import { AccessComponent } from './access.component'; -import { AuthInterceptor } from './auth/auth.interceptor'; -import { HasEveryRoleDirective } from './auth/directives/has-every-role.directive'; -import { HasRoleDirective } from './auth/directives/has-role.directive'; -import { HasSomeRolesDirective } from './auth/directives/has-some-roles.directive'; -import { IsAuthenticatedDirective } from './auth/directives/is-authenticated.directive'; -import { EuaInterceptor } from './auth/eua.interceptor'; -import { SigninInterceptor } from './auth/signin.interceptor'; -import { ConfigService } from './config.service'; -import { CoreRoutingModule } from './core-routing.module'; -import { UserEuaComponent } from './eua/user-eua.component'; -import { FeedbackModule } from './feedback/feedback.module'; -import { HelpModule } from './help/help.module'; -import { MasqueradeModule } from './masquerade/masquerade.module'; -import { MessagesModule } from './messages/messages.module'; -import { NavigationService } from './navigation.service'; -import { PageTitleStrategy } from './page-title.strategy'; -import { SigninComponent } from './signin/signin.component'; -import { SignedUpComponent } from './signup/signed-up.component'; -import { SignupComponent } from './signup/signup.component'; -import { SiteContainerComponent } from './site-container/site-container.component'; -import { SiteNavbarComponent } from './site-navbar/site-navbar.component'; -import { TeamsModule } from './teams/teams.module'; -import { UnauthorizedComponent } from './unauthorized.component'; - -export function getConfiguration(configService: ConfigService) { - return () => - firstValueFrom( - configService.getConfig().pipe( - tap((config) => { - if (config === null) { - throw new Error('Error loading application configuration.'); - } - }) - ) - ); -} - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - HttpClientModule, - RouterModule, - - ModalModule, - PopoverModule, - TooltipModule, - - HelpModule, - FeedbackModule, - TeamsModule, - CoreRoutingModule, - LoadingSpinnerModule, - SystemAlertModule, - MessagesModule, - MasqueradeModule, - DirectivesModule - ], - exports: [ - SiteContainerComponent, - UserEuaComponent, - IsAuthenticatedDirective, - HasRoleDirective, - HasEveryRoleDirective, - HasSomeRolesDirective - ], - declarations: [ - AboutComponent, - AccessComponent, - SignedUpComponent, - SigninComponent, - SignupComponent, - SiteContainerComponent, - SiteNavbarComponent, - UnauthorizedComponent, - UserEuaComponent, - IsAuthenticatedDirective, - HasRoleDirective, - HasEveryRoleDirective, - HasSomeRolesDirective - ], - providers: [ - { - provide: APP_INITIALIZER, - useFactory: getConfiguration, - deps: [ConfigService], - multi: true - }, - [ - { provide: HTTP_INTERCEPTORS, useClass: SigninInterceptor, multi: true }, - { provide: HTTP_INTERCEPTORS, useClass: EuaInterceptor, multi: true }, - { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } - ], - { - provide: TitleStrategy, - useClass: PageTitleStrategy - } - ] -}) -export class CoreModule { - constructor(private navigationService: NavigationService) { - this.navigationService.init(); - } -} - -export { User } from './auth/user.model'; -export { Role } from './auth/role.model'; -export { AuthorizationService } from './auth/authorization.service'; -export { ConfigService } from './config.service'; -export { NavbarTopics } from './site-navbar/navbar-topic.model'; -export { AuditObjectTypes, AuditActionTypes } from './audit/audit.classes'; - -AdminTopics.registerTopic({ - id: 'users', - title: 'User', - ordinal: 0, - path: 'users' -}); - -AdminTopics.registerTopic({ - id: 'cache-entries', - title: 'Cache Entries', - ordinal: 1, - path: 'cacheEntries' -}); - -AdminTopics.registerTopic({ - id: 'end-user-agreements', - title: 'EUAs', - ordinal: 2, - path: 'euas' -}); - -AdminTopics.registerTopic({ - id: 'messages', - title: 'Messages', - ordinal: 3, - path: 'messages' -}); - -AdminTopics.registerTopic({ - id: 'feedback', - title: 'Feedback', - ordinal: 4, - path: 'feedback' -}); diff --git a/src/app/core/eua/user-eua.component.ts b/src/app/core/eua/user-eua.component.ts index adae2506..cb162f82 100644 --- a/src/app/core/eua/user-eua.component.ts +++ b/src/app/core/eua/user-eua.component.ts @@ -1,9 +1,12 @@ +import { AsyncPipe, NgIf } from '@angular/common'; import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Observable } from 'rxjs'; +import { SystemAlertComponent } from '../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../common/system-alert/system-alert.service'; import { AuthorizationService } from '../auth/authorization.service'; import { SessionService } from '../auth/session.service'; @@ -11,7 +14,9 @@ import { NavigationService } from '../navigation.service'; @UntilDestroy() @Component({ - templateUrl: 'user-eua.component.html' + templateUrl: 'user-eua.component.html', + standalone: true, + imports: [NgIf, SystemAlertComponent, FormsModule, AsyncPipe] }) export class UserEuaComponent implements OnInit { agree = false; diff --git a/src/app/core/feedback/feedback-flyout/feedback-flyout.component.ts b/src/app/core/feedback/feedback-flyout/feedback-flyout.component.ts index 665f3fc7..37a9634b 100644 --- a/src/app/core/feedback/feedback-flyout/feedback-flyout.component.ts +++ b/src/app/core/feedback/feedback-flyout/feedback-flyout.component.ts @@ -1,6 +1,9 @@ +import { NgIf, NgTemplateOutlet } from '@angular/common'; import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { Router } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import isEmpty from 'lodash/isEmpty'; import { first } from 'rxjs/operators'; @@ -14,7 +17,9 @@ import { FeedbackService } from '../feedback.service'; @Component({ selector: 'app-feedback-flyout', templateUrl: './feedback-flyout.component.html', - styleUrls: ['./feedback-flyout.component.scss'] + styleUrls: ['./feedback-flyout.component.scss'], + standalone: true, + imports: [FlyoutComponent, NgIf, FormsModule, NgTemplateOutlet, NgSelectModule] }) export class FeedbackFlyoutComponent implements OnInit { @ViewChild(FlyoutComponent) flyout?: FlyoutComponent; diff --git a/src/app/core/feedback/feedback-flyout/feedback-flyout.spec.ts b/src/app/core/feedback/feedback-flyout/feedback-flyout.spec.ts index 4decc8b9..30ce4bf6 100644 --- a/src/app/core/feedback/feedback-flyout/feedback-flyout.spec.ts +++ b/src/app/core/feedback/feedback-flyout/feedback-flyout.spec.ts @@ -1,13 +1,10 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; -import { BrowserModule, By } from '@angular/platform-browser'; +import { By } from '@angular/platform-browser'; import { Router } from '@angular/router'; -import { NgSelectModule } from '@ng-select/ng-select'; import { AsyncSubject } from 'rxjs'; -import { FlyoutComponent } from '../../../common/flyout/flyout.component'; import { ConfigService } from '../../config.service'; import { FeedbackService } from '../feedback.service'; import { FeedbackFlyoutComponent } from './feedback-flyout.component'; @@ -29,8 +26,7 @@ describe('FeedbackFlyoutComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [FeedbackFlyoutComponent, FlyoutComponent], - imports: [BrowserModule, FormsModule, NgSelectModule], + imports: [FeedbackFlyoutComponent], providers: [ { provide: Router, useValue: { url: 'test-url' } }, { provide: ConfigService, useValue: { getConfig: () => configSubject$ } }, diff --git a/src/app/core/feedback/feedback-modal/feedback-modal.component.ts b/src/app/core/feedback/feedback-modal/feedback-modal.component.ts index 68201165..d37be2aa 100644 --- a/src/app/core/feedback/feedback-modal/feedback-modal.component.ts +++ b/src/app/core/feedback/feedback-modal/feedback-modal.component.ts @@ -1,11 +1,15 @@ +import { NgIf, NgTemplateOutlet } from '@angular/common'; import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { Router } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import isEmpty from 'lodash/isEmpty'; import { BsModalRef } from 'ngx-bootstrap/modal'; import { first } from 'rxjs/operators'; +import { ModalComponent } from '../../../common/modal/modal/modal.component'; import { ConfigService } from '../../config.service'; import { Feedback } from '../feedback.model'; import { FeedbackService } from '../feedback.service'; @@ -13,7 +17,9 @@ import { FeedbackService } from '../feedback.service'; @UntilDestroy() @Component({ templateUrl: 'feedback-modal.component.html', - styleUrls: ['feedback-modal.component.scss'] + styleUrls: ['feedback-modal.component.scss'], + standalone: true, + imports: [ModalComponent, FormsModule, NgIf, NgTemplateOutlet, NgSelectModule] }) export class FeedbackModalComponent implements OnInit { error: string | null = null; diff --git a/src/app/core/feedback/feedback.module.ts b/src/app/core/feedback/feedback.module.ts deleted file mode 100644 index a89405d4..00000000 --- a/src/app/core/feedback/feedback.module.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; - -import { FlyoutModule } from '../../common/flyout.module'; -import { ModalModule } from '../../common/modal.module'; -import { FeedbackFlyoutComponent } from './feedback-flyout/feedback-flyout.component'; -import { FeedbackModalComponent } from './feedback-modal/feedback-modal.component'; - -@NgModule({ - imports: [TooltipModule, NgSelectModule, CommonModule, FormsModule, FlyoutModule, ModalModule], - exports: [FeedbackModalComponent, FeedbackFlyoutComponent], - declarations: [FeedbackModalComponent, FeedbackFlyoutComponent] -}) -export class FeedbackModule {} diff --git a/src/app/core/help/getting-started/external-links.component.ts b/src/app/core/help/getting-started/external-links.component.ts index f9772516..35236241 100644 --- a/src/app/core/help/getting-started/external-links.component.ts +++ b/src/app/core/help/getting-started/external-links.component.ts @@ -1,3 +1,4 @@ +import { NgFor } from '@angular/common'; import { Component, Input } from '@angular/core'; import { UntilDestroy } from '@ngneat/until-destroy'; @@ -5,7 +6,9 @@ import { UntilDestroy } from '@ngneat/until-destroy'; @UntilDestroy() @Component({ selector: 'external-links', - templateUrl: 'external-links.component.html' + templateUrl: 'external-links.component.html', + standalone: true, + imports: [NgFor] }) export class ExternalLinksComponent { @Input() diff --git a/src/app/core/help/getting-started/getting-started-help.component.ts b/src/app/core/help/getting-started/getting-started-help.component.ts index 02b81f67..67ca4fff 100644 --- a/src/app/core/help/getting-started/getting-started-help.component.ts +++ b/src/app/core/help/getting-started/getting-started-help.component.ts @@ -1,14 +1,17 @@ +import { NgIf } from '@angular/common'; import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { first } from 'rxjs/operators'; -import { ConfigService } from '../../../core/config.service'; -import { HelpTopics } from '../help-topic.component'; +import { ConfigService } from '../../config.service'; +import { ExternalLinksComponent } from './external-links.component'; @UntilDestroy() @Component({ - templateUrl: 'getting-started-help.component.html' + templateUrl: 'getting-started-help.component.html', + standalone: true, + imports: [NgIf, ExternalLinksComponent] }) export class GettingStartedHelpComponent implements OnInit { @Output() readonly backEvent = new EventEmitter(); @@ -36,4 +39,3 @@ export class GettingStartedHelpComponent implements OnInit { this.backEvent.emit({}); } } -HelpTopics.registerTopic('getting-started', GettingStartedHelpComponent, 0); diff --git a/src/app/core/help/help-routes.ts b/src/app/core/help/help-routes.ts new file mode 100644 index 00000000..f17b96ef --- /dev/null +++ b/src/app/core/help/help-routes.ts @@ -0,0 +1,32 @@ +import { ActivatedRouteSnapshot, ResolveFn, Routes } from '@angular/router'; + +import { HelpTopicWrapperComponent } from './help-topic-wrapper.component'; +import { HelpTopics } from './help-topic.component'; +import { HelpComponent } from './help.component'; + +const breadcrumbResolver: ResolveFn = (route: ActivatedRouteSnapshot) => + HelpTopics.getTopicTitle(route.params['topic']); + +export const HELP_ROUTES: Routes = [ + { + path: '', + component: HelpComponent, + children: [ + /** + * Default Route + */ + { + path: '', + redirectTo: 'getting-started', + pathMatch: 'full' + }, + { + path: ':topic', + component: HelpTopicWrapperComponent, + resolve: { + breadcrumb: breadcrumbResolver + } + } + ] + } +]; diff --git a/src/app/core/help/help-routing.module.ts b/src/app/core/help/help-routing.module.ts deleted file mode 100644 index b8c3b655..00000000 --- a/src/app/core/help/help-routing.module.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { NgModule } from '@angular/core'; -import { ActivatedRouteSnapshot, ResolveFn, RouterModule } from '@angular/router'; - -import { HelpTopicWrapperComponent } from './help-topic-wrapper.component'; -import { HelpTopics } from './help-topic.component'; -import { HelpComponent } from './help.component'; - -const breadcrumbResolver: ResolveFn = (route: ActivatedRouteSnapshot) => - HelpTopics.getTopicTitle(route.params['topic']); - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: 'help', - component: HelpComponent, - children: [ - /** - * Default Route - */ - { - path: '', - redirectTo: 'getting-started', - pathMatch: 'full' - }, - { - path: ':topic', - component: HelpTopicWrapperComponent, - resolve: { - breadcrumb: breadcrumbResolver - } - } - ] - } - ]) - ], - exports: [] -}) -export class HelpRoutingModule {} diff --git a/src/app/core/help/help-topic-wrapper.component.ts b/src/app/core/help/help-topic-wrapper.component.ts index 18df72e9..07e2f533 100644 --- a/src/app/core/help/help-topic-wrapper.component.ts +++ b/src/app/core/help/help-topic-wrapper.component.ts @@ -3,11 +3,15 @@ import { ActivatedRoute, Params } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { HelpTopicComponent } from './help-topic.component'; + const defaultKey = 'getting-started'; @UntilDestroy() @Component({ - template: '' + template: '', + standalone: true, + imports: [HelpTopicComponent] }) export class HelpTopicWrapperComponent { key: string = defaultKey; diff --git a/src/app/core/help/help-topic.component.ts b/src/app/core/help/help-topic.component.ts index f16f1c3a..bcaba103 100644 --- a/src/app/core/help/help-topic.component.ts +++ b/src/app/core/help/help-topic.component.ts @@ -32,7 +32,8 @@ export class HelpTopics { @Component({ selector: 'help-topic', - template: '
' + template: '
', + standalone: true }) export class HelpTopicComponent { @ViewChild('content', { read: ViewContainerRef, static: true }) content?: ViewContainerRef; diff --git a/src/app/core/help/help.component.ts b/src/app/core/help/help.component.ts index 019f7f21..2252431d 100644 --- a/src/app/core/help/help.component.ts +++ b/src/app/core/help/help.component.ts @@ -1,9 +1,19 @@ +import { NgFor } from '@angular/common'; import { Component } from '@angular/core'; -import { ActivatedRoute, Event, NavigationEnd, Router } from '@angular/router'; +import { + ActivatedRoute, + Event, + NavigationEnd, + Router, + RouterLink, + RouterLinkActive, + RouterOutlet +} from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { filter } from 'rxjs/operators'; +import { BreadcrumbComponent } from '../../common/breadcrumb/breadcrumb.component'; import { Breadcrumb, BreadcrumbService } from '../../common/breadcrumb/breadcrumb.service'; import { HelpTopics } from './help-topic.component'; @@ -15,7 +25,9 @@ export interface HelpTopic { @UntilDestroy() @Component({ templateUrl: 'help.component.html', - styleUrls: ['help.component.scss'] + styleUrls: ['help.component.scss'], + standalone: true, + imports: [BreadcrumbComponent, NgFor, RouterLinkActive, RouterLink, RouterOutlet] }) export class HelpComponent { helpTopics: HelpTopic[] = []; diff --git a/src/app/core/help/help.module.ts b/src/app/core/help/help.module.ts deleted file mode 100644 index 960b95e1..00000000 --- a/src/app/core/help/help.module.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { ApplicationModule, NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; - -import { BreadcrumbModule } from '../../common/breadcrumb.module'; -import { ExternalLinksComponent } from './getting-started/external-links.component'; -import { GettingStartedHelpComponent } from './getting-started/getting-started-help.component'; -import { HelpRoutingModule } from './help-routing.module'; -import { HelpTopicWrapperComponent } from './help-topic-wrapper.component'; -import { HelpTopicComponent, HelpTopics } from './help-topic.component'; -import { HelpComponent } from './help.component'; - -@NgModule({ - imports: [ - ApplicationModule, - BreadcrumbModule, - HelpRoutingModule, - - CommonModule, - FormsModule, - RouterModule - ], - exports: [], - declarations: [ - ExternalLinksComponent, - GettingStartedHelpComponent, - HelpComponent, - HelpTopicComponent, - HelpTopicWrapperComponent - ], - providers: [HelpTopics, GettingStartedHelpComponent] -}) -export class HelpModule {} diff --git a/src/app/core/masquerade/masquerade-routing.module.ts b/src/app/core/masquerade/masquerade-routing.module.ts deleted file mode 100644 index e8a77eab..00000000 --- a/src/app/core/masquerade/masquerade-routing.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { MasqueradeComponent } from './masquerade/masquerade.component'; - -@NgModule({ - imports: [ - CommonModule, - RouterModule.forChild([ - { - path: 'masquerade', - component: MasqueradeComponent - } - ]) - ], - exports: [RouterModule], - declarations: [] -}) -export class MasqueradeRoutingModule {} diff --git a/src/app/core/masquerade/masquerade.interceptor.ts b/src/app/core/masquerade/masquerade.interceptor.ts index e26c064a..6850ddea 100644 --- a/src/app/core/masquerade/masquerade.interceptor.ts +++ b/src/app/core/masquerade/masquerade.interceptor.ts @@ -1,44 +1,37 @@ -import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; +import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http'; +import { inject } from '@angular/core'; -import { Observable } from 'rxjs'; -import { first } from 'rxjs/operators'; +import { Observable, switchMap } from 'rxjs'; +import { first, map } from 'rxjs/operators'; import { ConfigService } from '../config.service'; import { MasqueradeService } from './masquerade.service'; +const DEFAULT_HEADER: string = 'x-masquerade-user-dn'; + /** - * HTTP Interceptor that will add Masquerade related + * HTTP Interceptor that will add Masquerade related headers */ -@Injectable() -export class MasqueradeInterceptor implements HttpInterceptor { - private masqueradeHeader = 'x-masquerade-user-dn'; - - constructor( - private router: Router, - private masqueradeService: MasqueradeService, - private configService: ConfigService - ) { - this.configService +// eslint-disable-next-line rxjs/finnish +export function masqueradeInterceptor( + req: HttpRequest, + next: HttpHandlerFn +): Observable> { + const masqDn = inject(MasqueradeService).getMasqueradeDn(); + if (masqDn) { + return inject(ConfigService) .getConfig() - .pipe(first()) - .subscribe((config) => { - if (config?.masqueradeHeader) { - this.masqueradeHeader = config.masqueradeHeader; - } - }); - } - - intercept(req: HttpRequest, next: HttpHandler): Observable> { - const masqDn = this.masqueradeService.getMasqueradeDn(); - if (masqDn) { - req = req.clone({ - setHeaders: { - [this.masqueradeHeader]: masqDn - } - }); - } - return next.handle(req); + .pipe( + first(), + map((config) => + req.clone({ + setHeaders: { + [config?.masqueradeHeader ?? DEFAULT_HEADER]: masqDn ?? '' + } + }) + ), + switchMap((masReq) => next(masReq)) + ); } + return next(req); } diff --git a/src/app/core/masquerade/masquerade.module.ts b/src/app/core/masquerade/masquerade.module.ts deleted file mode 100644 index 1dcf5a50..00000000 --- a/src/app/core/masquerade/masquerade.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { HTTP_INTERCEPTORS } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; - -import { LoadingSpinnerModule } from '../../common/loading-spinner.module'; -import { MasqueradeRoutingModule } from './masquerade-routing.module'; -import { MasqueradeInterceptor } from './masquerade.interceptor'; -import { MasqueradeService } from './masquerade.service'; -import { MasqueradeComponent } from './masquerade/masquerade.component'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - NgSelectModule, - MasqueradeRoutingModule, - LoadingSpinnerModule - ], - declarations: [MasqueradeComponent], - providers: [ - MasqueradeService, - { provide: HTTP_INTERCEPTORS, useClass: MasqueradeInterceptor, multi: true } - ] -}) -export class MasqueradeModule {} diff --git a/src/app/core/masquerade/masquerade.service.ts b/src/app/core/masquerade/masquerade.service.ts index 75f5b22c..6af63606 100644 --- a/src/app/core/masquerade/masquerade.service.ts +++ b/src/app/core/masquerade/masquerade.service.ts @@ -8,7 +8,7 @@ import { NULL_PAGING_RESULTS, PagingResults } from '../../common/paging.model'; import { LocalStorageService } from '../../common/storage/local-storage.service'; import { User } from '../auth/user.model'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class MasqueradeService { LOCAL_STORAGE_KEY = 'MASQ_DN'; diff --git a/src/app/core/masquerade/masquerade/masquerade.component.ts b/src/app/core/masquerade/masquerade/masquerade.component.ts index 640bc644..731070f6 100644 --- a/src/app/core/masquerade/masquerade/masquerade.component.ts +++ b/src/app/core/masquerade/masquerade/masquerade.component.ts @@ -1,6 +1,9 @@ +import { AsyncPipe, NgIf } from '@angular/common'; import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { Router } from '@angular/router'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Observable, Subject, concat, of } from 'rxjs'; import { @@ -12,6 +15,7 @@ import { tap } from 'rxjs/operators'; +import { LoadingSpinnerComponent } from '../../../common/loading-spinner/loading-spinner.component'; import { isNotNullOrUndefined } from '../../../common/rxjs-utils'; import { SessionService } from '../../auth/session.service'; import { User } from '../../auth/user.model'; @@ -19,7 +23,9 @@ import { MasqueradeService } from '../masquerade.service'; @UntilDestroy() @Component({ - templateUrl: './masquerade.component.html' + templateUrl: './masquerade.component.html', + standalone: true, + imports: [NgIf, LoadingSpinnerComponent, FormsModule, NgSelectModule, AsyncPipe] }) export class MasqueradeComponent implements OnInit { usersLoading = false; diff --git a/src/app/core/messages/messages-routing.module.ts b/src/app/core/messages/messages-routing.module.ts deleted file mode 100644 index 53b482ef..00000000 --- a/src/app/core/messages/messages-routing.module.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { authGuard } from '../auth/auth.guard'; -import { ViewAllMessagesComponent } from './view-all-messages/view-all-messages.component'; - -@NgModule({ - declarations: [], - imports: [ - CommonModule, - RouterModule.forChild([ - { - path: 'messages', - component: ViewAllMessagesComponent, - canActivate: [authGuard], - data: { roles: ['user'] } - } - ]) - ] -}) -export class MessagesRoutingModule {} diff --git a/src/app/core/messages/messages.module.ts b/src/app/core/messages/messages.module.ts deleted file mode 100644 index e83076b2..00000000 --- a/src/app/core/messages/messages.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { PipesModule } from '../../common/pipes.module'; -import { SearchInputModule } from '../../common/search-input.module'; -import { SystemAlertModule } from '../../common/system-alert.module'; -import { MessagesRoutingModule } from './messages-routing.module'; -import { RecentMessagesComponent } from './recent-messages/recent-messages.component'; -import { ViewAllMessagesComponent } from './view-all-messages/view-all-messages.component'; - -@NgModule({ - imports: [ - CommonModule, - PipesModule, - MessagesRoutingModule, - RouterModule, - SystemAlertModule, - SearchInputModule - ], - exports: [RecentMessagesComponent], - declarations: [ViewAllMessagesComponent, RecentMessagesComponent] -}) -export class MessagesModule {} diff --git a/src/app/core/messages/recent-messages/recent-messages.component.spec.ts b/src/app/core/messages/recent-messages/recent-messages.component.spec.ts index d7b7c3de..e3ccdbd9 100644 --- a/src/app/core/messages/recent-messages/recent-messages.component.spec.ts +++ b/src/app/core/messages/recent-messages/recent-messages.component.spec.ts @@ -1,12 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { BehaviorSubject, Subject, of } from 'rxjs'; -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; import { Message, MessageType } from '../message.model'; import { MessageService } from '../message.service'; import { RecentMessagesComponent } from './recent-messages.component'; @@ -44,14 +39,7 @@ describe('Recent Messages Component Spec', () => { }); TestBed.configureTestingModule({ - declarations: [RecentMessagesComponent], - imports: [ - FormsModule, - RouterTestingModule, - PipesModule, - SearchInputModule, - SystemAlertModule - ], + imports: [RecentMessagesComponent], providers: [{ provide: MessageService, useValue: messageServiceSpy }] }); diff --git a/src/app/core/messages/recent-messages/recent-messages.component.ts b/src/app/core/messages/recent-messages/recent-messages.component.ts index 59e6a43b..f1587089 100644 --- a/src/app/core/messages/recent-messages/recent-messages.component.ts +++ b/src/app/core/messages/recent-messages/recent-messages.component.ts @@ -1,3 +1,4 @@ +import { LowerCasePipe, NgClass, NgFor, NgIf } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @@ -11,7 +12,9 @@ import { MessageService } from '../message.service'; @Component({ selector: 'app-recent-messages', templateUrl: './recent-messages.component.html', - styleUrls: ['./recent-messages.component.scss'] + styleUrls: ['./recent-messages.component.scss'], + standalone: true, + imports: [NgIf, NgFor, NgClass, LowerCasePipe] }) export class RecentMessagesComponent implements OnInit { @Input() container: any; diff --git a/src/app/core/messages/view-all-messages/view-all-messages.component.spec.ts b/src/app/core/messages/view-all-messages/view-all-messages.component.spec.ts index 4c8e7fb3..e5e169b7 100644 --- a/src/app/core/messages/view-all-messages/view-all-messages.component.spec.ts +++ b/src/app/core/messages/view-all-messages/view-all-messages.component.spec.ts @@ -1,13 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { Subject, of } from 'rxjs'; import { PagingResults } from '../../../common/paging.model'; -import { PipesModule } from '../../../common/pipes.module'; -import { SearchInputModule } from '../../../common/search-input.module'; -import { SystemAlertModule } from '../../../common/system-alert.module'; import { Message, MessageType } from '../message.model'; import { MessageService } from '../message.service'; import { ViewAllMessagesComponent } from './view-all-messages.component'; @@ -52,14 +47,7 @@ describe('View All Messages Component Spec', () => { }); TestBed.configureTestingModule({ - declarations: [ViewAllMessagesComponent], - imports: [ - FormsModule, - RouterTestingModule, - PipesModule, - SearchInputModule, - SystemAlertModule - ], + imports: [ViewAllMessagesComponent], providers: [{ provide: MessageService, useValue: messageServiceSpy }] }); diff --git a/src/app/core/messages/view-all-messages/view-all-messages.component.ts b/src/app/core/messages/view-all-messages/view-all-messages.component.ts index 9aca3d12..c17f5180 100644 --- a/src/app/core/messages/view-all-messages/view-all-messages.component.ts +++ b/src/app/core/messages/view-all-messages/view-all-messages.component.ts @@ -1,10 +1,13 @@ +import { LowerCasePipe, NgClass, NgFor, NgIf } from '@angular/common'; import { Component, HostListener, OnInit, ViewChild } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { PagingOptions, PagingResults } from '../../../common/paging.model'; +import { AgoDatePipe } from '../../../common/pipes/ago-date.pipe'; import { SearchInputComponent } from '../../../common/search-input/search-input.component'; import { SortDirection } from '../../../common/sorting.model'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { Message, MessageType } from '../message.model'; import { MessageService } from '../message.service'; @@ -12,7 +15,17 @@ import { MessageService } from '../message.service'; @Component({ selector: 'app-view-all-messages', templateUrl: './view-all-messages.component.html', - styleUrls: ['./view-all-messages.component.scss'] + styleUrls: ['./view-all-messages.component.scss'], + standalone: true, + imports: [ + SystemAlertComponent, + SearchInputComponent, + NgIf, + NgFor, + NgClass, + LowerCasePipe, + AgoDatePipe + ] }) export class ViewAllMessagesComponent implements OnInit { pageNumber = 0; diff --git a/src/app/core/provider.ts b/src/app/core/provider.ts new file mode 100644 index 00000000..e7a3607a --- /dev/null +++ b/src/app/core/provider.ts @@ -0,0 +1,98 @@ +import { APP_INITIALIZER, makeEnvironmentProviders } from '@angular/core'; +import { ROUTES } from '@angular/router'; + +import { firstValueFrom } from 'rxjs'; +import { tap } from 'rxjs/operators'; + +import { AdminTopics } from '../common/admin/admin-topic.model'; +import { ConfigService } from './config.service'; +import { CORE_ROUTES } from './core-routes'; +import { GettingStartedHelpComponent } from './help/getting-started/getting-started-help.component'; +import { HelpTopics } from './help/help-topic.component'; +import { NavigationService } from './navigation.service'; +import { TeamsHelpComponent } from './teams/help/teams-help.component'; + +export function provideCoreRoutes() { + // Registering Topics here. Need to find better alternative for this. + HelpTopics.registerTopic('getting-started', GettingStartedHelpComponent, 0); + HelpTopics.registerTopic('teams', TeamsHelpComponent, 9); + + AdminTopics.registerTopic({ + id: 'users', + title: 'User', + ordinal: 0, + path: 'users' + }); + + AdminTopics.registerTopic({ + id: 'cache-entries', + title: 'Cache Entries', + ordinal: 1, + path: 'cacheEntries' + }); + + AdminTopics.registerTopic({ + id: 'end-user-agreements', + title: 'EUAs', + ordinal: 2, + path: 'euas' + }); + + AdminTopics.registerTopic({ + id: 'messages', + title: 'Messages', + ordinal: 3, + path: 'messages' + }); + + AdminTopics.registerTopic({ + id: 'feedback', + title: 'Feedback', + ordinal: 4, + path: 'feedback' + }); + + return makeEnvironmentProviders([ + { + provide: ROUTES, + multi: true, + useValue: CORE_ROUTES + } + ]); +} +export function provideAppConfig() { + return makeEnvironmentProviders([ + { + provide: APP_INITIALIZER, + useFactory: (configService: ConfigService) => { + return () => + firstValueFrom( + configService.getConfig().pipe( + tap((config) => { + if (config === null) { + throw new Error('Error loading application configuration.'); + } + }) + ) + ); + }, + deps: [ConfigService], + multi: true + } + ]); +} + +export function provideNavigationService() { + return makeEnvironmentProviders([ + { + provide: APP_INITIALIZER, + useFactory: (navigationService: NavigationService) => { + return () => { + navigationService.init(); + }; + }, + deps: [NavigationService], + multi: true + } + ]); +} diff --git a/src/app/core/signin/signin.component.ts b/src/app/core/signin/signin.component.ts index 4ecfe91a..50dbba56 100644 --- a/src/app/core/signin/signin.component.ts +++ b/src/app/core/signin/signin.component.ts @@ -1,9 +1,13 @@ +import { NgIf } from '@angular/common'; import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { first } from 'rxjs/operators'; +import { LoadingSpinnerComponent } from '../../common/loading-spinner/loading-spinner.component'; import { SessionService } from '../auth/session.service'; import { ConfigService } from '../config.service'; import { NavigationService } from '../navigation.service'; @@ -11,7 +15,9 @@ import { NavigationService } from '../navigation.service'; @UntilDestroy() @Component({ templateUrl: 'signin.component.html', - styleUrls: ['signin.component.scss'] + styleUrls: ['signin.component.scss'], + standalone: true, + imports: [NgIf, LoadingSpinnerComponent, FormsModule, RouterLink] }) export class SigninComponent implements OnInit { loaded = false; diff --git a/src/app/core/signup/signed-up.component.ts b/src/app/core/signup/signed-up.component.ts index 1b237a46..4133799c 100644 --- a/src/app/core/signup/signed-up.component.ts +++ b/src/app/core/signup/signed-up.component.ts @@ -1,7 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: 'signed-up.component.html' + templateUrl: 'signed-up.component.html', + standalone: true, + imports: [RouterLink] }) export class SignedUpComponent {} diff --git a/src/app/core/signup/signup.component.ts b/src/app/core/signup/signup.component.ts index a63530bb..c0bab9cc 100644 --- a/src/app/core/signup/signup.component.ts +++ b/src/app/core/signup/signup.component.ts @@ -1,9 +1,13 @@ +import { NgFor, NgIf } from '@angular/common'; import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Params, RouterLink } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable } from 'rxjs'; +import { SystemAlertComponent } from '../../common/system-alert/system-alert.component'; import { ManageUserComponent } from '../admin/user-management/manage-user.component'; import { AuthenticationService } from '../auth/authentication.service'; import { User } from '../auth/user.model'; @@ -11,7 +15,9 @@ import { User } from '../auth/user.model'; @UntilDestroy() @Component({ selector: 'user-signup', - templateUrl: '../admin/user-management/manage-user.component.html' + templateUrl: '../admin/user-management/manage-user.component.html', + standalone: true, + imports: [NgIf, RouterLink, SystemAlertComponent, FormsModule, NgFor, TooltipModule] }) export class SignupComponent extends ManageUserComponent implements OnInit { mode = 'signup'; diff --git a/src/app/core/site-container/site-container.component.ts b/src/app/core/site-container/site-container.component.ts index 6dc58c01..d12fb143 100644 --- a/src/app/core/site-container/site-container.component.ts +++ b/src/app/core/site-container/site-container.component.ts @@ -1,15 +1,21 @@ +import { NgIf } from '@angular/common'; import { Component } from '@angular/core'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { first } from 'rxjs/operators'; +import { IsAuthenticatedDirective } from '../auth/directives/is-authenticated.directive'; import { ConfigService } from '../config.service'; +import { FeedbackFlyoutComponent } from '../feedback/feedback-flyout/feedback-flyout.component'; +import { SiteNavbarComponent } from '../site-navbar/site-navbar.component'; @UntilDestroy() @Component({ selector: 'site-container', templateUrl: 'site-container.component.html', - styleUrls: ['site-container.component.scss'] + styleUrls: ['site-container.component.scss'], + standalone: true, + imports: [NgIf, SiteNavbarComponent, IsAuthenticatedDirective, FeedbackFlyoutComponent] }) export class SiteContainerComponent { bannerHtml?: string; diff --git a/src/app/core/site-navbar/site-navbar.component.html b/src/app/core/site-navbar/site-navbar.component.html index 5715b271..e1ad2a56 100644 --- a/src/app/core/site-navbar/site-navbar.component.html +++ b/src/app/core/site-navbar/site-navbar.component.html @@ -94,7 +94,7 @@ container="body" [isDisabled]="navbarOpen" routerLinkActive="active-link" - routerLink="/teams" + routerLink="/team" > Teams diff --git a/src/app/core/site-navbar/site-navbar.component.spec.ts b/src/app/core/site-navbar/site-navbar.component.spec.ts index 3460d49a..015efbee 100644 --- a/src/app/core/site-navbar/site-navbar.component.spec.ts +++ b/src/app/core/site-navbar/site-navbar.component.spec.ts @@ -1,19 +1,13 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; import { ModalModule } from 'ngx-bootstrap/modal'; -import { PopoverDirective, PopoverModule } from 'ngx-bootstrap/popover'; -import { TooltipModule } from 'ngx-bootstrap/tooltip'; +import { PopoverDirective } from 'ngx-bootstrap/popover'; import { of } from 'rxjs'; import { AuthorizationService } from '../auth/authorization.service'; -import { HasRoleDirective } from '../auth/directives/has-role.directive'; -import { HasSomeRolesDirective } from '../auth/directives/has-some-roles.directive'; -import { IsAuthenticatedDirective } from '../auth/directives/is-authenticated.directive'; import { SessionService } from '../auth/session.service'; import { Config } from '../config.model'; import { ConfigService } from '../config.service'; @@ -82,22 +76,8 @@ describe('Site Navbar Component Spec', () => { masqServiceSpy.getMasqueradeDn.and.returnValue(undefined); TestBed.configureTestingModule({ - declarations: [ - SiteNavbarComponent, - IsAuthenticatedDirective, - HasRoleDirective, - HasSomeRolesDirective, - PopoverDirective - ], - imports: [ - HttpClientTestingModule, - BsDatepickerModule, - ModalModule.forRoot(), - TooltipModule, - PopoverModule, - FormsModule, - RouterTestingModule - ], + declarations: [PopoverDirective], + imports: [HttpClientTestingModule, ModalModule.forRoot(), RouterTestingModule], providers: [ { provide: AuthorizationService, useValue: authorizationServiceSpy }, { provide: ConfigService, useValue: configServiceSpy }, diff --git a/src/app/core/site-navbar/site-navbar.component.ts b/src/app/core/site-navbar/site-navbar.component.ts index 4667824d..0100c47f 100644 --- a/src/app/core/site-navbar/site-navbar.component.ts +++ b/src/app/core/site-navbar/site-navbar.component.ts @@ -1,23 +1,47 @@ +import { NgClass, NgFor, NgIf } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { RouterLink, RouterLinkActive } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { BsModalService } from 'ngx-bootstrap/modal'; +import { PopoverModule } from 'ngx-bootstrap/popover'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { first } from 'rxjs/operators'; import { AdminTopic, AdminTopics } from '../../common/admin/admin-topic.model'; +import { LinkAccessibilityDirective } from '../../common/directives/link-accessibility.directive'; +import { HasRoleDirective } from '../auth/directives/has-role.directive'; +import { HasSomeRolesDirective } from '../auth/directives/has-some-roles.directive'; +import { IsAuthenticatedDirective } from '../auth/directives/is-authenticated.directive'; import { Session } from '../auth/session.model'; import { SessionService } from '../auth/session.service'; import { ConfigService } from '../config.service'; import { FeedbackModalComponent } from '../feedback/feedback-modal/feedback-modal.component'; import { MasqueradeService } from '../masquerade/masquerade.service'; import { MessageService } from '../messages/message.service'; +import { RecentMessagesComponent } from '../messages/recent-messages/recent-messages.component'; import { NavbarTopic, NavbarTopics } from './navbar-topic.model'; @UntilDestroy() @Component({ selector: 'site-navbar', templateUrl: 'site-navbar.component.html', - styleUrls: ['site-navbar.component.scss'] + styleUrls: ['site-navbar.component.scss'], + standalone: true, + imports: [ + NgClass, + NgFor, + NgIf, + HasSomeRolesDirective, + RouterLinkActive, + TooltipModule, + RouterLink, + HasRoleDirective, + LinkAccessibilityDirective, + PopoverModule, + IsAuthenticatedDirective, + RecentMessagesComponent + ] }) export class SiteNavbarComponent implements OnInit { navbarOpenValue = false; diff --git a/src/app/core/teams/add-members-modal/add-members-modal.component.ts b/src/app/core/teams/add-members-modal/add-members-modal.component.ts index 52236a04..2a694898 100644 --- a/src/app/core/teams/add-members-modal/add-members-modal.component.ts +++ b/src/app/core/teams/add-members-modal/add-members-modal.component.ts @@ -1,11 +1,15 @@ +import { AsyncPipe, NgFor, NgIf } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { NgSelectComponent } from '@ng-select/ng-select'; +import { NgSelectComponent, NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { BsModalRef } from 'ngx-bootstrap/modal'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { Observable, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, startWith, switchMap, tap } from 'rxjs/operators'; +import { ModalComponent } from '../../../common/modal/modal/modal.component'; import { PagingOptions } from '../../../common/paging.model'; import { User } from '../../auth/user.model'; import { TeamRole } from '../team-role.model'; @@ -21,6 +25,16 @@ import { AddedMember, TeamsService } from '../teams.service'; display: contents; } ` + ], + standalone: true, + imports: [ + ModalComponent, + NgSelectModule, + NgIf, + NgFor, + BsDropdownModule, + TooltipModule, + AsyncPipe ] }) export class AddMembersModalComponent implements OnInit { diff --git a/src/app/core/teams/create-team/create-team.component.html b/src/app/core/teams/create-team/create-team.component.html index 20fd2621..0bdde87b 100644 --- a/src/app/core/teams/create-team/create-team.component.html +++ b/src/app/core/teams/create-team/create-team.component.html @@ -1,6 +1,6 @@
- + Back to Teams @@ -147,7 +147,7 @@

- +
- ` + `, + standalone: true }) export class UnauthorizedComponent { title = `ಠ_ಠ

Not Authorized`; diff --git a/src/app/site/example/admin/admin-example.component.ts b/src/app/site/example/admin/admin-example.component.ts index 078836bf..cbcce743 100644 --- a/src/app/site/example/admin/admin-example.component.ts +++ b/src/app/site/example/admin/admin-example.component.ts @@ -4,7 +4,8 @@ import { AdminTopics } from '../../../common/admin/admin-topic.model'; @Component({ selector: 'app-admin-example', - templateUrl: './admin-example.component.html' + templateUrl: './admin-example.component.html', + standalone: true }) export class AdminExampleComponent {} diff --git a/src/app/site/example/alerts/alerts.component.ts b/src/app/site/example/alerts/alerts.component.ts index 3e4d3ace..ea9bb52b 100644 --- a/src/app/site/example/alerts/alerts.component.ts +++ b/src/app/site/example/alerts/alerts.component.ts @@ -2,12 +2,15 @@ import { Component, OnInit } from '@angular/core'; import { UntilDestroy } from '@ngneat/until-destroy'; +import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component'; import { SystemAlertService } from '../../../common/system-alert/system-alert.service'; import { NavbarTopics } from '../../../core/site-navbar/navbar-topic.model'; @UntilDestroy() @Component({ - templateUrl: './alerts.component.html' + templateUrl: './alerts.component.html', + standalone: true, + imports: [SystemAlertComponent] }) export class AlertsComponent implements OnInit { constructor(public alertService: SystemAlertService) {} diff --git a/src/app/site/example/example-routes.ts b/src/app/site/example/example-routes.ts new file mode 100644 index 00000000..125ff9ff --- /dev/null +++ b/src/app/site/example/example-routes.ts @@ -0,0 +1,73 @@ +import { Routes } from '@angular/router'; + +import { AdminComponent } from '../../common/admin/admin.component'; +import { authGuard } from '../../core/auth/auth.guard'; +import { AdminExampleComponent } from './admin/admin-example.component'; +import { AlertsComponent } from './alerts/alerts.component'; +import { ExploreComponent } from './explore.component'; +import { FormsComponent } from './forms/forms.component'; +import { GridComponent } from './grid/grid.component'; +import { ExampleLoadingOverlayComponent } from './loading-overlay/example-loading-overlay.component'; +import { ModalComponent } from './modal/modal.component'; +import { SearchComponent } from './search.component'; +import { WelcomeComponent } from './welcome.component'; + +export const EXAMPLE_ROUTES: Routes = [ + { + path: '', + redirectTo: '/welcome', + pathMatch: 'full' + }, + { + path: 'welcome', + component: WelcomeComponent, + canActivate: [authGuard] + }, + { + path: 'explore', + component: ExploreComponent, + canActivate: [authGuard] + }, + { + path: 'search', + component: SearchComponent, + canActivate: [authGuard] + }, + { + path: 'forms', + component: FormsComponent, + canActivate: [authGuard] + }, + { + path: 'grid', + component: GridComponent, + canActivate: [authGuard] + }, + { + path: 'modal', + component: ModalComponent, + canActivate: [authGuard] + }, + { + path: 'loading-overlay', + component: ExampleLoadingOverlayComponent, + canActivate: [authGuard] + }, + { + path: 'alerts', + component: AlertsComponent, + canActivate: [authGuard] + }, + { + path: 'admin', + component: AdminComponent, + canActivate: [authGuard], + data: { roles: ['admin'] }, + children: [ + { + path: 'example', + component: AdminExampleComponent + } + ] + } +]; diff --git a/src/app/site/example/example-routing.module.ts b/src/app/site/example/example-routing.module.ts deleted file mode 100644 index a665dd45..00000000 --- a/src/app/site/example/example-routing.module.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { AdminComponent } from '../../common/admin/admin.component'; -import { authGuard } from '../../core/auth/auth.guard'; -import { AdminExampleComponent } from './admin/admin-example.component'; -import { AlertsComponent } from './alerts/alerts.component'; -import { ExploreComponent } from './explore.component'; -import { FormsComponent } from './forms/forms.component'; -import { GridComponent } from './grid/grid.component'; -import { ExampleLoadingOverlayComponent } from './loading-overlay/example-loading-overlay.component'; -import { ModalComponent } from './modal/modal.component'; -import { SearchComponent } from './search.component'; -import { WelcomeComponent } from './welcome.component'; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: '', - redirectTo: '/welcome', - pathMatch: 'full' - }, - { - path: 'welcome', - component: WelcomeComponent, - canActivate: [authGuard] - }, - { - path: 'explore', - component: ExploreComponent, - canActivate: [authGuard] - }, - { - path: 'search', - component: SearchComponent, - canActivate: [authGuard] - }, - { - path: 'forms', - component: FormsComponent, - canActivate: [authGuard] - }, - { - path: 'grid', - component: GridComponent, - canActivate: [authGuard] - }, - { - path: 'modal', - component: ModalComponent, - canActivate: [authGuard] - }, - { - path: 'loading-overlay', - component: ExampleLoadingOverlayComponent, - canActivate: [authGuard] - }, - { - path: 'alerts', - component: AlertsComponent, - canActivate: [authGuard] - }, - { - path: 'admin', - component: AdminComponent, - canActivate: [authGuard], - data: { roles: ['admin'] }, - children: [ - { - path: 'example', - component: AdminExampleComponent - } - ] - } - ]) - ], - exports: [RouterModule] -}) -export class ExampleRoutingModule {} diff --git a/src/app/site/example/example.module.ts b/src/app/site/example/example.module.ts deleted file mode 100644 index a0530262..00000000 --- a/src/app/site/example/example.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { NgSelectModule } from '@ng-select/ng-select'; - -import { AdminModule } from '../../common/admin.module'; -import { LoadingOverlayModule } from '../../common/loading-overlay.module'; -import { ModalModule } from '../../common/modal.module'; -import { SystemAlertModule } from '../../common/system-alert.module'; -import { AdminExampleComponent } from './admin/admin-example.component'; -import { AlertsComponent } from './alerts/alerts.component'; -import { ExampleRoutingModule } from './example-routing.module'; -import { ExploreComponent } from './explore.component'; -import { FormsComponent } from './forms/forms.component'; -import { GridComponent } from './grid/grid.component'; -import { ExampleHelpComponent } from './help/example-help.component'; -import { ExampleLoadingOverlayComponent } from './loading-overlay/example-loading-overlay.component'; -import { FormModalComponent } from './modal/form-modal.component'; -import { ModalComponent } from './modal/modal.component'; -import { SearchComponent } from './search.component'; -import { WelcomeComponent } from './welcome.component'; - -@NgModule({ - imports: [ - FormsModule, - AdminModule, - ExampleRoutingModule, - NgSelectModule, - ModalModule, - LoadingOverlayModule, - CommonModule, - SystemAlertModule - ], - exports: [], - declarations: [ - ExploreComponent, - SearchComponent, - WelcomeComponent, - ExampleHelpComponent, - FormsComponent, - GridComponent, - AdminExampleComponent, - FormModalComponent, - ModalComponent, - ExampleLoadingOverlayComponent, - AlertsComponent - ], - providers: [ExampleHelpComponent] -}) -export class ExampleModule {} diff --git a/src/app/site/example/explore.component.ts b/src/app/site/example/explore.component.ts index 5dfa3d40..1d737b25 100644 --- a/src/app/site/example/explore.component.ts +++ b/src/app/site/example/explore.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; -import { NavbarTopics } from '../../core/core.module'; +import { NavbarTopics } from '../../core/site-navbar/navbar-topic.model'; @Component({ template: ` @@ -12,7 +12,8 @@ import { NavbarTopics } from '../../core/core.module'; - ` + `, + standalone: true }) export class ExploreComponent {} diff --git a/src/app/site/example/forms/forms.component.ts b/src/app/site/example/forms/forms.component.ts index 398c4868..5533bf6d 100644 --- a/src/app/site/example/forms/forms.component.ts +++ b/src/app/site/example/forms/forms.component.ts @@ -1,5 +1,7 @@ import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { NgSelectModule } from '@ng-select/ng-select'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { of } from 'rxjs'; import { delay, first } from 'rxjs/operators'; @@ -9,7 +11,9 @@ import { NavbarTopics } from '../../../core/site-navbar/navbar-topic.model'; @UntilDestroy() @Component({ selector: 'app-forms', - templateUrl: './forms.component.html' + templateUrl: './forms.component.html', + standalone: true, + imports: [FormsModule, NgSelectModule] }) export class FormsComponent { fileSelected($event: Event) { diff --git a/src/app/site/example/grid/grid.component.ts b/src/app/site/example/grid/grid.component.ts index 039d3034..7de84509 100644 --- a/src/app/site/example/grid/grid.component.ts +++ b/src/app/site/example/grid/grid.component.ts @@ -1,11 +1,12 @@ import { Component } from '@angular/core'; -import { NavbarTopics } from '../../../core/core.module'; +import { NavbarTopics } from '../../../core/site-navbar/navbar-topic.model'; @Component({ selector: 'app-grid', templateUrl: './grid.component.html', - styleUrls: ['./grid.component.scss'] + styleUrls: ['./grid.component.scss'], + standalone: true }) export class GridComponent {} diff --git a/src/app/site/example/help/example-help.component.ts b/src/app/site/example/help/example-help.component.ts index 6a6e4960..aa9dd45f 100644 --- a/src/app/site/example/help/example-help.component.ts +++ b/src/app/site/example/help/example-help.component.ts @@ -1,9 +1,7 @@ import { Component } from '@angular/core'; -import { HelpTopics } from '../../../core/help/help-topic.component'; - @Component({ - template: '

Example help content.

' + template: '

Example help content.

', + standalone: true }) export class ExampleHelpComponent {} -HelpTopics.registerTopic('example', ExampleHelpComponent, 7); diff --git a/src/app/site/example/loading-overlay/example-loading-overlay.component.ts b/src/app/site/example/loading-overlay/example-loading-overlay.component.ts index efa0fbba..49dbe9a0 100644 --- a/src/app/site/example/loading-overlay/example-loading-overlay.component.ts +++ b/src/app/site/example/loading-overlay/example-loading-overlay.component.ts @@ -1,10 +1,13 @@ import { Component } from '@angular/core'; +import { LoadingOverlayComponent } from '../../../common/loading-overlay/loading-overlay.component'; import { NavbarTopics } from '../../../core/site-navbar/navbar-topic.model'; @Component({ selector: 'example-loading-overlay', - templateUrl: './example-loading-overlay.component.html' + templateUrl: './example-loading-overlay.component.html', + standalone: true, + imports: [LoadingOverlayComponent] }) export class ExampleLoadingOverlayComponent { isLoading = true; diff --git a/src/app/site/example/modal/form-modal.component.ts b/src/app/site/example/modal/form-modal.component.ts index 406c52ba..da31170c 100644 --- a/src/app/site/example/modal/form-modal.component.ts +++ b/src/app/site/example/modal/form-modal.component.ts @@ -4,10 +4,13 @@ import { UntilDestroy } from '@ngneat/until-destroy'; import { BsModalRef } from 'ngx-bootstrap/modal'; import { AbstractModalizableDirective } from '../../../common/modal/abstract-modalizable.directive'; +import { FormsComponent } from '../forms/forms.component'; @UntilDestroy() @Component({ - templateUrl: 'form-modal.component.html' + templateUrl: 'form-modal.component.html', + standalone: true, + imports: [FormsComponent] }) export class FormModalComponent extends AbstractModalizableDirective { modalRef = inject(BsModalRef); diff --git a/src/app/site/example/modal/modal.component.ts b/src/app/site/example/modal/modal.component.ts index 52148288..d056bd25 100644 --- a/src/app/site/example/modal/modal.component.ts +++ b/src/app/site/example/modal/modal.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { ModalConfig } from '../../../common/modal/modal.model'; import { ModalService } from '../../../common/modal/modal.service'; @@ -7,7 +8,9 @@ import { FormModalComponent } from './form-modal.component'; @Component({ selector: 'app-modal', - templateUrl: './modal.component.html' + templateUrl: './modal.component.html', + standalone: true, + imports: [FormsModule] }) export class ModalComponent { constructor(public modalService: ModalService) {} diff --git a/src/app/site/example/provider.ts b/src/app/site/example/provider.ts new file mode 100644 index 00000000..3126e792 --- /dev/null +++ b/src/app/site/example/provider.ts @@ -0,0 +1,19 @@ +import { makeEnvironmentProviders } from '@angular/core'; +import { ROUTES } from '@angular/router'; + +import { HelpTopics } from '../../core/help/help-topic.component'; +import { EXAMPLE_ROUTES } from './example-routes'; +import { ExampleHelpComponent } from './help/example-help.component'; + +export function provideExampleRoutes() { + // Registering Topics here. Need to find better alternative for this. + HelpTopics.registerTopic('example', ExampleHelpComponent, 7); + + return makeEnvironmentProviders([ + { + provide: ROUTES, + multi: true, + useValue: EXAMPLE_ROUTES + } + ]); +} diff --git a/src/app/site/example/search.component.ts b/src/app/site/example/search.component.ts index 3c387ed9..0998a871 100644 --- a/src/app/site/example/search.component.ts +++ b/src/app/site/example/search.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; -import { NavbarTopics } from '../../core/core.module'; +import { NavbarTopics } from '../../core/site-navbar/navbar-topic.model'; @Component({ template: ` @@ -12,7 +12,8 @@ import { NavbarTopics } from '../../core/core.module'; - ` + `, + standalone: true }) export class SearchComponent {} diff --git a/src/app/site/example/welcome.component.ts b/src/app/site/example/welcome.component.ts index 333312ec..57e9dedc 100644 --- a/src/app/site/example/welcome.component.ts +++ b/src/app/site/example/welcome.component.ts @@ -10,6 +10,7 @@ import { Component } from '@angular/core'; - ` + `, + standalone: true }) export class WelcomeComponent {} diff --git a/src/app/site/site.module.ts b/src/app/site/site.module.ts deleted file mode 100644 index 0498ddbb..00000000 --- a/src/app/site/site.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { CoreModule } from '../core/core.module'; -import { ExampleModule } from './example/example.module'; - -@NgModule({ - imports: [CoreModule, ExampleModule], - exports: [], - declarations: [], - providers: [] -}) -export class SiteModule {} diff --git a/src/main.ts b/src/main.ts index ea845f0f..dba6411f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,18 +1,69 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { provideHttpClient, withInterceptors, withInterceptorsFromDi } from '@angular/common/http'; +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { BrowserModule, bootstrapApplication } from '@angular/platform-browser'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { TitleStrategy, provideRouter, withHashLocation } from '@angular/router'; -import { AppModule } from './app/app.module'; +import { AlertModule } from 'ngx-bootstrap/alert'; +import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; +import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; +import { ModalModule } from 'ngx-bootstrap/modal'; +import { PopoverModule } from 'ngx-bootstrap/popover'; +import { TabsModule } from 'ngx-bootstrap/tabs'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; +import { TypeaheadModule } from 'ngx-bootstrap/typeahead'; + +import { AppComponent } from './app/app.component'; +import { authInterceptor } from './app/core/auth/auth.interceptor'; +import { euaInterceptor } from './app/core/auth/eua.interceptor'; +import { signinInterceptor } from './app/core/auth/signin.interceptor'; +import { masqueradeInterceptor } from './app/core/masquerade/masquerade.interceptor'; +import { PageTitleStrategy } from './app/core/page-title.strategy'; +import { provideAppConfig, provideCoreRoutes, provideNavigationService } from './app/core/provider'; +import { provideExampleRoutes } from './app/site/example/provider'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => { - const messageEl = document.querySelector('app-root .message'); - if (messageEl) { - messageEl.textContent = err.message; +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom( + BrowserModule, + AlertModule.forRoot(), + BsDatepickerModule.forRoot(), + BsDropdownModule.forRoot(), + ModalModule.forRoot(), + PopoverModule.forRoot(), + TabsModule.forRoot(), + TooltipModule.forRoot(), + TypeaheadModule.forRoot() + ), + provideAnimations(), + provideHttpClient( + withInterceptors([ + signinInterceptor, + euaInterceptor, + authInterceptor, + masqueradeInterceptor + ]), + // Ensures any legacy class based interceptors are used. + withInterceptorsFromDi() + ), + provideRouter([], withHashLocation()), + provideCoreRoutes(), + provideExampleRoutes(), + provideAppConfig(), + provideNavigationService(), + { + provide: TitleStrategy, + useClass: PageTitleStrategy } - }); + ] +}).catch((err) => { + const messageEl = document.querySelector('app-root .message'); + if (messageEl) { + messageEl.textContent = err.message; + } +});