Skip to content

Commit 6e7a412

Browse files
committed
added reactive forms support in search-customer component
1 parent 1f4f719 commit 6e7a412

File tree

15 files changed

+162
-82
lines changed

15 files changed

+162
-82
lines changed

src/Client/Logistics.OfficeApp/src/app/pages/dashboard/components/company-stats/company-stats.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
22
import {CommonModule, CurrencyPipe} from '@angular/common';
33
import {CompanyStats} from '@core/models';
44
import {ApiService} from '@core/services';
5-
import {DistanceConverter} from '@shared/utils';
5+
import {Converters} from '@shared/utils';
66
import {DistanceUnitPipe} from '@shared/pipes';
77
import {SharedModule} from 'primeng/api';
88
import {CardModule} from 'primeng/card';
@@ -45,7 +45,7 @@ export class CompanyStatsComponent implements OnInit {
4545
return 0;
4646
}
4747

48-
return gross / DistanceConverter.metersTo(distance, 'mi');
48+
return gross / Converters.metersTo(distance, 'mi');
4949
}
5050

5151
private fetchCompanyStats() {
@@ -55,7 +55,7 @@ export class CompanyStatsComponent implements OnInit {
5555
if (result.isSuccess && result.data) {
5656
const stats = result.data;
5757
this.companyStats = result.data;
58-
this.rpm = stats.totalGross / DistanceConverter.metersTo(stats.totalDistance, 'mi');
58+
this.rpm = stats.totalGross / Converters.metersTo(stats.totalDistance, 'mi');
5959
}
6060

6161
this.isLoading = false;

src/Client/Logistics.OfficeApp/src/app/pages/home/home.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {DailyGrosses, Load} from '@core/models';
1313
import {ApiService} from '@core/services';
1414
import {TrucksMapComponent} from '@shared/components';
1515
import {AddressPipe, DistanceUnitPipe} from '@shared/pipes';
16-
import {DateUtils, DistanceConverter} from '@shared/utils';
16+
import {DateUtils, Converters} from '@shared/utils';
1717
import {NotificationsPanelComponent} from './components';
1818

1919

@@ -98,7 +98,7 @@ export class HomeComponent implements OnInit {
9898

9999
this.weeklyGross = grosses.totalGross;
100100
this.weeklyDistance = grosses.totalDistance;
101-
this.weeklyRpm = this.weeklyGross / DistanceConverter.metersTo(this.weeklyDistance, 'mi');
101+
this.weeklyRpm = this.weeklyGross / Converters.metersTo(this.weeklyDistance, 'mi');
102102
this.drawChart(grosses);
103103
this.calcTodayGross(grosses);
104104
}

src/Client/Logistics.OfficeApp/src/app/pages/load/add-load/add-load.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {AppConfig} from '@configs';
1313
import {AuthService} from '@core/auth';
1414
import {CreateLoad, Customer} from '@core/models';
1515
import {ApiService, ToastService} from '@core/services';
16-
import {DistanceConverter} from '@shared/utils';
16+
import {Converters} from '@shared/utils';
1717
import {
1818
AddressAutocompleteComponent,
1919
DirectionsMapComponent,
@@ -104,7 +104,7 @@ export class AddLoadComponent implements OnInit {
104104

105105
updateDistance(eventData: RouteChangedEvent) {
106106
this.distanceMeters = eventData.distance;
107-
const distanceMiles = DistanceConverter.metersTo(this.distanceMeters, 'mi');
107+
const distanceMiles = Converters.metersTo(this.distanceMeters, 'mi');
108108
this.form.patchValue({distance: distanceMiles});
109109
}
110110

Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
<p-autoComplete #autoCompleteInput
1+
<p-autoComplete
22
[suggestions]="suggestedCustomers"
3-
styleClass="w-100" inputStyleClass="form-control"
3+
styleClass="w-100"
4+
inputStyleClass="form-control"
45
placeholder="Type a customer name"
5-
(completeMethod)="searchCustomer($event)"
66
[minLength]="2"
77
[forceSelection]="true"
88
field="name"
9+
(completeMethod)="searchCustomer($event)"
910
(onSelect)="changeSelectedCustomer($event)">
1011
</p-autoComplete>
Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import {Component, EventEmitter, Input, Output} from '@angular/core';
1+
import {Component, EventEmitter, Input, Output, forwardRef} from '@angular/core';
22
import {CommonModule} from '@angular/common';
3+
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
34
import {AutoCompleteModule, AutoCompleteOnSelectEvent} from 'primeng/autocomplete';
45
import {ApiService} from '@core/services';
56
import {Customer} from '@core/models';
@@ -9,20 +10,27 @@ import {Customer} from '@core/models';
910
selector: 'app-search-customer',
1011
standalone: true,
1112
templateUrl: './search-customer.component.html',
12-
styleUrls: [],
1313
imports: [
1414
CommonModule,
1515
AutoCompleteModule,
1616
],
17+
providers: [
18+
{
19+
provide: NG_VALUE_ACCESSOR,
20+
useExisting: forwardRef(() => SearchCustomerComponent),
21+
multi: true,
22+
},
23+
],
1724
})
18-
export class SearchCustomerComponent {
25+
export class SearchCustomerComponent implements ControlValueAccessor {
26+
private isDisabled = false;
27+
private customer: Customer | null = null;
1928
public suggestedCustomers: Customer[] = [];
2029

2130
@Input() selectedCustomer: Customer | null = null;
22-
@Output() selectedCustomerChange = new EventEmitter<Customer>();
31+
@Output() selectedCustomerChange = new EventEmitter<Customer | null>();
2332

24-
constructor(private readonly apiService: ApiService){
25-
}
33+
constructor(private readonly apiService: ApiService) {}
2634

2735
searchCustomer(event: {query: string}) {
2836
this.apiService.getCustomers({search: event.query}).subscribe((result) => {
@@ -33,6 +41,32 @@ export class SearchCustomerComponent {
3341
}
3442

3543
changeSelectedCustomer(event: AutoCompleteOnSelectEvent) {
36-
this.selectedCustomerChange.emit(event.value);
44+
this.customer = event.value;
45+
this.selectedCustomerChange.emit(this.customer);
46+
this.onChange(this.customer);
47+
}
48+
49+
//#region Implementation Reactive forms
50+
51+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
52+
private onChange(value: Customer | null): void {}
53+
private onTouched(): void {}
54+
55+
writeValue(obj: Customer | null): void {
56+
this.customer = obj;
57+
}
58+
59+
registerOnChange(fn: () => void): void {
60+
this.onChange = fn;
61+
}
62+
63+
registerOnTouched(fn: () => void): void {
64+
this.onTouched = fn;
3765
}
66+
67+
setDisabledState(isDisabled: boolean): void {
68+
this.isDisabled = isDisabled;
69+
}
70+
71+
//#endregion
3872
}

src/Client/Logistics.OfficeApp/src/app/pages/load/edit-load/edit-load.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ <h1>Edit a load #{{loadRefId}}</h1>
1111
<p-progressSpinner></p-progressSpinner>
1212
}
1313
<form [formGroup]="form" (ngSubmit)="updateLoad()">
14+
<app-validation-summary [form]="form"></app-validation-summary>
1415
<div class="mb-3">
1516
<label for="name" class="form-label">Name</label>
1617
<input id="name" formControlName="name" type="text" class="form-control" placeholder="Load name" />
1718
</div>
1819
<div class="mb-3">
1920
<label for="customer" class="form-label">Customer</label>
20-
<app-search-customer [(selectedCustomer)]="selectedCustomer"></app-search-customer>
21+
<app-search-customer formControlName="customer"></app-search-customer>
2122
</div>
2223
<div class="mb-3">
2324
<label for="orgAddress" class="form-label">Origin Address</label>

src/Client/Logistics.OfficeApp/src/app/pages/load/edit-load/edit-load.component.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@
22
width: 50px !important;
33
height: 50px !important;
44
}
5-

src/Client/Logistics.OfficeApp/src/app/pages/load/edit-load/edit-load.component.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-non-null-assertion */
22
import {Component, OnInit} from '@angular/core';
3-
import {NgIf} from '@angular/common';
3+
import {CommonModule} from '@angular/common';
44
import {FormControl, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms';
55
import {ActivatedRoute, Router, RouterLink} from '@angular/router';
66
import {ConfirmationService} from 'primeng/api';
@@ -15,12 +15,13 @@ import {AppConfig} from '@configs';
1515
import {EnumValue, LoadStatus, LoadStatusEnum, convertEnumToArray} from '@core/enums';
1616
import {Customer, UpdateLoad} from '@core/models';
1717
import {ApiService, ToastService} from '@core/services';
18-
import {DistanceConverter} from '@shared/utils';
18+
import {Converters} from '@shared/utils';
1919
import {
2020
AddressAutocompleteComponent,
2121
DirectionsMapComponent,
2222
RouteChangedEvent,
2323
SelectedAddressEvent,
24+
ValidationSummaryComponent,
2425
} from '@shared/components';
2526
import {TruckData, TruckHelper} from '../shared';
2627
import {SearchCustomerComponent, SearchTruckComponent} from '../components';
@@ -33,10 +34,10 @@ import {SearchCustomerComponent, SearchTruckComponent} from '../components';
3334
styleUrls: ['./edit-load.component.scss'],
3435
standalone: true,
3536
imports: [
37+
CommonModule,
3638
ToastModule,
3739
ConfirmDialogModule,
3840
CardModule,
39-
NgIf,
4041
ProgressSpinnerModule,
4142
FormsModule,
4243
ReactiveFormsModule,
@@ -47,7 +48,8 @@ import {SearchCustomerComponent, SearchTruckComponent} from '../components';
4748
AddressAutocompleteComponent,
4849
DirectionsMapComponent,
4950
SearchCustomerComponent,
50-
SearchTruckComponent
51+
SearchTruckComponent,
52+
ValidationSummaryComponent,
5153
],
5254
providers: [
5355
ConfirmationService,
@@ -62,7 +64,6 @@ export class EditLoadComponent implements OnInit {
6264
public isLoading: boolean;
6365
public form: FormGroup;
6466
public selectedTruck: TruckData | null;
65-
public selectedCustomer: Customer | null;
6667
public loadStatuses: EnumValue[];
6768
public originCoords?: [number, number] | null;
6869
public destinationCoords?: [number, number] | null;
@@ -77,12 +78,12 @@ export class EditLoadComponent implements OnInit {
7778
this.accessToken = AppConfig.mapboxToken;
7879
this.isLoading = false;
7980
this.selectedTruck = null;
80-
this.selectedCustomer = null;
8181
this.loadStatuses = convertEnumToArray(LoadStatusEnum);
8282
this.distanceMeters = 0;
8383

8484
this.form = new FormGroup({
8585
name: new FormControl(''),
86+
customer: new FormControl('', Validators.required),
8687
orgAddress: new FormControl('', Validators.required),
8788
orgCoords: new FormControl([], Validators.required),
8889
dstAddress: new FormControl('', Validators.required),
@@ -132,7 +133,7 @@ export class EditLoadComponent implements OnInit {
132133

133134
updateDistance(eventData: RouteChangedEvent) {
134135
this.distanceMeters = eventData.distance;
135-
const distanceMiles = DistanceConverter.metersTo(this.distanceMeters, 'mi');
136+
const distanceMiles = Converters.metersTo(this.distanceMeters, 'mi');
136137
this.form.patchValue({distance: distanceMiles});
137138
}
138139

@@ -155,7 +156,7 @@ export class EditLoadComponent implements OnInit {
155156
distance: this.distanceMeters,
156157
assignedDispatcherId: this.form.value.dispatcherId,
157158
assignedTruckId: this.selectedTruck!.truckId,
158-
customerId: this.selectedCustomer!.id,
159+
customerId: this.form.value.customer.id,
159160
status: this.form.value.status,
160161
};
161162

@@ -175,11 +176,6 @@ export class EditLoadComponent implements OnInit {
175176
return false;
176177
}
177178

178-
if (!this.selectedCustomer) {
179-
this.toastService.showError('Please select the customer');
180-
return false;
181-
}
182-
183179
if (!this.form.value.orgAddress) {
184180
this.toastService.showError('Please select the origin address');
185181
return false;
@@ -190,7 +186,7 @@ export class EditLoadComponent implements OnInit {
190186
return false;
191187
}
192188

193-
return true;
189+
return this.form.valid;
194190
}
195191

196192
private deleteLoad() {
@@ -217,13 +213,14 @@ export class EditLoadComponent implements OnInit {
217213

218214
this.form.patchValue({
219215
name: load.name,
216+
customer: load.customer,
220217
orgAddress: load.originAddress,
221218
orgCoords: [load.originAddressLong, load.originAddressLat],
222219
dstAddress: load.destinationAddress,
223220
dstCoords: [load.destinationAddressLong, load.destinationAddressLat],
224221
dispatchedDate: this.getLocaleDate(load.dispatchedDate),
225222
deliveryCost: load.deliveryCost,
226-
distance: DistanceConverter.metersTo(load.distance, 'mi'),
223+
distance: Converters.metersTo(load.distance, 'mi'),
227224
dispatcherName: load.assignedDispatcherName,
228225
dispatcherId: load.assignedDispatcherId,
229226
status: load.status,
@@ -247,3 +244,8 @@ export class EditLoadComponent implements OnInit {
247244
return '';
248245
}
249246
}
247+
248+
// interface EditLoadForm {
249+
// name: FormControl<string | null>;
250+
// orgAddress: FormControl<string>;
251+
// }

src/Client/Logistics.OfficeApp/src/app/pages/truck/components/truck-grosses-linechart/truck-grosses-linechart.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {CardModule} from 'primeng/card';
44
import {SkeletonModule} from 'primeng/skeleton';
55
import {ChartModule} from 'primeng/chart';
66
import {DailyGrosses} from '@core/models';
7-
import {DateUtils, DistanceConverter} from '@shared/utils';
7+
import {DateUtils, Converters} from '@shared/utils';
88
import {ApiService} from '@core/services';
99
import {RangeCalendarComponent} from '@shared/components';
1010

@@ -25,8 +25,8 @@ import {RangeCalendarComponent} from '@shared/components';
2525
export class TruckGrossesLinechartComponent implements OnInit {
2626
public isLoading: boolean;
2727
public dailyGrosses?: DailyGrosses;
28-
public chartData: any;
29-
public chartOptions: any;
28+
public chartData: unknown;
29+
public chartOptions: unknown;
3030
public startDate: Date;
3131
public endDate: Date;
3232

@@ -67,7 +67,7 @@ export class TruckGrossesLinechartComponent implements OnInit {
6767
this.apiService.getDailyGrosses(this.startDate, this.endDate, this.truckId).subscribe((result) => {
6868
if (result.isSuccess && result.data) {
6969
this.dailyGrosses = result.data;
70-
const rpm = this.dailyGrosses.totalGross / DistanceConverter.metersTo(this.dailyGrosses.totalDistance, 'mi');
70+
const rpm = this.dailyGrosses.totalGross / Converters.metersTo(this.dailyGrosses.totalDistance, 'mi');
7171

7272
this.drawChart(this.dailyGrosses);
7373
this.chartDrawn.emit({dailyGrosses: this.dailyGrosses, rpm: rpm});

src/Client/Logistics.OfficeApp/src/app/shared/components/address-autocomplete/address-autocomplete.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
[name]="field"
55
class="form-control"
66
[placeholder]="placeholder"
7-
(input)="onAddressInputChange($event)"
8-
(focusout)="onInputFocusOut($event)"
9-
[(ngModel)]="address" />
7+
(input)="handleAddressInputChange($event)"
8+
(focusout)="handleInputFocusOut($event)"
9+
[(ngModel)]="addressString" />
1010

1111
@if (searchResults.length) {
1212
<div class="popup">
1313
@for (result of searchResults; track result.id) {
1414
<div class="popup-item"
15-
(click)="onClickAddress(result.place_name, result.center)"
15+
(click)="handleClickAddress(result)"
1616
role="presentation">
1717
{{result.place_name}}
1818
</div>

0 commit comments

Comments
 (0)