@mis-wis/common 0.1.9 → 0.2.0

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.
Files changed (54) hide show
  1. package/esm2020/lib/components/create-non-shift-modal/create-non-shift-modal.component.mjs +233 -0
  2. package/esm2020/lib/constants/assets.constants.mjs +8 -0
  3. package/esm2020/lib/models/env.model.mjs +1 -1
  4. package/esm2020/lib/models/session.model.mjs +2 -0
  5. package/esm2020/lib/services/http.service.mjs +29 -9
  6. package/esm2020/lib/services/session.errors.mjs +28 -0
  7. package/esm2020/lib/services/session.service.mjs +148 -0
  8. package/esm2020/lib/wis-common.module.mjs +13 -8
  9. package/esm2020/public-api.mjs +5 -1
  10. package/fesm2015/mis-wis-common.mjs +459 -25
  11. package/fesm2015/mis-wis-common.mjs.map +1 -1
  12. package/fesm2020/mis-wis-common.mjs +451 -25
  13. package/fesm2020/mis-wis-common.mjs.map +1 -1
  14. package/lib/components/create-non-shift-modal/create-non-shift-modal.component.d.ts +56 -0
  15. package/lib/constants/assets.constants.d.ts +7 -0
  16. package/lib/models/env.model.d.ts +1 -0
  17. package/lib/models/session.model.d.ts +21 -0
  18. package/lib/services/http.service.d.ts +16 -5
  19. package/lib/services/session.errors.d.ts +15 -0
  20. package/lib/services/session.service.d.ts +49 -0
  21. package/lib/wis-common.module.d.ts +9 -4
  22. package/mis-wis-common-0.2.0.tgz +0 -0
  23. package/package.json +3 -2
  24. package/public-api.d.ts +4 -0
  25. package/src/assets/calendar.svg +7 -0
  26. package/src/assets/images/icons/Wis-icon.svg +4 -0
  27. package/src/assets/images/icons/brand.png +0 -0
  28. package/src/assets/images/icons/broascast.svg +3 -0
  29. package/src/assets/images/icons/bulk-upload.svg +3 -0
  30. package/src/assets/images/icons/desk-mgmt.svg +6 -0
  31. package/src/assets/images/icons/employees-sidebar.svg +3 -0
  32. package/src/assets/images/icons/help-section.svg +4 -0
  33. package/src/assets/images/icons/home.svg +3 -0
  34. package/src/assets/images/icons/logout.svg +4 -0
  35. package/src/assets/images/icons/manage-premise.svg +3 -0
  36. package/src/assets/images/icons/meeting-room.svg +7 -0
  37. package/src/assets/images/icons/mis-icon.svg +3 -0
  38. package/src/assets/images/icons/my-bookings.svg +5 -0
  39. package/src/assets/images/icons/profile.svg +3 -0
  40. package/src/assets/images/icons/reception.svg +14 -0
  41. package/src/assets/images/icons/report.svg +3 -0
  42. package/src/assets/images/icons/resource-group.svg +3 -0
  43. package/src/assets/images/icons/roles.svg +3 -0
  44. package/src/assets/images/icons/sanitize.svg +10 -0
  45. package/src/assets/images/icons/seat-mgmt.svg +3 -0
  46. package/src/assets/images/icons/settings-sidebar.svg +3 -0
  47. package/src/assets/images/icons/signout.svg +4 -0
  48. package/src/assets/images/icons/user-group.svg +6 -0
  49. package/src/assets/images/icons/user-permission.svg +5 -0
  50. package/src/assets/images/icons/utilisation.svg +3 -0
  51. package/src/assets/images/icons/vaccine_approval.svg +8 -0
  52. package/src/assets/images/icons/vaccine_upload.png +0 -0
  53. package/src/assets/images/icons/work-planner-sidebar.svg +3 -0
  54. package/src/assets/images/icons/workInSyncText.svg +14 -0
@@ -1,18 +1,28 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, NgModule, Component, Inject } from '@angular/core';
3
- import * as i1$1 from '@angular/common';
3
+ import * as i5 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
- import * as i1$3 from '@angular/common/http';
6
- import { HttpErrorResponse } from '@angular/common/http';
7
- import { tap } from 'rxjs/operators';
5
+ import * as i1$2 from '@angular/common/http';
6
+ import { HttpErrorResponse, HttpClientModule } from '@angular/common/http';
7
+ import { tap, finalize } from 'rxjs/operators';
8
8
  import * as i1 from '@angular/router';
9
9
  import * as i2 from 'mis-crystal-design-system/toast';
10
- import * as i1$2 from '@angular/cdk/overlay';
10
+ import * as i1$1 from '@angular/cdk/overlay';
11
11
  import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
12
12
  import { ComponentPortal } from '@angular/cdk/portal';
13
13
  import * as i2$1 from 'mis-crystal-design-system/loader';
14
14
  import { LoaderModule } from 'mis-crystal-design-system/loader';
15
- import { ReplaySubject } from 'rxjs';
15
+ import { map, forkJoin, ReplaySubject } from 'rxjs';
16
+ import * as i2$2 from '@angular/forms';
17
+ import { Validators, ReactiveFormsModule } from '@angular/forms';
18
+ import { parseZone } from 'moment';
19
+ import * as i1$3 from 'mis-design-system/mis-modal';
20
+ import { MODAL_DATA_VAR } from 'mis-design-system/mis-modal';
21
+ import * as i6 from 'mis-crystal-design-system/dropdown';
22
+ import { DropdownModule } from 'mis-crystal-design-system/dropdown';
23
+ import * as i7 from 'mis-crystal-design-system/datepicker_v2';
24
+ import { DatepickerModuleV2 } from 'mis-crystal-design-system/datepicker_v2';
25
+ import jwtDecode from 'jwt-decode';
16
26
 
