@mis-wis/common 0.1.9 → 0.2.1

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 (53) hide show
  1. package/esm2020/lib/components/create-non-shift-modal/create-non-shift-modal.component.mjs +237 -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 +45 -0
  7. package/esm2020/lib/services/session.service.mjs +198 -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 +530 -25
  11. package/fesm2015/mis-wis-common.mjs.map +1 -1
  12. package/fesm2020/mis-wis-common.mjs +522 -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 +22 -0
  18. package/lib/services/http.service.d.ts +16 -5
  19. package/lib/services/session.errors.d.ts +31 -0
  20. package/lib/services/session.service.d.ts +79 -0
  21. package/lib/wis-common.module.d.ts +9 -4
  22. package/package.json +9 -3
  23. package/public-api.d.ts +4 -0
  24. package/src/assets/calendar.svg +7 -0
  25. package/src/assets/images/icons/Wis-icon.svg +4 -0
  26. package/src/assets/images/icons/brand.png +0 -0
  27. package/src/assets/images/icons/broascast.svg +3 -0
  28. package/src/assets/images/icons/bulk-upload.svg +3 -0
  29. package/src/assets/images/icons/desk-mgmt.svg +6 -0
  30. package/src/assets/images/icons/employees-sidebar.svg +3 -0
  31. package/src/assets/images/icons/help-section.svg +4 -0
  32. package/src/assets/images/icons/home.svg +3 -0
  33. package/src/assets/images/icons/logout.svg +4 -0
  34. package/src/assets/images/icons/manage-premise.svg +3 -0
  35. package/src/assets/images/icons/meeting-room.svg +7 -0
  36. package/src/assets/images/icons/mis-icon.svg +3 -0
  37. package/src/assets/images/icons/my-bookings.svg +5 -0
  38. package/src/assets/images/icons/profile.svg +3 -0
  39. package/src/assets/images/icons/reception.svg +14 -0
  40. package/src/assets/images/icons/report.svg +3 -0
  41. package/src/assets/images/icons/resource-group.svg +3 -0
  42. package/src/assets/images/icons/roles.svg +3 -0
  43. package/src/assets/images/icons/sanitize.svg +10 -0
  44. package/src/assets/images/icons/seat-mgmt.svg +3 -0
  45. package/src/assets/images/icons/settings-sidebar.svg +3 -0
  46. package/src/assets/images/icons/signout.svg +4 -0
  47. package/src/assets/images/icons/user-group.svg +6 -0
  48. package/src/assets/images/icons/user-permission.svg +5 -0
  49. package/src/assets/images/icons/utilisation.svg +3 -0
  50. package/src/assets/images/icons/vaccine_approval.svg +8 -0
  51. package/src/assets/images/icons/vaccine_upload.png +0 -0
  52. package/src/assets/images/icons/work-planner-sidebar.svg +3 -0
  53. package/src/assets/images/icons/workInSyncText.svg +14 -0
@@ -1,18 +1,29 @@
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 dayjs from 'dayjs';
19
+ import customParseFormat from 'dayjs/plugin/customParseFormat';
20
+ import * as i1$3 from 'mis-crystal-design-system/modal';
21
+ import { MODAL_DATA_VAR } from 'mis-crystal-design-system/modal';
22
+ import * as i6 from 'mis-crystal-design-system/dropdown';
23
+ import { DropdownModule } from 'mis-crystal-design-system/dropdown';
24
+ import * as i7 from 'mis-crystal-design-system/datepicker_v2';
25
+ import { DatepickerModuleV2 } from 'mis-crystal-design-system/datepicker_v2';
26
+ import jwtDecode from 'jwt-decode';
16
27
 
17
28
  class AuthService {
18
29
  constructor() { }
@@ -145,7 +156,7 @@ class LoaderComponent {
145
156
  ngOnInit() { }
146
157
  }
147
158
  LoaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
148
- 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"] }] });
159
+ 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"] }] });
149
160
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderComponent, decorators: [{
150
161
  type: Component,
151
162
  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"] }]
@@ -199,14 +210,14 @@ class LoaderService {
199
210
  return { positionStrategy, width, backdropClass, hasMessage };
200
211
  }
201
212
  }
202
- 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 });
213
+ 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 });
203
214
  LoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderService, providedIn: "root" });
