Skip to content

Commit

Permalink
Confirmation Dialog Message Subcomponent (#174)
Browse files Browse the repository at this point in the history
* refactor (confirmation-dialog): a subcomponent now handles the message part of the confirmation dialog

* refactor (tests): confirmation dialog & message tests now use the mocked int value from the js-lib. confirmation dialog now mocks the confirmation message component.

* refactor (test): use async/await instead of using .then()
  • Loading branch information
mdelez committed Sep 14, 2020
1 parent 185eb76 commit a8a1ddb
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 57 deletions.
11 changes: 7 additions & 4 deletions projects/dsp-ui/src/lib/action/action.module.ts
Expand Up @@ -4,12 +4,15 @@ import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ConfirmationDialogComponent } from './components/confirmation-dialog/confirmation-dialog.component';
import { ConfirmationMessageComponent } from './components/confirmation-dialog/confirmation-message/confirmation-message.component';
import { LoginFormComponent } from './components/login-form/login-form.component';
import { MessageComponent } from './components/message/message.component';
import { ProgressIndicatorComponent } from './components/progress-indicator/progress-indicator.component';
Expand All @@ -24,8 +27,6 @@ import { FormattedBooleanPipe } from './pipes/formatting/formatted-boolean.pipe'
import { KnoraDatePipe } from './pipes/formatting/knoradate.pipe';
import { StringifyStringLiteralPipe } from './pipes/string-transformation/stringify-string-literal.pipe';
import { TruncatePipe } from './pipes/string-transformation/truncate.pipe';
import { ConfirmationDialogComponent } from './components/confirmation-dialog/confirmation-dialog.component';
import { MatDialogModule } from '@angular/material/dialog';

@NgModule({
declarations: [
Expand All @@ -43,7 +44,8 @@ import { MatDialogModule } from '@angular/material/dialog';
SortButtonComponent,
StringLiteralInputComponent,
LoginFormComponent,
ConfirmationDialogComponent
ConfirmationDialogComponent,
ConfirmationMessageComponent
],
imports: [
CommonModule,
Expand Down Expand Up @@ -75,7 +77,8 @@ import { MatDialogModule } from '@angular/material/dialog';
StringLiteralInputComponent,
LoginFormComponent,
ConfirmationDialogComponent,
GndDirective
GndDirective,
ConfirmationMessageComponent
]
})

Expand Down
@@ -1,6 +1,6 @@
<mat-dialog-content>
<p class="title"> {{data.title}} </p>
<p *ngIf="data.message && data.message.trim() !== ''" class="message" [innerHTML]="data.message"></p>
<p class="title"> Are you sure you want to delete this value from {{data.value.propertyLabel}}?</p>
<dsp-confirmation-message [value]="data.value"></dsp-confirmation-message>
</mat-dialog-content>
<mat-dialog-actions class="action-buttons">
<button class="cancel" mat-raised-button mat-dialog-close>{{data.buttonTextCancel}}</button>
Expand Down
Expand Up @@ -4,15 +4,6 @@
text-align: center;
}

.message {
font-size: 16px;
background-color: #ededf5;
border: 1px solid #d8d8df;
border-radius: 5px;
padding: 20px 10px 20px 10px;
text-align: center;
}

.action-buttons {
float: right;
}
@@ -1,12 +1,13 @@
import { OverlayContainer } from '@angular/cdk/overlay';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { Component } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
import { async, 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 } from './confirmation-dialog.component';

