@aggdirect/coolmap-services 4.0.7 → 10.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,107 +1,121 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, InjectionToken, signal, computed, Injectable, inject, NgZone } from '@angular/core';
3
- import { BehaviorSubject } from 'rxjs';
4
- import mapboxgl from 'mapbox-gl';
2
+ import { Injectable, Inject } from '@angular/core';
3
+ import * as mapboxgl from 'mapbox-gl';
5
4
  import * as turf from '@turf/turf';
6
- import { HttpClient } from '@angular/common/http';
5
+ import { BehaviorSubject } from 'rxjs';
6
+ import { MapboxLayer } from '@deck.gl/mapbox';
7
+ import { ArcLayer } from '@deck.gl/layers';
8
+ import * as i1 from '@angular/common/http';
9
+ import * as i2 from '@angular/material/snack-bar';
10
+ import * as i2$1 from '@angular/platform-browser';
7
11
 
8
- class CoolmapServices {
9
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapServices, deps: [], target: i0.ɵɵFactoryTarget.Component });
10
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: CoolmapServices, isStandalone: true, selector: "lib-coolmap-services", ngImport: i0, template: `
11
- <p>
12
- coolmap-services works!
13
- </p>
14
- `, isInline: true, styles: [""] });
12
+ class Route {
13
+ index = 0;
14
+ type;
15
+ // Job Code
16
+ customer_contact;
17
+ customer_name;
18
+ delivery_contact;
19
+ delivery_lat;
20
+ delivery_location;
21
+ delivery_lon;
22
+ driver_list;
23
+ material;
24
+ order_number;
25
+ pickup_lat;
26
+ pickup_location;
27
+ pickup_lon;
28
+ project;
29
+ total_count;
30
+ unit;
31
+ values;
32
+ job_id;
33
+ isSelected;
34
+ date;
35
+ // Add Route
36
+ created_at;
37
+ created_by_name;
38
+ customer_id;
39
+ delivery_lat_lng;
40
+ estimated_distance;
41
+ estimated_time;
42
+ materials_id;
43
+ path;
44
+ pickup_lat_lng;
45
+ route_id;
46
+ route_name;
47
+ unit_id;
48
+ note;
49
+ materialLabel;
50
+ isActive;
51
+ prevent;
15
52
  }
