Skip to content

Commit

Permalink
refactor(action): migrate action module (DSP-1852) (#509)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mdelez committed Aug 19, 2021
1 parent ea1cd55 commit 725c45e
Show file tree
Hide file tree
Showing 57 changed files with 5,264 additions and 3 deletions.
10 changes: 7 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions src/app/app.module.ts
Expand Up @@ -98,6 +98,22 @@ import { ResultsComponent } from './workspace/results/results.component';
import { AudioComponent } from './workspace/resource/representation/audio/audio.component';
import { IntermediateComponent } from './workspace/intermediate/intermediate.component';
import { ResourceLinkFormComponent } from './workspace/resource/resource-link-form/resource-link-form.component';
import { ConfirmationDialogComponent } from './main/action/confirmation-dialog/confirmation-dialog.component';
import { ConfirmationMessageComponent } from './main/action/confirmation-dialog/confirmation-message/confirmation-message.component';
import { LoginFormComponent } from './main/action/login-form/login-form.component';
import { MessageComponent } from './main/action/message/message.component';
import { ProgressIndicatorComponent } from './main/action/progress-indicator/progress-indicator.component';
import { StringLiteralInputComponent } from './main/action/string-literal-input/string-literal-input.component';
import { SortButtonComponent } from './main/action/sort-button/sort-button.component';
import { SelectedResourcesComponent } from './main/action/selected-resources/selected-resources.component';
import { AdminImageDirective } from './main/directive/admin-image/admin-image.directive';
import { ExistingNameDirective } from './main/directive/existing-name/existing-name.directive';
import { GndDirective } from './main/directive/gnd/gnd.directive';
import { FormattedBooleanPipe } from './main/pipes/formatting/formatted-boolean.pipe';
import { KnoraDatePipe } from './main/pipes/formatting/knoradate.pipe';
import { LinkifyPipe } from './main/pipes/string-transformation/linkify.pipe';
import { StringifyStringLiteralPipe } from './main/pipes/string-transformation/stringify-string-literal.pipe';
import { TruncatePipe } from './main/pipes/string-transformation/truncate.pipe';

// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
Expand Down Expand Up @@ -182,6 +198,22 @@ export function httpLoaderFactory(httpClient: HttpClient) {
AudioComponent,
IntermediateComponent,
ResourceLinkFormComponent,
ConfirmationDialogComponent,
ConfirmationMessageComponent,
LoginFormComponent,
MessageComponent,
ProgressIndicatorComponent,
StringLiteralInputComponent,
SortButtonComponent,
SelectedResourcesComponent,
AdminImageDirective,
ExistingNameDirective,
GndDirective,
FormattedBooleanPipe,
KnoraDatePipe,
LinkifyPipe,
StringifyStringLiteralPipe,
TruncatePipe,
],
imports: [
AppRoutingModule,
Expand Down
@@ -0,0 +1,11 @@
<div class="deletion-dialog">
<mat-dialog-content>
<p class="title"> Are you sure you want to delete this value from {{data.value.propertyLabel}}?</p>
<app-confirmation-message #confirmMessage [value]="data.value"></app-confirmation-message>
</mat-dialog-content>
<mat-dialog-actions class="action-buttons">
<button class="cancel" mat-raised-button mat-dialog-close>{{data.buttonTextCancel}}</button>
<button class="ok" mat-raised-button color="primary" (click)="onConfirmClick()">{{data.buttonTextOk}}</button>
</mat-dialog-actions>
</div>

@@ -0,0 +1 @@
@import "../../../../assets/style/viewer";
@@ -0,0 +1,168 @@
import { OverlayContainer } from '@angular/cdk/overlay';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { Component, Input, OnInit } from '@angular/core';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatDialogHarness } from '@angular/material/dialog/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MockResource, ReadIntValue, ReadValue } from '@dasch-swiss/dsp-js';
import { ConfirmationDialogComponent, ConfirmationDialogValueDeletionPayload } from './confirmation-dialog.component';

/**
* test host component to simulate parent component with a confirmation dialog.
*/
@Component({
template: `
<p> {{confirmationDialogResponse}} </p>`
})
class ConfirmationDialogTestHostComponent implements OnInit {

confirmationDialogResponse: string;

testValue: ReadIntValue;

constructor(private dialog: MatDialog) {
}

ngOnInit() {
MockResource.getTestThing().subscribe(res => {
this.testValue = res.getValuesAs('http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger', ReadIntValue)[0];
});
}

openDialog() {

this.dialog.open(ConfirmationDialogComponent, {
data: {
value: this.testValue,
buttonTextOk: 'OK',
buttonTextCancel: 'Cancel'
}
}).afterClosed().subscribe((payload: ConfirmationDialogValueDeletionPayload) => {
if (payload.confirmed) {
this.confirmationDialogResponse = 'Action was confirmed!';
} else {
this.confirmationDialogResponse = 'Action was cancelled';
}
});
}
}

@Component({ selector: 'app-confirmation-message', template: '' })
class MockConfirmationMessageComponent {
@Input() value: ReadValue;

constructor() { }
}

describe('ConfirmationDialogComponent', () => {
let testHostComponent: ConfirmationDialogTestHostComponent;
let testHostFixture: ComponentFixture<ConfirmationDialogTestHostComponent>;
let rootLoader: HarnessLoader;
let overlayContainer: OverlayContainer;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
ConfirmationDialogComponent,
ConfirmationDialogTestHostComponent,
MockConfirmationMessageComponent
],
imports: [
MatDialogModule,
BrowserAnimationsModule
],
providers: [
{
provide: MAT_DIALOG_DATA,
useValue: {}
},
{
provide: MatDialogRef,
useValue: {}
}
]
})
.compileComponents();