/**
Expand All @@ -15,18 +16,26 @@ import { ConfirmationDialogComponent } from './confirmation-dialog.component';
@Component({
template: `<p> {{confirmationDialogResponse}} </p>`
})
class ConfirmationDialogTestHostComponent {
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: {
title: 'Title',
message: 'Message',
value: this.testValue,
buttonTextOk: 'OK',
buttonTextCancel: 'Cancel'
}
Expand All @@ -40,6 +49,13 @@ class ConfirmationDialogTestHostComponent {
}
}

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

constructor() { }
}

describe('ConfirmationDialogComponent', () => {
let testHostComponent: ConfirmationDialogTestHostComponent;
let testHostFixture: ComponentFixture<ConfirmationDialogTestHostComponent>;
Expand All @@ -50,7 +66,8 @@ describe('ConfirmationDialogComponent', () => {
TestBed.configureTestingModule({
declarations: [
ConfirmationDialogComponent,
ConfirmationDialogTestHostComponent
ConfirmationDialogTestHostComponent,
MockConfirmationMessageComponent
],
imports: [
MatDialogModule,
Expand Down Expand Up @@ -88,22 +105,22 @@ describe('ConfirmationDialogComponent', () => {
overlayContainer.ngOnDestroy();
});

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

testHostComponent.openDialog();

testHostFixture.detectChanges();

testHostFixture.whenStable().then(() => {
const dialogDiv = document.querySelector('mat-dialog-container');
expect(dialogDiv).toBeTruthy();
await testHostFixture.whenStable();

const dialogTitle = dialogDiv.querySelector('.title');
expect(dialogTitle.innerHTML.trim()).toEqual('Title');
const dialogDiv = document.querySelector('mat-dialog-container');
expect(dialogDiv).toBeTruthy();

const dialogMessage = dialogDiv.querySelector('.message');
expect(dialogMessage.innerHTML.trim()).toEqual('Message');
});
const dspConfirmMsg = document.querySelector('dsp-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?');

});

Expand Down
@@ -1,9 +1,9 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { ReadValue } from '@dasch-swiss/dsp-js';

export class ConfirmationDialogData {
title: string;
message: string;
value: ReadValue;
buttonTextOk: string;
buttonTextCancel: string;
}
Expand Down
@@ -0,0 +1,6 @@
<div class="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>
</div>
@@ -0,0 +1,8 @@
.message {
font-size: 16px;
background-color: #ededf5;
border: 1px solid #d8d8df;
border-radius: 5px;
padding: 20px 10px 20px 10px;
text-align: center;
}
@@ -0,0 +1,87 @@
import { Component, OnInit } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { MockResource, ReadIntValue } from '@dasch-swiss/dsp-js';
import { ConfirmationMessageComponent } from './confirmation-message.component';

/**
* Test host component to simulate parent component with a confirmation dialog.
*/
@Component({
template: `<dsp-confirmation-message [value]="testValue"></dsp-confirmation-message>`
})
class ConfirmationMessageTestHostComponent implements OnInit {

testValue: ReadIntValue;

constructor() {
}

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

describe('ConfirmationMessageComponent', () => {
let testHostComponent: ConfirmationMessageTestHostComponent;
let testHostFixture: ComponentFixture<ConfirmationMessageTestHostComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
ConfirmationMessageTestHostComponent,
ConfirmationMessageComponent
]
})
.compileComponents();
}));

beforeEach(() => {
testHostFixture = TestBed.createComponent(ConfirmationMessageTestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
});

it('should create', () => {
expect(testHostComponent).toBeTruthy();
});

it('should bind the values correctly', () => {
testHostComponent.testValue.valueHasComment = 'My comment';
testHostFixture.detectChanges();

const hostCompDe = testHostFixture.debugElement;
const valueComponentDe = hostCompDe.query(By.directive(ConfirmationMessageComponent));

expect(valueComponentDe).toBeTruthy();

const label = valueComponentDe.query(By.css('.val-label')).nativeElement;
expect(label.innerText).toEqual('Confirming this action will delete the following value from Integer:');

const value = valueComponentDe.query(By.css('.val-value')).nativeElement;
expect(value.innerText).toEqual('Value: 1');

const comment = valueComponentDe.query(By.css('.val-comment')).nativeElement;
expect(comment.innerText).toEqual('Value Comment: My comment');

const creationDate = valueComponentDe.query(By.css('.val-creation-date')).nativeElement;
expect(creationDate.innerText).toEqual('Value Creation Date: 2018-05-28T15:52:03.897Z');

});

it('should default to "no comment" if the value does not contain a comment', () => {
testHostComponent.testValue.valueHasComment = null;
testHostFixture.detectChanges();

const hostCompDe = testHostFixture.debugElement;
const valueComponentDe = hostCompDe.query(By.directive(ConfirmationMessageComponent));

expect(valueComponentDe).toBeTruthy();

const comment = valueComponentDe.query(By.css('.val-comment')).nativeElement;
expect(comment.innerText).toEqual('Value Comment: No comment');

});
});
@@ -0,0 +1,15 @@
import { Component, Input } from '@angular/core';
import { ReadValue } from '@dasch-swiss/dsp-js';

