Skip to content

Commit 725c45e

Browse files
authored
refactor(action): migrate action module (DSP-1852) (#509)
* refactor(action): migrates: - _viewer.scss - statusMsg.ts - confirmation-dialog comp - confirmation-message comp - login-form comp - notification service - sorting service * fix: enable all tests * refactor(action): migrates: - message comp - progress indicator comp * refactor(action): migrates: - sort-button comp - string-literal-input comp * refactor(action): migrates selected-resource comp * refactor(action): migrates directives * fix: enable all tests * fix: removes USELESS regex to make github happy * fix: fixes import * refactor(action): rename existing-name directive * refactor(action): migrates all non-deprecated pipes
1 parent ea1cd55 commit 725c45e

57 files changed

Lines changed: 5264 additions & 3 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎package-lock.json‎

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/app/app.module.ts‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,22 @@ import { ResultsComponent } from './workspace/results/results.component';
9898
import { AudioComponent } from './workspace/resource/representation/audio/audio.component';
9999
import { IntermediateComponent } from './workspace/intermediate/intermediate.component';
100100
import { ResourceLinkFormComponent } from './workspace/resource/resource-link-form/resource-link-form.component';
101+
import { ConfirmationDialogComponent } from './main/action/confirmation-dialog/confirmation-dialog.component';
102+
import { ConfirmationMessageComponent } from './main/action/confirmation-dialog/confirmation-message/confirmation-message.component';
103+
import { LoginFormComponent } from './main/action/login-form/login-form.component';
104+
import { MessageComponent } from './main/action/message/message.component';
105+
import { ProgressIndicatorComponent } from './main/action/progress-indicator/progress-indicator.component';
106+
import { StringLiteralInputComponent } from './main/action/string-literal-input/string-literal-input.component';
107+
import { SortButtonComponent } from './main/action/sort-button/sort-button.component';
108+
import { SelectedResourcesComponent } from './main/action/selected-resources/selected-resources.component';
109+
import { AdminImageDirective } from './main/directive/admin-image/admin-image.directive';
110+
import { ExistingNameDirective } from './main/directive/existing-name/existing-name.directive';
111+
import { GndDirective } from './main/directive/gnd/gnd.directive';
112+
import { FormattedBooleanPipe } from './main/pipes/formatting/formatted-boolean.pipe';
113+
import { KnoraDatePipe } from './main/pipes/formatting/knoradate.pipe';
114+
import { LinkifyPipe } from './main/pipes/string-transformation/linkify.pipe';
115+
import { StringifyStringLiteralPipe } from './main/pipes/string-transformation/stringify-string-literal.pipe';
116+
import { TruncatePipe } from './main/pipes/string-transformation/truncate.pipe';
101117

102118
// translate: AoT requires an exported function for factories
103119
export function httpLoaderFactory(httpClient: HttpClient) {
@@ -182,6 +198,22 @@ export function httpLoaderFactory(httpClient: HttpClient) {
182198
AudioComponent,
183199
IntermediateComponent,
184200
ResourceLinkFormComponent,
201+
ConfirmationDialogComponent,
202+
ConfirmationMessageComponent,
203+
LoginFormComponent,
204+
MessageComponent,
205+
ProgressIndicatorComponent,
206+
StringLiteralInputComponent,
207+
SortButtonComponent,
208+
SelectedResourcesComponent,
209+
AdminImageDirective,
210+
ExistingNameDirective,
211+
GndDirective,
212+
FormattedBooleanPipe,
213+
KnoraDatePipe,
214+
LinkifyPipe,
215+
StringifyStringLiteralPipe,
216+
TruncatePipe,
185217
],
186218
imports: [
187219
AppRoutingModule,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="deletion-dialog">
2+
<mat-dialog-content>
3+
<p class="title"> Are you sure you want to delete this value from {{data.value.propertyLabel}}?</p>
4+
<app-confirmation-message #confirmMessage [value]="data.value"></app-confirmation-message>
5+
</mat-dialog-content>
6+
<mat-dialog-actions class="action-buttons">
7+
<button class="cancel" mat-raised-button mat-dialog-close>{{data.buttonTextCancel}}</button>
8+
<button class="ok" mat-raised-button color="primary" (click)="onConfirmClick()">{{data.buttonTextOk}}</button>
9+
</mat-dialog-actions>
10+
</div>
11+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "../../../../assets/style/viewer";
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import { OverlayContainer } from '@angular/cdk/overlay';
2+
import { HarnessLoader } from '@angular/cdk/testing';
3+
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
4+
import { Component, Input, OnInit } from '@angular/core';
5+
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
6+
import { MatButtonHarness } from '@angular/material/button/testing';
7+
import { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
8+
import { MatDialogHarness } from '@angular/material/dialog/testing';
9+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
10+
import { MockResource, ReadIntValue, ReadValue } from '@dasch-swiss/dsp-js';
11+
import { ConfirmationDialogComponent, ConfirmationDialogValueDeletionPayload } from './confirmation-dialog.component';
12+
13+
/**
14+
* test host component to simulate parent component with a confirmation dialog.
15+
*/
16+
@Component({
17+
template: `
18+
<p> {{confirmationDialogResponse}} </p>`
19+
})
20+
class ConfirmationDialogTestHostComponent implements OnInit {
21+
22+
confirmationDialogResponse: string;
23+
24+
testValue: ReadIntValue;
25+
26+
constructor(private dialog: MatDialog) {
27+
}
28+
29+
ngOnInit() {
30+
MockResource.getTestThing().subscribe(res => {
31+
this.testValue = res.getValuesAs('http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger', ReadIntValue)[0];
32+
});
33+
}
34+
35+
openDialog() {
36+
37+
this.dialog.open(ConfirmationDialogComponent, {
38+
data: {
39+
value: this.testValue,
40+
buttonTextOk: 'OK',
41+
buttonTextCancel: 'Cancel'
42+
}
43+
}).afterClosed().subscribe((payload: ConfirmationDialogValueDeletionPayload) => {
44+
if (payload.confirmed) {
45+
this.confirmationDialogResponse = 'Action was confirmed!';
46+
} else {
47+
this.confirmationDialogResponse = 'Action was cancelled';
48+
}
49+
});
50+
}
51+
}
52+
53+
@Component({ selector: 'app-confirmation-message', template: '' })
54+
class MockConfirmationMessageComponent {
55+
@Input() value: ReadValue;
56+
57+
constructor() { }
58+
}
59+
60+
describe('ConfirmationDialogComponent', () => {
61+
let testHostComponent: ConfirmationDialogTestHostComponent;
62+
let testHostFixture: ComponentFixture<ConfirmationDialogTestHostComponent>;
63+
let rootLoader: HarnessLoader;
64+
let overlayContainer: OverlayContainer;
65+
66+
beforeEach(waitForAsync(() => {
67+
TestBed.configureTestingModule({
68+
declarations: [
69+
ConfirmationDialogComponent,
70+
ConfirmationDialogTestHostComponent,
71+
MockConfirmationMessageComponent
72+
],
73+
imports: [
74+
MatDialogModule,
75+
BrowserAnimationsModule
76+
],
77+
providers: [
78+
{
79+
provide: MAT_DIALOG_DATA,
80+
useValue: {}
81+
},
82+
{
83+
provide: MatDialogRef,
84+
useValue: {}
85+
}
86+
]
87+
})
88+
.compileComponents();
89+
90+
overlayContainer = TestBed.inject(OverlayContainer);
91+
}));
92+
93+
beforeEach(() => {
94+
testHostFixture = TestBed.createComponent(ConfirmationDialogTestHostComponent);
95+
testHostComponent = testHostFixture.componentInstance;
96+
rootLoader = TestbedHarnessEnvironment.documentRootLoader(testHostFixture);
97+
testHostFixture.detectChanges();
98+
expect(testHostComponent).toBeTruthy();
99+
});
100+
101+
afterEach(async () => {
102+
const dialogs = await rootLoader.getAllHarnesses(MatDialogHarness);
103+
await Promise.all(dialogs.map(async d => await d.close()));
104+
105+
// angular won't call this for us so we need to do it ourselves to avoid leaks.
106+
overlayContainer.ngOnDestroy();
107+
});
108+
109+
it('should display a confirmation dialog', async () => {
110+
111+
testHostComponent.openDialog();
112+
113+
testHostFixture.detectChanges();
114+
115+
await testHostFixture.whenStable();
116+
117+
const dialogDiv = document.querySelector('mat-dialog-container');
118+
expect(dialogDiv).toBeTruthy();
119+
120+
const dspConfirmMsg = document.querySelector('app-confirmation-message');
121+
expect(dspConfirmMsg).toBeTruthy();
122+
123+
const dialogTitle = dialogDiv.querySelector('.title');
124+
expect(dialogTitle.innerHTML.trim()).toEqual('Are you sure you want to delete this value from Integer?');
125+
126+
});
127+
128+
it('should return a confirmation message when the OK button is clicked', async () => {
129+
130+
testHostComponent.openDialog();
131+
132+
let dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);
133+
134+
expect(dialogHarnesses.length).toEqual(1);
135+
136+
const okButton = await rootLoader.getHarness(MatButtonHarness.with({ selector: '.ok' }));
137+
138+
await okButton.click();
139+
140+
dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);
141+
142+
expect(dialogHarnesses.length).toEqual(0);
143+
144+
expect(testHostComponent.confirmationDialogResponse).toEqual('Action was confirmed!');
145+
146+
});
147+
148+
it('should return a cancelled message when the cancel button is clicked', async () => {
149+
150+
testHostComponent.openDialog();
151+
152+
let dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);
153+
154+
expect(dialogHarnesses.length).toEqual(1);
155+
156+
const cancelButton = await rootLoader.getHarness(MatButtonHarness.with({ selector: '.cancel' }));
157+
158+
await cancelButton.click();
159+
160+
dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);
161+
162+
expect(dialogHarnesses.length).toEqual(0);
163+
164+
expect(testHostComponent.confirmationDialogResponse).toEqual('Action was cancelled');
165+
166+
167+
});
168+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Component, Inject, ViewChild } from '@angular/core';
2+
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
3+
import { ReadValue } from '@dasch-swiss/dsp-js';
4+
import { ConfirmationMessageComponent } from './confirmation-message/confirmation-message.component';
5+
6+
export class ConfirmationDialogData {
7+
value: ReadValue;
8+
buttonTextOk: string;
9+
buttonTextCancel: string;
10+
}
11+
12+
export class ConfirmationDialogValueDeletionPayload {
13+
confirmed: boolean;
14+
deletionComment?: string;
15+
}
16+
17+
@Component({
18+
selector: 'app-confirmation-dialog',
19+
templateUrl: './confirmation-dialog.component.html',
20+
styleUrls: ['./confirmation-dialog.component.scss']
21+
})
22+
export class ConfirmationDialogComponent {
23+
@ViewChild('confirmMessage') confirmationMessageComponent: ConfirmationMessageComponent;
24+
25+
// type assertion doesn't seem to be enforced
26+
// https://stackoverflow.com/a/57787554
27+
constructor(
28+
@Inject(MAT_DIALOG_DATA) public data: ConfirmationDialogData,
29+
private _dialogRef: MatDialogRef<ConfirmationDialogComponent>
30+
) { }
31+
32+
onConfirmClick(): void {
33+
const payload = new ConfirmationDialogValueDeletionPayload();
34+
payload.confirmed = true;
35+
payload.deletionComment = this.confirmationMessageComponent.comment ? this.confirmationMessageComponent.comment : undefined;
36+
this._dialogRef.close(payload);
37+
}
38+
39+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<div class="deletion-dialog-message">
2+
<p class="val-label">Confirming this action will delete the following value from {{value.propertyLabel}}:</p>
3+
<p class="val-value">Value: {{value.strval}}</p>
4+
<p class="val-comment">Value Comment: {{value.valueHasComment ? value.valueHasComment : 'No comment'}}</p>
5+
<p class="val-creation-date">Value Creation Date: {{value.valueCreationDate}}</p>
6+
<textarea
7+
matinput
8+
class="deletion-comment"
9+
type="text"
10+
(keyup)="onKey($event)"
11+
[placeholder]="'Comment why value is being deleted'"
12+
></textarea>
13+
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "../../../../../assets/style/viewer";

0 commit comments

Comments
 (0)