From 975b9e84f7f1374054becb58b3fd6789552627be Mon Sep 17 00:00:00 2001 From: Daniel Appelgren Date: Thu, 16 Dec 2021 10:49:39 +0100 Subject: [PATCH] Pull request #293: Feature/TV-845 ui dialog Merge in TEA/mina-sidor-fa-web from feature/TV-845-ui-dialog-2 to develop Squashed commit of the following: commit 06ee26ccbe9d2fd5edfd12d7a292f42e3b747fb7 Author: Daniel Appelgren Date: Thu Dec 16 09:45:23 2021 +0100 refactor commit e2295202721b58fbd37341d3e02dae5a95cbb0c5 Author: Daniel Appelgren Date: Fri Dec 10 14:03:37 2021 +0100 Update ui-dialog-ref.ts commit c9507cd4579b4e542d0116f5e96b3a911c51600d Author: Daniel Appelgren Date: Fri Dec 10 13:00:05 2021 +0100 cleanup commit 0e4ded553352414b5ca670897a51f127a5a289b1 Author: Daniel Appelgren Date: Fri Dec 10 12:48:25 2021 +0100 cleanup commit 0a48220c8bcd5704f7436f1c0c84ca25bac4c8e8 Author: Daniel Appelgren Date: Fri Dec 10 12:36:16 2021 +0100 Dialog working commit c4c1e9fb42d99df7ec6c058b7bea30662a03bb33 Author: Daniel Appelgren Date: Fri Dec 10 11:14:36 2021 +0100 wip commit 6668dfb154022b873b0a042087181cd0e6f8994d Merge: 624b9439 9d96f0d9 Author: Daniel Appelgren Date: Fri Dec 10 10:47:27 2021 +0100 Merge branch 'develop' into feature/TV-845-ui-dialog-2 commit 624b94399689bef07178f89c015745c90af1b288 Author: Daniel Appelgren Date: Fri Dec 10 10:47:19 2021 +0100 wip commit 0478638ab0d0f8f62ce8d10489f20e4930099936 Author: Daniel Appelgren Date: Fri Dec 10 09:58:49 2021 +0100 wip commit 12234c22062124165c2da10ff75cc887997172a8 Author: Daniel Appelgren Date: Fri Dec 10 09:21:09 2021 +0100 wip --- ...agare-list-handelser-dialog.component.html | 154 ++++++++---------- ...ltagare-list-handelser-dialog.component.ts | 35 ++-- .../deltagare-list-table.component.html | 18 -- .../deltagare-list-table.component.ts | 24 +-- .../deltagare-list-table.module.ts | 4 +- .../services/deltagare-handelser.service.ts | 8 +- libs/ui/.eslintrc.json | 2 +- libs/ui/src/dialog/dialog.service.spec.ts | 16 ++ libs/ui/src/dialog/ui-dialog-ref.ts | 51 ++++++ libs/ui/src/dialog/ui-dialog.component.html | 29 ++++ libs/ui/src/dialog/ui-dialog.component.scss | 32 ++++ .../ui/src/dialog/ui-dialog.component.spec.ts | 24 +++ libs/ui/src/dialog/ui-dialog.component.ts | 53 ++++++ libs/ui/src/dialog/ui-dialog.model.ts | 23 +++ libs/ui/src/dialog/ui-dialog.module.ts | 13 ++ libs/ui/src/dialog/ui-dialog.service.ts | 44 +++++ 16 files changed, 391 insertions(+), 139 deletions(-) create mode 100644 libs/ui/src/dialog/dialog.service.spec.ts create mode 100644 libs/ui/src/dialog/ui-dialog-ref.ts create mode 100644 libs/ui/src/dialog/ui-dialog.component.html create mode 100644 libs/ui/src/dialog/ui-dialog.component.scss create mode 100644 libs/ui/src/dialog/ui-dialog.component.spec.ts create mode 100644 libs/ui/src/dialog/ui-dialog.component.ts create mode 100644 libs/ui/src/dialog/ui-dialog.model.ts create mode 100644 libs/ui/src/dialog/ui-dialog.module.ts create mode 100644 libs/ui/src/dialog/ui-dialog.service.ts diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.html index 9a902eb..187920f 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.html @@ -1,87 +1,77 @@ - -
-

{{deltagare.fullName}}

-

Genomförandereferens: {{deltagare.genomforandeReferens}}

- - -

