@mis-wis/common 0.2.0 → 0.3.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.
@@ -15,9 +15,10 @@ import { LoaderModule } from 'mis-crystal-design-system/loader';
15
15
  import { map, forkJoin, ReplaySubject } from 'rxjs';
16
16
  import * as i2$2 from '@angular/forms';
17
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';
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';
21
22
  import * as i6 from 'mis-crystal-design-system/dropdown';
22
23
  import { DropdownModule } from 'mis-crystal-design-system/dropdown';
23
24
  import * as i7 from 'mis-crystal-design-system/datepicker_v2';
@@ -225,19 +226,22 @@ const CONSTANTS_LOGGER = {
225
226
  };
226
227
 
227
228
  const envMap = {
228
- dev: "https://bff.devcl.moveinsync.com",
229
- qa: "https://bff.stage.moveinsync.com",
230
- production: "https://bff.moveinsync.com",
231
- uat: "https://wisbff-uat.moveinsync.com",
232
- "production-green": "https://wisempweb-green.moveinsync.com",
233
- "production-beta": "https://bff-beta.moveinsync.com",
234
- "production-eu": "https://bff.eu.moveinsync.com",
235
- "production-eu-green": "https://bff-green.eu.moveinsync.com",
236
- "production-mu": "https://bff.moveinsync.in"
229
+ dev: "https://ui-logger.stage.moveinsync.com",
230
+ qa: "https://ui-logger.stage.moveinsync.com",
231
+ production: "https://ui-logger.moveinsync.com",
232
+ uat: "https://ui-logger-uat.moveinsync.com",
233
+ "production-green": "https://ui-logger-green.moveinsync.com",
234
+ "production-beta": "https://ui-logger-beta.moveinsync.com",
235
+ "production-eu": "https://ui-logger.eu.moveinsync.com",
236
+ "production-eu-green": "https://ui-logger-green.eu.moveinsync.com",
237
+ "production-eu-beta": "https://ui-logger-beta.eu.moveinsync.com",
238
+ "production-mu": "https://ui-logger.moveinsync.in",
239
+ "production-mu-green": "https://ui-logger-green.moveinsync.in",
240
+ "production-mu-beta": "https://ui-logger-beta.moveinsync.in",
237
241
  };
238
242
  function environmentHandler(env) {
239
243
  if (!env) {
240
- return "/bff";
244
+ return "/logger";
241
245
  }
242
246
  return envMap[env];
243
247
  }
@@ -395,7 +399,10 @@ const CONSTANTS_ASSETS_WIS_COMMON = {
395
399
  ICONS: {}
396
400
  };
397
401
 
402
+ dayjs.extend(customParseFormat);
398
403
  const PROPERTIES = ["NON_SHIFT_TRIPS_CATEGORIES", "USE_VALID_OFFICE_FOR_IRREGULAR_TRIPS"];
