Skip to content

Commit

Permalink
refactor: introduce separate component for quote item list, remove qu…
Browse files Browse the repository at this point in the history
…oting from line-item-list
  • Loading branch information
dhhyi committed Nov 9, 2020
1 parent a3e1763 commit 4861060
Show file tree
Hide file tree
Showing 24 changed files with 537 additions and 89 deletions.
6 changes: 0 additions & 6 deletions src/app/core/models/line-item/line-item.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,10 @@ export interface LineItem {
total: PriceItem;
undiscountedTotal;
valueRebatesTotal?: PriceItem;

// attributes needed for quote feature
originTotal?: PriceItem;
};
isHiddenGift: boolean;
isFreeGift: boolean;

// attributes needed for quote feature
originSingleBasePrice?: PriceItem;

isQuantityFixed?: boolean;
}

Expand Down
3 changes: 3 additions & 0 deletions src/app/extensions/quoting/facades/quote-context.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export abstract class QuoteContextFacade
entityAsQuoteRequest: QuoteRequest;
entityAsQuote: Quote;
state: QuoteStatus;
editable: boolean;
justSubmitted: boolean;
}>
implements OnDestroy {
Expand Down Expand Up @@ -88,6 +89,8 @@ export abstract class QuoteContextFacade
'state',
timer(0, 2000).pipe(switchMapTo(this.select('entity').pipe(map(QuotingHelper.state))), distinctUntilChanged())
);

this.connect('editable', this.select('state').pipe(map(state => state === 'New')));
}

updateItem(item: LineItemUpdate) {
Expand Down
30 changes: 13 additions & 17 deletions src/app/extensions/quoting/models/quoting/quoting.mapper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ describe('Quoting Mapper', () => {
"type": "Money",
"value": 1002.95,
},
"originTotal": Object {
"currency": "USD",
"type": "Money",
"value": 1002.95,
},
"productSKU": "10696946",
"quantity": Object {
"type": "Quantity",
Expand All @@ -221,17 +226,10 @@ describe('Quoting Mapper', () => {
"type": "Money",
"value": 10.95,
},
"totals": Object {
"originTotal": Object {
"currency": "USD",
"type": "Money",
"value": 1002.95,
},
"total": Object {
"currency": "USD",
"type": "Money",
"value": 10.95,
},
"total": Object {
"currency": "USD",
"type": "Money",
"value": 10.95,
},
},
],
Expand Down Expand Up @@ -363,12 +361,10 @@ describe('Quoting Mapper', () => {
"type": "Money",
"value": 964.5,
},
"totals": Object {
"total": Object {
"currency": "USD",
"type": "Money",
"value": 964.5,
},
"total": Object {
"currency": "USD",
"type": "Money",
"value": 964.5,
},
},
],
Expand Down
8 changes: 3 additions & 5 deletions src/app/extensions/quoting/models/quoting/quoting.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,8 @@ export class QuotingMapper {

singleBasePrice: PriceMapper.fromData(item.singlePrice),
originSingleBasePrice: PriceMapper.fromData(item.originSinglePrice),
totals: {
total: PriceMapper.fromData(item.totalPrice),
originTotal: PriceMapper.fromData(item.originTotalPrice),
},
total: PriceMapper.fromData(item.totalPrice),
originTotal: PriceMapper.fromData(item.originTotalPrice),
})),
};
return mapped;
Expand Down Expand Up @@ -110,7 +108,7 @@ export class QuotingMapper {
productSKU: itemData.productSKU,
quantity: itemData.quantity,
singleBasePrice: PriceMapper.fromData(itemData.singlePrice),
totals: { total: PriceMapper.fromData(itemData.totalPrice) },
total: PriceMapper.fromData(itemData.totalPrice),
};
}
}),
Expand Down
10 changes: 4 additions & 6 deletions src/app/extensions/quoting/models/quoting/quoting.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,15 @@ export interface QuoteRequestItem extends QuoteItemStub {
quantity: Attribute<number>;

singleBasePrice: Price;
totals: { total: Price };
total: Price;
}