17
27
  class AuthService {
18
28
  constructor() { }
@@ -151,7 +161,7 @@ class LoaderComponent {
151
161
  ngOnInit() { }
152
162
  }
153
163
  LoaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
154
- LoaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LoaderComponent, selector: "mis-common-loader", ngImport: i0, template: "<div class=\"message-wrapper\" *ngIf=\"message; else noMessageLoader\">\n <span><mis-loader type=\"block\"></mis-loader></span>\n <p>{{ message }}</p>\n</div>\n<ng-template #noMessageLoader>\n <mis-loader></mis-loader>\n</ng-template>\n", styles: [".message-wrapper{max-width:343px;background-color:#fff;display:flex;flex-wrap:nowrap;align-items:center;padding:20px 16px;border-radius:6px}.message-wrapper span{position:relative;background-color:#fff;display:inline-block;width:40px;height:40px;margin-right:16px}.message-wrapper p{margin:0}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.LoaderComponent, selector: "mis-loader", inputs: ["mobileView"] }] });
164
+ LoaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LoaderComponent, selector: "mis-common-loader", ngImport: i0, template: "<div class=\"message-wrapper\" *ngIf=\"message; else noMessageLoader\">\n <span><mis-loader type=\"block\"></mis-loader></span>\n <p>{{ message }}</p>\n</div>\n<ng-template #noMessageLoader>\n <mis-loader></mis-loader>\n</ng-template>\n", styles: [".message-wrapper{max-width:343px;background-color:#fff;display:flex;flex-wrap:nowrap;align-items:center;padding:20px 16px;border-radius:6px}.message-wrapper span{position:relative;background-color:#fff;display:inline-block;width:40px;height:40px;margin-right:16px}.message-wrapper p{margin:0}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.LoaderComponent, selector: "mis-loader", inputs: ["mobileView"] }] });
155
165
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderComponent, decorators: [{
156
166
  type: Component,
157
167
  args: [{ selector: "mis-common-loader", template: "<div class=\"message-wrapper\" *ngIf=\"message; else noMessageLoader\">\n <span><mis-loader type=\"block\"></mis-loader></span>\n <p>{{ message }}</p>\n</div>\n<ng-template #noMessageLoader>\n <mis-loader></mis-loader>\n</ng-template>\n", styles: [".message-wrapper{max-width:343px;background-color:#fff;display:flex;flex-wrap:nowrap;align-items:center;padding:20px 16px;border-radius:6px}.message-wrapper span{position:relative;background-color:#fff;display:inline-block;width:40px;height:40px;margin-right:16px}.message-wrapper p{margin:0}\n"] }]
@@ -203,14 +213,14 @@ class LoaderService {
203
213
  return { positionStrategy, width, backdropClass, hasMessage };
204
214
  }
205
215
  }
206
- LoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderService, deps: [{ token: i1$2.Overlay }], target: i0.ɵɵFactoryTarget.Injectable });
216
+ LoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderService, deps: [{ token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Injectable });
207
217
  LoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderService, providedIn: "root" });
208
218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderService, decorators: [{
209
219
  type: Injectable,
210
220
  args: [{
211
221
  providedIn: "root"
212
222
  }]
213
- }], ctorParameters: function () { return [{ type: i1$2.Overlay }]; } });
223
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }]; } });
214
224
 
215
225
  /** @format */
216
226
  const CONSTANTS_LOGGER = {
@@ -268,14 +278,14 @@ class LoggerService {
268
278
  this.logRequest({ ...data, componentName, serviceUrl }, "error");
269
279
  }
270
280
  }
271
- LoggerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoggerService, deps: [{ token: i1$3.HttpClient }, { token: CONSTANTS_LOGGER.APP_NAME }, { token: CONSTANTS_LOGGER.ENV_VAR }], target: i0.ɵɵFactoryTarget.Injectable });
281
+ LoggerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoggerService, deps: [{ token: i1$2.HttpClient }, { token: CONSTANTS_LOGGER.APP_NAME }, { token: CONSTANTS_LOGGER.ENV_VAR }], target: i0.ɵɵFactoryTarget.Injectable });
272
282
  LoggerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoggerService, providedIn: "root" });
273
283
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoggerService, decorators: [{
274
284
  type: Injectable,
275
285
  args: [{
276
286
  providedIn: "root"
277
287
  }]
278
- }], ctorParameters: function () { return [{ type: i1$3.HttpClient }, { type: undefined, decorators: [{
288
+ }], ctorParameters: function () { return [{ type: i1$2.HttpClient }, { type: undefined, decorators: [{
279
289
  type: Inject,
280
290
  args: [CONSTANTS_LOGGER.APP_NAME]
281
291
  }] }, { type: undefined, decorators: [{
@@ -328,23 +338,43 @@ const API_URLS = {
328
338
  CONFIGURATIONS: "configurations"
329
339
  };
330
340
  class HttpService {
331
- constructor(env, auth, http) {
341
+ constructor(env, http) {
332
342
  this.env = env;
333
- this.auth = auth;
334
343
  this.http = http;
335
344
  }
336
- getConfigurations() {
337
- return this.http.get(`${this.env.empExp}/${this.auth.userDetails.buid}/${API_URLS.CONFIGURATIONS}`);
345
+ getProperties(Porperties) {
346
+ return this.http.get(`${this.env.ets}/ets/apis/properties/${Porperties.join(",")}`).pipe(map((res) => {
347
+ return res.reduce((acc, item) => {
348
+ acc[item.propertyName] = item.propertyValue === "true" ? true : item.propertyValue === "false" ? false : item.propertyValue;
349
+ return acc;
350
+ }, {});
351
+ }));
352
+ }
353
+ getOffices(nonce) {
354
+ const body = `CSRF_NONCE=${nonce}&method=getOfficeList`;
355
+ return this.http.post(`${this.env.ets}/Locality_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
356
+ }
357
+ listTransportLocalities(nonce) {
358
+ const body = `CSRF_NONCE=${nonce}&method=listTransportLocalities`;
359
+ return this.http.post(`${this.env.ets}/Locality_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
360
+ }
361
+ createEmptyIrregularTripSheet(nonce, direction) {
362
+ const body = `CSRF_NONCE=${nonce}&method=createEmptyIrregularTripSheet&direction=${direction}`;
363
+ return this.http.post(`${this.env.ets}/Tripsheet_Edit_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
364
+ }
365
+ addEmployeeToTripSheet(nonce, params) {
366
+ const body = `CSRF_NONCE=${nonce}&method=addEmployeeToTripSheet&tripsheet=${encodeURIComponent(JSON.stringify(params.tripsheet))}&employee=${encodeURIComponent(JSON.stringify(params.employee))}&pickupLoc=${encodeURIComponent(JSON.stringify(params.pickupLoc))}&dropLoc=${encodeURIComponent(JSON.stringify(params.dropLoc))}&pickUpTime="${params.pickUpTime}"&dropTime="${params.dropTime}"&position=${params.position}${params.routeSource ? "&routeSource=" + params.routeSource : ""}${params.assetList ? "&assetList=" + encodeURIComponent(JSON.stringify(params.assetList)) : ""}`;
367
+ return this.http.post(`${this.env.ets}/Tripsheet_Edit_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
338
368
  }
339
369
  }
340
- HttpService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpService, deps: [{ token: CONSTANTS_WIS_COMMON }, { token: AuthService }, { token: i1$3.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
370
+ HttpService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpService, deps: [{ token: CONSTANTS_WIS_COMMON }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
341
371
  HttpService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpService });
342
372
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpService, decorators: [{
343
373
  type: Injectable
344
374
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
345
375
  type: Inject,
346
376
  args: [CONSTANTS_WIS_COMMON]
347
- }] }, { type: AuthService }, { type: i1$3.HttpClient }]; } });
377
+ }] }, { type: i1$2.HttpClient }]; } });
348
378
 
349
379
  class SidenavComponent {
350
380
  constructor() { }
@@ -357,24 +387,250 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
357
387
  args: [{ selector: "wis-common-sidenav", template: "<div class=\"wis-sidenav-wrapper\">\n <div class=\"wis-sidenav-header\">\n <div class=\"wis-sidenav-header-logo\">\n <img src=\"assets/sidenav/assets/Wis-icon.svg\" alt=\"\" />\n </div>\n <div class=\"wis-sidenav-header-title\">\n <h1>WIS</h1>\n </div>\n </div>\n <div class=\"wis-sidenav-body\">\n <div class=\"wis-sidenav-body-item\">\n <div class=\"wis-sidenav-body-item-icon\">\n <i class=\"fas fa-home\"></i>\n </div>\n <div class=\"wis-sidenav-body-item-text\">\n <h3>Home</h3>\n </div>\n </div>\n <div class=\"wis-sidenav-body-item\">\n <div class=\"wis-sidenav-body-item-icon\">\n <i class=\"fas fa-user\"></i>\n </div>\n <div class=\"wis-sidenav-body-item-text\">\n <h3>Profile</h3>\n </div>\n </div>\n <div class=\"wis-sidenav-body-item\">\n <div class=\"wis-sidenav-body-item-icon\">\n <i class=\"fas fa-users\"></i>\n </div>\n <div class=\"wis-sidenav-body-item-text\">\n <h3>Users</h3>\n </div>\n </div>\n <div class=\"wis-sidenav-body-item\">\n <div class=\"wis-sidenav-body-item-icon\">\n <i class=\"fas fa-cog\"></i>\n </div>\n <div class=\"wis-sidenav-body-item-text\">\n <h3>Settings</h3>\n </div>\n </div>\n </div>\n</div>\n", styles: [".wis-sidenav-wrapper{width:72px;border-right:1px solid #e0e0e0}\n"] }]
358
388
  }], ctorParameters: function () { return []; } });
