Browse Source

SPA: Merge

pull/49/merge
Carlos Cañizares Estévez 8 years ago
parent
commit
f2681b93d2
38 changed files with 388 additions and 290 deletions
  1. +76
    -63
      src/Web/WebMVC/Views/Order/Create.cshtml
  2. +4
    -4
      src/Web/WebMVC/Views/Order/Detail.cshtml
  3. +44
    -66
      src/Web/WebMVC/Views/Order/_OrderItems.cshtml
  4. +1
    -1
      src/Web/WebMVC/wwwroot/css/app.min.css
  5. +1
    -0
      src/Web/WebMVC/wwwroot/css/basket/basket-status/basket-status.component.css
  6. +1
    -0
      src/Web/WebMVC/wwwroot/css/orders/orders-new/orders-new.component.css
  7. +3
    -1
      src/Web/WebMVC/wwwroot/css/shared/components/pager/pager.css
  8. +0
    -5
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts
  9. +1
    -0
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket-status/basket-status.component.html
  10. +6
    -0
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket-status/basket-status.component.scss
  11. +3
    -3
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.component.html
  12. +1
    -4
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.component.ts
  13. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.module.ts
  14. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.component.ts
  15. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.service.ts
  16. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.html
  17. +12
    -12
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-new/orders-new.component.html
  18. +1
    -0
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-new/orders-new.component.scss
  19. +3
    -4
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-new/orders-new.component.ts
  20. +4
    -5
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts
  21. +2
    -3
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/identity/identity.ts
  22. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/pager/pager.html
  23. +6
    -0
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/pager/pager.scss
  24. +1
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/pager/pager.ts
  25. +3
    -3
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/basket.model.ts
  26. +6
    -7
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/basketItem.model.ts
  27. +4
    -4
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalog.model.ts
  28. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogBrand.model.ts
  29. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogType.model.ts
  30. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts
  31. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/orderItem.model.ts
  32. +6
    -6
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/pager.model.ts
  33. +4
    -3
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/basket.wrapper.service.ts
  34. +5
    -5
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/data.service.ts
  35. +68
    -69
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/security.service.ts
  36. +2
    -2
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/shared.module.ts
  37. +5
    -4
      src/Web/WebSPA/eShopOnContainers.WebSPA/package.json
  38. +101
    -0
      src/Web/WebSPA/eShopOnContainers.WebSPA/tslint.json

+ 76
- 63
src/Web/WebMVC/Views/Order/Create.cshtml View File

@ -5,79 +5,92 @@
@{ @{
ViewData["Title"] = "New Order"; ViewData["Title"] = "New Order";
} }
<div class="brand-header-block">
<ul class="container">
<li class="brand-header-back"><a asp-area="" asp-controller="Cart" asp-action="Index">Back to cart</a></li>
</ul>
</div>
<div class="container order-create-container">
@Html.Partial("_Header", new Header() { Controller = "Cart", Text = "Back to cart" })
<div class="container">
<form method="post" asp-controller="Order" asp-action="Create"> <form method="post" asp-controller="Order" asp-action="Create">
<div asp-validation-summary="All" class="text-danger"></div>
<h4 class="order-create-section-title">SHIPPING ADDRESS</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="Street" class="control-label form-label">Address</label>
<input asp-for="Street" class="form-control form-input" />
<span asp-validation-for="Street" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="City" class="control-label form-label">City</label>
<input asp-for="City" class="form-control form-input" />
<span asp-validation-for="City" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="State" class="control-label form-label">State</label>
<input asp-for="State" class="form-control form-input" />
<span asp-validation-for="State" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="Country" class="control-label form-label">Country</label>
<input asp-for="Country" class="form-control form-input" />
<span asp-validation-for="Country" class="text-danger" />
</div>
</div>
<br /><br />
<div class="order-create-section-payment">
<h4 class="order-create-section-title">PAYMENT METHOD</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="CardNumber" class="control-label form-label">Card Number</label>
<input asp-for="CardNumber" class="form-control form-input" />
<span asp-validation-for="CardNumber" class="text-danger" />
<section class="esh-orders_new-section">
<h4 class="esh-orders_new-title">Shipping address</h4>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Street" class="esh-orders_new-title">Address</label>
<input asp-for="Street" class="form-control form-input" type="text" placeholder="Street"/>
<span asp-validation-for="Street" class="alert alert-danger" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="City" class="esh-orders_new-title">City</label>
<input asp-for="City" class="form-control form-input" type="text" placeholder="City"/>
<span asp-validation-for="City" class="alert alert-danger" />
</div>
</div> </div>
<div class="form-group col-sm-6">
<label asp-for="CardHolderName" class="control-label form-label">Cardholder Name</label>
<input asp-for="CardHolderName" class="form-control form-input" />
<span asp-validation-for="CardHolderName" class="text-danger" />
<div class="col-md-6">
<div class="form-group">
<label asp-for="State" class="esh-orders_new-title">State</label>
<input asp-for="State" class="form-control form-input" type="text" placeholder="State"/>
<span asp-validation-for="State" class="alert alert-danger" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="Country" class="esh-orders_new-title">Country</label>
<input asp-for="Country" class="form-control form-input" type="text" placeholder="Country"/>
<span asp-validation-for="Country" class="alert alert-danger" />
</div>
</div> </div>
</div> </div>
<div class="form-horizontal row">
<div class="form-group col-sm-3">
<label asp-for="CardExpirationShort" class="control-label form-label">Expiration Date</label>
<input asp-for="CardExpirationShort" placeholder="MM/YY" class="form-control form-select" />
<span asp-validation-for="CardExpirationShort" class="text-danger" />
</section>
<section class="esh-orders_new-section">
<h4 class="esh-orders_new-title">Payment method</h4>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="CardNumber" class="esh-orders_new-title">Card number</label>
<input asp-for="CardNumber" class="form-control form-input" type="text" placeholder="000000000"/>
<span asp-validation-for="CardNumber" class="alert alert-danger" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="CardHolderName" class="esh-orders_new-title">Cardholder name</label>
<input asp-for="CardHolderName" class="form-control form-input" type="text" placeholder="Cardholder"/>
<span asp-validation-for="CardHolderName" class="alert alert-danger" />
</div>
</div> </div>
<div class="form-group col-sm-3">
<label asp-for="CardSecurityNumber" class="control-label form-label">Security Code</label>
<input asp-for="CardSecurityNumber" class="form-control form-input form-input-small" />
<span asp-validation-for="CardSecurityNumber" class="text-danger" />
<div class="col-md-6">
<div class="form-group">
<label asp-for="CardExpirationShort" class="esh-orders_new-title">Expiration date</label>
<input asp-for="CardExpirationShort" class="form-control form-input" type="text" placeholder="00/00"/>
<span asp-validation-for="CardExpirationShort" class="alert alert-danger" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="CardSecurityNumber" class="esh-orders_new-title">Security code</label>
<input asp-for="CardSecurityNumber" class="form-control form-input" type="text" placeholder="000"/>
<span asp-validation-for="CardSecurityNumber" class="alert alert-danger" />
</div>
</div> </div>
</div> </div>
</div>
<br /><br />
<div class="col-md-12 order-create-section-items">
<section>
@*@await Component.InvokeAsync("CartList", new { user = UserManager.Parse(User) })*@
@await Html.PartialAsync("_OrderItems")
</section>
</div>
<div class="form-group">
<div class="col-md-offset-8 col-md-4">
<input type="submit" value="[ Place Order ]" name="action" class="btn btn-default btn-brand btn-cart" />
</section>
@await Html.PartialAsync("_OrderItems")
<section class="esh-orders_new-section">
<div class="form-group">
<div class="col-md-9">
</div>
<div class="col-md-2">
<input type="submit" value="[ Place Order ]" name="action" class="btn esh-orders_new-placeOrder" />
</div>
</div> </div>
</div>
</section>
</form> </form>
</div> </div>
@section Scripts { @section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");} @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
} }