@Component({
selector: 'dsp-confirmation-message',
templateUrl: './confirmation-message.component.html',
styleUrls: ['./confirmation-message.component.scss']
})
export class ConfirmationMessageComponent {

@Input() value: ReadValue;

constructor() { }

}
1 change: 1 addition & 0 deletions projects/dsp-ui/src/lib/action/index.ts
Expand Up @@ -18,6 +18,7 @@ export * from './components/sort-button/sort-button.component';
export * from './components/login-form/login-form.component';
export * from './components/string-literal-input/string-literal-input.component';
export * from './components/confirmation-dialog/confirmation-dialog.component';
export * from './components/confirmation-dialog/confirmation-message/confirmation-message.component';

// directives
export * from './directives/admin-image/admin-image.directive';
Expand Down
Expand Up @@ -186,9 +186,7 @@ export class DisplayEditComponent implements OnInit {
*/
openDialog() {
const dialogData = new ConfirmationDialogData();
dialogData.title = 'Are you sure want to delete this value from ' + this.displayValue.propertyLabel + '?';
dialogData.message = 'Confirming this action will delete the following value from ' +
this.displayValue.propertyLabel + ':<br/><br/>' + this._generateValueInfo();
dialogData.value = this.displayValue;
dialogData.buttonTextOk = 'Yes, delete the value';
dialogData.buttonTextCancel = 'No, keep the value';

Expand Down Expand Up @@ -279,21 +277,4 @@ export class DisplayEditComponent implements OnInit {
this.backgroundColor = '';
}

/**
* Generate the message body for the confirmation dialog.
*
* @returns A string consisting of the values: value, comment, and creation date.
*/
private _generateValueInfo(): string {
const value = this.displayValue.strval;
const comment = this.displayValue.valueHasComment ? this.displayValue.valueHasComment : 'No comment';
const creationDate = new Date(this.displayValue.valueCreationDate).toString();

const message = '<b>Value:</b> ' + value +
'<br/><br/><b>Value Comment:</b> ' + comment +
'<br/><br/><b>Value Creation Date:</b> ' + creationDate;

return message;
}

}
14 changes: 8 additions & 6 deletions src/app/action-playground/action-playground.component.ts
@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ApiResponseError, StringLiteral } from '@dasch-swiss/dsp-js';
import { ApiResponseError, ReadValue, StringLiteral } from '@dasch-swiss/dsp-js';
import { ConfirmationDialogComponent, ConfirmationDialogData, DspMessageData, SortingService } from '@dasch-swiss/dsp-ui';

@Component({
Expand All @@ -10,9 +10,6 @@ import { ConfirmationDialogComponent, ConfirmationDialogData, DspMessageData, So
})
export class ActionPlaygroundComponent implements OnInit {

// loading: boolean;
// session: Session;

sortProps: any = [
{
key: 'firstname',
Expand Down Expand Up @@ -174,9 +171,14 @@ export class ActionPlaygroundComponent implements OnInit {
// confirmation dialog

openDialog() {
const testValue = new ReadValue();
testValue.strval = 'My data 101010101';
testValue.propertyLabel = 'My label';
testValue.valueCreationDate = '1993-10-10T19:11:00.00Z';
testValue.valueHasComment = 'My comment';

const dialogData = new ConfirmationDialogData();
dialogData.title = 'Are you sure want to do this?';
dialogData.message = 'Confirming this action will delete the value. (Not really though, this is just a test message)';
dialogData.value = testValue;
dialogData.buttonTextOk = 'Yes, delete the value';
dialogData.buttonTextCancel = 'No, keep the value';

Expand Down

0 comments on commit a8a1ddb

Please sign in to comment.