359
389
 
390
+ /** @format */
391
+ const CONSTANTS_ASSETS_WIS_COMMON = {
392
+ IMAGES: {
393
+ CALENDAR_ICON: "assets/libraries/wis-common/calendar.svg"
394
+ },
395
+ ICONS: {}
396
+ };
397
+
398
+ const PROPERTIES = ["NON_SHIFT_TRIPS_CATEGORIES", "USE_VALID_OFFICE_FOR_IRREGULAR_TRIPS"];
399
+ class CreateNonShiftModalComponent {
400
+ constructor(modalData, modalRef, fb, http, toast) {
401
+ this.modalData = modalData;
402
+ this.modalRef = modalRef;
403
+ this.fb = fb;
404
+ this.http = http;
405
+ this.toast = toast;
406
+ this.CONSTANTS_ASSETS_WIS_COMMON = CONSTANTS_ASSETS_WIS_COMMON;
407
+ this.dateConfig = {
408
+ minDate: parseZone().format("DD/MM/YYYY"),
409
+ format: "DD/MM/YYYY"
410
+ };
411
+ this.offices = [];
412
+ this.locationDropdownData = [];
413
+ this.categoryDropdownData = [];
414
+ this.hoursDropdownData = [];
415
+ this.minutesDropdownData = [];
416
+ this.showOtherAddress = false;
417
+ this.loading = false;
418
+ this.isSubmitting = false;
419
+ this.TYPE_OFFICE = 6;
420
+ this.TYPE_TRANSPORT = 3;
421
+ this.TYPE_OTHER = 4;
422
+ this.properties = {};
423
+ }
424
+ ngOnInit() {
425
+ this.loading = true;
426
+ const $office = this.http.getOffices(this.modalData.nonce);
427
+ const $properties = this.http.getProperties(PROPERTIES);
428
+ forkJoin([$office, $properties])
429
+ .pipe(finalize(() => (this.loading = false)))
430
+ .subscribe({
431
+ next: ([offices, properties]) => {
432
+ this.properties = properties;
433
+ this.initializeForm();
434
+ this.initializeDropdownData(offices);
435
+ this.setupFormListeners();
436
+ },
437
+ error: error => {
438
+ console.error("Error loading form data:", error);
439
+ this.modalRef.close();
440
+ }
441
+ });
442
+ }
443
+ initializeForm() {
444
+ const currentTime = this.modalData?.date ?? parseZone().format("DD/MM/YYYY");
445
+ this.createTripsheetForm = this.fb.group({
446
+ direction: [this.modalData?.shiftType === "logout" ? "OUT" : "IN", Validators.required],
447
+ location: [{ label: "", value: "" }],
448
+ otherAddress: "",
449
+ tripCategory: [{ label: "", value: "" }],
450
+ date: [currentTime, Validators.required],
451
+ hours: [{ label: "", value: "" }],
452
+ mins: [{ label: "", value: "" }]
453
+ });
454
+ }
455
+ initializeDropdownData(offices) {
456
+ this.locationDropdownData = offices.map((office) => ({
457
+ label: office.address,
458
+ value: { type: this.TYPE_OFFICE, office: office || null }
459
+ }));
460
+ this.createTripsheetForm.get("location")?.setValue(this.locationDropdownData[0]);
461
+ if (!this.properties?.["USE_VALID_OFFICE_FOR_IRREGULAR_TRIPS"]) {
462
+ this.locationDropdownData.push({ label: "Airport", value: { type: this.TYPE_TRANSPORT, office: null } }, { label: "Other", value: { type: this.TYPE_OTHER, office: null } });
463
+ }
464
+ // Initialize category dropdown
465
+ const categoriesString = this.properties?.["NON_SHIFT_TRIPS_CATEGORIES"];
466
+ if (categoriesString && typeof categoriesString === "string") {
467
+ const categories = categoriesString.split(",").filter(cat => cat && cat.trim());
468
+ if (categories.length > 0) {
469
+ this.categoryDropdownData = categories.map(category => ({
470
+ label: category.trim(),
471
+ value: category.trim()
472
+ }));
473
+ }
474
+ }
475
+ const currentHour = new Date().getHours();
476
+ this.hoursDropdownData = Array.from({ length: 24 }, (_, i) => ({
477
+ label: this.padZero(i),
478
+ value: this.padZero(i)
479
+ }));
480
+ this.createTripsheetForm.patchValue({ hours: this.hoursDropdownData[currentHour] });
481
+ const currentMinute = new Date().getMinutes();
482
+ this.minutesDropdownData = Array.from({ length: 60 }, (_, i) => ({
483
+ label: this.padZero(i),
484
+ value: this.padZero(i)
485
+ }));
486
+ this.createTripsheetForm.patchValue({ mins: this.minutesDropdownData[currentMinute] });
487
+ }
488
+ setupFormListeners() {
489
+ this.createTripsheetForm?.valueChanges.subscribe(value => {
490
+ const { location } = this.createTripsheetForm?.value;
491
+ if (this.showOtherAddress !== (location?.value?.type === this.TYPE_OTHER)) {
492
+ this.showOtherAddress = location?.value?.type === this.TYPE_OTHER;
493
+ if (this.showOtherAddress) {
494
+ this.createTripsheetForm.get("otherAddress")?.setValidators([Validators.required]);
495
+ }
496
+ else {
497
+ this.createTripsheetForm.get("otherAddress")?.clearValidators();
498
+ }
499
+ this.createTripsheetForm.get("otherAddress")?.updateValueAndValidity();
500
+ }
501
+ });
502
+ }
503
+ padZero(num) {
504
+ return num.toString().padStart(2, "0");
505
+ }
506
+ onCancel() {
507
+ this.modalRef.close();
508
+ }
509
+ onSubmit() {
510
+ if (this.createTripsheetForm.invalid) {
511
+ return;
512
+ }
513
+ const formValue = this.createTripsheetForm.value;
514
+ const pickupTime = `${formValue.date} ${formValue.hours.value}/${formValue.mins.value}/00`;
515
+ const pickupTimeDate = parseZone(pickupTime).toDate();
516
+ if (this.isDateAndTimeFromPast(pickupTimeDate)) {
517
+ this.toast.displayMsg("Please select a future date and time.");
518
+ return;
519
+ }
520
+ if (this.categoryDropdownData.length > 0 && (!formValue.tripCategory || !formValue.tripCategory.value)) {
521
+ this.toast.displayMsg("Please provide a trip category.");
522
+ return;
523
+ }
524
+ if (formValue.location?.value?.type === this.TYPE_OTHER) {
525
+ if (!formValue.otherAddress || formValue.otherAddress.trim() === "") {
526
+ this.toast.displayMsg("Please provide the address.");
527
+ return;
528
+ }
529
+ if (formValue.otherAddress.includes(",")) {
530
+ this.toast.displayMsg("Special character (,) not allowed in address.");
531
+ return;
532
+ }
533
+ }
534
+ this.isSubmitting = true;
535
+ this.http.createEmptyIrregularTripSheet(this.modalData.nonce, formValue.direction).subscribe({
536
+ next: routeTripSheet => {
537
+ const pickupLoc = routeTripSheet.dir === "IN" ? this.modalData.employee.home : this.getLocation(formValue);
538
+ const dropLoc = routeTripSheet.dir === "OUT" ? this.modalData.employee.home : this.getLocation(formValue);
539
+ const pickupTimeFormatted = pickupTime;
540
+ const dropTimeFormatted = pickupTime;
541
+ const employee = { ...this.modalData.employee, employee_status: 1 };
542
+ const addEmployeeParams = {
543
+ tripsheet: routeTripSheet,
544
+ employee: employee,
545
+ pickupLoc: pickupLoc,
546
+ dropLoc: dropLoc,
547
+ pickUpTime: pickupTimeFormatted,
548
+ dropTime: dropTimeFormatted,
549
+ position: 0,
550
+ routeSource: this.modalData.routeSource,
551
+ assetList: this.modalData.assetList
552
+ };
553
+ this.http.addEmployeeToTripSheet(this.modalData.nonce, addEmployeeParams).subscribe({
554
+ next: updatedTripSheet => {
555
+ if (!updatedTripSheet.customMap) {
556
+ updatedTripSheet.customMap = {};
557
+ }
558
+ updatedTripSheet.customMap.tripCategory = formValue.tripCategory?.value || "";
559
+ this.modalRef.close({
560
+ success: true,
561
+ tripsheet: updatedTripSheet
562
+ });
563
+ },
564
+ error: error => {
565
+ console.error("Error adding employee to tripsheet:", error);
566
+ this.toast.displayMsg("Failed to add employee to tripsheet. Please try again.");
567
+ this.isSubmitting = false;
568
+ }
569
+ });
570
+ },
571
+ error: error => {
572
+ console.error("Error creating tripsheet:", error);
573
+ this.toast.displayMsg("Failed to create tripsheet. Please try again.");
574
+ this.isSubmitting = false;
575
+ }
576
+ });
577
+ }
578
+ isDateAndTimeFromPast(date) {
579
+ const now = new Date();
580
+ return date < now;
581
+ }
582
+ getLocation(formValue) {
583
+ const location = formValue.location?.value;
584
+ if (!location) {
585
+ return null;
586
+ }
587
+ const locType = location.type;
588
+ switch (locType) {
589
+ case this.TYPE_OFFICE:
590
+ return location.office;
591
+ case this.TYPE_TRANSPORT:
592
+ return {
593
+ id: null,
594
+ type: this.TYPE_TRANSPORT,
595
+ address: "Airport",
596
+ geoCord: null
597
+ };
598
+ case this.TYPE_OTHER:
599
+ return {
600
+ ...location.office,
601
+ address: formValue.otherAddress || ""
602
+ };
603
+ }
604
+ }
605
+ }
606
+ CreateNonShiftModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CreateNonShiftModalComponent, deps: [{ token: MODAL_DATA_VAR }, { token: i1$3.ModalRef }, { token: i2$2.FormBuilder }, { token: HttpService }, { token: i2.ToastService }], target: i0.ɵɵFactoryTarget.Component });
607
+ CreateNonShiftModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CreateNonShiftModalComponent, selector: "app-create-non-shift-modal", ngImport: i0, template: "<div class=\"createTripsheet\">\n <h2 class=\"modal-header\">Create Non-Shift Tripsheet</h2>\n\n <div *ngIf=\"loading\" class=\"loading-container\">\n <div class=\"spinner\"></div>\n <p>Loading...</p>\n </div>\n\n <form\n *ngIf=\"!loading && createTripsheetForm\"\n [formGroup]=\"createTripsheetForm\"\n (ngSubmit)=\"onSubmit()\"\n class=\"createTripsheetForm\"\n id=\"createTripsheetForm\"\n >\n <div class=\"form-content\">\n <!-- Radio buttons row -->\n <div [ngClass]=\"{ 'radio-row': true, disabled: modalData?.shiftSelectionDisabled }\">\n <label class=\"radio-label\">\n <input class=\"modern-checkbox\" type=\"radio\" formControlName=\"direction\" value=\"OUT\" id=\"startLoc\" />\n <span>Start Location Fixed (Logout)</span>\n </label>\n <label class=\"radio-label\">\n <input class=\"modern-checkbox\" type=\"radio\" formControlName=\"direction\" value=\"IN\" id=\"endLoc\" />\n <span>End Location Fixed (Login)</span>\n </label>\n </div>\n\n <!-- Location field -->\n <div class=\"form-field\">\n <div class=\"label-cell\">\n <label class=\"locText\">Location</label>\n </div>\n <div class=\"input-cell\">\n <mis-dropdown\n [searchEnabled]=\"true\"\n [width]=\"'100%'\"\n [height]=\"'40px'\"\n [data]=\"locationDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('location')?.value\"\n [label]=\"'Select location...'\"\n (onChange)=\"createTripsheetForm.get('location')?.setValue($event)\"\n ></mis-dropdown>\n </div>\n </div>\n\n <!-- Other address field -->\n <div class=\"form-field otherAddress\" *ngIf=\"showOtherAddress\">\n <div class=\"label-cell\">\n <label>Pick/Drop point <sup>*</sup></label>\n </div>\n <div class=\"input-cell\">\n <input type=\"text\" formControlName=\"otherAddress\" class=\"modern-input\" />\n </div>\n </div>\n\n <!-- Trip category field -->\n <div class=\"form-field\" *ngIf=\"categoryDropdownData.length > 0\">\n <div class=\"label-cell\">\n <label>Trip Category</label>\n </div>\n <div class=\"input-cell\">\n <mis-dropdown\n [searchEnabled]=\"false\"\n [width]=\"'250px'\"\n [height]=\"'40px'\"\n [data]=\"categoryDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('tripCategory')?.value\"\n [label]=\"'Select category...'\"\n (onChange)=\"createTripsheetForm.get('tripCategory')?.setValue($event)\"\n ></mis-dropdown>\n </div>\n </div>\n\n <!-- Time field -->\n <div class=\"form-field\">\n <div class=\"label-cell\">\n <label class=\"fixedTimeText\">Time</label>\n </div>\n <div class=\"input-cell modern-date-container\">\n <div class=\"date-select\">\n <input\n misTzDp\n readonly\n [dpConfig]=\"dateConfig\"\n [formControl]=\"createTripsheetForm.get('date')\"\n style=\"height: 44px !important; font-size: 16px !important; cursor: pointer; vertical-align: middle !important\"\n />\n <img [src]=\"CONSTANTS_ASSETS_WIS_COMMON.IMAGES.CALENDAR_ICON\" alt=\"Calendar Icon\" class=\"date-icon data-picker-icon\" />\n </div>\n\n <mis-dropdown\n [searchEnabled]=\"false\"\n [width]=\"'5rem'\"\n [height]=\"'40px'\"\n [data]=\"hoursDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('hours')?.value\"\n [label]=\"'HH'\"\n (onChange)=\"createTripsheetForm.get('hours')?.setValue($event)\"\n ></mis-dropdown>\n\n <mis-dropdown\n [searchEnabled]=\"false\"\n [width]=\"'5rem'\"\n [height]=\"'40px'\"\n [data]=\"minutesDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('mins')?.value\"\n [label]=\"'MM'\"\n (onChange)=\"createTripsheetForm.get('mins')?.setValue($event)\"\n ></mis-dropdown>\n </div>\n </div>\n </div>\n\n <div class=\"form-actions\">\n <button mis-button type=\"outline\" (click)=\"onCancel()\" [disabled]=\"isSubmitting\">Cancel</button>\n <button mis-button type=\"primary\" [disabled]=\"isSubmitting || createTripsheetForm?.invalid\">\n {{ isSubmitting ? \"Creating...\" : \"Create\" }}\n </button>\n </div>\n </form>\n</div>\n", styles: [".createTripsheet{width:40rem;margin:auto;background:#fff;border-radius:.5rem;padding:1.25rem}.createTripsheet .modal-header{font-size:1.25rem;font-weight:600;color:#333;margin:0 0 1.25rem;padding-bottom:.9375rem;border-bottom:.0625rem solid #e0e0e0}.createTripsheet .loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3.75rem 1.25rem;min-height:12.5rem}.createTripsheet .loading-container .spinner{border:.1875rem solid #f3f3f3;border-top:.1875rem solid #007bff;border-radius:50%;width:2.5rem;height:2.5rem;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.createTripsheet .createTripsheetForm .form-content{display:flex;flex-direction:column}.createTripsheet .createTripsheetForm .form-field{display:flex;align-items:flex-start;gap:1.25rem;padding:.9375rem 0}.createTripsheet .createTripsheetForm .form-field .label-cell{flex:0 0 30%;padding-top:.5rem}.createTripsheet .createTripsheetForm .form-field .label-cell label{font-size:.875rem;font-weight:500;color:#333}.createTripsheet .createTripsheetForm .form-field .input-cell{flex:1;display:flex}.createTripsheet .createTripsheetForm .radio-row{display:flex;gap:1.25rem;padding:.9375rem 0}.createTripsheet .createTripsheetForm .radio-label{font-size:.875rem;display:flex;align-items:center;cursor:pointer;margin:0}.createTripsheet .createTripsheetForm .radio-label .modern-checkbox{margin-right:.625rem;vertical-align:sub;cursor:pointer;width:1rem;height:1rem;accent-color:#007bff}.createTripsheet .createTripsheetForm .radio-label span{-webkit-user-select:none;user-select:none;white-space:nowrap}.createTripsheet .createTripsheetForm .modern-input{width:100%;padding:.5rem .75rem;border:.0625rem solid #ddd;border-radius:.25rem;font-size:.875rem;transition:border-color .3s}.createTripsheet .createTripsheetForm .modern-input:focus{outline:none;border-color:#007bff;box-shadow:0 0 0 .2rem #007bff40}.createTripsheet .createTripsheetForm .modern-input:disabled{background-color:#f5f5f5;cursor:not-allowed}.createTripsheet .createTripsheetForm sup{color:#dc3545}.createTripsheet .createTripsheetForm ::ng-deep mis-dropdown{display:block;width:100%}.createTripsheet .createTripsheetForm .modern-date-container{position:inherit;float:inherit;display:flex;align-items:center;gap:.625rem}.createTripsheet .createTripsheetForm .ng-invalid{border:.0625rem solid #dc3545}.createTripsheet .createTripsheetForm .form-actions{text-align:right;margin:.625rem;border-top:.0625rem solid #e0e0e0;padding:.625rem;display:flex;justify-content:flex-end;gap:.625rem;margin-bottom:0}.createTripsheet .createTripsheetForm .form-actions button{padding:.625rem 1.5rem;font-size:.875rem;font-weight:500;border-radius:.375rem;border:none;cursor:pointer;transition:all .3s ease;min-width:6.25rem}.createTripsheet .createTripsheetForm .form-actions button[type=primary]{background-color:#0937b2;color:#fff;border:.0625rem solid #0937b2}.createTripsheet .createTripsheetForm .form-actions button[type=outline]{background-color:transparent;color:#6c757d;border:.0625rem solid #ddd}.createTripsheet .createTripsheetForm .form-actions button:disabled{opacity:.6;cursor:not-allowed;box-shadow:none}.date-select{height:2.5rem;border:.0625rem solid #e0e0e0;padding:0;border-radius:.375rem;display:flex;flex-wrap:nowrap;justify-content:space-between;align-items:center;position:relative;overflow:hidden;left:-.5%;flex-shrink:0}.date-select input{background-color:transparent;display:inline-block;padding:.25rem 0 .25rem .75rem;width:100%;border:none;outline:none;cursor:pointer;font-size:.875rem}.date-select img{position:relative;right:1rem}.radio-row.disabled{pointer-events:none;opacity:.5}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.DropdownComponent, selector: "mis-dropdown", inputs: ["data", "height", "ariaLabel", "width", "label", "itemSizeForCdk", "showOnlyIcon", "higlightSelectedValue", "dropdownListHeight", "dropdownListWidth", "dropdownListPosition", "config", "searchEnabled", "selectedItem", "noDataMessage", "multiLine", "additionalInfoMessage", "scrollIntoView", "searchLabel", "customStyles", "activeItem"], outputs: ["onChange"] }, { kind: "directive", type: i2$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i7.TzDatepickerDirective, selector: "input[misTzDp]", inputs: ["dpConfig", "selectedDate", "datesDisabled", "dateMessages", "positionX", "positionY", "offsetX", "offsetY", "allowBookingOnDisabledDay", "disableBoxShadow", "disableOverLay", "openElement"], outputs: ["dateChange"] }] });
608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CreateNonShiftModalComponent, decorators: [{
609
+ type: Component,
610
+ args: [{ selector: "app-create-non-shift-modal", template: "<div class=\"createTripsheet\">\n <h2 class=\"modal-header\">Create Non-Shift Tripsheet</h2>\n\n <div *ngIf=\"loading\" class=\"loading-container\">\n <div class=\"spinner\"></div>\n <p>Loading...</p>\n </div>\n\n <form\n *ngIf=\"!loading && createTripsheetForm\"\n [formGroup]=\"createTripsheetForm\"\n (ngSubmit)=\"onSubmit()\"\n class=\"createTripsheetForm\"\n id=\"createTripsheetForm\"\n >\n <div class=\"form-content\">\n <!-- Radio buttons row -->\n <div [ngClass]=\"{ 'radio-row': true, disabled: modalData?.shiftSelectionDisabled }\">\n <label class=\"radio-label\">\n <input class=\"modern-checkbox\" type=\"radio\" formControlName=\"direction\" value=\"OUT\" id=\"startLoc\" />\n <span>Start Location Fixed (Logout)</span>\n </label>\n <label class=\"radio-label\">\n <input class=\"modern-checkbox\" type=\"radio\" formControlName=\"direction\" value=\"IN\" id=\"endLoc\" />\n <span>End Location Fixed (Login)</span>\n </label>\n </div>\n\n <!-- Location field -->\n <div class=\"form-field\">\n <div class=\"label-cell\">\n <label class=\"locText\">Location</label>\n </div>\n <div class=\"input-cell\">\n <mis-dropdown\n [searchEnabled]=\"true\"\n [width]=\"'100%'\"\n [height]=\"'40px'\"\n [data]=\"locationDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('location')?.value\"\n [label]=\"'Select location...'\"\n (onChange)=\"createTripsheetForm.get('location')?.setValue($event)\"\n ></mis-dropdown>\n </div>\n </div>\n\n <!-- Other address field -->\n <div class=\"form-field otherAddress\" *ngIf=\"showOtherAddress\">\n <div class=\"label-cell\">\n <label>Pick/Drop point <sup>*</sup></label>\n </div>\n <div class=\"input-cell\">\n <input type=\"text\" formControlName=\"otherAddress\" class=\"modern-input\" />\n </div>\n </div>\n\n <!-- Trip category field -->\n <div class=\"form-field\" *ngIf=\"categoryDropdownData.length > 0\">\n <div class=\"label-cell\">\n <label>Trip Category</label>\n </div>\n <div class=\"input-cell\">\n <mis-dropdown\n [searchEnabled]=\"false\"\n [width]=\"'250px'\"\n [height]=\"'40px'\"\n [data]=\"categoryDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('tripCategory')?.value\"\n [label]=\"'Select category...'\"\n (onChange)=\"createTripsheetForm.get('tripCategory')?.setValue($event)\"\n ></mis-dropdown>\n </div>\n </div>\n\n <!-- Time field -->\n <div class=\"form-field\">\n <div class=\"label-cell\">\n <label class=\"fixedTimeText\">Time</label>\n </div>\n <div class=\"input-cell modern-date-container\">\n <div class=\"date-select\">\n <input\n misTzDp\n readonly\n [dpConfig]=\"dateConfig\"\n [formControl]=\"createTripsheetForm.get('date')\"\n style=\"height: 44px !important; font-size: 16px !important; cursor: pointer; vertical-align: middle !important\"\n />\n <img [src]=\"CONSTANTS_ASSETS_WIS_COMMON.IMAGES.CALENDAR_ICON\" alt=\"Calendar Icon\" class=\"date-icon data-picker-icon\" />\n </div>\n\n <mis-dropdown\n [searchEnabled]=\"false\"\n [width]=\"'5rem'\"\n [height]=\"'40px'\"\n [data]=\"hoursDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('hours')?.value\"\n [label]=\"'HH'\"\n (onChange)=\"createTripsheetForm.get('hours')?.setValue($event)\"\n ></mis-dropdown>\n\n <mis-dropdown\n [searchEnabled]=\"false\"\n [width]=\"'5rem'\"\n [height]=\"'40px'\"\n [data]=\"minutesDropdownData\"\n [selectedItem]=\"createTripsheetForm.get('mins')?.value\"\n [label]=\"'MM'\"\n (onChange)=\"createTripsheetForm.get('mins')?.setValue($event)\"\n ></mis-dropdown>\n </div>\n </div>\n </div>\n\n <div class=\"form-actions\">\n <button mis-button type=\"outline\" (click)=\"onCancel()\" [disabled]=\"isSubmitting\">Cancel</button>\n <button mis-button type=\"primary\" [disabled]=\"isSubmitting || createTripsheetForm?.invalid\">\n {{ isSubmitting ? \"Creating...\" : \"Create\" }}\n </button>\n </div>\n </form>\n</div>\n", styles: [".createTripsheet{width:40rem;margin:auto;background:#fff;border-radius:.5rem;padding:1.25rem}.createTripsheet .modal-header{font-size:1.25rem;font-weight:600;color:#333;margin:0 0 1.25rem;padding-bottom:.9375rem;border-bottom:.0625rem solid #e0e0e0}.createTripsheet .loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3.75rem 1.25rem;min-height:12.5rem}.createTripsheet .loading-container .spinner{border:.1875rem solid #f3f3f3;border-top:.1875rem solid #007bff;border-radius:50%;width:2.5rem;height:2.5rem;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.createTripsheet .createTripsheetForm .form-content{display:flex;flex-direction:column}.createTripsheet .createTripsheetForm .form-field{display:flex;align-items:flex-start;gap:1.25rem;padding:.9375rem 0}.createTripsheet .createTripsheetForm .form-field .label-cell{flex:0 0 30%;padding-top:.5rem}.createTripsheet .createTripsheetForm .form-field .label-cell label{font-size:.875rem;font-weight:500;color:#333}.createTripsheet .createTripsheetForm .form-field .input-cell{flex:1;display:flex}.createTripsheet .createTripsheetForm .radio-row{display:flex;gap:1.25rem;padding:.9375rem 0}.createTripsheet .createTripsheetForm .radio-label{font-size:.875rem;display:flex;align-items:center;cursor:pointer;margin:0}.createTripsheet .createTripsheetForm .radio-label .modern-checkbox{margin-right:.625rem;vertical-align:sub;cursor:pointer;width:1rem;height:1rem;accent-color:#007bff}.createTripsheet .createTripsheetForm .radio-label span{-webkit-user-select:none;user-select:none;white-space:nowrap}.createTripsheet .createTripsheetForm .modern-input{width:100%;padding:.5rem .75rem;border:.0625rem solid #ddd;border-radius:.25rem;font-size:.875rem;transition:border-color .3s}.createTripsheet .createTripsheetForm .modern-input:focus{outline:none;border-color:#007bff;box-shadow:0 0 0 .2rem #007bff40}.createTripsheet .createTripsheetForm .modern-input:disabled{background-color:#f5f5f5;cursor:not-allowed}.createTripsheet .createTripsheetForm sup{color:#dc3545}.createTripsheet .createTripsheetForm ::ng-deep mis-dropdown{display:block;width:100%}.createTripsheet .createTripsheetForm .modern-date-container{position:inherit;float:inherit;display:flex;align-items:center;gap:.625rem}.createTripsheet .createTripsheetForm .ng-invalid{border:.0625rem solid #dc3545}.createTripsheet .createTripsheetForm .form-actions{text-align:right;margin:.625rem;border-top:.0625rem solid #e0e0e0;padding:.625rem;display:flex;justify-content:flex-end;gap:.625rem;margin-bottom:0}.createTripsheet .createTripsheetForm .form-actions button{padding:.625rem 1.5rem;font-size:.875rem;font-weight:500;border-radius:.375rem;border:none;cursor:pointer;transition:all .3s ease;min-width:6.25rem}.createTripsheet .createTripsheetForm .form-actions button[type=primary]{background-color:#0937b2;color:#fff;border:.0625rem solid #0937b2}.createTripsheet .createTripsheetForm .form-actions button[type=outline]{background-color:transparent;color:#6c757d;border:.0625rem solid #ddd}.createTripsheet .createTripsheetForm .form-actions button:disabled{opacity:.6;cursor:not-allowed;box-shadow:none}.date-select{height:2.5rem;border:.0625rem solid #e0e0e0;padding:0;border-radius:.375rem;display:flex;flex-wrap:nowrap;justify-content:space-between;align-items:center;position:relative;overflow:hidden;left:-.5%;flex-shrink:0}.date-select input{background-color:transparent;display:inline-block;padding:.25rem 0 .25rem .75rem;width:100%;border:none;outline:none;cursor:pointer;font-size:.875rem}.date-select img{position:relative;right:1rem}.radio-row.disabled{pointer-events:none;opacity:.5}\n"] }]
611
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
612
+ type: Inject,
613
+ args: [MODAL_DATA_VAR]
614
+ }] }, { type: i1$3.ModalRef }, { type: i2$2.FormBuilder }, { type: HttpService }, { type: i2.ToastService }]; } });
615
+
360
616
  class WisCommonModule {
361
617
  static forRoot(env) {
362
618
  return {
363
619
  ngModule: WisCommonModule,
364
- providers: [{ provide: CONSTANTS_WIS_COMMON, useValue: env }, ConfigurationService, LoaderService]
620
+ providers: [HttpService, { provide: CONSTANTS_WIS_COMMON, useValue: env }, ConfigurationService, LoaderService]
365
621
  };
366
622
  }
367
623
  }
