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