Skip to content

Commit 4e1bc8f

Browse files
committed
fix: #89 C1-edit and delete customres
1 parent 4ca6c8e commit 4e1bc8f

18 files changed

+521
-70
lines changed

src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
<div class="form-group">
44
<div
55
*ngIf="showAlert && messageToShow !== ''"
6-
[ngClass]="{'bg-secondary': messageToShow == 'Customer created successfully!', 'bg-primary': messageToShow != 'Customer created successfully!'}"
6+
[ngClass]="{'bg-secondary': messageToShow == 'Customer created successfully!' || messageToShow == 'Customer updated successfully!',
7+
'bg-primary': messageToShow !== 'Customer created successfully!' }"
78
class="alert alert-dismissible fade fade-in show text-white"
89
role="alert"
910
>

src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.spec.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { MockStore, provideMockStore } from '@ngrx/store/testing';
44

55
import { CreateCustomerComponent } from './create-customer';
66
import { CustomerState, CreateCustomer } from 'src/app/modules/customer-management/store';
7-
import * as models from 'src/app/modules/shared/models/index';
87
import { LoadCustomers } from './../../../../store/customer-management.actions';
8+
import * as models from 'src/app/modules/shared/models/index';
99

1010
describe('CreateCustomerComponent', () => {
1111
let component: CreateCustomerComponent;
@@ -16,6 +16,7 @@ describe('CreateCustomerComponent', () => {
1616
data: [],
1717
isLoading: false,
1818
message: '',
19+
customerIdToEdit: '',
1920
};
2021

2122
const customerData: models.Customer = {
@@ -35,7 +36,6 @@ describe('CreateCustomerComponent', () => {
3536
fixture = TestBed.createComponent(CreateCustomerComponent);
3637
component = fixture.componentInstance;
3738
fixture.detectChanges();
38-
3939
store = TestBed.inject(MockStore);
4040
store.setState(state);
4141
});
@@ -81,9 +81,7 @@ describe('CreateCustomerComponent', () => {
8181
spyOn(store, 'dispatch');
8282

8383
component.ngOnInit();
84-
8584
component.onSubmit(customerData);
86-
8785
component.setStatusOnScreen('Customer created successfully!');
8886

8987
expect(component.messageToShow).toEqual('Customer created successfully!');
@@ -97,12 +95,19 @@ describe('CreateCustomerComponent', () => {
9795
spyOn(store, 'dispatch');
9896

9997
component.ngOnInit();
100-
10198
component.onSubmit(customerData);
102-
10399
component.setStatusOnScreen('An error occurred, try again later.');
104100

105101
expect(component.messageToShow).toEqual('An error occurred, try again later.');
106102
expect(component.areTabsActive).toBeFalse();
107103
});
104+
105+
it('set data to update ', () => {
106+
spyOn(store, 'dispatch');
107+
108+
component.ngOnInit();
109+
component.setDataToUpdate(customerData);
110+
111+
expect(component.messageToShow).toEqual(undefined);
112+
});
108113
});

src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms';
33
import { Store, select } from '@ngrx/store';
44

55
import { Subscription } from 'rxjs';
6-
import { CustomerState, CreateCustomer, LoadCustomers } from 'src/app/modules/customer-management/store';
7-
import { getStatusMessage } from './../../../../store/customer-management.selectors';
6+
import { getStatusMessage, getCustomerById } from './../../../../store/customer-management.selectors';
7+
import { Customer } from 'src/app/modules/shared/models/index';
8+
import {
9+
CustomerState,
10+
CreateCustomer,
11+
LoadCustomers,
12+
UpdateCustomer,
13+
} from 'src/app/modules/customer-management/store';
814

915
@Component({
1016
selector: 'app-create-customer',
@@ -17,7 +23,9 @@ export class CreateCustomerComponent implements OnInit, OnDestroy {
1723
@Output() changeValueAreTabsActives = new EventEmitter<boolean>();
1824
showAlert = false;
1925
messageToShow = '';
26+
customerToEdit: Customer;
2027
saveSubscription: Subscription;
28+
editSubscription: Subscription;
2129

2230
constructor(private formBuilder: FormBuilder, private store: Store<CustomerState>) {
2331
this.customerForm = this.formBuilder.group({
@@ -31,17 +39,35 @@ export class CreateCustomerComponent implements OnInit, OnDestroy {
3139
this.saveSubscription = messages$.subscribe((valueMessage) => {
3240
this.setStatusOnScreen(valueMessage);
3341
});
42+
43+
const customers$ = this.store.pipe(select(getCustomerById));
44+
this.editSubscription = customers$.subscribe((customer) => {
45+
this.customerToEdit = customer;
46+
this.setDataToUpdate(this.customerToEdit);
47+
});
3448
}
3549

3650
ngOnDestroy() {
3751
this.areTabsActive = false;
3852
this.saveSubscription.unsubscribe();
53+
this.editSubscription.unsubscribe();
3954
}
4055

4156
onSubmit(customerData) {
42-
this.store.dispatch(new CreateCustomer(customerData));
43-
this.store.dispatch(new LoadCustomers());
57+
const key = 'id';
58+
if (this.customerToEdit) {
59+
const customer = {
60+
...customerData,
61+
id: this.customerToEdit[key],
62+
};
63+
this.store.dispatch(new UpdateCustomer(customer));
64+
this.customerForm.reset();
65+
} else {
66+
this.store.dispatch(new CreateCustomer(customerData));
67+
this.store.dispatch(new LoadCustomers());
68+
}
4469
this.showAlert = true;
70+
setTimeout(() => (this.showAlert = false), 3000);
4571
}
4672

4773
setStatusOnScreen(message: string) {
@@ -54,6 +80,16 @@ export class CreateCustomerComponent implements OnInit, OnDestroy {
5480
this.areTabsActive = false;
5581
this.changeValueAreTabsActives.emit(this.areTabsActive);
5682
}
83+
this.messageToShow = message;
84+
}
85+
86+
setDataToUpdate(customerData: Customer) {
87+
if (customerData) {
88+
this.customerForm.setValue({
89+
name: customerData.name,
90+
description: customerData.description,
91+
});
92+
}
5793
}
5894

5995
resetCustomerForm() {

src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.html

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
<div
2+
*ngIf="showAlert && messageToShow !== ''"
3+
[ngClass]="{
4+
'bg-secondary': messageToShow == 'Customer removed successfully!',
5+
'bg-primary': messageToShow != 'Customer removed successfully!'
6+
}"
7+
class="alert alert-dismissible fade fade-in show text-white"
8+
role="alert"
9+
>
10+
<strong>{{ messageToShow }}</strong>
11+
</div>
112
<table class="table table-sm table-bordered table-striped mb-0">
213
<thead class="thead-orange">
314
<tr class="d-flex">
@@ -12,10 +23,10 @@
1223
>
1324
<td class="col-sm-9">{{ customer.name }}</td>
1425
<td class="col-sm-3 text-center">
15-
<button type="button" class="btn btn-sm btn-secondary">
26+
<button (click)="editCustomer(customer.id)" type="button" class="btn btn-sm btn-secondary">
1627
<i class="fa fa-pencil fa-xs"></i>
1728
</button>
18-
<button type="button" class="btn btn-sm btn-danger ml-2">
29+
<button (click)="deleteCustomer(customer.id)" type="button" class="btn btn-sm btn-danger ml-2">
1930
<i class="fas fa-trash-alt fa-xs"></i>
2031
</button>
2132
</td>

src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.spec.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import { MockStore, provideMockStore } from '@ngrx/store/testing';
21
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { MockStore, provideMockStore } from '@ngrx/store/testing';
33

4-
import { CustomerListComponent } from './customer-list.component';
54
import { NgxPaginationModule } from 'ngx-pagination';
5+
import { CustomerListComponent } from './customer-list.component';
66
import { allCustomers } from './../../../../store/customer-management.selectors';
7-
import { CustomerState } from 'src/app/modules/customer-management/store';
7+
import { CustomerState, SetCustomerToEdit, DeleteCustomer } from 'src/app/modules/customer-management/store';
88

99
describe('CustomerTableListComponent', () => {
1010
let component: CustomerListComponent;
1111
let fixture: ComponentFixture<CustomerListComponent>;
1212
let store: MockStore<CustomerState>;
1313
let mockCustomerSelector;
1414

15-
1615
const state = {
1716
data: [{ tenant_id: 'id', name: 'name', description: 'description' }],
1817
isLoading: false,
1918
message: '',
19+
customerIdToEdit: '',
2020
};
2121

2222
beforeEach(async(() => {
@@ -50,8 +50,25 @@ describe('CustomerTableListComponent', () => {
5050
expect(component.customers).toEqual(state.data);
5151
});
5252

53+
it('onClick edit, dispatch SetCustomerToEdit and enable customer form', () => {
54+
spyOn(store, 'dispatch');
55+
56+
component.editCustomer('1');
57+
58+
expect(store.dispatch).toHaveBeenCalledWith(new SetCustomerToEdit('1'));
59+
expect(component.showCustomerForm).toBeTruthy();
60+
});
61+
62+
it('onClick delete, dispatch DeleteCustomer and enable show alert', () => {
63+
spyOn(store, 'dispatch');
64+
65+
component.deleteCustomer('1');
66+
67+
expect(store.dispatch).toHaveBeenCalledWith(new DeleteCustomer('1'));
68+
expect(component.showAlert).toBeTruthy();
69+
});
70+
5371
afterEach(() => {
5472
fixture.destroy();
5573
});
56-
5774
});
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,62 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
22
import { Store, select } from '@ngrx/store';
33

4-
import { allCustomers } from './../../../../store/customer-management.selectors';
5-
import { LoadCustomers } from './../../../../store/customer-management.actions';
4+
import { Subscription } from 'rxjs';
5+
import { allCustomers, getStatusMessage } from './../../../../store/customer-management.selectors';
6+
import { LoadCustomers, DeleteCustomer, SetCustomerToEdit } from './../../../../store/customer-management.actions';
67
import { Customer } from './../../../../../shared/models/customer.model';
78
import { ITEMS_PER_PAGE } from 'src/environments/environment';
89

9-
1010
@Component({
1111
selector: 'app-customer-list',
1212
templateUrl: './customer-list.component.html',
1313
styleUrls: ['./customer-list.component.scss'],
1414
})
15-
export class CustomerListComponent implements OnInit {
16-
15+
export class CustomerListComponent implements OnInit, OnDestroy {
1716
initPage1 = 1;
1817
itemsPerPage = ITEMS_PER_PAGE;
18+
@Input() showCustomerForm: boolean;
19+
@Output() changeValueShowCustomerForm = new EventEmitter<boolean>();
1920

2021
customers: Customer[] = [];
22+
messageToShow = '';
23+
showAlert = false;
24+
customerSubscription: Subscription;
25+
customerMessageSubscription: Subscription;
2126

2227
constructor(private store: Store<Customer>) {}
2328

2429
ngOnInit(): void {
2530
this.store.dispatch(new LoadCustomers());
2631
const customers$ = this.store.pipe(select(allCustomers));
27-
customers$.subscribe((response) => {
32+
this.customerSubscription = customers$.subscribe((response) => {
2833
this.customers = response;
2934
});
35+
36+
const messages$ = this.store.pipe(select(getStatusMessage));
37+
this.customerMessageSubscription = messages$.subscribe((valueMessage) => {
38+
this.setStatusOnScreen(valueMessage);
39+
});
40+
}
41+
42+
ngOnDestroy() {
43+
this.customerSubscription.unsubscribe();
44+
this.customerMessageSubscription.unsubscribe();
3045
}
3146

47+
setStatusOnScreen(message: string) {
48+
this.messageToShow = message;
49+
}
50+
51+
editCustomer(customerId: string) {
52+
this.showCustomerForm = true;
53+
this.changeValueShowCustomerForm.emit(this.showCustomerForm);
54+
this.store.dispatch(new SetCustomerToEdit(customerId));
55+
}
56+
57+
deleteCustomer(customerId: string) {
58+
this.showAlert = true;
59+
setTimeout(() => (this.showAlert = false), 3000);
60+
this.store.dispatch(new DeleteCustomer(customerId));
61+
}
3262
}
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,42 @@
1-
2-
<form style="width: 600px;" [formGroup]="projectTypeForm" (ngSubmit)="onSubmit(projectTypeForm.value)">
3-
<div class="form-group">
4-
<input
5-
type="text"
6-
class="form-control form-control-sm"
7-
id="name"
8-
formControlName="name"
9-
aria-describedby=""
10-
[class.is-invalid]="name.invalid && name.touched"
11-
required
12-
placeholder="Name"
13-
/>
14-
<div class="text-danger" *ngIf="(name.dirty || name.touched) && name.invalid && name.errors.required">
15-
Name is required.
1+
<form style="width: 600px;" [formGroup]="projectTypeForm" (ngSubmit)="onSubmit(projectTypeForm.value)">
2+
<div class="form-group">
3+
<input
4+
type="text"
5+
class="form-control form-control-sm"
6+
id="name"
7+
formControlName="name"
8+
aria-describedby=""
9+
[class.is-invalid]="name.invalid && name.touched"
10+
required
11+
placeholder="Name"
12+
/>
13+
<div class="text-danger" *ngIf="(name.dirty || name.touched) && name.invalid && name.errors.required">
14+
Name is required.
15+
</div>
16+
<textarea
17+
class="form-control form-control-sm mt-2"
18+
id="descriptionTextArea"
19+
rows="3"
20+
placeholder="Description"
21+
formControlName="description"
22+
></textarea>
23+
<div class="btn-toolbar" role="toolbar">
24+
<div class="btn-group mr-2" role="group">
25+
<button type="submit" class="btn btn-sm btn-primary mb-2 ml-2 mt-2" [disabled]="!projectTypeForm.valid">
26+
Save
27+
</button>
1628
</div>
17-
<textarea
18-
class="form-control form-control-sm mt-2"
19-
id="descriptionTextArea"
20-
rows="3"
21-
placeholder="Description"
22-
formControlName="description"
23-
></textarea>
24-
<div class="btn-toolbar" role="toolbar">
25-
<div class="btn-group mr-2" role="group">
26-
<button type="submit" class="btn btn-sm btn-primary mb-2 ml-2 mt-2" [disabled]="!projectTypeForm.valid">Save</button>
27-
</div>
28-
<div class="btn-group mr-2" role="group">
29-
<button class="btn btn-sm btn-secondary mb-2 ml-2 mt-2" type="reset" [hidden]="!projectTypeToEdit" (click)="cancelButton()">Cancel</button>
30-
</div>
29+
<div class="btn-group mr-2" role="group">
30+
<button
31+
class="btn btn-sm btn-secondary mb-2 ml-2 mt-2"
32+
type="reset"
33+
[hidden]="!projectTypeToEdit"
34+
(click)="cancelButton()"
35+
>
36+
Cancel
37+
</button>
3138
</div>
3239
</div>
33-
</form>
34-
<hr />
35-
40+
</div>
41+
</form>
42+
<hr />

src/app/modules/customer-management/components/projects/components/create-project/create-project.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class="container mb-1">
22
<form style="width: 600px;">
33
<div class="form-group">
4-
<input type="text" class="form-control form-control-sm" id="" aria-describedby="" placeholder="Project name" />
4+
<input type="text" class="form-control form-control-sm" id="projectName" placeholder="Project name" />
55
<textarea
66
class="form-control form-control-sm mt-2"
77
id="exampleFormControlTextarea1"

src/app/modules/customer-management/pages/customer.component.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ <h4>Customers</h4>
88
<app-search-project></app-search-project>
99
</div>
1010
</div>
11-
<app-customer-list></app-customer-list>
11+
<app-customer-list
12+
[showCustomerForm]="showCustomerForm"
13+
(changeValueShowCustomerForm)="showCustomerForm = $event"
14+
></app-customer-list>
1215
<div class="row" *ngIf="showCustomerForm">
1316
<div class="col">
1417
<app-management-customer-projects></app-management-customer-projects>

0 commit comments

Comments
 (0)