368
624
  WisCommonModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
369
- WisCommonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, declarations: [LoaderComponent, SidenavComponent], imports: [CommonModule, OverlayModule, LoaderModule], exports: [SidenavComponent] });
370
- WisCommonModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, providers: [HttpService], imports: [CommonModule, OverlayModule, LoaderModule] });
625
+ WisCommonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, declarations: [LoaderComponent, SidenavComponent, CreateNonShiftModalComponent], imports: [CommonModule, HttpClientModule, OverlayModule, LoaderModule, DropdownModule, ReactiveFormsModule, DatepickerModuleV2], exports: [SidenavComponent, CreateNonShiftModalComponent] });
626
+ WisCommonModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, imports: [CommonModule, HttpClientModule, OverlayModule, LoaderModule, DropdownModule, ReactiveFormsModule, DatepickerModuleV2] });
371
627
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, decorators: [{
372
628
  type: NgModule,
373
629
  args: [{
374
- declarations: [LoaderComponent, SidenavComponent],
375
- imports: [CommonModule, OverlayModule, LoaderModule],
376
- providers: [HttpService],
377
- exports: [SidenavComponent]
630
+ declarations: [LoaderComponent, SidenavComponent, CreateNonShiftModalComponent],
631
+ imports: [CommonModule, HttpClientModule, OverlayModule, LoaderModule, DropdownModule, ReactiveFormsModule, DatepickerModuleV2,],
632
+ providers: [],
633
+ exports: [SidenavComponent, CreateNonShiftModalComponent]
378
634
  }]
379
635
  }] });