overlayContainer = TestBed.inject(OverlayContainer);
}));

beforeEach(() => {
testHostFixture = TestBed.createComponent(ConfirmationDialogTestHostComponent);
testHostComponent = testHostFixture.componentInstance;
rootLoader = TestbedHarnessEnvironment.documentRootLoader(testHostFixture);
testHostFixture.detectChanges();
expect(testHostComponent).toBeTruthy();
});

afterEach(async () => {
const dialogs = await rootLoader.getAllHarnesses(MatDialogHarness);
await Promise.all(dialogs.map(async d => await d.close()));

// angular won't call this for us so we need to do it ourselves to avoid leaks.
overlayContainer.ngOnDestroy();
});

it('should display a confirmation dialog', async () => {

testHostComponent.openDialog();

testHostFixture.detectChanges();

await testHostFixture.whenStable();

const dialogDiv = document.querySelector('mat-dialog-container');
expect(dialogDiv).toBeTruthy();

const dspConfirmMsg = document.querySelector('app-confirmation-message');
expect(dspConfirmMsg).toBeTruthy();

const dialogTitle = dialogDiv.querySelector('.title');
expect(dialogTitle.innerHTML.trim()).toEqual('Are you sure you want to delete this value from Integer?');

});

it('should return a confirmation message when the OK button is clicked', async () => {

testHostComponent.openDialog();

let dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);

expect(dialogHarnesses.length).toEqual(1);

const okButton = await rootLoader.getHarness(MatButtonHarness.with({ selector: '.ok' }));

await okButton.click();

dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);

expect(dialogHarnesses.length).toEqual(0);

expect(testHostComponent.confirmationDialogResponse).toEqual('Action was confirmed!');

});

it('should return a cancelled message when the cancel button is clicked', async () => {

testHostComponent.openDialog();

let dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);

expect(dialogHarnesses.length).toEqual(1);

const cancelButton = await rootLoader.getHarness(MatButtonHarness.with({ selector: '.cancel' }));

await cancelButton.click();

dialogHarnesses = await rootLoader.getAllHarnesses(MatDialogHarness);

expect(dialogHarnesses.length).toEqual(0);

expect(testHostComponent.confirmationDialogResponse).toEqual('Action was cancelled');


});
});
@@ -0,0 +1,39 @@
import { Component, Inject, ViewChild } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { ReadValue } from '@dasch-swiss/dsp-js';
import { ConfirmationMessageComponent } from './confirmation-message/confirmation-message.component';

export class ConfirmationDialogData {
value: ReadValue;
buttonTextOk: string;
buttonTextCancel: string;
}

export class ConfirmationDialogValueDeletionPayload {
confirmed: boolean;
deletionComment?: string;
}

@Component({
selector: 'app-confirmation-dialog',
templateUrl: './confirmation-dialog.component.html',
styleUrls: ['./confirmation-dialog.component.scss']
})
export class ConfirmationDialogComponent {
@ViewChild('confirmMessage') confirmationMessageComponent: ConfirmationMessageComponent;

// type assertion doesn't seem to be enforced
// https://stackoverflow.com/a/57787554
constructor(
@Inject(MAT_DIALOG_DATA) public data: ConfirmationDialogData,
private _dialogRef: MatDialogRef<ConfirmationDialogComponent>
) { }

onConfirmClick(): void {
const payload = new ConfirmationDialogValueDeletionPayload();
payload.confirmed = true;
payload.deletionComment = this.confirmationMessageComponent.comment ? this.confirmationMessageComponent.comment : undefined;
this._dialogRef.close(payload);
}

}
@@ -0,0 +1,13 @@
<div class="deletion-dialog-message">
<p class="val-label">Confirming this action will delete the following value from {{value.propertyLabel}}:</p>
<p class="val-value">Value: {{value.strval}}</p>
<p class="val-comment">Value Comment: {{value.valueHasComment ? value.valueHasComment : 'No comment'}}</p>
<p class="val-creation-date">Value Creation Date: {{value.valueCreationDate}}</p>
<textarea
matinput
class="deletion-comment"
type="text"
(keyup)="onKey($event)"
[placeholder]="'Comment why value is being deleted'"
></textarea>
</div>
@@ -0,0 +1 @@
@import "../../../../../assets/style/viewer";

0 comments on commit 725c45e

Please sign in to comment.