404
+ const DATE_FORMAT = "DD/MM/YYYY";
405
+ const PICKUP_TIME_FORMAT = "DD/MM/YYYY HH/mm/ss";
399
406
  class CreateNonShiftModalComponent {
400
407
  constructor(modalData, modalRef, fb, http, toast) {
401
408
  this.modalData = modalData;
@@ -405,8 +412,8 @@ class CreateNonShiftModalComponent {
405
412
  this.toast = toast;
406
413
  this.CONSTANTS_ASSETS_WIS_COMMON = CONSTANTS_ASSETS_WIS_COMMON;
407
414
  this.dateConfig = {
408
- minDate: parseZone().format("DD/MM/YYYY"),
409
- format: "DD/MM/YYYY"
415
+ minDate: dayjs().format(DATE_FORMAT),
416
+ format: DATE_FORMAT
410
417
  };
411
418
  this.offices = [];
412
419
  this.locationDropdownData = [];
@@ -442,7 +449,7 @@ class CreateNonShiftModalComponent {
442
449
  }
443
450
  initializeForm() {
444
451
  var _a, _b, _c;
445
- const currentTime = (_b = (_a = this.modalData) === null || _a === void 0 ? void 0 : _a.date) !== null && _b !== void 0 ? _b : parseZone().format("DD/MM/YYYY");
452
+ const currentTime = (_b = (_a = this.modalData) === null || _a === void 0 ? void 0 : _a.date) !== null && _b !== void 0 ? _b : dayjs().format(DATE_FORMAT);
446
453
  this.createTripsheetForm = this.fb.group({
447
454
  direction: [((_c = this.modalData) === null || _c === void 0 ? void 0 : _c.shiftType) === "logout" ? "OUT" : "IN", Validators.required],
448
455
  location: [{ label: "", value: "" }],
@@ -517,7 +524,7 @@ class CreateNonShiftModalComponent {
517
524
  }
518
525
  const formValue = this.createTripsheetForm.value;
519
526
  const pickupTime = `${formValue.date} ${formValue.hours.value}/${formValue.mins.value}/00`;
520
- const pickupTimeDate = parseZone(pickupTime).toDate();
527
+ const pickupTimeDate = dayjs(pickupTime, PICKUP_TIME_FORMAT).toDate();
521
528
  if (this.isDateAndTimeFromPast(pickupTimeDate)) {
522
529
  this.toast.displayMsg("Please select a future date and time.");
523
530
  return;
@@ -693,6 +700,23 @@ class SessionClaimNotFoundError extends SessionError {
693
700
  this.name = 'SessionClaimNotFoundError';
694
701
  }
695
702
  }
703
+ /** Renders failures as `claim (reason), claim (reason)` for error messages. */
704
+ function describeClaimFailures(failures) {
705
+ return failures.map(f => `${f.claim} (${f.reason})`).join(', ');
706
+ }
707
+ /**
708
+ * Every claim `run`'s `next` failed to read, reported once after the block has finished.
709
+ * Extends `SessionClaimNotFoundError` — and reports the first failure as `claim` — so handlers
710
+ * written against the single-claim error keep working.
711
+ */
712
+ class SessionClaimsMissingError extends SessionClaimNotFoundError {
713
+ constructor(failures) {
714
+ super(failures[0].claim);
715
+ this.failures = failures;
716
+ this.name = 'SessionClaimsMissingError';
717
+ this.message = `Session claims not found: ${describeClaimFailures(failures)}.`;
718
+ }
719
+ }
696
720
 
697
721
  const DEFAULT_SESSION_TOKEN_PREFIX = 'sso-wis-token';
698
722
  const DEFAULT_SESSION_TOKEN_FALLBACK_KEY = 'x-wis-token';
@@ -703,6 +727,7 @@ class SessionService {
703
727
  this.config = {};
704
728
  this.cachedToken = null;
705
729
  this.cachedState = null;
730
+ this.collecting = null;
706
731
  }
707
732
  init(config) {
708
733
  this.config = Object.assign({}, config);
@@ -726,18 +751,50 @@ class SessionService {
726
751
  }
727
752
  /**
728
753
  * Statement-style variant of `read` for blocks of assignments/side effects with no return value.
754
+ *
755
+ * `next` always runs to completion: a claim that is absent or blank yields `undefined` instead of
756
+ * throwing, and every such failure is reported once afterwards via `handlers.error`, as a
757
+ * `SessionClaimsMissingError` listing all of them. An unusable token (missing, expired,
758
+ * undecodable) still aborts `next` immediately with the matching `SessionError`.
759
+ *
760
+ * Collecting covers the synchronous body of `next` only — claim reads deferred into a subscription,
761
+ * timeout or promise run after it has returned and throw as usual.
762
+ *
763
+ * An error `next` throws for any other reason propagates untouched, except that any claims missing
764
+ * at the time are appended to its message and attached as `sessionClaimFailures` — a collected
765
+ * `undefined` reaching the block is the usual cause, and that is the part worth knowing.
729
766
  */
730
767
  run(handlers) {
731
- this.read({
732
- next: s => { handlers.next(s); return undefined; },
733
- error: err => { handlers.error(err); return undefined; }
734
- });
768
+ const failures = [];
769
+ const previous = this.collecting;
770
+ this.collecting = failures;
771
+ try {
772
+ handlers.next(this);
773
+ }
774
+ catch (e) {
775
+ if (e instanceof SessionError) {
776
+ handlers.error(e);
777
+ return;
778
+ }
779
+ if (failures.length && e instanceof Error) {
780
+ e.sessionClaimFailures = failures;
781
+ e.message = `${e.message} — session claims missing during run(): ${describeClaimFailures(failures)}`;
782
+ }
783
+ throw e;
784
+ }
785
+ finally {
786
+ this.collecting = previous;
787
+ }
788
+ if (failures.length) {
789
+ handlers.error(new SessionClaimsMissingError(failures));
790
+ }
735
791
  }
736
792
  get isVET() {
737
793
  return this.state.isVET;
738
794
  }
739
795
  get sub() { return this.getClaim('sub'); }
740
796
  get empGuid() { return this.getClaim('employeeGUID'); }
797
+ get employeeId() { return this.getClaim('employeeId'); }
741
798
  get internalSsoRole() { return this.getClaim('internal_sso_role'); }
742
799
  get roles() { return this.getClaim('roles'); }
743
800
  get sessionId() { return this.getClaim('sessionId'); }
@@ -750,14 +807,23 @@ class SessionService {
750
807
  get vetUserId() { return this.getClaim('vetUserId'); }
751
808
  get source() { return this.getClaim('source'); }
752
809
  get roleId() {
753
- var _a, _b, _c;
754
- const claims = this.getClaims();
755
- const raw = ((_a = claims.internal_sso_role) === null || _a === void 0 ? void 0 : _a.trim()) || ((_c = (_b = claims.roles) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.trim());
756
- if (!raw || !/^\d+$/.test(raw)) {
757
- throw new SessionClaimNotFoundError('roleId');
810
+ const raw = this.resolveRole(this.getClaims());
811
+ if (!raw) {
812
+ return this.missingClaim('roleId', 'absent');
758
813
  }
759
814
  return Number(raw);
760
815
  }
816
+ /** First numeric role in `internal_sso_role` then `roles`, or `''` when the token carries none. */
817
+ resolveRole(claims) {
818
+ var _a, _b;
819
+ const candidates = [claims.internal_sso_role, ...((_a = claims.roles) !== null && _a !== void 0 ? _a : [])];
820
+ return (_b = candidates
821
+ .map(value => value === null || value === void 0 ? void 0 : value.trim())
822
+ .find(value => this.isDigitsOnly(value))) !== null && _b !== void 0 ? _b : '';
823
+ }
824
+ isDigitsOnly(value) {
825
+ return !!value && /^\d+$/.test(value);
826
+ }
761
827
  getClaims() {
762
828
  const state = this.state;
763
829
  if (state.status === 'ok') {
@@ -776,10 +842,18 @@ class SessionService {
776
842
  const value = claims[key];
777
843
  const isEmptyString = typeof value === 'string' && value.trim() === '';
778
844
  if (value === undefined || value === null || isEmptyString) {
779
- throw new SessionClaimNotFoundError(key);
845
+ return this.missingClaim(key, isEmptyString ? 'blank' : 'absent');
780
846
  }
781
847
  return (typeof value === 'string' ? value.trim() : value);
782
848
  }
849
+ /** Records the failure and yields `undefined` while `run` is collecting; throws otherwise. */
850
+ missingClaim(claim, reason) {
851
+ if (this.collecting) {
852
+ this.collecting.push({ claim, reason });
853
+ return undefined;
854
+ }
855
+ throw new SessionClaimNotFoundError(claim);
856
+ }
783
857
  get state() {
784
858
  const { token, isVET } = this.findToken();
785
859
  if (!this.cachedState || token !== this.cachedToken) {
@@ -846,5 +920,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
846
920
  * Generated bundle index. Do not edit.
847
921
  */
848
922
 
849
- export { AuthInterceptor, AuthModule, AuthService, ConfigurationService, CreateNonShiftModalComponent, LoaderService, LoggerModule, LoggerService, MfeCommunicationService, SessionClaimNotFoundError, SessionError, SessionService, SessionTokenExpiredError, SessionTokenInvalidError, SessionTokenNotFoundError, SidenavComponent, WisCommonModule, filterNavList, getCookie, getQueryParam, removeCookie, setCookie };
923
+ 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 };
850
924
  //# sourceMappingURL=mis-wis-common.mjs.map