380
636
 
@@ -404,6 +660,176 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
404
660
  }]
405
661
  }], ctorParameters: function () { return []; } });
406
662
 
663
+ class SessionError extends Error {
664
+ }
665
+ class SessionTokenNotFoundError extends SessionError {
666
+ constructor() {
667
+ super('Session token was not found.');
668
+ this.name = 'SessionTokenNotFoundError';
669
+ }
670
+ }
671
+ class SessionTokenExpiredError extends SessionError {
672
+ constructor() {
673
+ super('Session token has expired.');
674
+ this.name = 'SessionTokenExpiredError';
675
+ }
676
+ }
677
+ class SessionTokenInvalidError extends SessionError {
678
+ constructor() {
679
+ super('Session token could not be decoded.');
680
+ this.name = 'SessionTokenInvalidError';
681
+ }
682
+ }
683
+ class SessionClaimNotFoundError extends SessionError {
684
+ constructor(claim) {
685
+ super(`Session claim "${claim}" was not found in the token.`);
686
+ this.claim = claim;
687
+ this.name = 'SessionClaimNotFoundError';
688
+ }
689
+ }
690
+
691
+ const DEFAULT_SESSION_TOKEN_PREFIX = 'sso-wis-token';
692
+ const DEFAULT_SESSION_TOKEN_FALLBACK_KEY = 'x-wis-token';
693
+ const DEFAULT_VET_TOKEN_PREFIX = 'x-vet-token';
694
+ const LAUNCH_SOURCE_VET = 'VET';
695
+ class SessionService {
696
+ constructor() {
697
+ this.config = {};
698
+ this.cachedToken = null;
699
+ this.cachedState = null;
700
+ }
701
+ init(config) {
702
+ this.config = { ...config };
703
+ this.cachedToken = null;
704
+ this.cachedState = null;
705
+ }
706
+ /**
707
+ * Runs `handlers.next` and returns its result, or `handlers.error(error)` if it throws a `SessionError`.
708
+ * Centralizes the try/catch mechanics; the caller still supplies the actual handling logic.
709
+ */
710
+ read(handlers) {
711
+ try {
712
+ return handlers.next(this);
713
+ }
714
+ catch (e) {
715
+ if (e instanceof SessionError) {
716
+ return handlers.error(e);
717
+ }
718
+ throw e;
719
+ }
720
+ }
721
+ /**
722
+ * Statement-style variant of `read` for blocks of assignments/side effects with no return value.
723
+ */
724
+ run(handlers) {
725
+ this.read({
726
+ next: s => { handlers.next(s); return undefined; },
727
+ error: err => { handlers.error(err); return undefined; }
728
+ });
729
+ }
730
+ get isVET() {
731
+ return this.state.isVET;
732
+ }
733
+ get sub() { return this.getClaim('sub'); }
734
+ get empGuid() { return this.getClaim('employeeGUID'); }
735
+ get internalSsoRole() { return this.getClaim('internal_sso_role'); }
736
+ get roles() { return this.getClaim('roles'); }
737
+ get sessionId() { return this.getClaim('sessionId'); }
738
+ get loggedInUser() { return this.getClaim('loggedInUser'); }
739
+ get exp() { return this.getClaim('exp'); }
740
+ get iat() { return this.getClaim('iat'); }
741
+ get businessUnitId() { return this.getClaim('businessUnitId'); }
742
+ get allowedBuids() { return this.getClaim('ALLOWED_BUIDS'); }
743
+ get vetUserEmailId() { return this.getClaim('vetUserEmailId'); }
744
+ get vetUserId() { return this.getClaim('vetUserId'); }
745
+ get source() { return this.getClaim('source'); }
746
+ get roleId() {
747
+ const claims = this.getClaims();
748
+ const raw = claims.internal_sso_role?.trim() || claims.roles?.[0]?.trim();
749
+ if (!raw || !/^\d+$/.test(raw)) {
750
+ throw new SessionClaimNotFoundError('roleId');
751
+ }
752
+ return Number(raw);
753
+ }
754
+ getClaims() {
755
+ const state = this.state;
756
+ if (state.status === 'ok') {
757
+ return state.claims;
758
+ }
759
+ if (state.status === 'not-found') {
760
+ throw new SessionTokenNotFoundError();
761
+ }
762
+ if (state.status === 'expired') {
763
+ throw new SessionTokenExpiredError();
764
+ }
765
+ throw new SessionTokenInvalidError();
766
+ }
767
+ getClaim(key) {
768
+ const claims = this.getClaims();
769
+ const value = claims[key];
770
+ const isEmptyString = typeof value === 'string' && value.trim() === '';
771
+ if (value === undefined || value === null || isEmptyString) {
772
+ throw new SessionClaimNotFoundError(key);
773
+ }
774
+ return (typeof value === 'string' ? value.trim() : value);
775
+ }
776
+ get state() {
777
+ const { token, isVET } = this.findToken();
778
+ if (!this.cachedState || token !== this.cachedToken) {
779
+ this.cachedToken = token;
780
+ this.cachedState = this.build(token, isVET);
781
+ }
782
+ return this.cachedState;
783
+ }
784
+ build(token, isVET) {
785
+ if (!token) {
786
+ return { status: 'not-found', isVET };
787
+ }
788
+ let claims;
789
+ try {
790
+ claims = jwtDecode(token);
791
+ }
792
+ catch {
793
+ return { status: 'invalid', isVET };
794
+ }
795
+ if (this.isExpired(claims)) {
796
+ return { status: 'expired', isVET };
797
+ }
798
+ return { status: 'ok', claims, isVET };
799
+ }
800
+ isExpired(claims) {
801
+ return typeof claims.exp === 'number' && claims.exp * 1000 <= Date.now();
802
+ }
803
+ isVETSource() {
804
+ return getQueryParam('source') === LAUNCH_SOURCE_VET;
805
+ }
806
+ resolveBuid() {
807
+ return getQueryParam('buid') || getCookie('buid') || null;
808
+ }
809
+ findToken() {
810
+ const buid = this.resolveBuid();
811
+ if (this.isVETSource()) {
812
+ const vetKey = this.config.vetTokenCookieKey ?? (buid ? `${DEFAULT_VET_TOKEN_PREFIX}-${buid}` : null);
813
+ const vetToken = (vetKey ? getCookie(vetKey) : '') || '';
814
+ if (vetToken) {
815
+ return { token: vetToken, isVET: true };
816
+ }
817
+ }
818
+ const sessionToken = this.config.sessionTokenCookieKey
819
+ ? getCookie(this.config.sessionTokenCookieKey)
820
+ : (buid ? getCookie(`${DEFAULT_SESSION_TOKEN_PREFIX}-${buid}`) : '') || getCookie(DEFAULT_SESSION_TOKEN_FALLBACK_KEY);
821
+ return { token: sessionToken || '', isVET: false };
822
+ }
823
+ }
824
+ SessionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
825
+ SessionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SessionService, providedIn: 'root' });
826
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SessionService, decorators: [{
827
+ type: Injectable,
828
+ args: [{
829
+ providedIn: 'root'
830
+ }]
831
+ }] });
832
+
407
833
  /*
408
834
  * Public API Surface of wis-common
409
835
  */
@@ -412,5 +838,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
412
838
  * Generated bundle index. Do not edit.
413
839
  */
414
840
 
415
- export { AuthInterceptor, AuthModule, AuthService, ConfigurationService, LoaderService, LoggerModule, LoggerService, MfeCommunicationService, SidenavComponent, WisCommonModule, filterNavList, getCookie, getQueryParam, removeCookie, setCookie };
841
+ export { AuthInterceptor, AuthModule, AuthService, ConfigurationService, CreateNonShiftModalComponent, LoaderService, LoggerModule, LoggerService, MfeCommunicationService, SessionClaimNotFoundError, SessionError, SessionService, SessionTokenExpiredError, SessionTokenInvalidError, SessionTokenNotFoundError, SidenavComponent, WisCommonModule, filterNavList, getCookie, getQueryParam, removeCookie, setCookie };
416
842
  //# sourceMappingURL=mis-wis-common.mjs.map