Skip to content

Commit

Permalink
fix: 'submit quote request' and 'copy submitted quote request' from m…
Browse files Browse the repository at this point in the history
…odal dialog should not navigate to my account (#112)
  • Loading branch information
Sebastian-Haehnlein authored and shauke committed Feb 24, 2020
1 parent 553fedc commit 8039fe5
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ describe('Quote Handling as Anonymous User', () => {

it('user should be able to submit quote request', () => {
at(ProductDetailPage, page => page.addProductToQuoteRequest());
at(QuoteRequestDialog, dialog => dialog.submitQuoteRequest());
at(QuoteDetailPage, page => {
page.productId.eq(0).should('contain', _.product.sku);
page.quoteState.should('have.text', 'Submitted');
at(QuoteRequestDialog, dialog => {
dialog.submitQuoteRequest();
dialog.productId.eq(0).should('contain', _.product.sku);
dialog.quoteState.should('have.text', 'Submitted');
dialog.hide();
});
});

it('user should log out', () => {
at(QuoteDetailPage, page => page.header.logout());
at(ProductDetailPage, page => page.header.logout());
at(HomePage);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ describe('Quote Handling', () => {
at(FamilyPage, page => page.productList.addProductToQuoteRequest(_.product.sku));
at(QuoteRequestDialog, dialog => {
dialog.submitQuoteRequest();
dialog.gotoQuoteDetail();
});
at(QuoteDetailPage, page => {
page.quoteState.should('have.text', 'Submitted');
Expand All @@ -109,6 +110,7 @@ describe('Quote Handling', () => {
at(FamilyPage, page => page.productList.addProductToQuoteRequest(_.product.sku));
at(QuoteRequestDialog, dialog => {
dialog.submitQuoteRequest();
dialog.gotoQuoteDetail();
});
at(QuoteDetailPage, page => {
page.copyQuoteRequest();
Expand Down
4 changes: 2 additions & 2 deletions src/app/extensions/quoting/facades/quoting.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ export class QuotingFacade {
this.store.dispatch(new UpdateSubmitQuoteRequest(payload));
}

copyQuoteRequest() {
this.store.dispatch(new CreateQuoteRequestFromQuoteRequest());
copyQuoteRequest(preventRedirect?: boolean) {
this.store.dispatch(new CreateQuoteRequestFromQuoteRequest({ redirect: !preventRedirect }));
}

updateQuoteRequestItem(update: LineItemUpdate) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<ng-container *ngIf="activeQuoteRequest$ | async as quote">
<ng-container *ngIf="selectedQuoteRequest$ | async as quote">
<div class="modal-header">
<h2 class="modal-title" *ngIf="quote">
<!-- Titel and Description -->
<ng-container *ngIf="quote.displayName; else noDisplayName">
{{ 'quote.edit.unsubmitted.quote_request_details.text' | translate }} - {{ quote.displayName }}
<ng-container *ngIf="quote.state === 'Submitted'; else quoteTitle">
{{ 'quote.edit.submitted.heading' | translate }}
</ng-container>
<ng-template #noDisplayName>
{{ 'quote.edit.unsubmitted.quote_request_details.text' | translate }} - {{ quote.number }}
<ng-template #quoteTitle>
{{ 'quote.edit.unsubmitted.quote_request_details.text' | translate }} - {{ quote.displayName || quote.number }}
</ng-template>
</h2>
<button type="button" class="close" [attr.aria-label]="'dialog.close.text' | translate" (click)="hide()">
Expand All @@ -16,6 +16,24 @@ <h2 class="modal-title" *ngIf="quote">

<form [formGroup]="form" class="form-horizontal form-horizontal-inline">
<div class="modal-body">
<!-- Submitted -->
<ng-container *ngIf="quote.state === 'Submitted' && user$ | async as user">
<p>
{{ 'quote.edit.submitted.your_quote_number.text' | translate }}
<a [routerLink]="['/account/quote-request', quote.id]" (click)="hide()">{{ quote.number }}</a>
</p>
<p
[ishServerHtml]="
'quote.edit.submitted.your_quote_request.text'
| translate: { '0': 'route://account/quote-list', '1': 'route://account' }
"
[callbacks]="{
callbackHideDialogModal: callbackHideDialogModal
}"
></p>
<p>{{ 'quote.edit.submitted.we_will_email.text' | translate: { '0': user.email } }}</p>
</ng-container>

<ng-container *ngIf="quote">
<div class="row">
<label class="col-4 col-md-3 col-xl-2 col-form-label">{{
Expand All @@ -39,28 +57,45 @@ <h2 class="modal-title" *ngIf="quote">

<div class="section">
<!-- displayName -->
<ish-input
[form]="form"
controlName="displayName"
label="quote.edit.unsubmitted.name.label"
labelClass="col-4 col-md-3 col-xl-2"
inputClass="col-8 col-md-9 col-xl-10"
maxLength="256"
[placeholder]="'quote.edit.unsubmitted.enter_an_optional_name.text'"
></ish-input>
<ng-container *ngIf="quote.state != 'Submitted'; else staticDisplayName">
<ish-input
[form]="form"
controlName="displayName"
label="quote.edit.unsubmitted.name.label"
labelClass="col-4 col-md-3 col-xl-2"
inputClass="col-8 col-md-9 col-xl-10"
maxLength="256"
[placeholder]="'quote.edit.unsubmitted.enter_an_optional_name.text'"
></ish-input>
</ng-container>
<ng-template #staticDisplayName>
<div class="row has-feedback">
<label class="col-4 col-md-3 col-xl-2 col-form-label">{{
'quote.edit.unsubmitted.name.label' | translate
}}</label>
<div class="col-8 col-md-9 col-xl-10">
<p class="form-control-plaintext">{{ quote.displayName }}</p>
</div>
</div>
</ng-template>

<!-- description -->
<div class="row form-group">
<label for="#SHOUD_EQUAL_TEXTAREA_ID#" class="col-form-label col-4 col-md-3 col-xl-2">{{
<label for="quote-description" class="col-form-label col-4 col-md-3 col-xl-2">{{
'quote.edit.unsubmitted.comment.label' | translate
}}</label>
<div class="col-8 col-md-9 col-xl-10">
<textarea
formControlName="description"
class="form-control"
[placeholder]="'quote.edit.unsubmitted.provide_comment.text' | translate"
>
</textarea>
<!-- ><isif condition="#QuoteEditForm:Invalid#"><isprint value="#QuoteEditForm:Description:Value#"><iselse><isprint value="#Quote:Description#"></isif></textarea> -->
<ng-container *ngIf="quote.state != 'Submitted'; else staticDescription">
<textarea
formControlName="description"
class="form-control"
[placeholder]="'quote.edit.unsubmitted.provide_comment.text' | translate"
id="quote-description"
></textarea>
</ng-container>
<ng-template #staticDescription>
<p class="form-control-plaintext">{{ quote.description }}</p>
</ng-template>
</div>
</div>
</div>
Expand All @@ -85,27 +120,31 @@ <h3>{{ 'quote.items.table.heading' | translate }}</h3>

<div class="modal-footer flex-wrap flex-row-reverse justify-content-between">
<div>
<button
*ngIf="quote"
type="submit"
class="btn btn-secondary"
[disabled]="!quote"
(click)="update()"
data-testing-id="saveQuoteRequest"
>
{{ 'quote.edit.button.save.label' | translate }}
</button>
<button
*ngIf="quote"
[routerLink]="'/account/quote-request/' + quote.id"
type="submit"
class="btn btn-primary"
[disabled]="quote.items.length === 0"
(click)="submit()"
data-testing-id="submitQuoteRequest"
>
{{ 'quote.edit.button.submit.label' | translate }}
</button>
<ng-container *ngIf="quote.state != 'Submitted'; else copyQuoteRequest">
<button
type="submit"
class="btn btn-secondary"
[disabled]="!quote"
(click)="update()"
data-testing-id="saveQuoteRequest"
>
{{ 'quote.edit.button.save.label' | translate }}
</button>
<button
type="submit"
class="btn btn-primary"
[disabled]="quote.items.length === 0"
(click)="submit()"
data-testing-id="submitQuoteRequest"
>
{{ 'quote.edit.button.submit.label' | translate }}
</button>
</ng-container>
<ng-template #copyQuoteRequest>
<button class="btn btn-secondary" name="copy" type="submit" (click)="copy()">
{{ 'quote.edit.button.create_new_from_quote.label' | translate }}
</button>
</ng-template>
</div>
<div class="d-md-none row form-group md-left">
<a routerLink="/account/quote-list" (click)="hide()">{{ 'quote.edit.back_to_quotes.link' | translate }}</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import { ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { MockComponent } from 'ng-mocks';
import { MockComponent, MockDirective, MockPipe } from 'ng-mocks';
import { EMPTY, of } from 'rxjs';
import { anything, capture, instance, mock, verify, when } from 'ts-mockito';

import { ServerHtmlDirective } from 'ish-core/directives/server-html.directive';
import { AccountFacade } from 'ish-core/facades/account.facade';
import { MessageFacade } from 'ish-core/facades/message.facade';
import { DatePipe } from 'ish-core/pipes/date.pipe';
import { LineItemListComponent } from 'ish-shared/components/basket/line-item-list/line-item-list.component';
import { LoadingComponent } from 'ish-shared/components/common/loading/loading.component';
import { InputComponent } from 'ish-shared/forms/components/input/input.component';
Expand All @@ -23,10 +26,12 @@ describe('Product Add To Quote Dialog Component', () => {
let element: HTMLElement;
let quotingFacade: QuotingFacade;
let messageFacade: MessageFacade;
let accountFacade: AccountFacade;

beforeEach(async(() => {
quotingFacade = mock(QuotingFacade);
messageFacade = mock(MessageFacade);
accountFacade = mock(AccountFacade);

TestBed.configureTestingModule({
imports: [ReactiveFormsModule, RouterTestingModule, TranslateModule.forRoot()],
Expand All @@ -35,12 +40,15 @@ describe('Product Add To Quote Dialog Component', () => {
MockComponent(LineItemListComponent),
MockComponent(LoadingComponent),
MockComponent(QuoteStateComponent),
MockDirective(ServerHtmlDirective),
MockPipe(DatePipe),
ProductAddToQuoteDialogComponent,
],
providers: [
NgbActiveModal,
{ provide: QuotingFacade, useFactory: () => instance(quotingFacade) },
{ provide: MessageFacade, useFactory: () => instance(messageFacade) },
{ provide: AccountFacade, useFactory: () => instance(accountFacade) },
],
}).compileComponents();
}));
Expand All @@ -49,10 +57,11 @@ describe('Product Add To Quote Dialog Component', () => {
fixture = TestBed.createComponent(ProductAddToQuoteDialogComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
when(quotingFacade.activeQuoteRequest$).thenReturn(EMPTY);
});

it('should be created', () => {
when(quotingFacade.activeQuoteRequest$).thenReturn(EMPTY);
when(quotingFacade.quoteRequest$).thenReturn(EMPTY);

expect(component).toBeTruthy();
expect(element).toBeTruthy();
Expand All @@ -61,7 +70,7 @@ describe('Product Add To Quote Dialog Component', () => {

describe('Quote Request', () => {
beforeEach(() => {
when(quotingFacade.activeQuoteRequest$).thenReturn(
when(quotingFacade.quoteRequest$).thenReturn(
of({
id: 'ID',
type: 'QuoteRequest',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { Observable, Subject } from 'rxjs';
import { distinctUntilKeyChanged, filter, take, takeUntil } from 'rxjs/operators';
import { take, takeUntil } from 'rxjs/operators';

import { AccountFacade } from 'ish-core/facades/account.facade';
import { MessageFacade } from 'ish-core/facades/message.facade';
import { LineItemUpdate } from 'ish-core/models/line-item-update/line-item-update.model';
import { User } from 'ish-core/models/user/user.model';
import { whenTruthy } from 'ish-core/utils/operators';

import { QuotingFacade } from '../../../facades/quoting.facade';
Expand All @@ -17,8 +19,9 @@ import { QuoteRequest } from '../../../models/quote-request/quote-request.model'
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
activeQuoteRequest$: Observable<QuoteRequest>;
selectedQuoteRequest$: Observable<QuoteRequest>;
quoteRequestLoading$: Observable<boolean>;
user$: Observable<User>;

form: FormGroup;

Expand All @@ -27,7 +30,8 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
constructor(
public ngbActiveModal: NgbActiveModal,
private quotingFacade: QuotingFacade,
private messageFacade: MessageFacade
private messageFacade: MessageFacade,
private accountFacade: AccountFacade
) {
this.form = new FormGroup({
displayName: new FormControl(undefined, [Validators.maxLength(255)]),
Expand All @@ -36,10 +40,11 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.activeQuoteRequest$ = this.quotingFacade.activeQuoteRequest$;
this.user$ = this.accountFacade.user$;
this.selectedQuoteRequest$ = this.quotingFacade.quoteRequest$;
this.quoteRequestLoading$ = this.quotingFacade.quoteRequestLoading$;

this.activeQuoteRequest$
this.selectedQuoteRequest$
.pipe(
whenTruthy(),
takeUntil(this.destroy$)
Expand All @@ -48,11 +53,11 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
this.patchForm(quote);
});

this.activeQuoteRequest$
// make active quote request to selected
this.quotingFacade.activeQuoteRequest$
.pipe(
filter(quoteRequest => !!quoteRequest),
distinctUntilKeyChanged('id'),
takeUntil(this.destroy$)
whenTruthy(),
take(1)
)
.subscribe(quoteRequest => this.quotingFacade.selectQuoteRequest(quoteRequest.id));
}
Expand All @@ -76,7 +81,7 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
* @param item Item id and quantity pair that should be changed
*/
onUpdateItem(item: LineItemUpdate) {
this.activeQuoteRequest$
this.selectedQuoteRequest$
.pipe(
take(1),
whenTruthy()
Expand All @@ -96,7 +101,7 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
* Throws deleteQuoteRequest event when last item will be deleted.
*/
onDeleteItem(itemId: string) {
this.activeQuoteRequest$
this.selectedQuoteRequest$
.pipe(
take(1),
whenTruthy()
Expand All @@ -123,7 +128,6 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
} else {
this.quotingFacade.submitQuoteRequest();
}
this.hide();
}

/**
Expand All @@ -150,10 +154,26 @@ export class ProductAddToQuoteDialogComponent implements OnInit, OnDestroy {
return false;
}

/**
* Throws copyQuoteRequest event when copy button was clicked.
*/
copy() {
this.quotingFacade.copyQuoteRequest(true);
}

/**
* Hides modal dialog.
*/
hide() {
this.ngbActiveModal.close();
}

/**
* Callback function to hide modal dialog (used with ishServerHtml).
*/
get callbackHideDialogModal() {
return () => {
this.hide();
};
}
}
Loading

0 comments on commit 8039fe5

Please sign in to comment.