204
215
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoaderService, decorators: [{
205
216
  type: Injectable,
206
217
  args: [{
207
218
  providedIn: "root"
208
219
  }]
209
- }], ctorParameters: function () { return [{ type: i1$2.Overlay }]; } });
220
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }]; } });
210
221
 
211
222
  /** @format */
212
223
  const CONSTANTS_LOGGER = {
@@ -264,7 +275,7 @@ class LoggerService {
264
275
  this.logRequest(Object.assign(Object.assign({}, data), { componentName, serviceUrl }), "error");
265
276
  }
266
277
  }
267
- 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 });
278
+ 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 });
268
279
  LoggerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoggerService, providedIn: "root" });
269
280
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoggerService, decorators: [{
270
281
  type: Injectable,
@@ -272,7 +283,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
272
283
  providedIn: "root"
273
284
  }]
274
285
  }], ctorParameters: function () {
275
- return [{ type: i1$3.HttpClient }, { type: undefined, decorators: [{
286
+ return [{ type: i1$2.HttpClient }, { type: undefined, decorators: [{
276
287
  type: Inject,
277
288
  args: [CONSTANTS_LOGGER.APP_NAME]
278
289
  }] }, { type: undefined, decorators: [{
@@ -326,16 +337,36 @@ const API_URLS = {
326
337
  CONFIGURATIONS: "configurations"
327
338
  };
328
339
  class HttpService {
329
- constructor(env, auth, http) {
340
+ constructor(env, http) {
330
341
  this.env = env;
331
- this.auth = auth;
332
342
  this.http = http;
333
343
  }
334
- getConfigurations() {
335
- return this.http.get(`${this.env.empExp}/${this.auth.userDetails.buid}/${API_URLS.CONFIGURATIONS}`);
344
+ getProperties(Porperties) {
345
+ return this.http.get(`${this.env.ets}/ets/apis/properties/${Porperties.join(",")}`).pipe(map((res) => {
346
+ return res.reduce((acc, item) => {
347
+ acc[item.propertyName] = item.propertyValue === "true" ? true : item.propertyValue === "false" ? false : item.propertyValue;
348
+ return acc;
349
+ }, {});
350
+ }));
351
+ }
352
+ getOffices(nonce) {
353
+ const body = `CSRF_NONCE=${nonce}&method=getOfficeList`;
354
+ return this.http.post(`${this.env.ets}/Locality_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
355
+ }
356
+ listTransportLocalities(nonce) {
357
+ const body = `CSRF_NONCE=${nonce}&method=listTransportLocalities`;
358
+ return this.http.post(`${this.env.ets}/Locality_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
359
+ }
360
+ createEmptyIrregularTripSheet(nonce, direction) {
361
+ const body = `CSRF_NONCE=${nonce}&method=createEmptyIrregularTripSheet&direction=${direction}`;
362
+ return this.http.post(`${this.env.ets}/Tripsheet_Edit_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
363
+ }
364
+ addEmployeeToTripSheet(nonce, params) {
365
+ 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)) : ""}`;
366
+ return this.http.post(`${this.env.ets}/Tripsheet_Edit_Servlet`, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } });
336
367
  }
337
368
  }
338
- 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 });
369
+ 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 });
339
370
  HttpService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpService });
340
371
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpService, decorators: [{
341
372
  type: Injectable
@@ -343,7 +374,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
343
374
  return [{ type: undefined, decorators: [{
344
375
  type: Inject,
345
376
  args: [CONSTANTS_WIS_COMMON]
346
- }] }, { type: AuthService }, { type: i1$3.HttpClient }];
377
+ }] }, { type: i1$2.HttpClient }];
347
378
  } });
348
379
 
349
380
  class SidenavComponent {
@@ -357,24 +388,259 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
357
388
  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
389
  }], ctorParameters: function () { return []; } });
359
390
 