+ 4
- 4
src/Web/WebMVC/Views/Order/Detail.cshtml View File

@ -46,7 +46,7 @@
<section class="esh-orders_detail-section"> <section class="esh-orders_detail-section">
<article class="esh-orders_detail-titles row"> <article class="esh-orders_detail-titles row">
<section class="esh-orders_detail-title col-xs-12">Order details</section>
<section class="esh-orders_detail-title col-xs-12">ORDER DETAILS</section>
</article> </article>
@for (int i = 0; i < Model.OrderItems.Count; i++) @for (int i = 0; i < Model.OrderItems.Count; i++)
@ -66,12 +66,12 @@
<section class="esh-orders_detail-section esh-orders_detail-section--right"> <section class="esh-orders_detail-section esh-orders_detail-section--right">
<article class="esh-orders_detail-titles esh-basket-titles--clean row"> <article class="esh-orders_detail-titles esh-basket-titles--clean row">
<section class="esh-orders_detail-title col-xs-10"></section>
<section class="esh-orders_detail-title col-xs-2">Total</section>
<section class="esh-orders_detail-title col-xs-9"></section>
<section class="esh-orders_detail-title col-xs-2">TOTAL</section>
</article> </article>
<article class="esh-orders_detail-items row"> <article class="esh-orders_detail-items row">
<section class="esh-orders_detail-item col-xs-10"></section>
<section class="esh-orders_detail-item col-xs-9"></section>
<section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ @Model.Total</section> <section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ @Model.Total</section>
</article> </article>
</section> </section>


+ 44
- 66
src/Web/WebMVC/Views/Order/_OrderItems.cshtml View File

@ -1,70 +1,48 @@
@model Microsoft.eShopOnContainers.WebMVC.Models.Order @model Microsoft.eShopOnContainers.WebMVC.Models.Order
<div class="col-md-12">
<section>
<table class="table">
<thead>
<tr>
<th class="cart-product-column">
PRODUCT
</th>
<th>
</th>
<th>
BRAND
</th>
<th>
PRICE
</th>
<th>
QUANTITY
</th>
<th>
COST
</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.OrderItems.Count; i++)
{
var item = Model.OrderItems[i];
<section class="esh-orders_new-section">
<article class="esh-orders_new-titles row">
<section class="esh-orders_new-title col-xs-12">Order details</section>
</article>
<tr>
<td class="cart-product-column">
<img class="cart-product-image" src="@item.PictureUrl" />
<input type="hidden" value="@item.PictureUrl" name=@("orderitems[" + i + "].PictureUrl") />
</td>
<td class="cart-product-column">
<span class="cart-product-column-name">@item.ProductName</span>
<input type="hidden" value="@item.ProductName" name=@("orderitems[" + i + "].ProductName") />
</td>
<td class="cart-product-column">ROSLYN</td>
<td class="cart-product-column">$ @item.UnitPrice
<input type="hidden" value="@item.UnitPrice" name=@("orderitems[" + i + "].UnitPrice") />
</td>
<td class="cart-product-column">@item.Units
<input type="hidden" value="@item.Units" name=@("orderitems[" + i + "].Units") />
</td>
<td class="cart-product-column cart-total-value">$ @Math.Round(item.Units * item.UnitPrice, 2)</td>
</tr>
}
<tr class="cart-totals">
<td></td>
<td></td>
<td></td>
<td></td>
<td>
</td>
<td>
<div class="cart-total-value">
<div class="cart-total-label"><span>TOTAL</span></div>
<span>$ @Model.Total</span>
<input type="hidden" value="@Model.Total" name="Total"/>
</div>
</td>
</tr>
</tbody>
</table>
</section>
</div>
@for (int i = 0; i < Model.OrderItems.Count; i++)
{
var item = Model.OrderItems[i];
<article class="esh-orders_new-items esh-orders_new-items--border row">
<section class="esh-orders_new-item col-md-4 hidden-md-down">
<img class="esh-orders_new-image" src="@item.PictureUrl">
<input type="hidden" value="@item.PictureUrl" name=@("orderitems[" + i + "].PictureUrl") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-4">
@item.ProductName
<input type="hidden" value="@item.ProductName" name=@("orderitems[" + i + "].ProductName") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
$ @item.UnitPrice
<input type="hidden" value="@item.UnitPrice" name=@("orderitems[" + i + "].UnitPrice") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-1">
@item.Units
<input type="hidden" value="@item.Units" name=@("orderitems[" + i + "].Units") />
</section>
<section class="esh-orders_new-item esh-orders_new-item--middle col-xs-2">$ @Math.Round(item.Units * item.UnitPrice, 2)</section>
</article>
}
</section>
<section class="esh-orders_new-section esh-orders_new-section--right">
<article class="esh-orders_new-titles row">
<section class="esh-orders_new-title col-xs-9"></section>
<section class="esh-orders_new-title col-xs-2">Total</section>
</article>
<article class="esh-orders_new-items row">
<section class="esh-orders_new-item col-xs-9"></section>
<section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">
$ @Model.Total
<input type="hidden" value="@Model.Total" name="Total"/>
</section>
</article>
</section>

