Skip to content

Commit a7ce8bf

Browse files
committed
Updated clean up script and fixed UI components
1 parent f4edd18 commit a7ce8bf

File tree

15 files changed

+120
-36
lines changed

15 files changed

+120
-36
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ Once the above script finishes successfully, go to the CodePipeline page, inside
5454

5555
## Steps to Clean-up
5656

57-
Run the following helper script to clean up reference solution resources:
57+
Run the following helper script to clean up reference solution resources.
58+
Please make sure "jq" JSON processor installed in your environment before invoking below script.
59+
60+
NOTE: Below script before deleting each resource, it will prompt for user confirmation. Please make sure in your AWS account you don't have resources/stacks with names similar to what this workshop has provisioned, otherwise it might cause accidental deletion of your resources. In such cases, you can manually delete the resource/stacks following below listed steps.
5861

5962
```bash
6063
./cleanup.sh

cleanup.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ else
7575
echo "skip_flag disabled. Script will pause for confirmation before deleting resources."
7676
fi
7777

78-
delete_stack_after_confirming "serverless-saas-workshop-lab1"
78+
# delete_stack_after_confirming "serverless-saas-workshop-lab1"
7979
delete_stack_after_confirming "stack-pooled"
8080

8181
echo "$(date) cleaning up platinum tenants..."
@@ -111,7 +111,7 @@ delete_stack_after_confirming "serverless-saas"
111111
delete_stack_after_confirming "serverless-saas-pipeline"
112112

113113
delete_codecommit_repo_after_confirming "aws-saas-factory-ref-serverless-saas"
114-
delete_codecommit_repo_after_confirming "aws-serverless-saas-workshop"
114+
# delete_codecommit_repo_after_confirming "aws-serverless-saas-workshop"
115115

116116
echo "$(date) cleaning up buckets..."
117117
for i in $(aws s3 ls | awk '{print $3}' | grep -E "^serverless-saas-*|^sam-bootstrap-*"); do

clients/Admin/src/app/views/tenants/create/create.component.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,22 @@
5454
color="primary"
5555
(click)="(submit)"
5656
[disabled]="!tenantForm.valid"
57+
type="submit"
58+
*ngIf="!submitting"
5759
>
5860
Submit
5961
</button>
60-
<button mat-raised-button color="warn" [routerLink]="['/list']">
62+
<button mat-raised-button color="warn" [routerLink]="['/tenants']" type="button" *ngIf="!submitting">
6163
Cancel
6264
</button>
65+
<mat-card *ngIf="submitting" style="display: flex; justify-content: center; align-items: center">
66+
<mat-progress-spinner
67+
color="primary"
68+
mode="indeterminate"
69+
diameter="15"
70+
>
71+
</mat-progress-spinner>
72+
</mat-card>
6373
</div>
6474
</mat-card-footer>
6575
</mat-card-content>

clients/Admin/src/app/views/tenants/create/create.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ export class CreateComponent implements OnInit {
4242

4343
this.tenantSvc.post(this.tenantForm.value).subscribe({
4444
next: () => {
45+
this.submitting = false;
4546
this.openErrorMessageSnackBar('Successfully created new tenant!');
4647
this.router.navigate(['tenants']);
4748
},
4849
error: (err) => {
50+
this.submitting = false;
4951
this.openErrorMessageSnackBar('An unexpected error occurred!');
5052
console.error(err);
5153
},

clients/Application/src/app/views/orders/create/create.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,15 @@
5757
mat-raised-button
5858
color="primary"
5959
type="submit"
60-
[disabled]="!orderForm.valid"
60+
[disabled]="!orderForm.valid || !productQuantity"
6161
>
6262
Submit
6363
</button>
6464
<button
6565
mat-raised-button
6666
color="warn"
67-
[routerLink]="['orders']"
67+
[routerLink]="['/orders']"
68+
type="button"
6869
>
6970
Cancel
7071
</button>

clients/Application/src/app/views/orders/create/create.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ export class CreateComponent implements OnInit {
4646
return this.orderForm.get('name');
4747
}
4848

49+
get productQuantity() {
50+
return this.orderProducts
51+
.filter((p) => !!p.quantity).length > 0;
52+
}
53+
54+
4955
add(op: LineItem) {
5056
const orderProduct = this.orderProducts.find(
5157
(p) => p?.product.productId === op.product.productId

clients/Application/src/app/views/orders/list/list.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ <h2>Order List</h2>
77
<ng-container matColumnDef="name">
88
<th mat-header-cell *matHeaderCellDef>Name</th>
99
<td mat-cell *matCellDef="let element">
10-
<a class="link" routerLink="/orders/detail/{{ element.orderId }}">
10+
<a class="link" routerLink="/orders/detail/{{ element.shardId }}:{{ element.orderId }}">
1111
{{ element.orderName }}
1212
</a>
1313
</td>

clients/Application/src/app/views/products/edit/edit.component.html

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
<div class="product-form">
2-
<form [formGroup]="productForm!">
2+
<form [formGroup]="productForm" (submit)="submit()">
33
<mat-card class="card">
4-
<mat-card-title>Create new Product</mat-card-title>
4+
<mat-card-title>Edit Product</mat-card-title>
55
<mat-card-content>
6+
<mat-form-field>
7+
<mat-label>Product ID</mat-label>
8+
<input
9+
matInput
10+
value="{{ productId$ | async }}"
11+
[readonly]="true"
12+
/>
13+
</mat-form-field>
614
<mat-form-field>
715
<mat-label>Enter product name</mat-label>
816
<input
@@ -25,17 +33,30 @@
2533
<mat-error *ngIf="price?.invalid">Price is required</mat-error>
2634
</mat-form-field>
2735
<mat-form-field>
28-
<mat-label>Description</mat-label>
36+
<mat-label>SKU</mat-label>
2937
<input
3038
matInput
3139
type="text"
32-
formControlName="description"
33-
placeholder="Enter product description"
40+
formControlName="sku"
41+
placeholder="Enter product sku"
3442
/>
3543
</mat-form-field>
44+
<mat-form-field>
45+
<mat-label>Category</mat-label>
46+
<mat-select formControlName="category" required>
47+
<mat-option *ngFor="let category of categories" [value]="category">
48+
{{ category }}
49+
</mat-option>
50+
</mat-select>
51+
</mat-form-field>
3652
<mat-card-footer>
3753
<div class="button-panel">
38-
<button mat-raised-button color="primary" (click)="(submit)">
54+
<button
55+
mat-raised-button
56+
color="primary"
57+
(click)="(submit)"
58+
[disabled]="!productForm.valid"
59+
>
3960
Submit
4061
</button>
4162
<button mat-raised-button color="warn" (click)="cancel()">
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.card {
2+
margin: 20px;
3+
display: flex;
4+
flex-direction: column;
5+
align-items: flex-start;
6+
}
7+
8+
.product-form {
9+
display: flex;
10+
flex-direction: column;
11+
align-items: flex-start;
12+
}
13+
14+
.mat-form-field {
15+
display: flex;
16+
}
17+
18+
.button-panel {
19+
display: flex;
20+
align-items: center;
21+
justify-content: center;
22+
margin-bottom: 8px;
23+
}
24+
25+
button {
26+
margin: 4px;
27+
}
28+

clients/Application/src/app/views/products/edit/edit.component.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,50 @@
33
* SPDX-License-Identifier: MIT-0
44
*/
55
import { Component, OnInit } from '@angular/core';
6-
import { FormBuilder, FormGroup } from '@angular/forms';
6+
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
77
import { ActivatedRoute, Router } from '@angular/router';
88
import { Observable, of } from 'rxjs';
99
import { map, switchMap } from 'rxjs/operators';
1010
import { Product } from '../models/product.interface';
1111
import { ProductService } from '../product.service';
12+
1213
@Component({
1314
selector: 'app-edit',
1415
templateUrl: './edit.component.html',
1516
styleUrls: ['./edit.component.scss'],
1617
})
1718
export class EditComponent implements OnInit {
18-
productForm: FormGroup | undefined;
19+
productForm: FormGroup;
20+
categories: string[] = ['category1', 'category2', 'category3', 'category4'];
1921
product$: Observable<Product | undefined> | undefined;
2022
productId$: Observable<string> | undefined;
2123
productName$: Observable<string | undefined> | undefined;
2224

2325
constructor(
24-
private route: ActivatedRoute,
25-
private router: Router,
26+
private fb: FormBuilder,
2627
private productSvc: ProductService,
27-
private fb: FormBuilder
28-
) {}
28+
private router: Router,
29+
private route: ActivatedRoute
30+
) {
31+
this.productForm = this.fb.group({});
32+
}
2933

3034
ngOnInit(): void {
35+
this.productForm = this.fb.group({
36+
shardId: [],
37+
productId: [],
38+
name: ['', Validators.required],
39+
price: ['', Validators.required],
40+
sku: '',
41+
category: '',
42+
});
43+
3144
this.productId$ = this.route.params.pipe(map((p) => p['productId']));
3245
this.product$ = this.productId$.pipe(
3346
switchMap((p) => this.productSvc.get(p))
3447
);
3548
this.productName$ = this.product$.pipe(map((p) => p?.name));
3649

37-
this.productForm = this.fb.group({
38-
productId: [''],
39-
name: [''],
40-
price: [''],
41-
description: [''],
42-
});
43-
4450
this.product$.subscribe((val) => {
4551
this.productForm?.patchValue({
4652
...val,
@@ -57,7 +63,7 @@ export class EditComponent implements OnInit {
5763
}
5864

5965
submit() {
60-
this.productSvc.patch(this.productForm?.value).subscribe({
66+
this.productSvc.put(this.productForm?.value).subscribe({
6167
next: () => this.router.navigate(['products']),
6268
error: (err) => console.error(err),
6369
});

clients/Application/src/app/views/products/list/list.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ <h2>Product List</h2>
66
<!-- Name Column -->
77
<ng-container matColumnDef="name">
88
<th mat-header-cell *matHeaderCellDef>Name</th>
9-
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
9+
<td mat-cell *matCellDef="let element">
10+
<a class="link" routerLink="/products/edit/{{ element.shardId }}:{{ element.productId }}">
11+
{{ element.name }}
12+
</a>
13+
</td>
1014
</ng-container>
1115

1216
<!-- Price Column -->

clients/Application/src/app/views/products/models/product.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
export interface Product {
66
key: string;
7+
shardId: string;
78
productId: string;
89
name: string;
910
price: number;

clients/Application/src/app/views/products/product.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ export class ProductService {
2424
}
2525

2626
delete(product: Product) {
27-
const url = `${this.baseUrl}/product/${product.productId}`;
27+
const url = `${this.baseUrl}/product/${product.shardId}:${product.productId}`;
2828
return this.http.delete<Product>(url);
2929
}
3030

31-
patch(product: Product) {
32-
const url = `${this.baseUrl}/product/${product.productId}`;
33-
return this.http.patch<Product>(url, product);
31+
put(product: Product) {
32+
const url = `${this.baseUrl}/product/${product.shardId}:${product.productId}`;
33+
return this.http.put<Product>(url, product);
3434
}
3535

3636
post(product: Product) {

server/OrderService/order_service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import logger
77
import metrics_manager
88
import order_service_dal
9+
from decimal import Decimal
910
from types import SimpleNamespace
1011
from aws_lambda_powertools import Tracer
1112
tracer = Tracer()
@@ -31,7 +32,7 @@ def create_order(event, context):
3132
tracer.put_annotation(key="TenantId", value=tenantId)
3233

3334
logger.log_with_tenant_context(event, "Request received to create a order")
34-
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d))
35+
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d), parse_float=Decimal)
3536
order = order_service_dal.create_order(event, payload)
3637
logger.log_with_tenant_context(event, "Request completed to create a order")
3738
metrics_manager.record_metric(event, "OrderCreated", "Count", 1)
@@ -43,7 +44,7 @@ def update_order(event, context):
4344
tracer.put_annotation(key="TenantId", value=tenantId)
4445

4546
logger.log_with_tenant_context(event, "Request received to update a order")
46-
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d))
47+
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d), parse_float=Decimal)
4748
params = event['pathParameters']
4849
key = params['id']
4950
order = order_service_dal.update_order(event, payload, key)

server/ProductService/product_service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import logger
77
import metrics_manager
88
import product_service_dal
9+
from decimal import Decimal
910
from aws_lambda_powertools import Tracer
1011
from types import SimpleNamespace
1112
tracer = Tracer()
@@ -32,7 +33,7 @@ def create_product(event, context):
3233
tracer.put_annotation(key="TenantId", value=tenantId)
3334

3435
logger.log_with_tenant_context(event, "Request received to create a product")
35-
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d))
36+
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d), parse_float=Decimal)
3637
product = product_service_dal.create_product(event, payload)
3738
logger.log_with_tenant_context(event, "Request completed to create a product")
3839
metrics_manager.record_metric(event, "ProductCreated", "Count", 1)
@@ -44,7 +45,7 @@ def update_product(event, context):
4445
tracer.put_annotation(key="TenantId", value=tenantId)
4546

4647
logger.log_with_tenant_context(event, "Request received to update a product")
47-
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d))
48+
payload = json.loads(event['body'], object_hook=lambda d: SimpleNamespace(**d), parse_float=Decimal)
4849
params = event['pathParameters']
4950
key = params['id']
5051
product = product_service_dal.update_product(event, payload, key)

0 commit comments

Comments
 (0)