16
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapServices, decorators: [{
17
- type: Component,
18
- args: [{ selector: 'lib-coolmap-services', imports: [], template: `
19
- <p>
20
- coolmap-services works!
21
- </p>
22
- ` }]
23
- }] });
24
-
25
- const COOLMAP_CONFIG = new InjectionToken('COOLMAP_CONFIG');
26
- function provideCoolmapConfig(config) {
27
- return {
28
- provide: COOLMAP_CONFIG,
29
- useValue: config
30
- };
53
+ const EstinationData = ['estimated_distance', 'estimated_time'];
54
+ var EstinationEnum;
55
+ (function (EstinationEnum) {
56
+ EstinationEnum["estimated_distance"] = "miles";
57
+ EstinationEnum["estimated_time"] = "time";
58
+ })(EstinationEnum || (EstinationEnum = {}));
59
+ const JobCodeOverviewData = ['order_number', 'customer_name', 'project', 'unit', 'material', 'customer_contact', 'delivery_contact', 'pickup_location', 'delivery_location'];
60
+ var JobCodeOverviewEnum;
61
+ (function (JobCodeOverviewEnum) {
62
+ JobCodeOverviewEnum["material"] = "Material";
63
+ JobCodeOverviewEnum["order_number"] = "Job Code";
64
+ JobCodeOverviewEnum["customer_name"] = "Customer";
65
+ JobCodeOverviewEnum["customer_contact"] = "Customer Contact";
66
+ JobCodeOverviewEnum["delivery_contact"] = "Delivery Contact";
67
+ JobCodeOverviewEnum["project"] = "Project Name";
68
+ JobCodeOverviewEnum["unit"] = "Job Type";
69
+ JobCodeOverviewEnum["pickup_location"] = "Pickup";
70
+ JobCodeOverviewEnum["delivery_location"] = "Delivery";
71
+ })(JobCodeOverviewEnum || (JobCodeOverviewEnum = {}));
72
+ const DriversmsCardKey = ['order_number', 'date', 'values', 'material', 'unit', 'pickup_location', 'delivery_location'];
73
+ var DriverSmsCardEnum;
74
+ (function (DriverSmsCardEnum) {
75
+ DriverSmsCardEnum["order_number"] = "Jobcode";
76
+ DriverSmsCardEnum["date"] = "Date";
77
+ DriverSmsCardEnum["values"] = "Total tasks";
78
+ DriverSmsCardEnum["material"] = "Material";
79
+ DriverSmsCardEnum["unit"] = "Unit";
80
+ DriverSmsCardEnum["pickup_location"] = "Pickup Address";
81
+ DriverSmsCardEnum["delivery_location"] = "Delivery Address";
82
+ })(DriverSmsCardEnum || (DriverSmsCardEnum = {}));
83
+ class PopupData {
84
+ coordinate;
85
+ pickup;
86
+ jobCode;
87
+ customer;
88
+ drop;
89
+ routeType;
90
+ title;
91
+ material;
92
+ type;
31
93
  }
32
-
33
- class AgToastService {
34
- _toasts = signal([], ...(ngDevMode ? [{ debugName: "_toasts" }] : []));
35
- defaultDuration = 5000;
36
- position = signal('top-right', ...(ngDevMode ? [{ debugName: "position" }] : []));
37
- toasts = computed(() => this._toasts(), ...(ngDevMode ? [{ debugName: "toasts" }] : []));
38
- toastPosition = computed(() => this.position(), ...(ngDevMode ? [{ debugName: "toastPosition" }] : []));
39
- generateId() {
40
- return `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
41
- }
42
- setPosition(pos) {
43
- this.position.set(pos);
44
- }
45
- show(config) {
46
- // Prevent duplicate toasts
47
- const currentToasts = this._toasts();
48
- const incomingVariant = config.variant || 'info';
49
- const isDuplicate = currentToasts.find(t => t.message === config.message && t.variant === incomingVariant && t.title === config.title);
50
- if (isDuplicate) {
51
- return isDuplicate.id;
52
- }
53
- const toast = {
54
- id: this.generateId(),
55
- message: config.message,
56
- title: config.title,
57
- variant: incomingVariant,
58
- duration: config.duration ?? this.defaultDuration,
59
- dismissible: config.dismissible ?? true,
60
- action: config.action,
61
- createdAt: new Date()
62
- };
63
- this._toasts.update(toasts => [...toasts, toast]);
64
- // Auto-dismiss if duration > 0
65
- if (toast.duration > 0) {
66
- setTimeout(() => {
67
- this.dismiss(toast.id);
68
- }, toast.duration);
69
- }
70
- return toast.id;
71
- }
72
- success(message, title, duration) {
73
- return this.show({ message, title, variant: 'success', duration });
74
- }
75
- error(message, title, duration) {
76
- return this.show({ message, title, variant: 'error', duration });
77
- }
78
- warning(message, title, duration) {
79
- return this.show({ message, title, variant: 'warning', duration });
80
- }
81
- info(message, title, duration) {
82
- return this.show({ message, title, variant: 'info', duration });
83
- }
84
- dismiss(id) {
85
- this._toasts.update(toasts => toasts.filter(t => t.id !== id));
86
- }
87
- dismissAll() {
88
- this._toasts.set([]);
89
- }
90
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AgToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
91
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AgToastService, providedIn: 'root' });
94
+ class CoolmapConfigModel {
95
+ analyticsRESTURL;
96
+ RESTURLPrefix;
97
+ repository;
98
+ mapboxStyle;
99
+ mapboxAccessToken;
92
100
  }
93
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AgToastService, decorators: [{
94
- type: Injectable,
95
- args: [{
96
- providedIn: 'root'
97
- }]
98
- }] });
99
101
 
100
102
  class UtilsService {
101
- http = inject(HttpClient);
102
- config = inject(COOLMAP_CONFIG);
103
- ngZone = inject(NgZone);
104
- // BehaviorSubjects for state (converting to simple Signals later where practical)
103
+ http;
104
+ snackBar;
105
+ config;
106
+ ngZone;
107
+ analyticsRESTURL = '';
108
+ RESTURLPrefix = '';
109
+ pickupOptions = [];
110
+ destOptions = [];
111
+ ownerOptions = [];
112
+ customerOptions = [];
113
+ unitOptions = [];
114
+ materialOptions = [];
115
+ jcodeOptions = [];
116
+ driverOption = [];
117
+ truckingCompanayOption = [];
118
+ routeNameOptions = [];
105
119
  preventnavChange = new BehaviorSubject(false);
106
120
  navChangeObserve = this.preventnavChange.asObservable();
107
121
  clearViewRouteforJobCode = new BehaviorSubject(false);
@@ -117,110 +131,92 @@ class UtilsService {
117
131
  materialsList;
118
132
  materialsListForCustomer;
119
133
  customersList;
120
- locationList;
121
- // Options filtering properties
122
- pickupOptions = [];
123
- destOptions = [];
124
- ownerOptions = [];
125
- customerOptions = [];
126
- unitOptions = [];
127
- materialOptions = [];
128
- jcodeOptions = [];
129
- driverOption = [];
130
- truckingCompanayOption = [];
131
- routeNameOptions = [];
134
+ constructor(http, snackBar, config, ngZone) {
135
+ this.http = http;
136
+ this.snackBar = snackBar;
137
+ this.config = config;
138
+ this.ngZone = ngZone;
139
+ this.analyticsRESTURL = config.analyticsRESTURL;
140
+ this.RESTURLPrefix = config.RESTURLPrefix;
141
+ }
132
142
  getDateFormat(strVal, seprater) {
133
143
  seprater = seprater ? seprater : '-';
134
144
  const mydate = strVal;
135
- if (!mydate)
136
- return '';
137
- const month = String(mydate.getMonth() + 1).padStart(2, '0');
138
- const day = String(mydate.getDate()).padStart(2, '0');
139
- return (mydate.getFullYear() +
145
+ return (mydate?.getFullYear() +
140
146
  seprater +
141
- month +
147
+ ((mydate ? mydate.getMonth() : 0) + 1) +
142
148
  seprater +
143
- day);
149
+ mydate?.getDate());
144
150
  }
145
151
  getData(path) {
146
- return this.http.get(`${this.config.analyticsRESTURL}${this.config.repository}/${path}`);
147
- }
148
- getRestData(path) {
149
- return this.http.get(`${this.config.RESTURLPrefix}${path}`);
152
+ return this.http.get(`${this.analyticsRESTURL}${this.config.repository}/${path}`);
150
153
  }
151
154
  postdata(path, data) {
152
- return this.http.post(`${this.config.analyticsRESTURL}${this.config.repository}/${path}`, data);
155
+ return this.http.post(`${this.analyticsRESTURL}${this.config.repository}/${path}`, data);
153
156
  }
154
157
  postDataWithRestUrl(path, data) {
155
- return this.http.post(`${this.config.RESTURLPrefix}${path}`, data);
158
+ return this.http.post(`${this.RESTURLPrefix}${path}`, data);
156
159
  }
157
- toastService = inject(AgToastService);
158
- // Instead of MatSnackBar, we use AgToastService.
159
- openSnackBar(message, className) {
160
- if (className === 'success') {
161
- this.toastService.success(message);
162
- }
163
- else if (className === 'error') {
164
- this.toastService.error(message);
165
- }
166
- else if (className === 'warning') {
167
- this.toastService.warning(message);
168
- }
169
- else {
170
- this.toastService.info(message);
171
- }
160
+ autocomplete(searchElementRef, form) {
161
+ return new Promise((resolve, reject) => {
162
+ const autocomplete = new google.maps.places.Autocomplete(searchElementRef.nativeElement, {
163
+ types: ['address']
164
+ });
165
+ google.maps.event.addListener(autocomplete, 'place_changed', () => {
166
+ this.ngZone.run(() => {
167
+ const place = autocomplete.getPlace();
168
+ console.log(place.geometry.location.lat(), place.geometry.location.lng());
169
+ resolve({ lat: place.geometry.location.lat(), lng: place.geometry.location.lng() });
170
+ });
171
+ });
172
+ });
172
173
  }
173
- clearOptions() {
174
- this.pickupOptions = [];
175
- this.destOptions = [];
176
- this.ownerOptions = [];
177
- this.customerOptions = [];
178
- this.unitOptions = [];
179
- this.materialOptions = [];
180
- this.jcodeOptions = [];
181
- this.routeNameOptions = [];
174
+ openSnackBar(message, className) {
175
+ this.snackBar.open(message, '', {
176
+ duration: 5000,
177
+ verticalPosition: 'top',
178
+ horizontalPosition: 'center',
179
+ panelClass: [className ? className : 'default'],
180
+ });
182
181
  }
183
182
  makeOptions(item) {
184
- // Porting V1 makeOptions safely
185
183
  if (item.order_number) {
186
- if (this.jcodeOptions.findIndex((elem) => elem.job_id === item.job_id) === -1) {
187
- this.jcodeOptions.push({ job_code: item.order_number, job_id: item.job_id });
188
- }
189
- // Assuming tasks structure if Mapbox Route logic was merged, else driver_list from V1
190
- const driver_list = item.driver_list || [];
191
- if (driver_list.length > 0) {
192
- driver_list.forEach((driver) => {
193
- if (this.driverOption.findIndex((elem) => elem === driver.driver_name) === -1) {
194
- this.driverOption.push(driver.driver_name);
195
- }
196
- if (this.truckingCompanayOption.findIndex((elem) => elem === driver.trucking_company) === -1) {
197
- this.truckingCompanayOption.push(driver.trucking_company);
198
- }
184
+ this.jcodeOptions.findIndex((elem) => elem.job_id === item.job_id) === -1
185
+ ? this.jcodeOptions.push({
186
+ job_code: item.order_number,
187
+ job_id: item.job_id,
188
+ })
189
+ : null;
190
+ if (item.driver_list && item.driver_list?.length > 0) {
191
+ item.driver_list.forEach((driver) => {
192
+ this.driverOption.findIndex((elem) => elem === driver['driver_name']) === -1
193
+ ? this.driverOption.push(driver['driver_name'])
194
+ : null;
195
+ this.truckingCompanayOption.findIndex((elem) => elem === driver['trucking_company']) === -1
196
+ ? this.truckingCompanayOption.push(driver['trucking_company'])
197
+ : null;
199
198
  });
200
199
  }
201
200
  }
202
- if (item.pickup_location && this.pickupOptions.findIndex((elem) => elem === item.pickup_location) === -1)
203
- this.pickupOptions.push(item.pickup_location);
204
- if (item.delivery_location && this.destOptions.findIndex((elem) => elem === item.delivery_location) === -1)
205
- this.destOptions.push(item.delivery_location);
206
- if (item.customer_name && this.customerOptions.findIndex((customer) => customer === item.customer_name) === -1)
207
- this.customerOptions.push(item.customer_name);
208
- if (item.unit && this.unitOptions.findIndex((elem) => elem === item.unit) === -1)
209
- this.unitOptions.push(item.unit);
210
- if (item.material && this.materialOptions.findIndex((elem) => elem === item.material) === -1)
211
- this.materialOptions.push(item.material);
212
- if (item.route_name && this.routeNameOptions.findIndex((elem) => elem === item.route_name) === -1)
213
- this.routeNameOptions.push(item.route_name);
214
- }
215
- setdictValue(key, value) {
216
- this.dict.set(key, value);
217
- }
218
- getdictValue(key) {
219
- const val = this.dict.get(key);
220
- return val ? JSON.parse(val) : null;
221
- }
222
- removedictValue(key) {
223
- this.dict.delete(key);
201
+ this.pickupOptions.findIndex((elem) => elem === item.pickup_location) === -1
202
+ ? this.pickupOptions.push(item.pickup_location)
203
+ : null;
204
+ this.destOptions.findIndex((elem) => elem === item.delivery_location) === -1
205
+ ? this.destOptions.push(item.delivery_location)
206
+ : null;
207
+ this.customerOptions.findIndex((customer) => customer === item.customer_name) === -1
208
+ ? this.customerOptions.push(item.customer_name)
209
+ : null;
210
+ this.unitOptions.findIndex((elem) => elem === item.unit) === -1
211
+ ? this.unitOptions.push(item.unit)
212
+ : null;
213
+ this.materialOptions.findIndex((elem) => elem === item.material) === -1
214
+ ? this.materialOptions.push(item.material)
215
+ : null;
216
+ if (item.route_name)
217
+ this.routeNameOptions.findIndex((elem) => elem === item.route_name) === -1
218
+ ? this.routeNameOptions.push(item.route_name)
219
+ : null;
224
220
  }
225
221
  filter(value, filters) {
226
222
  if (typeof value !== 'string') {
@@ -231,24 +227,22 @@ class UtilsService {
231
227
  return [];
232
228
  }
233
229
  const searchResults = [];
234
- this.unitOptions.forEach((unit) => {
230
+ this.unitOptions.map((unit) => {
235
231
  if (unit.toLowerCase().includes(filterValue)) {
236
232
  searchResults.push({ type: 'unit', label: unit, value: unit });
237
233
  }
238
234
  });
239
- this.customerOptions.forEach((unit) => {
235
+ this.customerOptions.map((unit) => {
240
236
  if (unit.toLowerCase().includes(filterValue)) {
241
237
  searchResults.push({ type: 'customer', label: unit, value: unit });
242
238
  }
243
239
  });
244
- if (this.materialOptions && this.materialOptions.length) {
245
- this.materialOptions.forEach((unit) => {
246
- if (unit.toLowerCase().includes(filterValue)) {
247
- searchResults.push({ type: 'material', label: unit, value: unit });
248
- }
249
- });
250
- }
251
- this.pickupOptions.forEach((unit) => {
240
+ this.materialOptions.map((unit) => {
241
+ if (unit.toLowerCase().includes(filterValue)) {
242
+ searchResults.push({ type: 'material', label: unit, value: unit });
243
+ }
244
+ });
245
+ this.pickupOptions.map((unit) => {
252
246
  if (unit.toLowerCase().includes(filterValue)) {
253
247
  searchResults.push({
254
248
  type: 'pickup location',
@@ -257,7 +251,7 @@ class UtilsService {
257
251
  });
258
252
  }
259
253
  });
260
- this.destOptions.forEach((unit) => {
254
+ this.destOptions.map((unit) => {
261
255
  if (unit.toLowerCase().includes(filterValue)) {
262
256
  searchResults.push({
263
257
  type: 'destination location',
@@ -266,7 +260,7 @@ class UtilsService {
266
260
  });
267
261
  }
268
262
  });
269
- this.jcodeOptions.forEach((unit) => {
263
+ this.jcodeOptions.map((unit) => {
270
264
  if (unit.job_code.toLowerCase().includes(filterValue)) {
271
265
  searchResults.push({
272
266
  type: 'job',
@@ -275,12 +269,12 @@ class UtilsService {
275
269
  });
276
270
  }
277
271
  });
278
- this.driverOption.forEach((unit) => {
272
+ this.driverOption.map((unit) => {
279
273
  if (unit.toLowerCase().includes(filterValue)) {
280
274
  searchResults.push({ type: 'Driver', label: unit, value: unit });
281
275
  }
282
276
  });
283
- this.truckingCompanayOption.forEach((unit) => {
277
+ this.truckingCompanayOption.map((unit) => {
284
278
  if (unit.toLowerCase().includes(filterValue)) {
285
279
  searchResults.push({
286
280
  type: 'Trucking Company',
@@ -289,19 +283,20 @@ class UtilsService {
289
283
  });
290
284
  }
291
285
  });
292
- this.routeNameOptions.forEach((unit) => {
286
+ this.routeNameOptions.map((unit) => {
293
287
  if (unit.toLowerCase().includes(filterValue)) {
294
288
  searchResults.push({ type: 'Route name', label: unit, value: unit });
295
289
  }
296
290
  });
297
- // Filter out options that are already selected in the filters array
298
291
  const searchDict = {};
299
- filters.forEach((filter) => {
292
+ filters.map((filter) => {
300
293
  searchDict[filter['name'] + filter['type']] = filter;
301
294
  });
302
295
  const furtherFilter = [];
303
- searchResults.forEach((search) => {
304
- if (!(search['label'] + search['type'] in searchDict)) {
296
+ searchResults.map((search) => {
297
+ if (search['label'] + search['type'] in searchDict) {
298
+ }
299
+ else {
305
300
  furtherFilter.push(search);
306
301
  }
307
302
  });
@@ -312,13 +307,15 @@ class UtilsService {
312
307
  const result_list_boolean = [];
313
308
  if (filterval.length > 0) {
314
309
  if (filterval[0]['type'] === 'unit') {
315
- result_list_boolean.push(filterval[0]['name'] === element['unit']);
310
+ result_list_boolean.push(filterval[0]['name'] ===
311
+ element[filterval[0]['type']]);
316
312
  }
317
313
  if (filterval[0]['type'] === 'customer') {
318
314
  result_list_boolean.push(filterval[0]['name'] === element['customer_name']);
319
315
  }
320
316
  if (filterval[0]['type'] === 'material') {
321
- result_list_boolean.push(filterval[0]['name'] === element['material']);
317
+ result_list_boolean.push(filterval[0]['name'] ===
318
+ element[filterval[0]['type']]);
322
319
  }
323
320
  if (filterval[0]['type'] === 'pickup location') {
324
321
  result_list_boolean.push(filterval[0]['name'] === element['pickup_location']);
@@ -333,16 +330,14 @@ class UtilsService {
333
330
  result_list_boolean.push(filterval[0]['name'] === element['route_name']);
334
331
  }
335
332
  if (filterval[0]['type'] === 'Driver') {
336
- const driverList = element.driver_list || [];
337
- const index = driverList.findIndex((ele) => {
333
+ const index = element.driver_list?.findIndex((ele) => {
338
334
  return filterval[0]['name'] === ele['driver_name'];
339
335
  });
340
336
  if (index !== -1)
341
337
  result_list_boolean.push(true);
342
338
  }
343
339
  if (filterval[0]['type'] === 'Trucking Company') {
344
- const driverList = element.driver_list || [];
345
- const index = driverList.findIndex((ele) => {
340
+ const index = element.driver_list?.findIndex((ele) => {
346
341
  return filterval[0]['name'] === ele['trucking_company'];
347
342
  });
348
343
  if (index !== -1)
@@ -355,8 +350,32 @@ class UtilsService {
355
350
  return false;
356
351
  });
357
352
  }
353
+ clearOptions() {
354
+ this.pickupOptions = [];
355
+ this.destOptions = [];
356
+ this.ownerOptions = [];
357
+ this.customerOptions = [];
358
+ this.unitOptions = [];
359
+ this.materialOptions = [];
360
+ this.jcodeOptions = [];
361
+ this.routeNameOptions = [];
362
+ }
363
+ setdictValue(key, value) {
364
+ this.dict.set(key, value);
365
+ }
366
+ getdictValue(key) {
367
+ return JSON.parse(this.dict.get(key));
368
+ }
369
+ removedictValue(key) {
370
+ this.dict.delete(key);
371
+ }
372
+ conveySearchIcon(value) {
373
+ if (value && typeof value !== 'object')
374
+ return true;
375
+ return false;
376
+ }
358
377
  fetchUnitsList() {
359
- return new Promise((resolve) => {
378
+ return new Promise((resolve, reject) => {
360
379
  if (!this.unitsList) {
361
380
  this.getData('unit/list/view').subscribe((res) => {
362
381
  if (res) {
@@ -370,38 +389,49 @@ class UtilsService {
370
389
  }
371
390
  });
372
391
  }
373
- fetchMaterialsListForCustomer() {
374
- return new Promise((resolve) => {
375
- if (!this.materialsListForCustomer) {
392
+ fetchMaterialsList() {
393
+ return new Promise((resolve, reject) => {
394
+ if (!this.materialsList) {
376
395
  this.getData('material/list/view').subscribe((res) => {
377
- this.materialsListForCustomer = this.filtermaterialList(res.data);
378
- resolve(this.materialsListForCustomer);
396
+ res.data.sort((a, b) => a.material.localeCompare(b.material));
397
+ this.materialsList = res.data;
398
+ resolve(this.materialsList);
379
399
  });
380
400
  }
381
401
  else {
382
- resolve(this.materialsListForCustomer);
402
+ resolve(this.materialsList);
383
403
  }
384
404
  });
385
405
  }
386
- filtermaterialList(list) {
387
- let meterialList = [];
388
- list.forEach((item) => {
389
- if (item.sub && item.sub.length > 0) {
390
- item.sub.forEach((subItem) => {
391
- if (subItem.add_to_marketplace) {
392
- subItem.material = item.material;
393
- subItem.material_id = item.material_id;
394
- subItem.label = item.material + ' | ' + subItem.sub_material;
395
- meterialList.push(subItem);
396
- }
406
+ fetchMaterialsListForCustomer() {
407
+ return new Promise((resolve, reject) => {
408
+ if (!this.materialsListForCustomer) {
409
+ this.getData('material/list/view').subscribe((res) => {
410
+ let meterialListDetails = [];
411
+ res.data.map((item) => {
412
+ if (item.sub.length > 0) {
413
+ item.sub.map((subItem) => {
414
+ if (subItem.add_to_marketplace) {
415
+ subItem.material = item.material;
416
+ subItem.material_id = item.material_id;
417
+ subItem.label = item.material + ' | ' + subItem.sub_material;
418
+ meterialListDetails.push(subItem);
419
+ }
420
+ });
421
+ }
422
+ });
423
+ meterialListDetails.sort((a, b) => a.label.localeCompare(b.label));
424
+ this.materialsListForCustomer = meterialListDetails;
425
+ resolve(this.materialsListForCustomer);
397
426
  });
398
427
  }
428
+ else {
429
+ resolve(this.materialsListForCustomer);
430
+ }
399
431
  });
400
- meterialList.sort((a, b) => a.label.localeCompare(b.label));
401
- return meterialList;
402
432
  }
403
433
  fetchCustomersList() {
404
- return new Promise((resolve) => {
434
+ return new Promise((resolve, reject) => {
405
435
  if (!this.customersList) {
406
436
  this.getData('company/list/view').subscribe((res) => {
407
437
  if (res) {
@@ -415,166 +445,74 @@ class UtilsService {
415
445
  }
416
446
  });
417
447
  }
418
- fetchLocationlist() {
419
- return new Promise((resolve, reject) => {
420
- this.getRestData('locations/all').subscribe({
421
- next: (res) => {
422
- if (res) {
423
- this.locationList = res.data.map((object) => {
424
- object.formatted_address = `${object.name} | ${object.street} ${object.city}, ${object.state} ${object.zip}`;
425
- return {
426
- city: object.city,
427
- lng: object.longitude,
428
- location_id: object.location_id,
429
- lat: object.latitude,
430
- name: object.name,
431
- state: object.state,
432
- street: object.street,
433
- zip: object.zip,
434
- formatted_address: object.formatted_address
435
- };
436
- });
437
- resolve(this.locationList);
438
- }
439
- },
440
- error: (err) => {
441
- console.error(err);
442
- reject(err);
443
- }
444
- });
445
- });
446
- }
447
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UtilsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
448
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UtilsService, providedIn: 'root' });
448
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: UtilsService, deps: [{ token: i1.HttpClient }, { token: i2.MatSnackBar }, { token: 'memberData' }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
449
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: UtilsService, providedIn: 'root' });
449
450
  }
450
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UtilsService, decorators: [{
451
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: UtilsService, decorators: [{
451
452
  type: Injectable,
452
453
  args: [{ providedIn: 'root' }]
453
- }] });
454
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.MatSnackBar }, { type: CoolmapConfigModel, decorators: [{
455
+ type: Inject,
456
+ args: ['memberData']
457
+ }] }, { type: i0.NgZone }] });
454
458
 
455
- class MapboxService {
459
+ class CoolmapService {
460
+ utils;
461
+ eventManager;
462
+ config;
456
463
  map;
457
- mapContainer = null;
458
- resizeObserver = null;
459
- markerOriginList = new Map();
460
- markerDestinationList = new Map();
461
- activeRoutesRegistry = new Map();
462
- pathCache = new Map();
463
- // Native 3D Simulation Engine
464
- svgOverlay = null;
465
- activeArcs = {};
464
+ markerOriginList = [];
465
+ markerDestinationList = [];
466
466
  initiatecoolmap = new BehaviorSubject(true);
467
467
  reintiatecoolmap = this.initiatecoolmap.asObservable();
468
- isMapReady = signal(false, ...(ngDevMode ? [{ debugName: "isMapReady" }] : []));
469
468
  bounds = new mapboxgl.LngLatBounds();
470
- originDestinationCordinates = new Map();
469
+ originDestinationCordinates = [];
471
470
  padding;
472
- windowActualHeightWidth = { availHeight: 0 };
471
+ windowActualHeightWidth;
473
472
  popup;
474
473
  customTopForCustomer;
475
- utils = inject(UtilsService);
476
- config = inject(COOLMAP_CONFIG);
477
- currentStyleIsDark = false;
478
- constructor() {
474
+ constructor(utils, eventManager, config) {
475
+ this.utils = utils;
476
+ this.eventManager = eventManager;
477
+ this.config = config;
479
478
  this.customTopForCustomer = this.config.repository === 'customer' ? 65 : 0;
480
- if (typeof window !== 'undefined') {
481
- this.windowActualHeightWidth.availHeight = window.innerHeight > window.screen.availHeight ? window.innerHeight : window.screen.availHeight;
482
- window.addEventListener('resize', this.onResize.bind(this));
483
- }
479
+ this.windowActualHeightWidth = { availHeight: 0 };
480
+ window.addEventListener('resize', this.onResize.bind(this));
484
481
  }
485
- updateTheme(isDark) {
486
- if (!this.map) {
487
- this.currentStyleIsDark = isDark;
488
- return;
489
- }
490
- if (this.currentStyleIsDark === isDark)
491
- return;
492
- this.currentStyleIsDark = isDark;
493
- const style = isDark
494
- ? 'mapbox://styles/mapbox/dark-v11'
495
- : 'mapbox://styles/mapbox/light-v11';
496
- this.map.setStyle(style);
497
- this.map.once('style.load', () => {
498
- this.reAddLayers();
499
- });
500
- }
501
- getRegistryKeys() {
502
- return Array.from(this.activeRoutesRegistry.keys());
503
- }
504
- // Renamed to initializeMap to preserve the existing bindings in coolmap.component.ts
505
- initializeMap(el, isDark = false) {
506
- this.currentStyleIsDark = isDark;
507
- const styleUrl = isDark ? 'mapbox://styles/mapbox/dark-v11' : 'mapbox://styles/mapbox/light-v11';
508
- // If map already exists for this container, just update style and clear routes to avoid flickering
509
- if (this.map && this.mapContainer === el) {
510
- el.style.transition = 'opacity 0.3s ease-in-out';
511
- el.style.opacity = '0.7';
512
- this.map.setStyle(styleUrl);
513
- return new Promise((resolve) => {
514
- this.map.once('style.load', () => {
515
- this.clearAllRoutes();
516
- this.isMapReady.set(true);
517
- el.style.opacity = '1';
518
- resolve(this.map);
519
- });
520
- });
521
- }
482
+ initiateMapForAddRoute(el) {
522
483
  return new Promise((resolve, reject) => {
523
- this.mapContainer = el;
524
- if (this.map) {
484
+ if (this.map)
525
485
  this.map.remove();
526
- if (this.resizeObserver) {
527
- this.resizeObserver.disconnect();
528
- this.resizeObserver = null;
529
- }
530
- }
531
- // Add a smooth fade-in for fresh initialization
532
- el.style.transition = 'opacity 0.5s ease-in-out';
533
- el.style.opacity = '0';
534
- const token = typeof window !== 'undefined' ? window.__env?.mapboxAccessToken || '' : '';
535
- mapboxgl.accessToken = token;
536
486
  this.map = new mapboxgl.Map({
487
+ accessToken: this.config.mapboxAccessToken,
537
488
  container: el,
538
- style: styleUrl,
489
+ style: this.config.mapboxStyle,
539
490
  center: [-77.036873, 38.907192],
540
491
  zoom: 10,
541
492
  bearing: 0,
542
493
  pitch: 65,
543
494
  interactive: true,
544
- attributionControl: false,
545
- antialias: true,
546
- projection: { name: 'globe' }
547
- });
548
- this.map.addControl(new mapboxgl.AttributionControl({ compact: true }), 'bottom-right');
549
- this.map.addControl(new mapboxgl.NavigationControl({ showCompass: false }), 'top-right');
550
- this.resizeObserver = new ResizeObserver(() => {
551
- if (this.map) {
552
- this.map.resize();
553
- }
554
495
  });
555
- this.resizeObserver.observe(el);
556
496
  this.map.once('load', (res) => {
557
- this.isMapReady.set(true);
558
- if (this.mapContainer)
559
- this.mapContainer.style.opacity = '1';
560
497
  resolve(res);
561
498
  });
562
499
  });
563
500
  }
564
- // Animated gradient path
565
- loadMapProperty(pinRouteGeojson, index, unit, routeProps, bottom) {
566
- return new Promise((resolve) => {
567
- if (!this.map || !this.isMapReady())
568
- return resolve(false);
569
- const origin = pinRouteGeojson.features[0].geometry.coordinates[0];
501
+ // Below method Load route with animation
502
+ loadMapProperty(pinRouteGeojson, index, unit, route, bottom) {
503
+ return new Promise((resolve, reject) => {
504
+ let origin = pinRouteGeojson.features[0].geometry.coordinates[0];
570
505
  const linecolor = unit === 'Ton' ? '#ff7272' : unit === 'Load' ? '#a3c52e' : '#ae23d1';
571
- const destination = pinRouteGeojson.features[0].geometry.coordinates[pinRouteGeojson.features[0].geometry.coordinates.length - 1];
572
- const registryId = `addroute-${index}`;
573
- this.extendBound(pinRouteGeojson.features[0].geometry.coordinates, true, registryId).then(() => {
506
+ let destination = pinRouteGeojson.features[0].geometry.coordinates[pinRouteGeojson.features[0].geometry.coordinates.length - 1];
507
+ this.extendBound(pinRouteGeojson.features[0].geometry.coordinates, true).then((res) => {
574
508
  const point = {
575
509
  type: 'FeatureCollection',
576
510
  features: [
577
- { type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: origin } },
511
+ {
512
+ type: 'Feature',
513
+ properties: {},
514
+ geometry: { type: 'Point', coordinates: origin },
515
+ },
578
516
  ],
579
517
  };
580
518
  const lineDistance = turf.length(pinRouteGeojson.features[0]);
@@ -586,356 +524,256 @@ class MapboxService {
586
524
  }
587
525
  pinRouteGeojson.features[0].geometry.coordinates = arc;
588
526
  const pinRoute = pinRouteGeojson.features[0].geometry.coordinates;
589
- if (pinRoute && pinRoute.length) {
590
- const marker = new mapboxgl.Marker(document.createElement('div'))
591
- .setLngLat(pinRoute[0])
592
- .addTo(this.map)
593
- .togglePopup();
594
- if (this.map.getSource(`line${index}`)) {
595
- this.removeRouteAndMarker(index, 'addroute').then(() => { });
596
- }
597
- this.map.addSource(`line${index}`, {
598
- type: 'geojson',
599
- lineMetrics: true,
600
- data: pinRouteGeojson,
601
- });
602
- this.map.addLayer({
603
- type: 'line',
604
- source: `line${index}`,
605
- id: `line${index}`,
606
- paint: {
607
- 'line-width': 2,
608
- 'line-gradient': [
609
- 'interpolate', ['linear'], ['line-progress'],
610
- 0, unit === 'Ton' ? '#d7f7e4' : unit === 'Load' ? '#c9d8f5' : '#f5dcc1',
611
- 1, unit === 'Ton' ? '#ff7272' : unit === 'Load' ? '#a3c52e' : '#ae23d1',
612
- ],
613
- },
614
- layout: { 'line-cap': 'round', 'line-join': 'round' },
615
- });
616
- const dataSetForMap = {
617
- counter: 0,
618
- pinRouteGeojson,
619
- steps,
620
- point,
621
- pointId: `point${index}`,
622
- marker,
623
- pinRoute,
624
- lineId: `line${index}`,
625
- index,
626
- origin,
627
- destination,
628
- lineDistance,
629
- linecolor,
630
- route: routeProps,
631
- routeType: 'addroute',
632
- isViewRoute: true,
633
- };
634
- this.createMarker(dataSetForMap);
635
- this.map.on('mouseenter', `line${index}`, (e) => {
636
- this.map.setPaintProperty(`line${index}`, 'line-width', 5);
637
- this.map.setPaintProperty(`line${index}`, 'line-opacity', 1);
638
- const datasetForPopup = {
639
- coordinate: [e.lngLat.lng, e.lngLat.lat],
640
- pickup: routeProps?.pickup_location || '',
641
- drop: routeProps?.delivery_location || '',
642
- routeType: routeProps?.project ? 'Project' : 'Route',
643
- title: routeProps?.project ? routeProps.project : routeProps?.route_name || '',
644
- material: routeProps?.material || '',
645
- type: routeProps?.unit || '',
646
- };
647
- if (this.popup)
648
- this.popup.remove();
649
- this.createPopup(datasetForPopup);
650
- });
651
- this.map.on('mouseleave', `line${index}`, () => {
652
- this.map.setPaintProperty(`line${index}`, 'line-width', 2);
653
- if (this.popup)
654
- this.popup.remove();
655
- });
527
+ const marker = new mapboxgl.Marker(document.createElement('div'))
528
+ .setLngLat(pinRoute[0])
529
+ .addTo(this.map)
530
+ .togglePopup();
531
+ if (this.map.getSource(`line${index}`)) {
532
+ this.removeRouteAndMarker(index).then(() => { });
656
533
  }
534
+ this.map.addSource(`line${index}`, {
535
+ type: 'geojson',
536
+ lineMetrics: true,
537
+ data: pinRouteGeojson,
538
+ });
539
+ this.map.addLayer({
540
+ type: 'line',
541
+ source: `line${index}`,
542
+ id: `line${index}`,
543
+ paint: {
544
+ 'line-width': 2,
545
+ 'line-gradient': [
546
+ 'interpolate',
547
+ ['linear'],
548
+ ['line-progress'],
549
+ 0,
550
+ unit === 'Ton'
551
+ ? '#d7f7e4'
552
+ : unit === 'Load'
553
+ ? '#c9d8f5'
554
+ : '#f5dcc1',
555
+ 1,
556
+ unit === 'Ton'
557
+ ? '#ff7272'
558
+ : unit === 'Load'
559
+ ? '#a3c52e'
560
+ : '#ae23d1',
561
+ ],
562
+ },
563
+ layout: { 'line-cap': 'round', 'line-join': 'round' },
564
+ });
565
+ const dataSetForMap = {
566
+ counter: 0,
567
+ pinRouteGeojson,
568
+ steps,
569
+ point,
570
+ pointId: `point${index}`,
571
+ marker,
572
+ pinRoute,
573
+ lineId: `line${index}`,
574
+ index,
575
+ origin,
576
+ destination,
577
+ lineDistance,
578
+ linecolor,
579
+ route,
580
+ isViewRoute: true,
581
+ };
582
+ this.createMarker(dataSetForMap);
583
+ this.map.on('mouseenter', `line${index}`, (e) => {
584
+ this.map.setPaintProperty(`line${index}`, 'line-width', 5);
585
+ this.map.setPaintProperty(`line${index}`, 'line-opacity', 1);
586
+ const datasetForPopup = {
587
+ coordinate: [e.lngLat.lng, e.lngLat.lat],
588
+ pickup: route.pickup_location ? route.pickup_location : '',
589
+ drop: route.delivery_location ? route.delivery_location : '',
590
+ routeType: route.project ? 'Project' : 'Route',
591
+ title: route.project
592
+ ? route.project
593
+ : route.route_name
594
+ ? route.route_name
595
+ : '',
596
+ material: route.materialLabel ? route.materialLabel : '',
597
+ type: route.unit ? route.unit : '',
598
+ };
599
+ this.createPopup(datasetForPopup);
600
+ });
601
+ this.map.on('mouseleave', `line${index}`, (e) => {
602
+ this.map.setPaintProperty(`line${index}`, 'line-width', 2);
603
+ if (this.popup) {
604
+ this.popup.remove();
605
+ }
606
+ });
657
607
  });
658
- this.map.once('idle', () => {
608
+ this.map.once('idle', (res) => {
659
609
  resolve(true);
660
610
  });
661
611
  });
662
612
  }
663
- createMarker(routeDetails) {
664
- if (!this.map || !routeDetails.origin[0] || !routeDetails.origin[1] || !routeDetails.destination[0] || !routeDetails.destination[1])
665
- return;
666
- const popup = new mapboxgl.Popup({ closeButton: false, className: 'pointer-events-none', offset: 20 }).setHTML('<div class="p-3"><b>Pickup: </b>' + (routeDetails.route?.pickup_location || '') + '</div>');
667
- const popupForDestination = new mapboxgl.Popup({ closeButton: false, className: 'pointer-events-none', offset: 20 }).setHTML('<div class="p-3"><b>Delivery: </b>' + (routeDetails.route?.delivery_location || '') + '</div>');
668
- // Origin Marker (Pickup)
669
- const el = document.createElement('div');
670
- el.className = 'cursor-pointer active:scale-95 transition-transform duration-200 drop-shadow-lg';
671
- el.style.zIndex = '100';
672
- const pickupLabel = 'P';
673
- el.innerHTML = `
674
- <svg width="30" height="38" viewBox="0 0 30 38" fill="none" xmlns="http://www.w3.org/2000/svg">
675
- <path d="M15 0C6.71573 0 0 6.71573 0 15C0 26.25 15 38 15 38C15 38 30 26.25 30 15C30 6.71573 23.2843 0 15 0Z" fill="${routeDetails.linecolor}"/>
676
- <circle cx="15" cy="15" r="9" fill="white"/>
677
- <text x="15" y="19" text-anchor="middle" fill="black" style="font-family: Inter, sans-serif; font-size: 13px; font-weight: 800;">${pickupLabel}</text>
678
- </svg>
679
- `;
680
- const originMarker = new mapboxgl.Marker({ element: el, anchor: 'bottom' })
681
- .setLngLat(routeDetails.origin)
682
- .addTo(this.map);
683
- originMarker.getElement().addEventListener('mouseenter', () => {
684
- popup.setLngLat(routeDetails.origin).addTo(this.map);
685
- });
686
- originMarker.getElement().addEventListener('mouseleave', () => {
687
- popup.remove();
688
- });
689
- // Destination Marker (Delivery)
690
- const elementForDestination = document.createElement('div');
691
- elementForDestination.className = 'cursor-pointer active:scale-95 transition-transform duration-200 drop-shadow-lg';
692
- elementForDestination.style.zIndex = '100';
693
- const deliveryLabel = 'D';
694
- elementForDestination.innerHTML = `
695
- <svg width="30" height="38" viewBox="0 0 30 38" fill="none" xmlns="http://www.w3.org/2000/svg">
696
- <path d="M15 0C6.71573 0 0 6.71573 0 15C0 26.25 15 38 15 38C15 38 30 26.25 30 15C30 6.71573 23.2843 0 15 0Z" fill="${routeDetails.linecolor}"/>
697
- <circle cx="15" cy="15" r="9" fill="white"/>
698
- <text x="15" y="19" text-anchor="middle" fill="black" style="font-family: Inter, sans-serif; font-size: 13px; font-weight: 800;">${deliveryLabel}</text>
699
- </svg>
700
- `;
701
- const destinationMarker = new mapboxgl.Marker({ element: elementForDestination, anchor: 'bottom' })
702
- .setLngLat(routeDetails.destination)
703
- .addTo(this.map);
704
- destinationMarker.getElement().addEventListener('mouseenter', () => {
705
- popupForDestination.setLngLat(routeDetails.destination).addTo(this.map);
706
- });
707
- destinationMarker.getElement().addEventListener('mouseleave', () => {
708
- popupForDestination.remove();
709
- });
710
- const id = `${routeDetails.routeType}-${routeDetails.index}`;
711
- this.markerOriginList.set(id, originMarker);
712
- this.markerDestinationList.set(id, destinationMarker);
713
- // True 3D Elevated Arc Simulation Engine using Native SVG Overlays
714
- try {
715
- this.initSvgOverlay();
716
- const pathEl = document.createElementNS('http://www.w3.org/2000/svg', 'path');
717
- pathEl.setAttribute('fill', 'none');
718
- pathEl.setAttribute('stroke-width', '3');
719
- pathEl.style.cursor = 'pointer';
720
- pathEl.style.pointerEvents = 'stroke'; // Allow interactivity!
721
- const gradId = `arc-grad-${id}`;
722
- const defs = this.svgOverlay.querySelector('defs');
723
- let grad = defs.querySelector(`#${gradId}`);
724
- if (!grad) {
725
- grad = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
726
- grad.setAttribute('id', gradId);
727
- defs.appendChild(grad);
613
+ // Below method Load route without animation
614
+ drawLine(cordinates, index, route, enablefitbound, routeType) {
615
+ let linecolor;
616
+ let origin = cordinates[0];
617
+ let destination = cordinates[cordinates.length - 1];
618
+ if (origin[0] &&
619
+ origin[1] &&
620
+ destination &&
621
+ destination[0] &&
622
+ destination[1]) {
623
+ linecolor = this.provideLineColor(route['unit'], routeType);
624
+ if (enablefitbound) {
625
+ const padding = {
626
+ top: this.padding.top + this.customTopForCustomer,
627
+ bottom: this.padding.bottom +
628
+ (this.windowActualHeightWidth.availHeight -
629
+ (window.innerHeight - 65)),
630
+ left: this.padding.left,
631
+ right: this.padding.right,
632
+ };
633
+ this.map.fitBounds([origin, destination], { padding, pitch: 65 }, { fitboundCompleteJob: true });
634
+ }
635
+ if (this.map.getSource(`route-source-for-job-code${index}`)) {
636
+ this.removeRouteAndMarker(index).then(() => { });
728
637
  }
729
- grad.innerHTML = `
730
- <stop offset="0%" stop-color="${routeDetails.linecolor}" stop-opacity="1"/>
731
- <stop offset="100%" stop-color="#ffffff" stop-opacity="0.8"/>
732
- `;
733
- pathEl.setAttribute('stroke', `url(#${gradId})`);
734
- this.svgOverlay.appendChild(pathEl);
735
- this.activeArcs[id] = {
736
- origin: routeDetails.origin,
737
- destination: routeDetails.destination,
738
- color: routeDetails.linecolor,
739
- pathEl
638
+ this.map.addSource(`route-source-for-job-code${index}`, {
639
+ type: 'geojson',
640
+ data: {
641
+ type: 'Feature',
642
+ properties: {},
643
+ geometry: { type: 'LineString', coordinates: cordinates },
644
+ },
645
+ });
646
+ this.map.addLayer({
647
+ id: `route-for-job-code${index}`,
648
+ type: 'line',
649
+ source: `route-source-for-job-code${index}`,
650
+ paint: { 'line-color': linecolor, 'line-width': 2 },
651
+ layout: { 'line-cap': 'round', 'line-join': 'round' },
652
+ });
653
+ const dataSetForMap = {
654
+ origin,
655
+ destination,
656
+ index,
657
+ linecolor,
658
+ route,
740
659
  };
741
- // Native tooltips hovering strictly matching V1 Deck.GL behaviors
742
- pathEl.addEventListener('mouseenter', (e) => {
743
- pathEl.setAttribute('stroke-width', '6');
744
- // Find geo coordinate exactly under cursor natively
745
- const rect = this.svgOverlay.getBoundingClientRect();
746
- const lngLat = this.map.unproject([e.clientX - rect.left, e.clientY - rect.top]);
747
- const payload = {
748
- layer: { props: { data: { route: routeDetails.route, index: routeDetails.index, routeType: routeDetails.routeType } } },
749
- coordinate: [lngLat.lng, lngLat.lat],
750
- color: routeDetails.linecolor
660
+ this.createMarker(dataSetForMap);
661
+ this.map.on('mouseenter', `route-for-job-code${index}`, (e) => {
662
+ if (this.popup) {
663
+ this.popup.remove();
664
+ }
665
+ this.map.setPaintProperty(`route-for-job-code${index}`, 'line-width', 5);
666
+ this.map.setPaintProperty(`route-for-job-code${index}`, 'line-opacity', 1);
667
+ const datasetForPopup = {
668
+ coordinate: [e.lngLat.lng, e.lngLat.lat],
669
+ pickup: route.pickup_location ? route.pickup_location : '',
670
+ drop: route.delivery_location ? route.delivery_location : '',
671
+ jobCode: route.project ? route.order_number : null,
672
+ customer: route.project ? route.customer_name : null,
673
+ routeType: route.project ? 'Project' : 'Route',
674
+ title: route.project
675
+ ? route.project
676
+ : route.route_name
677
+ ? route.route_name
678
+ : '',
679
+ material: route.materialLabel ? route.materialLabel : '',
680
+ type: route.unit ? route.unit : '',
751
681
  };
752
- this.showRoutePopup(payload, e, routeDetails.isViewRoute);
682
+ this.createPopup(datasetForPopup);
753
683
  });
754
- pathEl.addEventListener('mouseleave', () => {
755
- pathEl.setAttribute('stroke-width', '3');
756
- const payload = { color: null, layer: { props: { data: { index: routeDetails.index, routeType: routeDetails.routeType } } } };
757
- this.showRoutePopup(payload, null, routeDetails.isViewRoute);
684
+ this.map.on('mouseleave', `route-for-job-code${index}`, (e) => {
685
+ this.map.setPaintProperty(`route-for-job-code${index}`, 'line-width', 2);
686
+ if (this.popup) {
687
+ this.popup.remove();
688
+ }
758
689
  });
759
- this.updateSvgPaths(); // Force plot
760
690
  }
761
- catch (e) {
762
- console.warn("Native overarching arc generation skipped:", e);
691
+ }
692
+ provideLineColor(unitType, type) {
693
+ let checkType = type && !['jobrouteList', 'addroute'].includes(type) ? true : false;
694
+ let color;
695
+ switch (unitType) {
696
+ case 'Ton':
697
+ color = checkType ? '#39c471' : '#ff7272';
698
+ break;
699
+ case 'Load':
700
+ color = checkType ? '#326ad3' : '#a3c52e';
701
+ break;
702
+ case 'Hourly':
703
+ color = checkType ? '#ffad56' : '#ae23d1';
704
+ break;
763
705
  }
706
+ return color;
764
707
  }
765
708
  showRoutePopup(arcDetails, event, isViewRoute) {
766
- const data = arcDetails.layer.props.data;
767
- const layerId = isViewRoute
768
- ? `line${data.index}`
769
- : `route-layer-${data.routeType || 'jobcode'}-${data.index}`;
770
709
  if (this.popup) {
771
710
  this.popup.remove();
772
- if (this.map.getLayer(layerId)) {
773
- this.map.setPaintProperty(layerId, 'line-width', 2);
774
- }
711
+ this.map.setPaintProperty(`${isViewRoute ? 'line' : 'route-for-job-code'}${arcDetails.layer.props.data.index}`, 'line-width', 2);
775
712
  }
776
- if (arcDetails.color && this.map.getLayer(layerId) && this.map.getLayoutProperty(layerId, 'visibility') !== 'none') {
777
- this.map.setPaintProperty(layerId, 'line-width', 5);
778
- // Removed line-opacity overwrite here because bezier lines inherit opacity and break if set raw on a gradient.
713
+ if (arcDetails.color &&
714
+ this.map.getLayoutProperty(arcDetails.layer.id, 'visibility') !== 'none') {
715
+ this.map.setPaintProperty(`${isViewRoute ? 'line' : 'route-for-job-code'}${arcDetails.layer.props.data.index}`, 'line-width', 5);
716
+ this.map.setPaintProperty(`${isViewRoute ? 'line' : 'route-for-job-code'}${arcDetails.layer.props.data.index}`, 'line-opacity', 1);
779
717
  const datasetForPopup = {
780
718
  coordinate: arcDetails.coordinate,
781
- pickup: arcDetails.layer.props.data.route.pickup_location || '',
782
- drop: arcDetails.layer.props.data.route.delivery_location || '',
783
- jobCode: arcDetails.layer.props.data.route.project ? arcDetails.layer.props.data.route.order_number : '',
784
- customer: arcDetails.layer.props.data.route.project ? arcDetails.layer.props.data.route.customer_name : '',
785
- routeType: arcDetails.layer.props.data.route.project ? 'Project' : 'Route',
786
- title: arcDetails.layer.props.data.route.project ? arcDetails.layer.props.data.route.project : arcDetails.layer.props.data.route.route_name || '',
787
- material: arcDetails.layer.props.data.route.material || '',
788
- type: arcDetails.layer.props.data.route.unit || '',
719
+ pickup: arcDetails.layer.props.data.route.pickup_location
720
+ ? arcDetails.layer.props.data.route.pickup_location
721
+ : '',
722
+ drop: arcDetails.layer.props.data.route.delivery_location
723
+ ? arcDetails.layer.props.data.route.delivery_location
724
+ : '',
725
+ jobCode: arcDetails.layer.props.data.route.project
726
+ ? arcDetails.layer.props.data.route.order_number
727
+ : '',
728
+ customer: arcDetails.layer.props.data.route.project
729
+ ? arcDetails.layer.props.data.route.customer_name
730
+ : '',
731
+ routeType: arcDetails.layer.props.data.route.project
732
+ ? 'Project'
733
+ : 'Route',
734
+ title: arcDetails.layer.props.data.route.project
735
+ ? arcDetails.layer.props.data.route.project
736
+ : arcDetails.layer.props.data.route.route_name
737
+ ? arcDetails.layer.props.data.route.route_name
738
+ : '',
739
+ material: arcDetails.layer.props.data.route.materialLabel
740
+ ? arcDetails.layer.props.data.route.materialLabel
741
+ : '',
742
+ type: arcDetails.layer.props.data.route.unit
743
+ ? arcDetails.layer.props.data.route.unit
744
+ : '',
789
745
  };
790
746
  this.createPopup(datasetForPopup);
791
747
  }
792
748
  }
793
749
  createPopup(datasetForPopup) {
794
- if (!this.map)
795
- return;
796
750
  this.popup = new mapboxgl.Popup({
797
751
  closeButton: false,
798
752
  closeOnClick: false,
799
753
  closeOnMove: true,
800
- className: 'pointer-events-none',
801
754
  anchor: 'bottom-left',
802
755
  });
803
- // Extract location short names
804
- const pickupDisplay = datasetForPopup.pickup?.split('|')[1] || datasetForPopup.pickup || 'Unknown Pickup';
805
- const dropDisplay = datasetForPopup.drop?.split('|')[1] || datasetForPopup.drop || 'Unknown Delivery';
806
756
  this.popup
807
757
  .setLngLat(datasetForPopup.coordinate)
808
- .setHTML(`<div class="destination p-3 bg-white dark:bg-slate-800 rounded shadow-lg text-sm text-gray-800 dark:text-gray-200">
809
- <div class="duration space-y-1 mb-2 bg-gray-100 dark:bg-slate-900 border border-gray-300 dark:border-slate-700 px-2 py-2 rounded-lg text-[12px]">
810
- <p class="pickprt text-green-600 dark:text-green-400"><b>Pickup Location:</b> ${pickupDisplay}</p>
811
- <p class="dropprt text-red-600"><b>Drop Location:</b> ${dropDisplay}</p>
758
+ .setHTML(`
759
+ <div class="destination">
760
+ <div class="duration">
761
+ <p class="pickprt"><b>Pickup Location:</b> ${datasetForPopup.pickup}</p>
762
+ <p class="dropprt"><b>Drop Location:</b> ${datasetForPopup.drop}</p>
812
763
  </div>
813
- ${datasetForPopup.jobCode ? `<span class="block text-xs text-gray-600 dark:text-gray-300 mb-1"><b>Job Code:</b> ${datasetForPopup.jobCode}</span>` : ''}
814
- ${datasetForPopup.customer ? `<span class="block text-xs text-gray-600 dark:text-gray-300 mb-1"><b>Customer:</b> ${datasetForPopup.customer}</span>` : ''}
815
- <span class="block text-xs text-gray-600 dark:text-gray-300 mb-1"><b>${datasetForPopup.routeType} Name:</b> ${datasetForPopup.title}</span>
816
- ${datasetForPopup.material ? `<span class="block text-xs text-gray-600 dark:text-gray-300 mb-1"><b>Material:</b> ${datasetForPopup.material}</span>` : ''}
817
- <span class="block text-xs text-gray-600 dark:text-gray-300 mb-1"><b>Type:</b> ${datasetForPopup.type}</span>
818
- </div>`)
764
+ ${datasetForPopup.jobCode
765
+ ? '<span><b>Job Code:</b> ' + datasetForPopup.jobCode + '</span>'
766
+ : ''}
767
+ ${datasetForPopup.customer
768
+ ? '<span><b>Customer:</b> ' + datasetForPopup.customer + '</span>'
769
+ : ''}
770
+ <span><b>${datasetForPopup.routeType} Name:</b> ${datasetForPopup.title}</span>
771
+ <span><b>Material:</b> ${datasetForPopup.material}</span>
772
+ <span><b>Type:</b> ${datasetForPopup.type}</span>
773
+ </div>
774
+ `)
819
775
  .addTo(this.map);
820
776
  }
821
- // Draw Line
822
- drawLine(cordinates, index, route, enablefitbound, routeType, isStyleRefresh) {
823
- return new Promise((resolve) => {
824
- if (!this.map || !this.isMapReady()) {
825
- resolve();
826
- return;
827
- }
828
- // Calculate bounds for this specific route
829
- const routeBounds = new mapboxgl.LngLatBounds();
830
- if (cordinates && cordinates.length > 0) {
831
- cordinates.forEach((coord) => routeBounds.extend(coord));
832
- }
833
- const registryId = `${routeType}-${index}`;
834
- // Register the route with its coordinates and pre-calculated bounds
835
- this.activeRoutesRegistry.set(registryId, {
836
- cordinates,
837
- route,
838
- routeType,
839
- bounds: routeBounds,
840
- index
841
- });
842
- let origin = cordinates[0];
843
- let destination = cordinates[cordinates.length - 1];
844
- if (origin[0] && origin[1] && destination && destination[0] && destination[1]) {
845
- // Execute plotting logic IMMEDIATELY to trigger the map's render cycle
846
- const linecolor = this.provideLineColor(route['unit'], routeType);
847
- if (enablefitbound) {
848
- const padTop = Math.max(0, (this.padding?.top || 0) + this.customTopForCustomer + 50);
849
- const padBot = Math.max(0, (this.padding?.bottom || 0) + (this.windowActualHeightWidth.availHeight - (window.innerHeight - 65)) + 50);
850
- const padLeft = Math.max(0, (this.padding?.left || 0) + 350);
851
- const padRight = Math.max(0, (this.padding?.right || 0) + 50);
852
- const customPadding = { top: padTop, bottom: padBot, left: padLeft, right: padRight };
853
- this.map.fitBounds([origin, destination], { padding: customPadding, pitch: 65 }, { fitboundCompleteJob: true });
854
- }
855
- const sourceId = `route-source-${routeType}-${index}`;
856
- const layerId = `route-layer-${routeType}-${index}`;
857
- if (this.map.getSource(sourceId)) {
858
- this.removeRouteAndMarker(index, routeType).then(() => {
859
- this.extendBound(cordinates, enablefitbound, registryId);
860
- });
861
- }
862
- this.map.addSource(sourceId, {
863
- type: 'geojson',
864
- data: {
865
- type: 'Feature',
866
- properties: {},
867
- geometry: { type: 'LineString', coordinates: cordinates },
868
- },
869
- });
870
- this.map.addLayer({
871
- id: layerId,
872
- type: 'line',
873
- source: sourceId,
874
- paint: { 'line-color': linecolor, 'line-width': 2 },
875
- layout: { 'line-cap': 'round', 'line-join': 'round' },
876
- });
877
- if (!isStyleRefresh) {
878
- const dataSetForMap = { origin, destination, index, linecolor, route, routeType };
879
- this.createMarker(dataSetForMap);
880
- }
881
- this.map.on('mouseenter', layerId, (e) => {
882
- if (this.popup)
883
- this.popup.remove();
884
- this.map.setPaintProperty(layerId, 'line-width', 5);
885
- this.map.setPaintProperty(layerId, 'line-opacity', 1);
886
- const datasetForPopup = {
887
- coordinate: [e.lngLat.lng, e.lngLat.lat],
888
- pickup: route.pickup_location || '',
889
- drop: route.delivery_location || '',
890
- jobCode: route.project ? route.order_number : null,
891
- customer: route.project ? route.customer_name : null,
892
- routeType: route.project ? 'Project' : 'Route',
893
- title: route.project ? route.project : route.route_name || '',
894
- material: route.material || '',
895
- type: route.unit || '',
896
- };
897
- this.createPopup(datasetForPopup);
898
- });
899
- this.map.on('mouseleave', layerId, () => {
900
- this.map.setPaintProperty(layerId, 'line-width', 2);
901
- if (this.popup)
902
- this.popup.remove();
903
- });
904
- // SAFETY: Use a timeout to ensure resolve() is always called even if 'idle' event skips
905
- let resolved = false;
906
- const complete = () => {
907
- if (!resolved) {
908
- resolved = true;
909
- resolve();
910
- }
911
- };
912
- this.map.once('idle', complete);
913
- setTimeout(complete, 500); // 500ms safety timeout
914
- }
915
- else {
916
- resolve();
917
- }
918
- });
919
- }
920
- provideLineColor(unitType, type) {
921
- let checkType = type && !['jobrouteList', 'addroute', 'viewroute'].includes(type) ? true : false;
922
- let color;
923
- switch (unitType) {
924
- case 'Ton':
925
- color = checkType ? '#39c471' : '#ff7272';
926
- break;
927
- case 'Load':
928
- color = checkType ? '#326ad3' : '#a3c52e';
929
- break;
930
- case 'Hourly':
931
- color = checkType ? '#ffad56' : '#ae23d1';
932
- break;
933
- default:
934
- color = '#3b82f6';
935
- break;
936
- }
937
- return color;
938
- }
939
777
  hexToRGB(hex) {
940
778
  return hex
941
779
  .replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (m, r, g, b) => '#' + r + r + g + g + b + b)
@@ -943,147 +781,105 @@ class MapboxService {
943
781
  .match(/.{2}/g)
944
782
  .map((x) => parseInt(x, 16));
945
783
  }
946
- // --- SVG 3D Engine Methods ---
947
- initSvgOverlay() {
948
- if (this.svgOverlay || !this.mapContainer)
949
- return;
950
- this.svgOverlay = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
951
- this.svgOverlay.style.position = 'absolute';
952
- this.svgOverlay.style.top = '0';
953
- this.svgOverlay.style.left = '0';
954
- this.svgOverlay.style.width = '100%';
955
- this.svgOverlay.style.height = '100%';
956
- this.svgOverlay.style.pointerEvents = 'none';
957
- this.svgOverlay.style.zIndex = '10';
958
- const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
959
- this.svgOverlay.appendChild(defs);
960
- this.mapContainer.appendChild(this.svgOverlay);
961
- this.map.on('render', () => this.updateSvgPaths());
962
- }
963
- updateSvgPaths() {
964
- if (!this.svgOverlay || !this.map)
965
- return;
966
- for (const key in this.activeArcs) {
967
- const arc = this.activeArcs[key];
968
- const p1 = this.map.project(arc.origin);
969
- const p2 = this.map.project(arc.destination);
970
- // Safety Guard: Check for Infinity and extreme numbers (Number.MAX_VALUE)
971
- // which Mapbox can return during transitions.
972
- // 1e15 is a safe threshold for JS math and SVG rendering engines.
973
- const isUsable = (p) => Number.isFinite(p.x) && Math.abs(p.x) < 1e15 &&
974
- Number.isFinite(p.y) && Math.abs(p.y) < 1e15;
975
- if (!isUsable(p1) || !isUsable(p2))
976
- continue;
977
- const dx = p2.x - p1.x;
978
- const dy = p2.y - p1.y;
979
- const dist = Math.sqrt(dx * dx + dy * dy);
980
- // Secondary check for distance finiteness
981
- if (!Number.isFinite(dist) || dist > 1e15)
982
- continue;
983
- const mx = (p1.x + p2.x) / 2;
984
- let controlY = ((p1.y + p2.y) / 2) - (dist * 1.05);
985
- // Final sanity check for calculated curve peaks
986
- controlY = Math.max(100, controlY);
987
- if (!Number.isFinite(controlY) || !Number.isFinite(mx))
988
- continue;
989
- // Update with rounded values to ensure clean and valid attribute data
990
- arc.pathEl.setAttribute('d', `M ${p1.x.toFixed(2)} ${p1.y.toFixed(2)} Q ${mx.toFixed(2)} ${controlY.toFixed(2)} ${p2.x.toFixed(2)} ${p2.y.toFixed(2)}`);
991
- // Sync the gradient positioning physically mapped to coordinate space
992
- const grad = this.svgOverlay.querySelector(`#arc-grad-${key}`);
993
- if (grad) {
994
- const minX = Math.min(p1.x, p2.x);
995
- const maxX = Math.max(p1.x, p2.x);
996
- const minY = Math.min(p1.y, p2.y, controlY);
997
- const maxY = Math.max(p1.y, p2.y, controlY);
998
- const w = Math.max(1, maxX - minX);
999
- const h = Math.max(1, maxY - minY);
1000
- grad.setAttribute('x1', `${((p1.x - minX) / w) * 100}%`);
1001
- grad.setAttribute('y1', `${((p1.y - minY) / h) * 100}%`);
1002
- grad.setAttribute('x2', `${((p2.x - minX) / w) * 100}%`);
1003
- grad.setAttribute('y2', `${((p2.y - minY) / h) * 100}%`);
1004
- }
784
+ createMarker(routeDetails) {
785
+ if (routeDetails.origin[0] &&
786
+ routeDetails.origin[1] &&
787
+ routeDetails.destination[0] &&
788
+ routeDetails.destination[1]) {
789
+ const popup = new mapboxgl.Popup({ closeButton: false }).setHTML('<b>Pickup: </b>' + routeDetails.route?.pickup_location);
790
+ const popupForDestination = new mapboxgl.Popup({
791
+ closeButton: false,
792
+ }).setHTML('<b>Delivery: </b>' + routeDetails.route?.delivery_location);
793
+ const el = document.createElement('div');
794
+ el.className = 'marker';
795
+ el.innerHTML = `<span class='markerPointer' style='background:${routeDetails.linecolor}'><b>P</b><span class='markerSpan' style='border-top: 10px solid ${routeDetails.linecolor}'></span></span>`;
796
+ const originMarker = new mapboxgl.Marker(el)
797
+ .setPopup(popup)
798
+ .setLngLat(routeDetails.origin)
799
+ .addTo(this.map);
800
+ originMarker
801
+ .getElement()
802
+ .addEventListener('mouseenter', () => originMarker.togglePopup());
803
+ originMarker
804
+ .getElement()
805
+ .addEventListener('mouseleave', () => originMarker.togglePopup());
806
+ const elementForDestination = document.createElement('div');
807
+ elementForDestination.className = 'marker';
808
+ elementForDestination.innerHTML = `<span class='markerPointer' style='background:${routeDetails.linecolor}'><b>D</b><span class='markerSpan' style='border-top: 10px solid ${routeDetails.linecolor}'></span></span>`;
809
+ const destinationMarker = new mapboxgl.Marker(elementForDestination)
810
+ .setPopup(popupForDestination)
811
+ .setLngLat(routeDetails.destination)
812
+ .addTo(this.map);
813
+ destinationMarker
814
+ .getElement()
815
+ .addEventListener('mouseenter', () => destinationMarker.togglePopup());
816
+ destinationMarker
817
+ .getElement()
818
+ .addEventListener('mouseleave', () => destinationMarker.togglePopup());
819
+ this.markerOriginList[routeDetails.index] = originMarker;
820
+ this.markerDestinationList[routeDetails.index] = destinationMarker;
821
+ const colorArray = this.hexToRGB(routeDetails.linecolor);
822
+ const arcLayer = new MapboxLayer({
823
+ id: 'arc-layer' + routeDetails.index,
824
+ type: ArcLayer,
825
+ pickable: true,
826
+ data: { route: routeDetails.route, index: routeDetails.index },
827
+ getWidth: 1,
828
+ getSourcePosition: routeDetails.origin,
829
+ getTargetPosition: routeDetails.destination,
830
+ getTargetColor: [255, 255, 255],
831
+ getSourceColor: [colorArray[0], colorArray[1], colorArray[2]],
832
+ onHover: (info, event) => this.showRoutePopup(info, event, routeDetails.isViewRoute),
833
+ });
834
+ this.map.addLayer(arcLayer);
1005
835
  }
1006
836
  }
1007
- async removeRouteAndMarker(index, routeType = 'jobcode') {
1008
- const registryId = `${routeType}-${index}`;
1009
- // Clean up registry
1010
- if (this.activeRoutesRegistry.has(registryId)) {
1011
- this.activeRoutesRegistry.delete(registryId);
1012
- }
1013
- if (!this.map)
1014
- return true;
1015
- try {
1016
- if (this.activeArcs[registryId]) {
1017
- const arc = this.activeArcs[registryId];
1018
- if (arc.pathEl.parentNode)
1019
- arc.pathEl.parentNode.removeChild(arc.pathEl);
1020
- delete this.activeArcs[registryId];
1021
- }
1022
- if (this.svgOverlay) {
1023
- const grad = this.svgOverlay.querySelector(`defs #arc-grad-${registryId}`);
1024
- if (grad && grad.parentNode)
1025
- grad.parentNode.removeChild(grad);
1026
- }
1027
- const layerId = `route-layer-${routeType}-${index}`;
1028
- const sourceId = `route-source-${routeType}-${index}`;
1029
- this.map.getLayer(layerId) ? this.map.removeLayer(layerId) : null;
1030
- this.map.getLayer(`line${index}`) ? this.map.removeLayer(`line${index}`) : null;
1031
- this.map.getSource(sourceId) ? this.map.removeSource(sourceId) : null;
1032
- this.map.getSource(`line${index}`) ? this.map.removeSource(`line${index}`) : null;
1033
- this.markerOriginList.get(registryId)?.remove();
1034
- this.markerOriginList.delete(registryId);
1035
- this.markerDestinationList.get(registryId)?.remove();
1036
- this.markerDestinationList.delete(registryId);
1037
- this.markerOriginList.get(String(index))?.remove();
1038
- this.markerDestinationList.get(String(index))?.remove();
1039
- this.originDestinationCordinates.delete(registryId);
1040
- this.originDestinationCordinates.delete(String(index));
1041
- if (this.popup)
1042
- this.popup.remove();
1043
- return true;
1044
- }
1045
- catch (e) {
1046
- console.warn('Error removing route/marker:', e);
1047
- return false;
837
+ async removeRouteAndMarker(index) {
838
+ if (this.map) {
839
+ this.map.getLayer(`arc-layer${index}`)
840
+ ? this.map.removeLayer(`arc-layer${index}`)
841
+ : '';
842
+ this.map.getLayer(`line${index}`)
843
+ ? this.map.removeLayer(`line${index}`)
844
+ : '';
845
+ this.map.getLayer(`custom_layer${index}`)
846
+ ? this.map.removeLayer(`custom_layer${index}`)
847
+ : '';
848
+ this.map.getSource(`line${index}`)
849
+ ? this.map.removeSource(`line${index}`)
850
+ : '';
851
+ this.map.getLayer(`route-for-job-code${index}`)
852
+ ? this.map.removeLayer(`route-for-job-code${index}`)
853
+ : '';
854
+ this.map.getSource(`route-source-for-job-code${index}`)
855
+ ? this.map.removeSource(`route-source-for-job-code${index}`)
856
+ : '';
857
+ this.findMarkerBound(index);
858
+ this.markerOriginList[index] ? this.markerOriginList[index].remove() : '';
859
+ this.markerDestinationList[index]
860
+ ? this.markerDestinationList[index].remove()
861
+ : '';
862
+ await true;
1048
863
  }
1049
864
  }
1050
- reAddLayers() {
1051
- this.activeRoutesRegistry.forEach((data, regId) => {
1052
- // Use the stored raw index instead of the composite registry key
1053
- this.drawLine(data.cordinates, data.index, data.route, false, data.routeType, true);
1054
- });
1055
- }
1056
865
  findMarkerBound(index) {
1057
- const id = String(index);
1058
- const originMarker = this.markerOriginList.get(id);
1059
- const originLng = originMarker?.getLngLat()?.lng;
1060
- const originLat = originMarker?.getLngLat()?.lat;
1061
- if (originLng !== undefined && originLat !== undefined) {
1062
- for (const [key, x] of this.originDestinationCordinates.entries()) {
1063
- if (x[0][0].toFixed(6) === originLng.toFixed(6) &&
1064
- x[0][1].toFixed(6) === originLat.toFixed(6)) {
1065
- this.originDestinationCordinates.delete(key);
1066
- break;
1067
- }
1068
- }
866
+ const indexOfCordinates = this.originDestinationCordinates.findIndex((x) => x[0][0].toFixed(6) ==
867
+ this.markerOriginList[index]?.getLngLat()?.lng.toFixed(6) &&
868
+ x[0][1].toFixed(6) ==
869
+ this.markerOriginList[index]?.getLngLat()?.lat.toFixed(6));
870
+ if (indexOfCordinates >= 0) {
871
+ this.originDestinationCordinates.splice(indexOfCordinates, 1);
1069
872
  }
1070
873
  }
1071
874
  async filterRoute(ID, visibility, showAllFitbound) {
1072
- if (ID && this.map) {
875
+ if (ID) {
1073
876
  if (this.map.getLayer(`route-for-job-code${ID}`)) {
1074
877
  this.map.setLayoutProperty(`route-for-job-code${ID}`, 'visibility', visibility);
1075
- const id = String(ID);
1076
- const originM = this.markerOriginList.get(id);
1077
- if (originM) {
1078
- originM.getElement().style.display = visibility === 'visible' ? 'block' : 'none';
1079
- }
1080
- const destinationM = this.markerDestinationList.get(id);
1081
- if (destinationM) {
1082
- destinationM.getElement().style.display = visibility === 'visible' ? 'block' : 'none';
1083
- }
1084
- if (this.activeArcs[ID]) {
1085
- this.activeArcs[ID].pathEl.style.display = visibility === 'visible' ? 'block' : 'none';
1086
- }
878
+ const originM = this.markerOriginList[ID].getElement();
879
+ originM.style.display = visibility === 'visible' ? 'block' : visibility;
880
+ const destinationM = this.markerDestinationList[ID].getElement();
881
+ destinationM.style.display =
882
+ visibility === 'visible' ? 'block' : visibility;
1087
883
  if (visibility === 'none' && showAllFitbound) {
1088
884
  this.findMarkerBound(ID);
1089
885
  this.extendReBound();
@@ -1093,320 +889,154 @@ class MapboxService {
1093
889
  this.map.setLayoutProperty(`arc-layer${ID}`, 'visibility', visibility);
1094
890
  }
1095
891
  }
1096
- return true;
892
+ await true;
1097
893
  }
1098
- extendBound(route, showAllFitbound, id) {
1099
- return new Promise((resolve) => {
1100
- if (route && this.map && id) {
894
+ extendBound(route, showAllFitbound) {
895
+ return new Promise((resolve, reject) => {
896
+ if (route) {
1101
897
  if (typeof route === 'string') {
1102
898
  let path = route.split(';');
1103
- path = path.map((ele) => this.formateLatLong(ele));
1104
- path = path.filter((ele) => ele && ele.length > 1);
899
+ path = path.map((ele) => {
900
+ return (ele = this.formateLatLong(ele));
901
+ });
902
+ path.forEach((ele, index) => {
903
+ if (ele.length === 1)
904
+ path.splice(index, 1);
905
+ });
1105
906
  route = path;
1106
907
  }
1107
- if (route[0] && route[0][0] && route[0][1] && route[route.length - 1] && route[route.length - 1][0] && route[route.length - 1][1]) {
1108
- this.originDestinationCordinates.set(id, route);
1109
- }
1110
- }
1111
- const localBounds = new mapboxgl.LngLatBounds();
1112
- if (this.originDestinationCordinates.size > 0) {
1113
- this.originDestinationCordinates.forEach((routeItem) => {
1114
- routeItem.forEach((coord) => {
1115
- localBounds.extend(coord);
908
+ if (route[0][0] &&
909
+ route[0][1] &&
910
+ route[route.length - 1][0] &&
911
+ route[route.length - 1][1]) {
912
+ this.originDestinationCordinates.push(route);
913
+ route.map((item) => {
914
+ this.bounds.extend(item);
1116
915
  });
1117
- });
916
+ }
1118
917
  }
1119
- this.bounds = localBounds;
1120
- if (showAllFitbound && this.map && !localBounds.isEmpty()) {
1121
- requestAnimationFrame(() => {
1122
- this.map.stop();
1123
- this.map.fitBounds(localBounds, {
1124
- pitch: 65,
1125
- maxZoom: 12,
1126
- padding: 100,
1127
- duration: 1000
1128
- }, { fitboundComplete: true });
1129
- });
918
+ if (showAllFitbound) {
919
+ setTimeout(() => {
920
+ if (showAllFitbound && Object.keys(this.bounds).length > 0)
921
+ this.map.fitBounds(this.bounds, { pitch: 65 }, { fitboundComplete: true });
922
+ }, 100);
1130
923
  this.map.once('moveend', (event) => {
1131
924
  if (event.fitboundComplete) {
1132
925
  resolve(true);
1133
926
  }
1134
927
  });
1135
928
  }
1136
- else {
1137
- resolve(true);
1138
- }
1139
929
  });
1140
930
  }
1141
931
  extendReBound(bottom) {
1142
- return new Promise((resolve) => {
1143
- const localBounds = new mapboxgl.LngLatBounds();
1144
- if (this.originDestinationCordinates.size > 0) {
1145
- this.originDestinationCordinates.forEach((item) => {
1146
- item.forEach((route) => {
1147
- localBounds.extend(route);
932
+ return new Promise((resolve, reject) => {
933
+ this.bounds = new mapboxgl.LngLatBounds();
934
+ if (this.originDestinationCordinates.length >= 0) {
935
+ this.originDestinationCordinates.map((item, index) => {
936
+ item.map((route) => {
937
+ this.bounds.extend(route);
1148
938
  });
1149
- });
1150
- this.bounds = localBounds;
1151
- const padTop = Math.max(0, (this.padding?.top || 0) + this.customTopForCustomer + 80);
1152
- const padBot = Math.max(0, (this.padding?.bottom || 0) + (this.windowActualHeightWidth.availHeight - (window.innerHeight - 65)) + 80);
1153
- const padLeft = Math.max(0, (this.padding?.left || 0) + 350);
1154
- const padRight = Math.max(0, (this.padding?.right || 0) + 80);
1155
- const customPadding = {
1156
- top: padTop, bottom: padBot,
1157
- left: padLeft, right: padRight,
1158
- };
1159
- requestAnimationFrame(() => {
1160
- if (!localBounds.isEmpty() && this.map) {
1161
- this.map.stop();
1162
- this.map.fitBounds(localBounds, {
1163
- padding: customPadding,
1164
- pitch: 65,
1165
- maxZoom: 12,
1166
- duration: 1000
1167
- });
939
+ if (index === this.originDestinationCordinates.length - 1) {
940
+ const padding = {
941
+ top: this.padding.top + this.customTopForCustomer,
942
+ bottom: this.padding.bottom +
943
+ (this.windowActualHeightWidth.availHeight -
944
+ (window.innerHeight - 65)),
945
+ left: this.padding.left,
946
+ right: this.padding.right,
947
+ };
948
+ setTimeout(() => {
949
+ if (this.originDestinationCordinates.length > 0)
950
+ this.map.fitBounds(this.bounds, { padding, pitch: 65 });
951
+ }, 500);
952
+ resolve(true);
1168
953
  }
1169
954
  });
1170
- resolve(true);
1171
955
  }
1172
956
  else {
1173
957
  resolve(true);
1174
958
  }
1175
959
  });
1176
960
  }
1177
- async plotRoute(route, i, type, enablefitbound, showAllFitbound) {
1178
- const cacheKey = route['job_id'] || route['route_id'];
1179
- // 1. Check cache FIRST
1180
- if (this.pathCache.has(cacheKey)) {
1181
- const path = this.pathCache.get(cacheKey);
1182
- route['path'] = path;
1183
- this.extendBound(path, showAllFitbound);
1184
- await this.drawLine(path, i, route, enablefitbound, type);
1185
- route['index'] = i;
1186
- return true;
1187
- }
1188
- // 2. Check for inline path (Avoid API if already available)
1189
- if (route['path'] && (Array.isArray(route['path']) || typeof route['path'] === 'string')) {
1190
- let path = typeof route['path'] === 'string' ? route['path'].split(';') : route['path'];
1191
- if (Array.isArray(path) && path.length > 0) {
1192
- // Format if they are still strings
1193
- if (typeof path[0] === 'string') {
1194
- path = path.map((ele) => this.formateLatLong(ele));
1195
- path = path.filter((ele) => ele && ele.length > 1);
1196
- }
1197
- if (path.length > 0) {
1198
- this.pathCache.set(cacheKey, path);
1199
- route['path'] = path;
1200
- this.extendBound(path, showAllFitbound);
1201
- await this.drawLine(path, i, route, enablefitbound, type);
1202
- route['index'] = i;
1203
- return true;
1204
- }
1205
- }
1206
- }
1207
- // 3. Fallback to API call ONLY for jobcode (if path was missing)
961
+ plotRoute(route, i, type, enablefitbound, showAllFitbound) {
1208
962
  return new Promise((resolve, reject) => {
1209
- if (['jobcode'].includes(type) || route['job_id']) {
1210
- let param = { job: route['job_id'] };
1211
- this.utils.postDataWithRestUrl('schedule/job/path', param).subscribe({
1212
- next: async (res) => {
1213
- let path = [];
1214
- if (res['data'] && res['data']['route']) {
1215
- path = res['data']['route'].split(';');
1216
- path = path.map((ele) => this.formateLatLong(ele));
1217
- path = path.filter((ele) => ele && ele.length > 1);
1218
- this.pathCache.set(cacheKey, path);
1219
- }
1220
- if (path && path.length > 0) {
1221
- route['path'] = path;
1222
- this.extendBound(route['path'], showAllFitbound);
1223
- await this.drawLine(route['path'], i, route, enablefitbound, type);
1224
- route['index'] = i;
1225
- }
1226
- else {
1227
- this.extendBound(null, showAllFitbound);
1228
- }
1229
- resolve(true);
1230
- },
1231
- error: (err) => {
1232
- console.warn('Failed path retrieval', err);
963
+ let param = {};
964
+ if (['jobcode'].includes(type)) {
965
+ param['job'] = route['job_id'];
966
+ this.utils.postDataWithRestUrl('schedule/job/path', param).subscribe((res) => {
967
+ if (res['data']['route']) {
968
+ let path = res['data']['route'].split(';');
969
+ path = path.map((ele) => {
970
+ return (ele = this.formateLatLong(ele));
971
+ });
972
+ path.forEach((ele, index) => {
973
+ if (ele.length === 1)
974
+ path.splice(index, 1);
975
+ });
976
+ route['path'] = path;
977
+ this.extendBound(route['path'], showAllFitbound);
978
+ if (route['path'] && route['path'].length > 0)
979
+ this.drawLine(route['path'], i, route, enablefitbound, type);
980
+ route['index'] = i;
981
+ }
982
+ else {
983
+ this.extendBound(null, showAllFitbound);
984
+ }
985
+ resolve(true);
986
+ }, (err) => {
987
+ if (err) {
1233
988
  reject(false);
1234
989
  }
1235
990
  });
1236
991
  }
1237
- else {
1238
- this.extendBound(null, showAllFitbound);
1239
- resolve(true);
1240
- }
1241
- });
1242
- }
1243
- /**
1244
- * Batch toggle visibility for routes on the map.
1245
- * If visibleIds is empty, shows everything in the registry.
1246
- * Otherwise, shows only those in visibleIds and hides the rest.
1247
- */
1248
- setRoutesVisibility(visibleIds, showAllOverride, prefix) {
1249
- const showAll = showAllOverride !== undefined ? showAllOverride : (visibleIds.length === 0);
1250
- this.activeRoutesRegistry.forEach((data, id) => {
1251
- const registryId = String(id).trim();
1252
- // If a prefix is provided, only operate on routes matching that prefix.
1253
- if (prefix && !registryId.startsWith(`${prefix}-`)) {
1254
- return;
1255
- }
1256
- const isVisible = showAll || visibleIds.includes(registryId);
1257
- const visibility = isVisible ? 'visible' : 'none';
1258
- const display = isVisible ? 'block' : 'none';
1259
- // Toggle New Layer Format
1260
- const newLayerId = `route-layer-${data.routeType}-${data.index || id}`;
1261
- if (this.map.getLayer(newLayerId)) {
1262
- this.map.setLayoutProperty(newLayerId, 'visibility', visibility);
1263
- }
1264
- // Legacy/Alternate Layer Formats
1265
- const legacyId = `route-for-job-code${id}`;
1266
- if (this.map.getLayer(legacyId)) {
1267
- this.map.setLayoutProperty(legacyId, 'visibility', visibility);
1268
- }
1269
- if (this.map.getLayer(`line${id}`)) {
1270
- this.map.setLayoutProperty(`line${id}`, 'visibility', visibility);
1271
- }
1272
- // Toggle Markers
1273
- const originM = this.markerOriginList.get(registryId);
1274
- if (originM)
1275
- originM.getElement().style.display = display;
1276
- const destM = this.markerDestinationList.get(registryId);
1277
- if (destM)
1278
- destM.getElement().style.display = display;
1279
- // Toggle Arcs
1280
- if (this.activeArcs[registryId]) {
1281
- this.activeArcs[registryId].pathEl.style.display = display;
1282
- }
1283
- });
1284
- // Recalculate bounds based on visible routes
1285
- this.recalculateVisibleBounds(visibleIds, prefix, showAll);
1286
- }
1287
- recalculateVisibleBounds(visibleIds, prefix, showAllOverride) {
1288
- const showAll = showAllOverride !== undefined ? showAllOverride : (visibleIds.length === 0);
1289
- this.bounds = new mapboxgl.LngLatBounds();
1290
- this.originDestinationCordinates.clear();
1291
- const normalizedVisibleIds = visibleIds.map(vid => String(vid).trim());
1292
- this.activeRoutesRegistry.forEach((data, id) => {
1293
- const registryId = String(id).trim();
1294
- // If a prefix is provided, only include routes that match it for the bounding box.
1295
- // This prevents "showAll" from zooming to hidden routes from other sections.
1296
- if (prefix && !registryId.startsWith(`${prefix}-`)) {
1297
- return;
1298
- }
1299
- if (showAll || normalizedVisibleIds.includes(registryId)) {
1300
- if (data.bounds && !data.bounds.isEmpty()) {
1301
- this.bounds.extend(data.bounds);
1302
- this.originDestinationCordinates.set(registryId, data.cordinates);
1303
- }
1304
- else if (data.cordinates && data.cordinates.length > 0) {
1305
- // Fallback if bounds weren't pre-calculated
1306
- data.cordinates.forEach((coord) => this.bounds.extend(coord));
1307
- this.originDestinationCordinates.set(registryId, data.cordinates);
992
+ else if (['jobrouteList', 'addroute'].includes(type)) {
993
+ if (route['path'] && route['path'].length > 0) {
994
+ let path = route['path'].split(';');
995
+ path = path.map((ele) => {
996
+ return (ele = this.formateLatLong(ele));
997
+ });
998
+ path.forEach((ele, index) => {
999
+ if (ele.length === 1)
1000
+ path.splice(index, 1);
1001
+ });
1002
+ this.extendBound(path, showAllFitbound);
1003
+ this.drawLine(path, i, route, enablefitbound, type);
1308
1004
  }
1309
1005
  }
1310
1006
  });
1311
- if (!this.bounds.isEmpty() && this.map) {
1312
- const canvas = this.map.getCanvas();
1313
- const mapW = canvas.clientWidth;
1314
- const mapH = canvas.clientHeight;
1315
- let padTop = Math.max(0, (Number(this.padding?.top) || 0) + (Number(this.customTopForCustomer) || 0) + 80);
1316
- let padBot = Math.max(0, (Number(this.padding?.bottom) || 0) + (Math.max(0, Number(this.windowActualHeightWidth.availHeight) - (Number(window.innerHeight) - 65))) + 80);
1317
- let padLeft = Math.max(0, (Number(this.padding?.left) || 0) + (window.innerWidth > 1000 ? 350 : 50));
1318
- let padRight = Math.max(0, (Number(this.padding?.right) || 0) + 80);
1319
- // Safety Clamps: Ensure padding doesn't exceed canvas size
1320
- const maxHorizPad = mapW * 0.8;
1321
- const maxVertPad = mapH * 0.8;
1322
- if (padLeft + padRight > maxHorizPad) {
1323
- const factor = maxHorizPad / (padLeft + padRight);
1324
- padLeft *= factor;
1325
- padRight *= factor;
1326
- }
1327
- if (padTop + padBot > maxVertPad) {
1328
- const factor = maxVertPad / (padTop + padBot);
1329
- padTop *= factor;
1330
- padBot *= factor;
1331
- }
1332
- try {
1333
- this.map.fitBounds(this.bounds, {
1334
- padding: { top: padTop, bottom: padBot, left: padLeft, right: padRight },
1335
- pitch: 65,
1336
- maxZoom: 12,
1337
- duration: 800
1338
- });
1339
- }
1340
- catch (err) {
1341
- console.warn('fitBounds failed, trying with default padding', err);
1342
- this.map.fitBounds(this.bounds, { padding: 50, pitch: 65, maxZoom: 12 });
1343
- }
1344
- }
1345
- }
1346
- async clearAllRoutes() {
1347
- // 1. Remove all markers
1348
- this.markerOriginList.forEach(marker => marker.remove());
1349
- this.markerDestinationList.forEach(marker => marker.remove());
1350
- this.markerOriginList.clear();
1351
- this.markerDestinationList.clear();
1352
- // 2. Remove all arcs
1353
- Object.keys(this.activeArcs).forEach(index => {
1354
- const arc = this.activeArcs[index];
1355
- if (arc.pathEl.parentNode)
1356
- arc.pathEl.parentNode.removeChild(arc.pathEl);
1357
- if (this.svgOverlay) {
1358
- const grad = this.svgOverlay.querySelector(`defs #arc-grad-${index}`);
1359
- if (grad && grad.parentNode)
1360
- grad.parentNode.removeChild(grad);
1361
- }
1362
- });
1363
- this.activeArcs = {};
1364
- // 3. Remove all line layers and sources using registry metadata
1365
- this.activeRoutesRegistry.forEach((data, regId) => {
1366
- const type = data.routeType || 'jobcode';
1367
- const idx = data.index || regId.split('-').pop();
1368
- const layerId = `route-layer-${type}-${idx}`;
1369
- const sourceId = `route-source-${type}-${idx}`;
1370
- this.map.getLayer(layerId) ? this.map.removeLayer(layerId) : null;
1371
- this.map.getSource(sourceId) ? this.map.removeSource(sourceId) : null;
1372
- // Legacy fallback cleanup
1373
- this.map.getLayer(`line${idx}`) ? this.map.removeLayer(`line${idx}`) : null;
1374
- this.map.getSource(`line${idx}`) ? this.map.removeSource(`line${idx}`) : null;
1375
- this.map.getLayer(`route-for-job-code${idx}`) ? this.map.removeLayer(`route-for-job-code${idx}`) : null;
1376
- this.map.getSource(`route-source-for-job-code${idx}`) ? this.map.removeSource(`route-source-for-job-code${idx}`) : null;
1377
- });
1378
- // 4. Reset registries and bounds
1379
- this.activeRoutesRegistry.clear();
1380
- this.originDestinationCordinates.clear();
1381
- this.bounds = new mapboxgl.LngLatBounds();
1382
- if (this.popup)
1383
- this.popup.remove();
1384
- return true;
1385
1007
  }
1386
1008
  clearBound() {
1387
1009
  this.bounds = new mapboxgl.LngLatBounds();
1388
- this.originDestinationCordinates.clear();
1010
+ this.originDestinationCordinates = [];
1389
1011
  this.clearPadding();
1390
1012
  }
1391
1013
  formateLatLong(latlong) {
1392
- return latlong ? latlong.split(',').map((x) => +x).reverse() : null;
1014
+ return latlong
1015
+ ? latlong
1016
+ .split(',')
1017
+ .map((x) => +x)
1018
+ .reverse()
1019
+ : null;
1393
1020
  }
1394
1021
  clearBoundWithCordinates() {
1395
1022
  this.bounds = new mapboxgl.LngLatBounds();
1396
- this.originDestinationCordinates.clear();
1023
+ this.originDestinationCordinates = [];
1397
1024
  }
1398
1025
  onResize(event) {
1399
- if (!this.bounds.isEmpty() && this.map) {
1026
+ if (!this.bounds.isEmpty()) {
1400
1027
  this.windowActualHeightWidth.availHeight =
1401
- window.innerHeight > window.screen.availHeight ? window.innerHeight : window.screen.availHeight;
1028
+ window.innerHeight > window.screen.availHeight
1029
+ ? window.innerHeight
1030
+ : window.screen.availHeight;
1402
1031
  setTimeout(() => {
1403
- const hRes = event.target ? event.target.innerHeight : window.innerHeight;
1404
1032
  this.map.fitBounds(this.bounds, {
1405
1033
  padding: {
1406
- top: (this.padding?.top || 0) + this.customTopForCustomer,
1407
- bottom: (this.padding?.bottom || 0) + (this.windowActualHeightWidth.availHeight - (hRes - 65)),
1408
- left: (this.padding?.left || 0),
1409
- right: (this.padding?.right || 0),
1034
+ top: this.padding.top + this.customTopForCustomer,
1035
+ bottom: this.padding.bottom +
1036
+ (this.windowActualHeightWidth.availHeight -
1037
+ (event.target.innerHeight - 65)),
1038
+ left: this.padding.left,
1039
+ right: this.padding.right,
1410
1040
  },
1411
1041
  pitch: 65,
1412
1042
  });
@@ -1423,7 +1053,7 @@ class MapboxService {
1423
1053
  this.padding = null;
1424
1054
  }
1425
1055
  removeJobFromMap(data) {
1426
- data.forEach((ele, index) => {
1056
+ data.map((ele, index) => {
1427
1057
  const id = ele['job_id'] ? ele['job_id'] : ele['route_id'];
1428
1058
  this.removeRouteAndMarker(id);
1429
1059
  if (index === data.length - 1) {
@@ -1431,58 +1061,24 @@ class MapboxService {
1431
1061
  }
1432
1062
  });
1433
1063
  }
1434
- resize() {
1435
- if (this.map) {
1436
- setTimeout(() => this.map.resize(), 0);
1437
- }
1438
- }
1439
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MapboxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1440
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MapboxService, providedIn: 'root' });
1441
- }
1442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MapboxService, decorators: [{
1443
- type: Injectable,
1444
- args: [{
1445
- providedIn: 'root'
1446
- }]
1447
- }], ctorParameters: () => [] });
1448
-
1449
- class CoolmapService {
1450
- mapbox = inject(MapboxService);
1451
- isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1452
- isDataFetched = signal(false, ...(ngDevMode ? [{ debugName: "isDataFetched" }] : []));
1453
- plottingIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "plottingIds" }] : []));
1454
- resetModals = signal(0, ...(ngDevMode ? [{ debugName: "resetModals" }] : []));
1455
- plotRoute(route, i, type = 'jobcode', enablefitbound, showAllFitbound) {
1456
- if (!route)
1457
- return;
1458
- return this.mapbox.plotRoute(route, i, type, enablefitbound, showAllFitbound);
1459
- }
1460
- loadMapProperty(pinRouteGeojson, index, unit, routeProps) {
1461
- this.mapbox.loadMapProperty(pinRouteGeojson, index, unit, routeProps);
1462
- }
1463
- removeRouteAndMarker(index, type = 'jobcode') {
1464
- return this.mapbox.removeRouteAndMarker(index, type);
1465
- }
1466
- clearAllRoutes() {
1467
- return this.mapbox.clearAllRoutes();
1468
- }
1469
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1470
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapService, providedIn: 'root' });
1064
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: CoolmapService, deps: [{ token: UtilsService }, { token: i2$1.EventManager }, { token: 'memberData' }], target: i0.ɵɵFactoryTarget.Injectable });
1065
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: CoolmapService, providedIn: 'root' });
1471
1066
  }
1472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CoolmapService, decorators: [{
1067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: CoolmapService, decorators: [{
1473
1068
  type: Injectable,
1474
- args: [{
1475
- providedIn: 'root'
1476
- }]
1477
- }] });
1069
+ args: [{ providedIn: 'root' }]
1070
+ }], ctorParameters: () => [{ type: UtilsService }, { type: i2$1.EventManager }, { type: CoolmapConfigModel, decorators: [{
1071
+ type: Inject,
1072
+ args: ['memberData']
1073
+ }] }] });
1478
1074
 
1479
1075
  /*
1480
- * Public API Surface of coolmap-services
1076
+ * Public API Surface of @aggdirect/coolmap-services
1481
1077
  */
1482
1078
 
1483
1079
  /**
1484
1080
  * Generated bundle index. Do not edit.
1485
1081
  */
1486
1082
 
1487
- export { AgToastService, COOLMAP_CONFIG, CoolmapService, CoolmapServices, MapboxService, UtilsService, provideCoolmapConfig };
1083
+ export { CoolmapConfigModel, CoolmapService, DriverSmsCardEnum, DriversmsCardKey, EstinationData, EstinationEnum, JobCodeOverviewData, JobCodeOverviewEnum, PopupData, Route, UtilsService };
1488
1084
  //# sourceMappingURL=aggdirect-coolmap-services.mjs.map