391
+ /** @format */
392
+ const CONSTANTS_ASSETS_WIS_COMMON = {
393
+ IMAGES: {
394
+ CALENDAR_ICON: "assets/libraries/wis-common/calendar.svg"
395
+ },
396
+ ICONS: {}
397
+ };
398
+
399
+ dayjs.extend(customParseFormat);
400
+ const PROPERTIES = ["NON_SHIFT_TRIPS_CATEGORIES", "USE_VALID_OFFICE_FOR_IRREGULAR_TRIPS"];
401
+ const DATE_FORMAT = "DD/MM/YYYY";
402
+ const PICKUP_TIME_FORMAT = "DD/MM/YYYY HH/mm/ss";
403
+ class CreateNonShiftModalComponent {
404
+ constructor(modalData, modalRef, fb, http, toast) {
405
+ this.modalData = modalData;
406
+ this.modalRef = modalRef;
407
+ this.fb = fb;
408
+ this.http = http;
409
+ this.toast = toast;
410
+ this.CONSTANTS_ASSETS_WIS_COMMON = CONSTANTS_ASSETS_WIS_COMMON;
411
+ this.dateConfig = {
412
+ minDate: dayjs().format(DATE_FORMAT),
413
+ format: DATE_FORMAT
414
+ };
415
+ this.offices = [];
416
+ this.locationDropdownData = [];
417
+ this.categoryDropdownData = [];
418
+ this.hoursDropdownData = [];
419
+ this.minutesDropdownData = [];
420
+ this.showOtherAddress = false;
421
+ this.loading = false;
422
+ this.isSubmitting = false;
423
+ this.TYPE_OFFICE = 6;
424
+ this.TYPE_TRANSPORT = 3;
425
+ this.TYPE_OTHER = 4;
426
+ this.properties = {};
427
+ }
428
+ ngOnInit() {
429
+ this.loading = true;
430
+ const $office = this.http.getOffices(this.modalData.nonce);
431
+ const $properties = this.http.getProperties(PROPERTIES);
432
+ forkJoin([$office, $properties])
433
+ .pipe(finalize(() => (this.loading = false)))
434
+ .subscribe({
435
+ next: ([offices, properties]) => {
436
+ this.properties = properties;
437
+ this.initializeForm();
438
+ this.initializeDropdownData(offices);
439
+ this.setupFormListeners();
440
+ },
441
+ error: error => {
442
+ console.error("Error loading form data:", error);
443
+ this.modalRef.close();
444
+ }
445
+ });
446
+ }
447
+ initializeForm() {
448
+ var _a, _b, _c;
449
+ const currentTime = (_b = (_a = this.modalData) === null || _a === void 0 ? void 0 : _a.date) !== null && _b !== void 0 ? _b : dayjs().format(DATE_FORMAT);
450
+ this.createTripsheetForm = this.fb.group({
451
+ direction: [((_c = this.modalData) === null || _c === void 0 ? void 0 : _c.shiftType) === "logout" ? "OUT" : "IN", Validators.required],
452
+ location: [{ label: "", value: "" }],
453
+ otherAddress: "",
454
+ tripCategory: [{ label: "", value: "" }],
455
+ date: [currentTime, Validators.required],
456
+ hours: [{ label: "", value: "" }],
457
+ mins: [{ label: "", value: "" }]
458
+ });
459
+ }
460
+ initializeDropdownData(offices) {
461
+ var _a, _b, _c;
462
+ this.locationDropdownData = offices.map((office) => ({
463
+ label: office.address,
464
+ value: { type: this.TYPE_OFFICE, office: office || null }
465
+ }));
466
+ (_a = this.createTripsheetForm.get("location")) === null || _a === void 0 ? void 0 : _a.setValue(this.locationDropdownData[0]);
467
+ if (!((_b = this.properties) === null || _b === void 0 ? void 0 : _b["USE_VALID_OFFICE_FOR_IRREGULAR_TRIPS"])) {
468
+ this.locationDropdownData.push({ label: "Airport", value: { type: this.TYPE_TRANSPORT, office: null } }, { label: "Other", value: { type: this.TYPE_OTHER, office: null } });
469
+ }
470
+ // Initialize category dropdown
471
+ const categoriesString = (_c = this.properties) === null || _c === void 0 ? void 0 : _c["NON_SHIFT_TRIPS_CATEGORIES"];
472
+ if (categoriesString && typeof categoriesString === "string") {
473
+ const categories = categoriesString.split(",").filter(cat => cat && cat.trim());
474
+ if (categories.length > 0) {
475
+ this.categoryDropdownData = categories.map(category => ({
476
+ label: category.trim(),
477
+ value: category.trim()
478
+ }));
479
+ }
480
+ }
481
+ const currentHour = new Date().getHours();
482
+ this.hoursDropdownData = Array.from({ length: 24 }, (_, i) => ({
483
+ label: this.padZero(i),
484
+ value: this.padZero(i)
485
+ }));
486
+ this.createTripsheetForm.patchValue({ hours: this.hoursDropdownData[currentHour] });
487
+ const currentMinute = new Date().getMinutes();
488
+ this.minutesDropdownData = Array.from({ length: 60 }, (_, i) => ({
489
+ label: this.padZero(i),
490
+ value: this.padZero(i)
491
+ }));
492
+ this.createTripsheetForm.patchValue({ mins: this.minutesDropdownData[currentMinute] });
493
+ }
494
+ setupFormListeners() {
495
+ var _a;
496
+ (_a = this.createTripsheetForm) === null || _a === void 0 ? void 0 : _a.valueChanges.subscribe(value => {
497
+ var _a, _b, _c, _d, _e, _f;
498
+ const { location } = (_a = this.createTripsheetForm) === null || _a === void 0 ? void 0 : _a.value;
499
+ if (this.showOtherAddress !== (((_b = location === null || location === void 0 ? void 0 : location.value) === null || _b === void 0 ? void 0 : _b.type) === this.TYPE_OTHER)) {
500
+ this.showOtherAddress = ((_c = location === null || location === void 0 ? void 0 : location.value) === null || _c === void 0 ? void 0 : _c.type) === this.TYPE_OTHER;
501
+ if (this.showOtherAddress) {
502
+ (_d = this.createTripsheetForm.get("otherAddress")) === null || _d === void 0 ? void 0 : _d.setValidators([Validators.required]);
503
+ }
504
+ else {
505
+ (_e = this.createTripsheetForm.get("otherAddress")) === null || _e === void 0 ? void 0 : _e.clearValidators();
506
+ }
507
+ (_f = this.createTripsheetForm.get("otherAddress")) === null || _f === void 0 ? void 0 : _f.updateValueAndValidity();
508
+ }
509
+ });
510
+ }
511
+ padZero(num) {
512
+ return num.toString().padStart(2, "0");
513
+ }
514
+ onCancel() {
515
+ this.modalRef.close();
516
+ }
517
+ onSubmit() {
518
+ var _a, _b;
519
+ if (this.createTripsheetForm.invalid) {
520
+ return;
521
+ }
522
+ const formValue = this.createTripsheetForm.value;
523
+ const pickupTime = `${formValue.date} ${formValue.hours.value}/${formValue.mins.value}/00`;
524
+ const pickupTimeDate = dayjs(pickupTime, PICKUP_TIME_FORMAT).toDate();
525
+ if (this.isDateAndTimeFromPast(pickupTimeDate)) {
526
+ this.toast.displayMsg("Please select a future date and time.");
527
+ return;
528
+ }
529
+ if (this.categoryDropdownData.length > 0 && (!formValue.tripCategory || !formValue.tripCategory.value)) {
530
+ this.toast.displayMsg("Please provide a trip category.");
531
+ return;
532
+ }
533
+ if (((_b = (_a = formValue.location) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.type) === this.TYPE_OTHER) {
534
+ if (!formValue.otherAddress || formValue.otherAddress.trim() === "") {
535
+ this.toast.displayMsg("Please provide the address.");
536
+ return;
537
+ }
538
+ if (formValue.otherAddress.includes(",")) {
539
+ this.toast.displayMsg("Special character (,) not allowed in address.");
540
+ return;
541
+ }
542
+ }
543
+ this.isSubmitting = true;
544
+ this.http.createEmptyIrregularTripSheet(this.modalData.nonce, formValue.direction).subscribe({
545
+ next: routeTripSheet => {
546
+ const pickupLoc = routeTripSheet.dir === "IN" ? this.modalData.employee.home : this.getLocation(formValue);
547
+ const dropLoc = routeTripSheet.dir === "OUT" ? this.modalData.employee.home : this.getLocation(formValue);
548
+ const pickupTimeFormatted = pickupTime;
549
+ const dropTimeFormatted = pickupTime;
550
+ const employee = Object.assign(Object.assign({}, this.modalData.employee), { employee_status: 1 });
551
+ const addEmployeeParams = {
552
+ tripsheet: routeTripSheet,
553
+ employee: employee,
554
+ pickupLoc: pickupLoc,
555
+ dropLoc: dropLoc,
556
+ pickUpTime: pickupTimeFormatted,
557
+ dropTime: dropTimeFormatted,
558
+ position: 0,
559
+ routeSource: this.modalData.routeSource,
560
+ assetList: this.modalData.assetList
561
+ };
562
+ this.http.addEmployeeToTripSheet(this.modalData.nonce, addEmployeeParams).subscribe({
563
+ next: updatedTripSheet => {
564
+ var _a;
565
+ if (!updatedTripSheet.customMap) {
566
+ updatedTripSheet.customMap = {};
567
+ }
568
+ updatedTripSheet.customMap.tripCategory = ((_a = formValue.tripCategory) === null || _a === void 0 ? void 0 : _a.value) || "";
569
+ this.modalRef.close({
570
+ success: true,
571
+ tripsheet: updatedTripSheet
572
+ });
573
+ },
574
+ error: error => {
575
+ console.error("Error adding employee to tripsheet:", error);
576
+ this.toast.displayMsg("Failed to add employee to tripsheet. Please try again.");
577
+ this.isSubmitting = false;
578
+ }
579
+ });
580
+ },
581
+ error: error => {
582
+ console.error("Error creating tripsheet:", error);
583
+ this.toast.displayMsg("Failed to create tripsheet. Please try again.");
584
+ this.isSubmitting = false;
585
+ }
586
+ });
587
+ }
588
+ isDateAndTimeFromPast(date) {
589
+ const now = new Date();
590
+ return date < now;
591
+ }
592
+ getLocation(formValue) {
593
+ var _a;
594
+ const location = (_a = formValue.location) === null || _a === void 0 ? void 0 : _a.value;
595
+ if (!location) {
596
+ return null;
597
+ }
598
+ const locType = location.type;
599
+ switch (locType) {
600
+ case this.TYPE_OFFICE:
601
+ return location.office;
602
+ case this.TYPE_TRANSPORT:
603
+ return {
604
+ id: null,
605
+ type: this.TYPE_TRANSPORT,
606
+ address: "Airport",
607
+ geoCord: null
608
+ };
609
+ case this.TYPE_OTHER:
610
+ return Object.assign(Object.assign({}, location.office), { address: formValue.otherAddress || "" });
611
+ }
612
+ }
613
+ }
614
+ 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 });
615
+ 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"] }] });
616
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CreateNonShiftModalComponent, decorators: [{
617
+ type: Component,
618
+ 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"] }]
619
+ }], ctorParameters: function () {
620
+ return [{ type: undefined, decorators: [{
621
+ type: Inject,
622
+ args: [MODAL_DATA_VAR]
623
+ }] }, { type: i1$3.ModalRef }, { type: i2$2.FormBuilder }, { type: HttpService }, { type: i2.ToastService }];
624
+ } });
625
+
360
626
  class WisCommonModule {
361
627
  static forRoot(env) {
362
628
  return {
363
629
  ngModule: WisCommonModule,
364
- providers: [{ provide: CONSTANTS_WIS_COMMON, useValue: env }, ConfigurationService, LoaderService]
630
+ providers: [HttpService, { provide: CONSTANTS_WIS_COMMON, useValue: env }, ConfigurationService, LoaderService]
365
631
  };
366
632
  }
367
633
  }