+ 1
- 1
src/Web/WebMVC/wwwroot/css/app.min.css
File diff suppressed because it is too large
View File


+ 1
- 0
src/Web/WebMVC/wwwroot/css/basket/basket-status/basket-status.component.css View File

@ -1,5 +1,6 @@
.esh-basketstatus { .esh-basketstatus {
cursor: pointer; cursor: pointer;
display: inline-block;
float: right; float: right;
position: relative; position: relative;
transition: all 0.35s; transition: all 0.35s;


+ 1
- 0
src/Web/WebMVC/wwwroot/css/orders/orders-new/orders-new.component.css View File

@ -55,6 +55,7 @@
.esh-orders_new-title { .esh-orders_new-title {
font-size: 1.25rem; font-size: 1.25rem;
text-transform: uppercase;
} }
.esh-orders_new-items--border { .esh-orders_new-items--border {


+ 3
- 1
src/Web/WebMVC/wwwroot/css/shared/components/pager/pager.css View File

@ -8,11 +8,13 @@
} }
.esh-pager-item--navigable { .esh-pager-item--navigable {
display: inline-block;
cursor: pointer; cursor: pointer;
} }
.esh-pager-item--navigable.is-disabled { .esh-pager-item--navigable.is-disabled {
display: none;
opacity: 0;
pointer-events: none;
} }
.esh-pager-item--navigable:hover { .esh-pager-item--navigable:hover {


+ 0
- 5
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts View File

@ -13,11 +13,6 @@ export const routes: Routes = [
{ path: 'orders', component: OrdersComponent }, { path: 'orders', component: OrdersComponent },
{ path: 'orders/:id', component: OrdersDetailComponent }, { path: 'orders/:id', component: OrdersDetailComponent },
{ path: 'order', component: OrdersNewComponent } { path: 'order', component: OrdersNewComponent }
//Lazy async modules (angular-loader-router) and enable a router in each module.
//{
// path: 'basket', loadChildren: '/basket/basket.module' });
// })
//}
]; ];
export const routing = RouterModule.forRoot(routes); export const routing = RouterModule.forRoot(routes);

+ 1
- 0
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket-status/basket-status.component.html View File

@ -1,4 +1,5 @@
<a class="esh-basketstatus" <a class="esh-basketstatus"
[ngClass]="{'is-disabled': badge < 1}"
[routerLink]="['basket']"> [routerLink]="['basket']">
<div class="esh-basketstatus-image"> <div class="esh-basketstatus-image">


+ 6
- 0
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket-status/basket-status.component.scss View File

@ -2,10 +2,16 @@
.esh-basketstatus { .esh-basketstatus {
cursor: pointer; cursor: pointer;
display: inline-block;
float: right; float: right;
position: relative; position: relative;
transition: all $animation-speed-default; transition: all $animation-speed-default;
&.is-disabled {
opacity: .5;
pointer-events: none;
}
&-image { &-image {
height: 36px; height: 36px;
margin-top: .5rem; margin-top: .5rem;


+ 3
- 3
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.component.html View File

@ -31,18 +31,18 @@
<div class="container"> <div class="container">
<article class="esh-basket-titles esh-basket-titles--clean row"> <article class="esh-basket-titles esh-basket-titles--clean row">
<section class="esh-basket-title col-xs-10"></section>
<section class="esh-basket-title col-xs-9"></section>
<section class="esh-basket-title col-xs-2">Total</section> <section class="esh-basket-title col-xs-2">Total</section>
</article> </article>
<article class="esh-basket-items row"> <article class="esh-basket-items row">
<section class="esh-basket-item col-xs-10"></section>
<section class="esh-basket-item col-xs-9"></section>
<section class="esh-basket-item esh-basket-item--mark col-xs-2">$ {{totalPrice}}</section> <section class="esh-basket-item esh-basket-item--mark col-xs-2">$ {{totalPrice}}</section>
</article> </article>
<article class="esh-basket-items row"> <article class="esh-basket-items row">
<section class="esh-basket-item col-xs-9"></section> <section class="esh-basket-item col-xs-9"></section>
<section class="esh-basket-item col-xs-3">
<section class="esh-basket-item col-xs-2">
<div (click)="checkOut($event)" class="btn esh-basket-checkout">[ Checkout ]</div> <div (click)="checkOut($event)" class="btn esh-basket-checkout">[ Checkout ]</div>
</section> </section>
</article> </article>


+ 1
- 4
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.component.ts View File

@ -37,10 +37,7 @@ export class BasketComponent implements OnInit {
private calculateTotalPrice() { private calculateTotalPrice() {
this.totalPrice = 0; this.totalPrice = 0;
this.basket.items.forEach(item => { this.basket.items.forEach(item => {
this.totalPrice += (item.unitPrice * item.quantity)
this.totalPrice += (item.unitPrice * item.quantity);
}); });
} }
} }

+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.module.ts View File

@ -9,7 +9,7 @@ import { Header } from '../shared/components/header/header';
@NgModule({ @NgModule({
imports: [SharedModule], imports: [SharedModule],
declarations: [BasketComponent, BasketStatusComponent],
declarations: [BasketComponent, BasketStatusComponent],
providers: [BasketService], providers: [BasketService],
exports: [BasketStatusComponent] exports: [BasketStatusComponent]
}) })


+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.component.ts View File

@ -54,7 +54,7 @@ export class CatalogComponent implements OnInit {
this.basketService.addItemToBasket(item); this.basketService.addItemToBasket(item);
} }
getCatalog(pageSize:number, pageIndex: number, brand?: number, type?: number) {
getCatalog(pageSize: number, pageIndex: number, brand?: number, type?: number) {
this.service.getCatalog(pageIndex, pageSize, brand, type).subscribe(catalog => { this.service.getCatalog(pageIndex, pageSize, brand, type).subscribe(catalog => {
this.catalog = catalog; this.catalog = catalog;


+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.service.ts View File

@ -22,7 +22,7 @@ export class CatalogService {
} }
getCatalog(pageIndex: number, pageSize: number, brand: number, type: number): Observable<ICatalog> { getCatalog(pageIndex: number, pageSize: number, brand: number, type: number): Observable<ICatalog> {
var url = this.catalogUrl;
let url = this.catalogUrl;
if (brand || type) { if (brand || type) {
url = this.catalogUrl + '/type/' + ((type) ? type.toString() : 'null') + '/brand/' + ((brand) ? brand.toString() : 'null'); url = this.catalogUrl + '/type/' + ((type) ? type.toString() : 'null') + '/brand/' + ((brand) ? brand.toString() : 'null');
} }


+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.html View File

@ -55,12 +55,12 @@
<section class="esh-orders_detail-section esh-orders_detail-section--right"> <section class="esh-orders_detail-section esh-orders_detail-section--right">
<article class="esh-orders_detail-titles esh-basket-titles--clean row"> <article class="esh-orders_detail-titles esh-basket-titles--clean row">
<section class="esh-orders_detail-title col-xs-10"></section>
<section class="esh-orders_detail-title col-xs-9"></section>
<section class="esh-orders_detail-title col-xs-2">Total</section> <section class="esh-orders_detail-title col-xs-2">Total</section>
</article> </article>
<article class="esh-orders_detail-items row"> <article class="esh-orders_detail-items row">
<section class="esh-orders_detail-item col-xs-10"></section>
<section class="esh-orders_detail-item col-xs-9"></section>
<section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ {{order.total}}</section> <section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ {{order.total}}</section>
</article> </article>
</section> </section>


+ 12
- 12
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-new/orders-new.component.html View File

@ -7,32 +7,32 @@
<div class="container"> <div class="container">
<form [formGroup]="newOrderForm" (ngSubmit)="submitForm(newOrderForm.value)"> <form [formGroup]="newOrderForm" (ngSubmit)="submitForm(newOrderForm.value)">
<section class="esh-orders_new-section"> <section class="esh-orders_new-section">
<h4>SHIPPING ADDRESS</h4>
<h4 class="esh-orders_new-title">Shipping Address</h4>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['street'].valid && newOrderForm.controls['street'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['street'].valid && newOrderForm.controls['street'].touched}">
<label>ADDRESS</label>
<label class="esh-orders_new-title">Address</label>
<input class="form-control form-input" type="text" placeholder="Street" [formControl]="newOrderForm.controls['street']"> <input class="form-control form-input" type="text" placeholder="Street" [formControl]="newOrderForm.controls['street']">
<div *ngIf="newOrderForm.controls['street'].hasError('required') && newOrderForm.controls['street'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['street'].hasError('required') && newOrderForm.controls['street'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['city'].valid && newOrderForm.controls['city'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['city'].valid && newOrderForm.controls['city'].touched}">
<label>CITY</label>
<label class="esh-orders_new-title">City</label>
<input class="form-control form-input" type="text" placeholder="City" [formControl]="newOrderForm.controls['city']"> <input class="form-control form-input" type="text" placeholder="City" [formControl]="newOrderForm.controls['city']">
<div *ngIf="newOrderForm.controls['city'].hasError('required') && newOrderForm.controls['city'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['city'].hasError('required') && newOrderForm.controls['city'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['state'].valid && newOrderForm.controls['state'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['state'].valid && newOrderForm.controls['state'].touched}">
<label>STATE</label>
<label class="esh-orders_new-title">State</label>
<input class="form-control form-input" type="text" placeholder="state" [formControl]="newOrderForm.controls['state']"> <input class="form-control form-input" type="text" placeholder="state" [formControl]="newOrderForm.controls['state']">
<div *ngIf="newOrderForm.controls['state'].hasError('required') && newOrderForm.controls['state'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['state'].hasError('required') && newOrderForm.controls['state'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['country'].valid && newOrderForm.controls['country'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['country'].valid && newOrderForm.controls['country'].touched}">
<label>COUNTRY</label>
<label class="esh-orders_new-title">Country</label>
<input class="form-control form-input" type="text" placeholder="country" [formControl]="newOrderForm.controls['country']"> <input class="form-control form-input" type="text" placeholder="country" [formControl]="newOrderForm.controls['country']">
<div *ngIf="newOrderForm.controls['country'].hasError('required') && newOrderForm.controls['country'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['country'].hasError('required') && newOrderForm.controls['country'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
@ -40,32 +40,32 @@
</div> </div>
</section> </section>
<section class="esh-orders_new-section"> <section class="esh-orders_new-section">
<h4>PAYMENT METHOD</h4>
<h4 class="esh-orders_new-title">Payment method</h4>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['cardnumber'].valid && newOrderForm.controls['cardnumber'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['cardnumber'].valid && newOrderForm.controls['cardnumber'].touched}">
<label>CARD NUMBER</label>
<label class="esh-orders_new-title">Card number</label>
<input class="form-control form-input" type="text" placeholder="Card number" [formControl]="newOrderForm.controls['cardnumber']"> <input class="form-control form-input" type="text" placeholder="Card number" [formControl]="newOrderForm.controls['cardnumber']">
<div *ngIf="newOrderForm.controls['cardnumber'].hasError('required') && newOrderForm.controls['cardnumber'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['cardnumber'].hasError('required') && newOrderForm.controls['cardnumber'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['cardholdername'].valid && newOrderForm.controls['cardholdername'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['cardholdername'].valid && newOrderForm.controls['cardholdername'].touched}">
<label>CARDHOLDER NAME</label>
<label class="esh-orders_new-title">Cardholder name</label>
<input class="form-control form-input" type="text" placeholder="Card holder" [formControl]="newOrderForm.controls['cardholdername']"> <input class="form-control form-input" type="text" placeholder="Card holder" [formControl]="newOrderForm.controls['cardholdername']">
<div *ngIf="newOrderForm.controls['cardholdername'].hasError('required') && newOrderForm.controls['cardholdername'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['cardholdername'].hasError('required') && newOrderForm.controls['cardholdername'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['expirationdate'].valid && newOrderForm.controls['expirationdate'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['expirationdate'].valid && newOrderForm.controls['expirationdate'].touched}">
<label>EXPIRATION DATE</label>
<label class="esh-orders_new-title">Expiration date</label>
<input class="form-control form-input form-input-medium" type="text" placeholder="Card expiration" [formControl]="newOrderForm.controls['expirationdate']"> <input class="form-control form-input form-input-medium" type="text" placeholder="Card expiration" [formControl]="newOrderForm.controls['expirationdate']">
<div *ngIf="newOrderForm.controls['expirationdate'].hasError('required') && newOrderForm.controls['expirationdate'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['expirationdate'].hasError('required') && newOrderForm.controls['expirationdate'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['securitycode'].valid && newOrderForm.controls['securitycode'].touched}"> <div class="form-group" [ngClass]="{'has-error':!newOrderForm.controls['securitycode'].valid && newOrderForm.controls['securitycode'].touched}">
<label>SECURITY CODE</label>
<label class="esh-orders_new-title">Security code</label>
<input class="form-control form-input form-input-small" type="text" placeholder="Card security Code" [formControl]="newOrderForm.controls['securitycode']"> <input class="form-control form-input form-input-small" type="text" placeholder="Card security Code" [formControl]="newOrderForm.controls['securitycode']">
<div *ngIf="newOrderForm.controls['securitycode'].hasError('required') && newOrderForm.controls['securitycode'].touched" class="alert alert-danger">Required field.</div> <div *ngIf="newOrderForm.controls['securitycode'].hasError('required') && newOrderForm.controls['securitycode'].touched" class="alert alert-danger">Required field.</div>
</div> </div>
@ -91,12 +91,12 @@
<section class="esh-orders_new-section esh-orders_new-section--right"> <section class="esh-orders_new-section esh-orders_new-section--right">
<article class="esh-orders_new-titles row"> <article class="esh-orders_new-titles row">
<section class="esh-orders_new-title col-xs-10"></section>
<section class="esh-orders_new-title col-xs-9"></section>
<section class="esh-orders_new-title col-xs-2">Total</section> <section class="esh-orders_new-title col-xs-2">Total</section>
</article> </article>
<article class="esh-orders_new-items row"> <article class="esh-orders_new-items row">
<section class="esh-orders_new-item col-xs-10"></section>
<section class="esh-orders_new-item col-xs-9"></section>
<section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">$ {{order.total}}</section> <section class="esh-orders_new-item esh-orders_new-item--mark col-xs-2">$ {{order.total}}</section>
</article> </article>
</section> </section>


+ 1
- 0
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-new/orders-new.component.scss View File

@ -58,6 +58,7 @@
&-title { &-title {
font-size: $font-size-l; font-size: $font-size-l;
text-transform: uppercase;
} }
&-items { &-items {


+ 3
- 4
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-new/orders-new.component.ts View File

@ -12,11 +12,11 @@ import { Router } from '@angular/router';
templateUrl: './orders-new.component.html' templateUrl: './orders-new.component.html'
}) })
export class OrdersNewComponent implements OnInit { export class OrdersNewComponent implements OnInit {
private newOrderForm : FormGroup; // new order form
private newOrderForm: FormGroup; // new order form
private order: IOrder; private order: IOrder;
constructor(private service: OrdersService, fb: FormBuilder, private router: Router, private basketEvents: BasketWrapperService) { constructor(private service: OrdersService, fb: FormBuilder, private router: Router, private basketEvents: BasketWrapperService) {
//Obtener información del perfil de usuario.
// Obtener información del perfil de usuario.
this.order = service.mapBasketAndIdentityInfoNewOrder(); this.order = service.mapBasketAndIdentityInfoNewOrder();
this.newOrderForm = fb.group({ this.newOrderForm = fb.group({
'street': [this.order.street, Validators.required], 'street': [this.order.street, Validators.required],
@ -31,7 +31,6 @@ export class OrdersNewComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
} }
submitForm(value: any) { submitForm(value: any) {
@ -45,7 +44,7 @@ export class OrdersNewComponent implements OnInit {
this.order.cardsecuritynumber = this.newOrderForm.controls['securitycode'].value; this.order.cardsecuritynumber = this.newOrderForm.controls['securitycode'].value;
this.service.postOrder(this.order).subscribe(res => { this.service.postOrder(this.order).subscribe(res => {
//this will emit an observable. Basket service is subscribed to this observable, and will react deleting the basket for the current user.
// this will emit an observable. Basket service is subscribed to this observable, and will react deleting the basket for the current user.
this.basketEvents.orderCreated(); this.basketEvents.orderCreated();
this.router.navigate(['orders']); this.router.navigate(['orders']);


+ 4
- 5
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts View File

@ -36,7 +36,7 @@ export class OrdersService {
return response.json(); return response.json();
}); });
} }
postOrder(item): Observable<boolean> { postOrder(item): Observable<boolean> {
return this.service.post(this.ordersUrl + '/new', item).map((response: Response) => { return this.service.post(this.ordersUrl + '/new', item).map((response: Response) => {
return true; return true;
@ -51,7 +51,7 @@ export class OrdersService {
console.log(basket); console.log(basket);
console.log(identityInfo); console.log(identityInfo);
//Identity data mapping:
// Identity data mapping:
order.street = identityInfo.address_street; order.street = identityInfo.address_street;
order.city = identityInfo.address_city; order.city = identityInfo.address_city;
order.country = identityInfo.address_country; order.country = identityInfo.address_country;
@ -65,10 +65,9 @@ export class OrdersService {
order.total = 0; order.total = 0;
order.expiration = identityInfo.card_expiration; order.expiration = identityInfo.card_expiration;
//basket data mapping:
// basket data mapping:
order.orderItems = new Array<IOrderItem>(); order.orderItems = new Array<IOrderItem>();
basket.items.forEach(x =>
{
basket.items.forEach(x => {
let item: IOrderItem = <IOrderItem>{}; let item: IOrderItem = <IOrderItem>{};
item.pictureurl = x.pictureUrl; item.pictureurl = x.pictureUrl;
item.productId = +x.productId; item.productId = +x.productId;


+ 2
- 3
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/identity/identity.ts View File

@ -12,15 +12,14 @@ import { SecurityService } from '../../services/security.service';
export class Identity implements OnInit { export class Identity implements OnInit {
private authenticated: boolean = false; private authenticated: boolean = false;
private subscription: Subscription; private subscription: Subscription;
private userName: string = "";
private userName: string = '';
constructor(private service: SecurityService) { constructor(private service: SecurityService) {
} }
ngOnInit() { ngOnInit() {
this.subscription = this.service.authenticationChallenge$.subscribe(res =>
{
this.subscription = this.service.authenticationChallenge$.subscribe(res => {
this.authenticated = res; this.authenticated = res;
this.userName = this.service.UserData.email; this.userName = this.service.UserData.email;
}); });


+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/pager/pager.html View File

@ -4,7 +4,7 @@
<nav> <nav>
<span class="esh-pager-item esh-pager-item--navigable" <span class="esh-pager-item esh-pager-item--navigable"
id="Previous" id="Previous"
[hidden]="buttonStates?.previousDisabled"
[ngClass]="{'is-disabled': buttonStates?.previousDisabled}"
(click)="onPreviousCliked($event)" (click)="onPreviousCliked($event)"
aria-label="Previous"> aria-label="Previous">
Previous Previous
@ -16,7 +16,7 @@
<span class="esh-pager-item esh-pager-item--navigable" <span class="esh-pager-item esh-pager-item--navigable"
id="Next" id="Next"
[hidden]="buttonStates?.nextDisabled"
[ngClass]="{'is-disabled': buttonStates?.nextDisabled}"
(click)="onNextClicked($event)" (click)="onNextClicked($event)"
aria-label="Next"> aria-label="Next">
Next Next


+ 6
- 0
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/pager/pager.scss View File

@ -11,8 +11,14 @@
$margin: 5vw; $margin: 5vw;
margin: 0 $margin; margin: 0 $margin;
&.is-disabled {
opacity: 0;
pointer-events: none;
}
&--navigable { &--navigable {
cursor: pointer; cursor: pointer;
display: inline-block;
&:hover { &:hover {
color: $color-secondary; color: $color-secondary;


+ 1
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/components/pager/pager.ts View File

@ -18,10 +18,9 @@ export class Pager implements OnInit, OnChanges {
buttonStates: any = { buttonStates: any = {
nextDisabled: true, nextDisabled: true,
previousDisabled: true, previousDisabled: true,
}
};
ngOnInit() { ngOnInit() {
//console.log(this.model);
} }
ngOnChanges() { ngOnChanges() {


+ 3
- 3
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/basket.model.ts View File

@ -1,6 +1,6 @@
import { IBasketItem } from './basketItem.model'; import { IBasketItem } from './basketItem.model';
export interface IBasket { export interface IBasket {
items: IBasketItem[]
buyerId: string
}
items: IBasketItem[];
buyerId: string;
}

+ 6
- 7
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/basketItem.model.ts View File

@ -1,9 +1,8 @@
export interface IBasketItem { export interface IBasketItem {
id: string
productId: string
productName: string
unitPrice: number,
quantity: number,
pictureUrl: string
id: string;
productId: string;
productName: string;
unitPrice: number;
quantity: number;
pictureUrl: string;
} }

+ 4
- 4
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalog.model.ts View File

@ -1,8 +1,8 @@
import {ICatalogItem} from './catalogItem.model'; import {ICatalogItem} from './catalogItem.model';
export interface ICatalog { export interface ICatalog {
pageIndex: number
data: ICatalogItem[]
pageSize: number
count: number
pageIndex: number;
data: ICatalogItem[];
pageSize: number;
count: number;
} }

+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogBrand.model.ts View File

@ -1,4 +1,4 @@
export interface ICatalogBrand { export interface ICatalogBrand {
id: number
brand: string
id: number;
brand: string;
} }

+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogType.model.ts View File

@ -1,4 +1,4 @@
export interface ICatalogType { export interface ICatalogType {
id: number
type: string
id: number;
type: string;
} }

+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts View File

@ -13,7 +13,7 @@ export interface IOrder {
cardholdername: string; cardholdername: string;
cardtypeid: number; cardtypeid: number;
buyer: string; buyer: string;
ordernumber: string,
total: number,
ordernumber: string;
total: number;
orderItems: IOrderItem[]; orderItems: IOrderItem[];
} }

+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/orderItem.model.ts View File

@ -3,5 +3,5 @@ export interface IOrderItem {
productname: string; productname: string;
unitprice: number; unitprice: number;
units: number; units: number;
productId: number
productId: number;
} }

+ 6
- 6
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/pager.model.ts View File

@ -1,7 +1,7 @@
export interface IPager { export interface IPager {
itemsPage: number,
totalItems: number,
actualPage: number,
totalPages: number,
items: number,
}
itemsPage: number;
totalItems: number;
actualPage: number;
totalPages: number;
items: number;
}

+ 4
- 3
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/basket.wrapper.service.ts View File

@ -8,11 +8,11 @@ import { SecurityService } from '../services/security.service';
@Injectable() @Injectable()
export class BasketWrapperService { export class BasketWrapperService {
public basket: IBasket
public basket: IBasket;
constructor(private identityService: SecurityService) { } constructor(private identityService: SecurityService) { }
//observable that is fired when a product is added to the cart
// observable that is fired when a product is added to the cart
private addItemToBasketSource = new Subject<IBasketItem>(); private addItemToBasketSource = new Subject<IBasketItem>();
addItemToBasket$ = this.addItemToBasketSource.asObservable(); addItemToBasket$ = this.addItemToBasketSource.asObservable();
@ -28,7 +28,8 @@ export class BasketWrapperService {
quantity: 1, quantity: 1,
unitPrice: item.price, unitPrice: item.price,
id: '' id: ''
}
};
this.addItemToBasketSource.next(basket); this.addItemToBasketSource.next(basket);
} else { } else {
this.identityService.Authorize(); this.identityService.Authorize();


+ 5
- 5
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/data.service.ts View File

@ -19,9 +19,9 @@ export class DataService {
if (this.securityService) { if (this.securityService) {
options.headers = new Headers(); options.headers = new Headers();
options.headers.append("Authorization", "Bearer " + this.securityService.GetToken());
options.headers.append('Authorization', 'Bearer ' + this.securityService.GetToken());
} }
return this.http.get(url, options).map( return this.http.get(url, options).map(
(res: Response) => { (res: Response) => {
return res; return res;
@ -33,7 +33,7 @@ export class DataService {
if (this.securityService) { if (this.securityService) {
options.headers = new Headers(); options.headers = new Headers();
options.headers.append("Authorization", "Bearer " + this.securityService.GetToken());
options.headers.append('Authorization', 'Bearer ' + this.securityService.GetToken());
} }
return this.http.post(url, data, options).map( return this.http.post(url, data, options).map(
@ -47,11 +47,11 @@ export class DataService {
if (this.securityService) { if (this.securityService) {
options.headers = new Headers(); options.headers = new Headers();
options.headers.append("Authorization", "Bearer " + this.securityService.GetToken());
options.headers.append('Authorization', 'Bearer ' + this.securityService.GetToken());
} }
console.log('data.service deleting'); console.log('data.service deleting');
//return this.http.delete(url, options).subscribe(
// return this.http.delete(url, options).subscribe(
// return res; // return res;
// ); // );


+ 68
- 69
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/services/security.service.ts View File

@ -3,7 +3,6 @@ import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
//import { Configuration } from '../app.constants';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@ -20,45 +19,45 @@ export class SecurityService {
this.headers = new Headers(); this.headers = new Headers();
this.headers.append('Content-Type', 'application/json'); this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json'); this.headers.append('Accept', 'application/json');
this.storage = sessionStorage; //localStorage;
this.storage = sessionStorage; // localStorage;
if (this.retrieve("IsAuthorized") !== "") {
this.IsAuthorized = this.retrieve("IsAuthorized");
if (this.retrieve('IsAuthorized') !== '') {
this.IsAuthorized = this.retrieve('IsAuthorized');
this.authenticationSource.next(true); this.authenticationSource.next(true);
this.UserData = this.retrieve("userData");
this.UserData = this.retrieve('userData');
} }
} }
public IsAuthorized: boolean; public IsAuthorized: boolean;
public GetToken(): any { public GetToken(): any {
return this.retrieve("authorizationData");
return this.retrieve('authorizationData');
} }
public ResetAuthorizationData() { public ResetAuthorizationData() {
this.store("authorizationData", "");
this.store("authorizationDataIdToken", "");
this.store('authorizationData', '');
this.store('authorizationDataIdToken', '');
this.IsAuthorized = false; this.IsAuthorized = false;
this.store("IsAuthorized", false);
this.store('IsAuthorized', false);
} }
public UserData: any; public UserData: any;
public SetAuthorizationData(token: any, id_token:any) {
if (this.retrieve("authorizationData") !== "") {
this.store("authorizationData", "");
public SetAuthorizationData(token: any, id_token: any) {
if (this.retrieve('authorizationData') !== '') {
this.store('authorizationData', '');
} }
this.store("authorizationData", token);
this.store("authorizationDataIdToken", id_token);
this.store('authorizationData', token);
this.store('authorizationDataIdToken', id_token);
this.IsAuthorized = true; this.IsAuthorized = true;
this.store("IsAuthorized", true);
this.store('IsAuthorized', true);
this.getUserData() this.getUserData()
.subscribe(data => { .subscribe(data => {
this.UserData = data; this.UserData = data;
this.store("userData", data);
//emit observable
this.store('userData', data);
// emit observable
this.authenticationSource.next(true); this.authenticationSource.next(true);
window.location.href = 'http://localhost:5104'; window.location.href = 'http://localhost:5104';
}, },
@ -71,25 +70,25 @@ export class SecurityService {
public Authorize() { public Authorize() {
this.ResetAuthorizationData(); this.ResetAuthorizationData();
var authorizationUrl = 'http://10.0.75.1:5105/connect/authorize';
var client_id = 'js';
var redirect_uri = 'http://localhost:5104/';
var response_type = "id_token token";
var scope = "openid profile orders basket";
var nonce = "N" + Math.random() + "" + Date.now();
var state = Date.now() + "" + Math.random();
this.store("authStateControl", state);
this.store("authNonce", nonce);
var url =
authorizationUrl + "?" +
"response_type=" + encodeURI(response_type) + "&" +
"client_id=" + encodeURI(client_id) + "&" +
"redirect_uri=" + encodeURI(redirect_uri) + "&" +
"scope=" + encodeURI(scope) + "&" +
"nonce=" + encodeURI(nonce) + "&" +
"state=" + encodeURI(state);
let authorizationUrl = 'http://localhost:5105/connect/authorize';
let client_id = 'js';
let redirect_uri = 'http://localhost:5104/';
let response_type = 'id_token token';
let scope = 'openid profile orders basket';
let nonce = 'N' + Math.random() + '' + Date.now();
let state = Date.now() + '' + Math.random();
this.store('authStateControl', state);
this.store('authNonce', nonce);
let url =
authorizationUrl + '?' +
'response_type=' + encodeURI(response_type) + '&' +
'client_id=' + encodeURI(client_id) + '&' +
'redirect_uri=' + encodeURI(redirect_uri) + '&' +
'scope=' + encodeURI(scope) + '&' +
'nonce=' + encodeURI(nonce) + '&' +
'state=' + encodeURI(state);
window.location.href = url; window.location.href = url;
} }
@ -97,41 +96,41 @@ export class SecurityService {
public AuthorizedCallback() { public AuthorizedCallback() {
this.ResetAuthorizationData(); this.ResetAuthorizationData();
var hash = window.location.hash.substr(1);
let hash = window.location.hash.substr(1);
var result: any = hash.split('&').reduce(function (result : any, item: string) {
var parts = item.split('=');
let result: any = hash.split('&').reduce(function (result: any, item: string) {
let parts = item.split('=');
result[parts[0]] = parts[1]; result[parts[0]] = parts[1];
return result; return result;
}, {}); }, {});
console.log(result); console.log(result);
var token = "";
var id_token = "";
var authResponseIsValid = false;
let token = '';
let id_token = '';
let authResponseIsValid = false;
if (!result.error) { if (!result.error) {
if (result.state !== this.retrieve("authStateControl")) {
console.log("AuthorizedCallback incorrect state");
if (result.state !== this.retrieve('authStateControl')) {
console.log('AuthorizedCallback incorrect state');
} else { } else {
token = result.access_token; token = result.access_token;
id_token = result.id_token
id_token = result.id_token;
var dataIdToken: any = this.getDataFromToken(id_token);
let dataIdToken: any = this.getDataFromToken(id_token);
console.log(dataIdToken); console.log(dataIdToken);
// validate nonce // validate nonce
if (dataIdToken.nonce !== this.retrieve("authNonce")) {
console.log("AuthorizedCallback incorrect nonce");
if (dataIdToken.nonce !== this.retrieve('authNonce')) {
console.log('AuthorizedCallback incorrect nonce');
} else { } else {
this.store("authNonce", "");
this.store("authStateControl", "");
this.store('authNonce', '');
this.store('authStateControl', '');
authResponseIsValid = true; authResponseIsValid = true;
console.log("AuthorizedCallback state and nonce validated, returning access token");
console.log('AuthorizedCallback state and nonce validated, returning access token');
} }
} }
} }
@ -143,18 +142,18 @@ export class SecurityService {
} }
public Logoff() { public Logoff() {
var authorizationUrl = 'http://10.0.75.1:5105/connect/endsession';
var id_token_hint = this.retrieve("authorizationDataIdToken");
var post_logout_redirect_uri = 'http://localhost:5104/';
let authorizationUrl = 'http://localhost:5105/connect/endsession';
let id_token_hint = this.retrieve('authorizationDataIdToken');
let post_logout_redirect_uri = 'http://localhost:5104/';
var url =
authorizationUrl + "?" +
"id_token_hint=" + encodeURI(id_token_hint) + "&" +
"post_logout_redirect_uri=" + encodeURI(post_logout_redirect_uri);
let url =
authorizationUrl + '?' +
'id_token_hint=' + encodeURI(id_token_hint) + '&' +
'post_logout_redirect_uri=' + encodeURI(post_logout_redirect_uri);
this.ResetAuthorizationData(); this.ResetAuthorizationData();
//emit observable
// emit observable
this.authenticationSource.next(false); this.authenticationSource.next(false);
window.location.href = url; window.location.href = url;
} }
@ -162,16 +161,16 @@ export class SecurityService {
public HandleError(error: any) { public HandleError(error: any) {
console.log(error); console.log(error);
if (error.status == 403) { if (error.status == 403) {
this._router.navigate(['/Forbidden'])
this._router.navigate(['/Forbidden']);
} }
else if (error.status == 401) { else if (error.status == 401) {
//this.ResetAuthorizationData();
this._router.navigate(['/Unauthorized'])
// this.ResetAuthorizationData();
this._router.navigate(['/Unauthorized']);
} }
} }
private urlBase64Decode(str: string) { private urlBase64Decode(str: string) {
var output = str.replace('-', '+').replace('_', '/');
let output = str.replace('-', '+').replace('_', '/');
switch (output.length % 4) { switch (output.length % 4) {
case 0: case 0:
break; break;
@ -189,9 +188,9 @@ export class SecurityService {
} }
private getDataFromToken(token: any) { private getDataFromToken(token: any) {
var data = {};
let data = {};
if (typeof token !== 'undefined') { if (typeof token !== 'undefined') {
var encoded = token.split('.')[1];
let encoded = token.split('.')[1];
data = JSON.parse(this.urlBase64Decode(encoded)); data = JSON.parse(this.urlBase64Decode(encoded));
} }
@ -199,7 +198,7 @@ export class SecurityService {
} }
private retrieve(key: string): any { private retrieve(key: string): any {
var item = this.storage.getItem(key);
let item = this.storage.getItem(key);
if (item && item !== 'undefined') { if (item && item !== 'undefined') {
return JSON.parse(this.storage.getItem(key)); return JSON.parse(this.storage.getItem(key));
@ -214,7 +213,7 @@ export class SecurityService {
private getUserData = (): Observable<string[]> => { private getUserData = (): Observable<string[]> => {
this.setHeaders(); this.setHeaders();
return this._http.get('http://10.0.75.1:5105/connect/userinfo', {
return this._http.get('http://localhost:5105/connect/userinfo', {
headers: this.headers, headers: this.headers,
body: '' body: ''
}).map(res => res.json()); }).map(res => res.json());
@ -225,9 +224,9 @@ export class SecurityService {
this.headers.append('Content-Type', 'application/json'); this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json'); this.headers.append('Accept', 'application/json');
var token = this.GetToken();
let token = this.GetToken();
if (token !== "") {
if (token !== '') {
this.headers.append('Authorization', 'Bearer ' + token); this.headers.append('Authorization', 'Bearer ' + token);
} }
} }

+ 2
- 2
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/shared.module.ts View File

@ -10,7 +10,7 @@ import { DataService } from './services/data.service';
import { BasketWrapperService} from './services/basket.wrapper.service'; import { BasketWrapperService} from './services/basket.wrapper.service';
import { SecurityService } from './services/security.service'; import { SecurityService } from './services/security.service';
//Components:
// Components:
import { Pager } from './components/pager/pager'; import { Pager } from './components/pager/pager';
import { Header } from './components/header/header'; import { Header } from './components/header/header';
import { Identity } from './components/identity/identity'; import { Identity } from './components/identity/identity';
@ -51,7 +51,7 @@ export class SharedModule {
providers: [ providers: [
// Providers // Providers
DataService, DataService,
BasketWrapperService,
BasketWrapperService,
SecurityService SecurityService
] ]
}; };


+ 5
- 4
src/Web/WebSPA/eShopOnContainers.WebSPA/package.json View File

@ -29,10 +29,11 @@
"build:main": "node node_modules/webpack/bin/webpack.js --config config/webpack.config.js", "build:main": "node node_modules/webpack/bin/webpack.js --config config/webpack.config.js",
"setdev": "set ASPNETCORE_ENVIRONMENT=Development", "setdev": "set ASPNETCORE_ENVIRONMENT=Development",
"setprod": "set ASPNETCORE_ENVIRONMENT=Production", "setprod": "set ASPNETCORE_ENVIRONMENT=Production",
"build:dev": "npm run lint:sass && npm run setdev && npm run clean:dist && npm run build:vendor && npm run build:main",
"build:dev": "npm run setdev && npm run clean:dist && npm run build:vendor && npm run build:main",
"build:prod": "npm run setprod && npm run clean:dist && npm run build:vendor && npm run build:main", "build:prod": "npm run setprod && npm run clean:dist && npm run build:vendor && npm run build:main",
"version": "npm run build", "version": "npm run build",
"lint:sass": "sass-lint -c .sass-lint.yml Client/**/*.scss --verbose"
"lint:sass": "sass-lint -c .sass-lint.yml Client/**/*.scss --verbose",
"lint:ts": "tslint -c tslint.json Client/**/*.ts"
}, },
"dependencies": { "dependencies": {
"@angular/common": "2.1.2", "@angular/common": "2.1.2",
@ -92,9 +93,9 @@
"sass-loader": "4.0.2", "sass-loader": "4.0.2",
"ts-helpers": "1.1.1", "ts-helpers": "1.1.1",
"ts-node": "1.4.3", "ts-node": "1.4.3",
"tslint": "3.15.1",
"tslint": "^3.15.1",
"typedoc": "0.5.0", "typedoc": "0.5.0",
"typescript": "2.0.6",
"typescript": "^2.0.6",
"url-loader": "^0.5.7", "url-loader": "^0.5.7",
"webpack": "2.1.0-beta.25", "webpack": "2.1.0-beta.25",
"webpack-externals-plugin": "1.0.0", "webpack-externals-plugin": "1.0.0",


+ 101
- 0
src/Web/WebSPA/eShopOnContainers.WebSPA/tslint.json View File

@ -0,0 +1,101 @@
{
"jsRules": {
"class-name": true,
"comment-format": [
true,
"check-space"
],
"indent": [
true,
"spaces"
],
"no-duplicate-variable": true,
"no-eval": true,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"quotemark": [
true,
"single"
],
"semicolon": [
true,
"always"
],
"triple-equals": [
false,
"allow-null-check"
],
"variable-name": [
true,
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
},
"rules": {
"class-name": true,
"comment-format": [
true,
"check-space"
],
"indent": [
true,
"spaces"
],
"no-eval": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"no-var-keyword": true,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"quotemark": [
true,
"single"
],
"semicolon": [
true,
"always"
],
"triple-equals": [
false,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [
true,
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}

Loading…
Cancel
Save