interface QuoteItem extends QuoteRequestItem {
export interface QuoteItem extends QuoteRequestItem {
originQuantity: Attribute<number>;

originSingleBasePrice: Price;
totals: {
total: Price;
originTotal: Price;
};
total: Price;
originTotal: Price;
}

interface QuoteBase<ItemType> extends QuoteStub {
Expand Down
4 changes: 4 additions & 0 deletions src/app/extensions/quoting/quoting.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ProductAddToQuoteComponent } from './shared/product-add-to-quote/produc
import { QuoteEditComponent } from './shared/quote-edit/quote-edit.component';
import { QuoteExpirationDateComponent } from './shared/quote-expiration-date/quote-expiration-date.component';
import { QuoteInteractionsComponent } from './shared/quote-interactions/quote-interactions.component';
import { QuoteLineItemListElementComponent } from './shared/quote-line-item-list-element/quote-line-item-list-element.component';
import { QuoteLineItemListComponent } from './shared/quote-line-item-list/quote-line-item-list.component';
import { QuoteStateComponent } from './shared/quote-state/quote-state.component';
import { QuoteViewComponent } from './shared/quote-view/quote-view.component';
import { QuoteWidgetComponent } from './shared/quote-widget/quote-widget.component';
Expand All @@ -21,6 +23,8 @@ import { QuoteWidgetComponent } from './shared/quote-widget/quote-widget.compone
QuoteEditComponent,
QuoteExpirationDateComponent,
QuoteInteractionsComponent,
QuoteLineItemListComponent,
QuoteLineItemListElementComponent,
QuoteStateComponent,
QuoteViewComponent,
QuoteWidgetComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,7 @@
<!-- Quote Item List -->
<div class="section">
<h3>{{ 'quote.items.table.heading' | translate }}</h3>
<ish-line-item-list
*ngIf="quote.items"
[lineItems]="quote.items"
[editable]="true"
lineItemViewType="availability"
[total]="quote.total"
(updateItem)="onUpdateItem($event)"
(deleteItem)="onDeleteItem($event)"
></ish-line-item-list>
<ish-quote-line-item-list *ngIf="quote.items"></ish-quote-line-item-list>
</div>
</form>
</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { EMPTY } from 'rxjs';
import { instance, mock, when } from 'ts-mockito';

import { InplaceEditComponent } from 'ish-shared/components/common/inplace-edit/inplace-edit.component';
import { LineItemListComponent } from 'ish-shared/components/line-item/line-item-list/line-item-list.component';

import { QuoteContextFacade } from '../../facades/quote-context.facade';
import { QuoteLineItemListComponent } from '../quote-line-item-list/quote-line-item-list.component';
import { QuoteStateComponent } from '../quote-state/quote-state.component';

import { QuoteEditComponent } from './quote-edit.component';
Expand All @@ -26,7 +26,7 @@ describe('Quote Edit Component', () => {
imports: [ReactiveFormsModule, TranslateModule.forRoot()],
declarations: [
MockComponent(InplaceEditComponent),
MockComponent(LineItemListComponent),
MockComponent(QuoteLineItemListComponent),
MockComponent(QuoteStateComponent),
QuoteEditComponent,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { FormControl, FormGroup } from '@angular/forms';
import { pick } from 'lodash-es';
import { Observable } from 'rxjs';

import { LineItemUpdate } from 'ish-core/models/line-item-update/line-item-update.model';

import { QuoteContextFacade } from '../../facades/quote-context.facade';
import { QuoteRequest } from '../../models/quoting/quoting.model';

Expand Down Expand Up @@ -52,12 +50,4 @@ export class QuoteEditComponent implements OnInit {
reset() {
this.form.reset(this.valuesFromQuote);
}

onUpdateItem(item: LineItemUpdate) {
this.context.updateItem(item);
}

onDeleteItem(itemId: string) {
this.context.deleteItem(itemId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<div
*ngIf="product$ | async as product"
class="row list-item-row list-item-row-big"
data-testing-id="product-list-item"
>
<!-- Product Image -->
<div class="col-2 list-item">
<a [routerLink]="product | ishProductRoute">
<ish-product-image [product]="product" imageType="S" class="product-image"></ish-product-image>
</a>
</div>

<div class="col-7 col-md-6 col-xl-4 list-item">
<!--Product Description -->
<div class="pli-description">
<a class="product-title" [routerLink]="product | ishProductRoute">{{ product.name }}</a>

<!-- Product ID -->
<ish-product-id [product]="product"></ish-product-id>

<!-- Product Variations -->
<ish-product-variation-display
*ngIf="isVariationProduct(product)"
[product]="product"
></ish-product-variation-display>
<!-- Product Bundles -->
<ish-product-bundle-display
*ngIf="isBundleProduct(product)"
[productBundleSKU]="product.sku"
></ish-product-bundle-display>

<ish-product-inventory [product]="product"></ish-product-inventory>
<div *ngIf="editable$ | async" class="d-flex align-items-center">
<ish-lazy-product-add-to-order-template
[class]="'btn btn-link btn-tool add-to-order-template'"
[product]="product"
displayType="icon"
[quantity]="lineItem.quantity.value"
></ish-lazy-product-add-to-order-template>
<ish-lazy-product-add-to-wishlist
class="btn-tool ml-0"
[product]="product"
displayType="icon"
></ish-lazy-product-add-to-wishlist>
<a
class="btn-tool"
[attr.data-testing-id]="'remove-pli-' + lineItem.id + '-element'"
[attr.data-id]="lineItem.id"
title="{{ 'shopping_cart.remove.item.button.label' | translate }}"
(click)="onDeleteItem()"
>
<fa-icon [icon]="['fas', 'trash-alt']"></fa-icon>
</a>
</div>
</div>

<!-- mobile quantity -->
<div class="quantity d-xl-none">
<div class="form-group">
<ng-container *ngIf="editable$ | async; else readonlyQuantity">
<ish-input
[form]="form$ | async"
controlName="quantity"
type="number"
label="shopping_cart.pli.qty.label"
labelClass="d-xl-none col-form-label"
inputClass="w-100"
[min]="0"
markRequiredLabel="off"
[max]="product.maxOrderQuantity"
[errorMessages]="{
required: 'shopping_cart.quantity.invalid.error',
max: 'shopping_cart.quantity.invalid.error.maxvalue',
integer: 'shopping_cart.quantity.invalid.error'
}"
></ish-input>
</ng-container>
<ng-template #readonlyQuantity>
<label class="d-xl-none col-form-label">{{ 'shopping_cart.pli.qty.label' | translate }}</label>
{{ lineItem.quantity.value | number }}
</ng-template>
</div>
</div>
</div>

<!-- desktop quantity -->
<div class="quantity col-xl-2 list-item d-none d-xl-flex">
<div class="form-group w-100" [ngClass]="{ 'text-right': editable$ | async }">
<ng-container *ngIf="editable$ | async; else readonlyQuantity">
<ish-input
[form]="form$ | async"
controlName="quantity"
type="number"
label="shopping_cart.pli.qty.label"
labelClass="d-xl-none col-form-label"
inputClass="w-100"
[min]="0"
markRequiredLabel="off"
[max]="product.maxOrderQuantity"
[errorMessages]="{
required: 'shopping_cart.quantity.invalid.error',
max: 'shopping_cart.quantity.invalid.error.maxvalue',
integer: 'shopping_cart.quantity.invalid.error'
}"
></ish-input>
</ng-container>
<ng-template #readonlyQuantity>
<label class="d-xl-none col-form-label">{{ 'shopping_cart.pli.qty.label' | translate }}</label>
{{ lineItem.quantity.value | number }}
</ng-template>
</div>
</div>

<!-- Prices -->
<div class="col-md-2 d-none d-md-block list-item column-price single-price">
<!-- Original Single Base Price -->
<p *ngIf="lineItem.originSingleBasePrice">
{{ 'quote.items.original_price.label' | translate }} {{ lineItem.originSingleBasePrice | ishPrice }}
</p>

<!-- (Suggested) Single Base Price -->
<p>
<ng-container *ngIf="lineItem.originSingleBasePrice">{{
'quote.items.suggested_price.label' | translate
}}</ng-container>
{{ lineItem.singleBasePrice | ishPrice }}
</p>
</div>
<div class="col-3 col-md-2 list-item column-price">
<div>
<p *ngIf="lineItem.originTotal">{{ lineItem.originTotal | ishPrice }}</p>

<!-- (Suggested) Total Price -->
<span *ngIf="lineItem.originTotal" class="d-md-none">{{ 'quote.items.suggested_price.label' | translate }}</span>
<div data-testing-id="total-price">{{ lineItem.total | ishPrice }}</div>
</div>
</div>
</div>
Loading

1 comment on commit 4861060

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Azure Demo Servers are available:

Please sign in to comment.