{{activeHandelseMotivation.motivation}}

-
+

Händelser för {{deltagare.fullName}}

- - - - - - - - - - - - - - - - - - - - -
- Lista med alla händelser för {{deltagare.fullName}} -
InkomHändelseEffektMotivering
- - - - {{handelse.description}} - - - {{handelse.effectDescription}}: - - - - - - Motivering till beslut - -
-
- - - - -
+
+

{{deltagare.fullName}}

+

Genomförandereferens: {{deltagare.genomforandeReferens}}

+ + +

{{activeHandelseMotivation.motivation}}

-
- + + + + + + + + + + + + + + + + + + + + + +
+ Lista med alla händelser för {{deltagare.fullName}} +
InkomHändelseEffektMotivering
+ + + + {{handelse.description}} + + + {{handelse.effectDescription}}: + + + + + + Motivering till beslut + +
+
+ + + + +
+
+

Inga händelser har inkommit.

diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.ts index b7d88bf..c762df9 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component.ts @@ -1,13 +1,4 @@ -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Input, - OnChanges, - OnDestroy, - Output, - SimpleChanges, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject, OnDestroy } from '@angular/core'; import { DeltagareHandelse, DeltagareHandelseData, @@ -19,6 +10,8 @@ import { DeltagareHandelserService } from '@msfa-services/deltagare-handelser.se import { UiIconSize } from '@ui/icon/icon-size.enum'; import { UiIconType } from '@ui/icon/icon-type.enum'; import { BehaviorSubject, Observable } from 'rxjs'; +import { UI_DIALOG_DATA } from '@ui/dialog/ui-dialog.model'; +import { UiDialogRef } from '@ui/dialog/ui-dialog-ref'; @Component({ selector: 'msfa-deltagare-list-handelser-dialog', @@ -26,27 +19,25 @@ import { BehaviorSubject, Observable } from 'rxjs'; styleUrls: ['./deltagare-list-handelser-dialog.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DeltagareListHandelserDialogComponent implements OnChanges, OnDestroy { - @Input() deltagare: DeltagareCompact; - @Output() closeDialog = new EventEmitter(); +export class DeltagareListHandelserDialogComponent implements OnDestroy { IconType = UiIconType; IconSize = UiIconSize; deltagareHandelserData$: Observable; private _activeHandelseMotivation$ = new BehaviorSubject(null); - constructor(private deltagareHandelserService: DeltagareHandelserService) {} + constructor( + private deltagareHandelserService: DeltagareHandelserService, + @Inject(UI_DIALOG_DATA) public deltagare: DeltagareCompact, + private uiDialogRef: UiDialogRef + ) { + this.deltagareHandelserService.setGenomforandeReferens$(this.deltagare.genomforandeReferens); + this.deltagareHandelserData$ = this.deltagareHandelserService.deltagareHandelserData$; + } ngOnDestroy(): void { this.deltagareHandelserService.resetParams(); } - ngOnChanges(changes: SimpleChanges): void { - if (changes.deltagare && changes.deltagare.currentValue) { - this.deltagareHandelserService.setGenomforandeReferens$(this.deltagare.genomforandeReferens); - this.deltagareHandelserData$ = this.deltagareHandelserService.deltagareHandelserData$; - } - } - get activeHandelseMotivation(): DeltagareHandelseMotivation { return this._activeHandelseMotivation$.getValue(); } @@ -89,6 +80,6 @@ export class DeltagareListHandelserDialogComponent implements OnChanges, OnDestr emitCloseDialog(): void { this._activeHandelseMotivation$.next(null); - this.closeDialog.emit(); + this.uiDialogRef.close(); } } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.html index bc5cd2c..8a5f613 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.html @@ -84,21 +84,3 @@ > - - - diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.ts index b442333..325e656 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.component.ts @@ -6,8 +6,8 @@ import { PaginationMeta } from '@msfa-models/pagination-meta.model'; import { Sort } from '@msfa-models/sort.model'; import { UiIconSize } from '@ui/icon/icon-size.enum'; import { UiIconType } from '@ui/icon/icon-type.enum'; -import { BehaviorSubject } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { DeltagareListHandelserDialogComponent } from '../deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component'; +import { UiDialog } from '@ui/dialog/ui-dialog.service'; @Component({ selector: 'msfa-deltagare-list-table', @@ -22,9 +22,10 @@ export class DeltagareListTableComponent { @Input() sort: Sort; @Output() sorted = new EventEmitter(); @Output() paginated = new EventEmitter(); - handelserDialogDeltagare$ = new BehaviorSubject(null); - handelserDialogIsOpen$ = this.handelserDialogDeltagare$.pipe(map(deltagare => !!deltagare)); + constructor(public uiDialog: UiDialog) {} + + handelserDialogComponent = DeltagareListHandelserDialogComponent; IconType = UiIconType; IconSize = UiIconSize; @@ -81,6 +82,13 @@ export class DeltagareListTableComponent { return end < this.count ? end : this.count; } + openHandelser(singleDeltagare: DeltagareCompact): void { + this.uiDialog.open(this.handelserDialogComponent, { + data: singleDeltagare, + primaryButtonText: 'Stäng', + }); + } + getAvropDate(deltagare: DeltagareCompact, avropDate?: string): Date { return avropDate === 'startdatumAvrop' ? new Date(deltagare.startdatumAvrop) : new Date(deltagare.slutdatumAvrop); } @@ -92,12 +100,4 @@ export class DeltagareListTableComponent { setNewPage(page: number): void { this.paginated.emit(page); } - - openHandelser(deltagareCompact: DeltagareCompact): void { - this.handelserDialogDeltagare$.next(deltagareCompact); - } - - closeHandelser(): void { - this.handelserDialogDeltagare$.next(null); - } } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.module.ts index 645794d..77267d7 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.module.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-list/components/deltagare-list-table/deltagare-list-table.module.ts @@ -1,4 +1,3 @@ -import { DigiNgDialogModule } from '@af/digi-ng/_dialog/dialog'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; @@ -6,11 +5,12 @@ import { UiIconModule } from '@ui/icon/icon.module'; import { UiLoaderModule } from '@ui/loader/loader.module'; import { DeltagareListHandelserDialogComponent } from '../deltagare-list-handelser-dialog/deltagare-list-handelser-dialog.component'; import { DeltagareListTableComponent } from './deltagare-list-table.component'; +import { UiDialogModule } from '@ui/dialog/ui-dialog.module'; @NgModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [DeltagareListTableComponent, DeltagareListHandelserDialogComponent], - imports: [CommonModule, RouterModule, UiIconModule, UiLoaderModule, DigiNgDialogModule], + imports: [CommonModule, RouterModule, UiIconModule, UiDialogModule, UiLoaderModule], exports: [DeltagareListTableComponent], }) export class DeltagareListTableModule {} diff --git a/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts b/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts index dd8ae87..072709d 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts @@ -1,8 +1,9 @@ import { Injectable } from '@angular/core'; import { PaginationParams } from '@msfa-models/api/params.model'; -import { BehaviorSubject, combineLatest } from 'rxjs'; +import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { DeltagareHandelserApiService } from './api/deltagare-handelser.api.service'; +import { DeltagareHandelseData } from '@msfa-models/deltagare-handelse.model'; const DEFAULT_PARAMS: PaginationParams = { page: 1, @@ -16,7 +17,10 @@ export class DeltagareHandelserService { private _params$ = new BehaviorSubject(DEFAULT_PARAMS); private _genomforandeReferens$ = new BehaviorSubject(null); - deltagareHandelserData$ = combineLatest([this._genomforandeReferens$, this._params$]).pipe( + deltagareHandelserData$: Observable = combineLatest([ + this._genomforandeReferens$, + this._params$, + ]).pipe( switchMap(([genomforandeReferens, params]) => { return this.deltagareHandelserApiService.fetchDeltagareHandelser$(genomforandeReferens, params); }) diff --git a/libs/ui/.eslintrc.json b/libs/ui/.eslintrc.json index c353e8c..b093caf 100644 --- a/libs/ui/.eslintrc.json +++ b/libs/ui/.eslintrc.json @@ -12,7 +12,7 @@ "plugin:@typescript-eslint/recommended-requiring-type-checking", "plugin:@angular-eslint/template/process-inline-templates" ], - "parserOptions": { "project": ["apps/mina-sidor-fa/tsconfig.*?.json"] }, + "parserOptions": { "project": ["libs/ui/tsconfig.*?.json"] }, "rules": { "max-len": [ 1, diff --git a/libs/ui/src/dialog/dialog.service.spec.ts b/libs/ui/src/dialog/dialog.service.spec.ts new file mode 100644 index 0000000..5d914ab --- /dev/null +++ b/libs/ui/src/dialog/dialog.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { UiDialog } from './ui-dialog.service'; + +describe('DialogService', () => { + let service: UiDialog; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(UiDialog); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/libs/ui/src/dialog/ui-dialog-ref.ts b/libs/ui/src/dialog/ui-dialog-ref.ts new file mode 100644 index 0000000..dc69b69 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog-ref.ts @@ -0,0 +1,51 @@ +import { Subject } from 'rxjs'; + +import { OverlayRef } from '@angular/cdk/overlay'; + +import { TemplateRef, Type } from '@angular/core'; +import { UiDialogConfig } from '@ui/dialog/ui-dialog.model'; + +export interface OverlayCloseEvent { + type: 'backdropClick' | 'close'; + data: R; +} + +export class UiDialogRef { + afterClosed$ = new Subject>(); + + constructor( + public overlay: OverlayRef, + public content: string | TemplateRef | Type, + public config: UiDialogConfig + ) { + overlay.backdropClick().subscribe(() => this._close('backdropClick', null)); + } + + get primaryButtonText(): string { + return this.config.primaryButtonText; + } + get secondaryButtonText(): string { + return this.config.secondaryButtonText; + } + + close(data?: CloseResponseData): void { + this._close('close', data); + } + + private _close(type: 'backdropClick' | 'close', data: CloseResponseData) { + this.overlay.dispose(); + this.afterClosed$.next({ + type, + data, + }); + + this.afterClosed$.complete(); + } + + primaryAction(): void { + this.config.primaryAction ? this.config.primaryAction(this) : this.close(); + } + secondaryAction(): void { + this.config.secondaryAction ? this.config.secondaryAction(this) : this.close(); + } +} diff --git a/libs/ui/src/dialog/ui-dialog.component.html b/libs/ui/src/dialog/ui-dialog.component.html new file mode 100644 index 0000000..fb4db96 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.component.html @@ -0,0 +1,29 @@ +
+ + +
+
+
+
+ + + + + + + + +
+ +
+ {{primaryButtonText}} + + {{secondaryButtonText}} + +
+ + +
diff --git a/libs/ui/src/dialog/ui-dialog.component.scss b/libs/ui/src/dialog/ui-dialog.component.scss new file mode 100644 index 0000000..5ff0520 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.component.scss @@ -0,0 +1,32 @@ +@import 'libs/styles/src/variables/shadows'; +@import 'libs/styles/src/variables/gutters'; + +.ui-dialog { + background: white; + border-radius: var(--digi--ui--border--radius); + box-shadow: $msfa__shadow; + padding: $digi--layout--gutter--s $digi--layout--gutter--xl $digi--layout--gutter--l; + position: relative; + + &__close-button { + position: absolute; + top: var(--digi--layout--gutter); + right: var(--digi--layout--gutter--s); + background: transparent; + border: none; + display: flex; + justify-content: center; + align-items: center; + } + + &__close-button-text { + font-size: var(--digi--typography--font-size--s); + } + + &__footer { + min-height: var(--digi--layout--gutter); + display: flex; + margin-top: $digi--layout--gutter--l; + gap: var(--digi--layout--gutter); + } +} diff --git a/libs/ui/src/dialog/ui-dialog.component.spec.ts b/libs/ui/src/dialog/ui-dialog.component.spec.ts new file mode 100644 index 0000000..696cdc2 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UiDialogComponent } from './ui-dialog.component'; + +describe('DialogComponent', () => { + let component: UiDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [UiDialogComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(UiDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/ui/src/dialog/ui-dialog.component.ts b/libs/ui/src/dialog/ui-dialog.component.ts new file mode 100644 index 0000000..0fe0110 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.component.ts @@ -0,0 +1,53 @@ +import { Component, OnInit, TemplateRef, Type } from '@angular/core'; +import { UiDialogRef } from '@ui/dialog/ui-dialog-ref'; +import { UiIconSize } from '@ui/icon/icon-size.enum'; +import { UiIconType } from '@ui/icon/icon-type.enum'; + +@Component({ + selector: 'ui-dialog', + templateUrl: './ui-dialog.component.html', + styleUrls: ['./ui-dialog.component.scss'], +}) +export class UiDialogComponent implements OnInit { + UiIconType = UiIconType; + UiIconSize = UiIconSize; + contentType: 'template' | 'string' | 'component'; + content: string | TemplateRef | Type; + context; + + constructor(private uiDialogRef: UiDialogRef) {} + + close(): void { + this.uiDialogRef.close(null); + } + + get primaryButtonText(): string { + return this.uiDialogRef.primaryButtonText ?? 'Stäng'; + } + + get secondaryButtonText(): string { + return this.uiDialogRef.secondaryButtonText; + } + + primaryAction(): void { + this.uiDialogRef.primaryAction(); + } + + secondaryAction(): void { + this.uiDialogRef.secondaryAction(); + } + + ngOnInit(): void { + this.content = this.uiDialogRef.content; + if (typeof this.content === 'string') { + this.contentType = 'string'; + } else if (this.content instanceof TemplateRef) { + this.contentType = 'template'; + this.context = { + close: this.uiDialogRef.close.bind(this.uiDialogRef) as unknown, + }; + } else { + this.contentType = 'component'; + } + } +} diff --git a/libs/ui/src/dialog/ui-dialog.model.ts b/libs/ui/src/dialog/ui-dialog.model.ts new file mode 100644 index 0000000..f8033d3 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.model.ts @@ -0,0 +1,23 @@ +import { UiDialogRef } from '@ui/dialog/ui-dialog-ref'; + +export const UI_DIALOG_DATA = 'UI_DIALOG_DATA'; + +export interface UiDialogConfig { + data: DialogInputData; + + /** + * primaryButtonText defaults to 'Stäng' + */ + primaryButtonText?: string; + + /** + * primaryAction defaults to closing the dialog + */ + primaryAction?: (uiDialogRef?: UiDialogRef) => unknown; + secondaryButtonText?: string; + + /** + * secondaryAction defaults to closing the dialog + */ + secondaryAction?: (uiDialogRef?: UiDialogRef) => unknown; +} diff --git a/libs/ui/src/dialog/ui-dialog.module.ts b/libs/ui/src/dialog/ui-dialog.module.ts new file mode 100644 index 0000000..a9d2764 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.module.ts @@ -0,0 +1,13 @@ +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { UiDialogComponent } from './ui-dialog.component'; +import { UiIconModule } from '@ui/icon/icon.module'; +import { UiDialog } from '@ui/dialog/ui-dialog.service'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [UiDialogComponent], + imports: [CommonModule, UiIconModule], + providers: [UiDialog], +}) +export class UiDialogModule {} diff --git a/libs/ui/src/dialog/ui-dialog.service.ts b/libs/ui/src/dialog/ui-dialog.service.ts new file mode 100644 index 0000000..2d6a200 --- /dev/null +++ b/libs/ui/src/dialog/ui-dialog.service.ts @@ -0,0 +1,44 @@ +import { Injectable, Injector, TemplateRef, Type } from '@angular/core'; +import { ComponentPortal } from '@angular/cdk/portal'; +import { Overlay, OverlayConfig } from '@angular/cdk/overlay'; +import { UiDialogRef } from '@ui/dialog/ui-dialog-ref'; +import { UiDialogComponent } from './ui-dialog.component'; +import { UI_DIALOG_DATA, UiDialogConfig } from '@ui/dialog/ui-dialog.model'; + +@Injectable() +export class UiDialog { + constructor(private overlay: Overlay, private injector: Injector) {} + + private static _createInjector(uiDialogRef: UiDialogRef, injector: Injector, config: UiDialogConfig): Injector { + return Injector.create({ + parent: injector, + providers: [ + { provide: UiDialogRef, useValue: uiDialogRef }, + { provide: UI_DIALOG_DATA, useValue: config.data }, + ], + }); + } + + open( + content: string | TemplateRef | Type, + config: UiDialogConfig + ): UiDialogRef { + const positionStrategy = this.overlay.position().global().centerHorizontally().centerVertically(); + const configs = new OverlayConfig({ + positionStrategy, + minWidth: '40rem', + minHeight: '40rem', + hasBackdrop: true, + scrollStrategy: this.overlay.scrollStrategies.close(), + backdropClass: 'cdk-overlay-dark-backdrop', + }); + + const overlayRef = this.overlay.create(configs); + const uiDialogRef = new UiDialogRef(overlayRef, content, config); + + const injector = UiDialog._createInjector(uiDialogRef, this.injector, config); + overlayRef.attach(new ComponentPortal(UiDialogComponent, null, injector)); + + return uiDialogRef; + } +}