368
634
  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] });
635
+ 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] });
636
+ 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
637
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WisCommonModule, decorators: [{
372
638
  type: NgModule,
373
639
  args: [{
374
- declarations: [LoaderComponent, SidenavComponent],
375
- imports: [CommonModule, OverlayModule, LoaderModule],
376
- providers: [HttpService],
377
- exports: [SidenavComponent]
640
+ declarations: [LoaderComponent, SidenavComponent, CreateNonShiftModalComponent],
641
+ imports: [CommonModule, HttpClientModule, OverlayModule, LoaderModule, DropdownModule, ReactiveFormsModule, DatepickerModuleV2,],
642
+ providers: [],
643
+ exports: [SidenavComponent, CreateNonShiftModalComponent]
378
644
  }]
379
645
  }] });
380
646
 
@@ -404,6 +670,245 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
404
670
  }]
405
671
  }], ctorParameters: function () { return []; } });
406
672
 
673
+ class SessionError extends Error {
674
+ }
675
+ class SessionTokenNotFoundError extends SessionError {
676
+ constructor() {
677
+ super('Session token was not found.');
678
+ this.name = 'SessionTokenNotFoundError';
679
+ }
680
+ }
681
+ class SessionTokenExpiredError extends SessionError {
682
+ constructor() {
683
+ super('Session token has expired.');
684
+ this.name = 'SessionTokenExpiredError';
685
+ }
686
+ }
687
+ class SessionTokenInvalidError extends SessionError {
688
+ constructor() {
689
+ super('Session token could not be decoded.');
690
+ this.name = 'SessionTokenInvalidError';
691
+ }
692
+ }
693
+ class SessionClaimNotFoundError extends SessionError {
694
+ constructor(claim) {
695
+ super(`Session claim "${claim}" was not found in the token.`);
696
+ this.claim = claim;
697
+ this.name = 'SessionClaimNotFoundError';
698
+ }
699
+ }
700
+ /** Renders failures as `claim (reason), claim (reason)` for error messages. */
701
+ function describeClaimFailures(failures) {
702
+ return failures.map(f => `${f.claim} (${f.reason})`).join(', ');
703
+ }
704
+ /**
705
+ * Every claim `run`'s `next` failed to read, reported once after the block has finished.
706
+ * Extends `SessionClaimNotFoundError` — and reports the first failure as `claim` — so handlers
707
+ * written against the single-claim error keep working.
708
+ */
709
+ class SessionClaimsMissingError extends SessionClaimNotFoundError {
710
+ constructor(failures) {
711
+ super(failures[0].claim);
712
+ this.failures = failures;
713
+ this.name = 'SessionClaimsMissingError';
714
+ this.message = `Session claims not found: ${describeClaimFailures(failures)}.`;
715
+ }
716
+ }
717
+
718
+ const DEFAULT_SESSION_TOKEN_PREFIX = 'sso-wis-token';
719
+ const DEFAULT_SESSION_TOKEN_FALLBACK_KEY = 'x-wis-token';
720
+ const DEFAULT_VET_TOKEN_PREFIX = 'x-vet-token';
721
+ const LAUNCH_SOURCE_VET = 'VET';
722
+ class SessionService {
723
+ constructor() {
724
+ this.config = {};
725
+ this.cachedToken = null;
726
+ this.cachedState = null;
727
+ this.collecting = null;
728
+ }
729
+ init(config) {
730
+ this.config = Object.assign({}, config);
731
+ this.cachedToken = null;
732
+ this.cachedState = null;
733
+ }
734
+ /**
735
+ * Runs `handlers.next` and returns its result, or `handlers.error(error)` if it throws a `SessionError`.
736
+ * Centralizes the try/catch mechanics; the caller still supplies the actual handling logic.
737
+ */
738
+ read(handlers) {
739
+ try {
740
+ return handlers.next(this);
741
+ }
742
+ catch (e) {
743
+ if (e instanceof SessionError) {
744
+ return handlers.error(e);
745
+ }
746
+ throw e;
747
+ }
748
+ }
749
+ /**
750
+ * Statement-style variant of `read` for blocks of assignments/side effects with no return value.
751
+ *
752
+ * `next` always runs to completion: a claim that is absent or blank yields `undefined` instead of
753
+ * throwing, and every such failure is reported once afterwards via `handlers.error`, as a
754
+ * `SessionClaimsMissingError` listing all of them. An unusable token (missing, expired,
755
+ * undecodable) still aborts `next` immediately with the matching `SessionError`.
756
+ *
757
+ * Collecting covers the synchronous body of `next` only — claim reads deferred into a subscription,
758
+ * timeout or promise run after it has returned and throw as usual.
759
+ *
760
+ * An error `next` throws for any other reason propagates untouched, except that any claims missing
761
+ * at the time are appended to its message and attached as `sessionClaimFailures` — a collected
762
+ * `undefined` reaching the block is the usual cause, and that is the part worth knowing.
763
+ */
764
+ run(handlers) {
765
+ const failures = [];
766
+ const previous = this.collecting;
767
+ this.collecting = failures;
768
+ try {
769
+ handlers.next(this);
770
+ }
771
+ catch (e) {
772
+ if (e instanceof SessionError) {
773
+ handlers.error(e);
774
+ return;
775
+ }
776
+ if (failures.length && e instanceof Error) {
777
+ e.sessionClaimFailures = failures;
778
+ e.message = `${e.message} — session claims missing during run(): ${describeClaimFailures(failures)}`;
779
+ }
780
+ throw e;
781
+ }
782
+ finally {
783
+ this.collecting = previous;
784
+ }
785
+ if (failures.length) {
786
+ handlers.error(new SessionClaimsMissingError(failures));
787
+ }
788
+ }
789
+ get isVET() {
790
+ return this.state.isVET;
791
+ }
792
+ get sub() { return this.getClaim('sub'); }
793
+ get empGuid() { return this.getClaim('employeeGUID'); }
794
+ get employeeId() { return this.getClaim('employeeId'); }
795
+ get internalSsoRole() { return this.getClaim('internal_sso_role'); }
796
+ get roles() { return this.getClaim('roles'); }
797
+ get sessionId() { return this.getClaim('sessionId'); }
798
+ get loggedInUser() { return this.getClaim('loggedInUser'); }
799
+ get exp() { return this.getClaim('exp'); }
800
+ get iat() { return this.getClaim('iat'); }
801
+ get businessUnitId() { return this.getClaim('businessUnitId'); }
802
+ get allowedBuids() { return this.getClaim('ALLOWED_BUIDS'); }
803
+ get vetUserEmailId() { return this.getClaim('vetUserEmailId'); }
804
+ get vetUserId() { return this.getClaim('vetUserId'); }
805
+ get source() { return this.getClaim('source'); }
806
+ get roleId() {
807
+ const raw = this.resolveRole(this.getClaims());
808
+ if (!raw) {
809
+ return this.missingClaim('roleId', 'absent');
810
+ }
811
+ return Number(raw);
812
+ }
813
+ /** First numeric role in `internal_sso_role` then `roles`, or `''` when the token carries none. */
814
+ resolveRole(claims) {
815
+ var _a, _b;
816
+ const candidates = [claims.internal_sso_role, ...((_a = claims.roles) !== null && _a !== void 0 ? _a : [])];
817
+ return (_b = candidates
818
+ .map(value => value === null || value === void 0 ? void 0 : value.trim())
819
+ .find(value => this.isDigitsOnly(value))) !== null && _b !== void 0 ? _b : '';
820
+ }
821
+ isDigitsOnly(value) {
822
+ return !!value && /^\d+$/.test(value);
823
+ }
824
+ getClaims() {
825
+ const state = this.state;
826
+ if (state.status === 'ok') {
827
+ return state.claims;
828
+ }
829
+ if (state.status === 'not-found') {
830
+ throw new SessionTokenNotFoundError();
831
+ }
832
+ if (state.status === 'expired') {
833
+ throw new SessionTokenExpiredError();
834
+ }
835
+ throw new SessionTokenInvalidError();
836
+ }
837
+ getClaim(key) {
838
+ const claims = this.getClaims();
839
+ const value = claims[key];
840
+ const isEmptyString = typeof value === 'string' && value.trim() === '';
841
+ if (value === undefined || value === null || isEmptyString) {
842
+ return this.missingClaim(key, isEmptyString ? 'blank' : 'absent');
843
+ }
844
+ return (typeof value === 'string' ? value.trim() : value);
845
+ }
846
+ /** Records the failure and yields `undefined` while `run` is collecting; throws otherwise. */
847
+ missingClaim(claim, reason) {
848
+ if (this.collecting) {
849
+ this.collecting.push({ claim, reason });
850
+ return undefined;
851
+ }
852
+ throw new SessionClaimNotFoundError(claim);
853
+ }
854
+ get state() {
855
+ const { token, isVET } = this.findToken();
856
+ if (!this.cachedState || token !== this.cachedToken) {
857
+ this.cachedToken = token;
858
+ this.cachedState = this.build(token, isVET);
859
+ }
860
+ return this.cachedState;
861
+ }
862
+ build(token, isVET) {
863
+ if (!token) {
864
+ return { status: 'not-found', isVET };
865
+ }
866
+ let claims;
867
+ try {
868
+ claims = jwtDecode(token);
869
+ }
870
+ catch (_a) {
871
+ return { status: 'invalid', isVET };
872
+ }
873
+ if (this.isExpired(claims)) {
874
+ return { status: 'expired', isVET };
875
+ }
876
+ return { status: 'ok', claims, isVET };
877
+ }
878
+ isExpired(claims) {
879
+ return typeof claims.exp === 'number' && claims.exp * 1000 <= Date.now();
880
+ }
881
+ isVETSource() {
882
+ return getQueryParam('source') === LAUNCH_SOURCE_VET;
883
+ }
884
+ resolveBuid() {
885
+ return getQueryParam('buid') || getCookie('buid') || null;
886
+ }
887
+ findToken() {
888
+ var _a;
889
+ const buid = this.resolveBuid();
890
+ if (this.isVETSource()) {
891
+ const vetKey = (_a = this.config.vetTokenCookieKey) !== null && _a !== void 0 ? _a : (buid ? `${DEFAULT_VET_TOKEN_PREFIX}-${buid}` : null);
892
+ const vetToken = (vetKey ? getCookie(vetKey) : '') || '';
893
+ if (vetToken) {
894
+ return { token: vetToken, isVET: true };
895
+ }
896
+ }
897
+ const sessionToken = this.config.sessionTokenCookieKey
898
+ ? getCookie(this.config.sessionTokenCookieKey)
899
+ : (buid ? getCookie(`${DEFAULT_SESSION_TOKEN_PREFIX}-${buid}`) : '') || getCookie(DEFAULT_SESSION_TOKEN_FALLBACK_KEY);
900
+ return { token: sessionToken || '', isVET: false };
901
+ }
902
+ }
903
+ SessionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
904
+ SessionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SessionService, providedIn: 'root' });
905
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SessionService, decorators: [{
906
+ type: Injectable,
907
+ args: [{
908
+ providedIn: 'root'
909
+ }]
910
+ }] });
911
+
407
912
  /*
408
913
  * Public API Surface of wis-common
409
914
  */
@@ -412,5 +917,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
412
917
  * Generated bundle index. Do not edit.
413
918
  */
414
919
 
415
- export { AuthInterceptor, AuthModule, AuthService, ConfigurationService, LoaderService, LoggerModule, LoggerService, MfeCommunicationService, SidenavComponent, WisCommonModule, filterNavList, getCookie, getQueryParam, removeCookie, setCookie };
920
+ export { AuthInterceptor, AuthModule, AuthService, ConfigurationService, CreateNonShiftModalComponent, LoaderService, LoggerModule, LoggerService, MfeCommunicationService, SessionClaimNotFoundError, SessionClaimsMissingError, SessionError, SessionService, SessionTokenExpiredError, SessionTokenInvalidError, SessionTokenNotFoundError, SidenavComponent, WisCommonModule, describeClaimFailures, filterNavList, getCookie, getQueryParam, removeCookie, setCookie };
416
921
  //# sourceMappingURL=mis-wis-common.mjs.map