vc-error-handlers 0.1.7 → 0.1.9

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 (39) hide show
  1. package/esm2020/lib/shared/components/chunk-unavailable/chunk-unavailable.component.mjs +26 -6
  2. package/esm2020/lib/shared/components/error-modal/error-modal.component.mjs +61 -0
  3. package/esm2020/lib/shared/components/page-not-found/page-not-found.component.mjs +27 -25
  4. package/esm2020/lib/shared/components/server-error/server-error.component.mjs +63 -6
  5. package/esm2020/lib/shared/components/session-expired/session-expired.component.mjs +11 -11
  6. package/esm2020/lib/shared/components/unauthorized/unauthorized.component.mjs +21 -22
  7. package/esm2020/lib/shared/constants/api-config.constants.mjs +43 -0
  8. package/esm2020/lib/shared/constants/error-handling.constants.mjs +19 -2
  9. package/esm2020/lib/shared/errorhandler/sentry-error.handler.mjs +15 -10
  10. package/esm2020/lib/shared/interceptors/http.interceptor.mjs +8 -3
  11. package/esm2020/lib/shared/services/global-error.service.mjs +115 -5
  12. package/esm2020/lib/shared/services/util.service.mjs +21 -0
  13. package/esm2020/lib/shared/types/global-error.types.mjs +1 -1
  14. package/esm2020/lib/ui-kit/snack-bar/snack-bar/snack-bar.component.mjs +1 -2
  15. package/esm2020/lib/vc-error-handlers.component.mjs +65 -10
  16. package/esm2020/lib/vc-error-handlers.module.mjs +6 -6
  17. package/esm2020/public-api.mjs +2 -2
  18. package/fesm2015/vc-error-handlers.mjs +552 -223
  19. package/fesm2015/vc-error-handlers.mjs.map +1 -1
  20. package/fesm2020/vc-error-handlers.mjs +550 -223
  21. package/fesm2020/vc-error-handlers.mjs.map +1 -1
  22. package/lib/shared/components/chunk-unavailable/chunk-unavailable.component.d.ts +10 -2
  23. package/lib/shared/components/error-modal/error-modal.component.d.ts +17 -0
  24. package/lib/shared/components/page-not-found/page-not-found.component.d.ts +5 -1
  25. package/lib/shared/components/server-error/server-error.component.d.ts +12 -5
  26. package/lib/shared/components/session-expired/session-expired.component.d.ts +1 -3
  27. package/lib/shared/components/unauthorized/unauthorized.component.d.ts +3 -1
  28. package/lib/shared/constants/api-config.constants.d.ts +19 -0
  29. package/lib/shared/constants/error-handling.constants.d.ts +18 -1
  30. package/lib/shared/errorhandler/sentry-error.handler.d.ts +5 -3
  31. package/lib/shared/services/global-error.service.d.ts +20 -1
  32. package/lib/shared/services/util.service.d.ts +6 -0
  33. package/lib/shared/types/global-error.types.d.ts +1 -1
  34. package/lib/vc-error-handlers.component.d.ts +15 -2
  35. package/lib/vc-error-handlers.module.d.ts +2 -2
  36. package/package.json +1 -1
  37. package/public-api.d.ts +1 -1
  38. package/esm2020/lib/shared/components/session-expired-modal/session-expired-modal.component.mjs +0 -48
  39. package/lib/shared/components/session-expired-modal/session-expired-modal.component.d.ts +0 -18
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Component, Directive, ViewChild, NgModule, Optional, InjectionToken, ErrorHandler } from '@angular/core';
2
+ import { Injectable, Component, Input, Directive, ViewChild, NgModule, Optional, InjectionToken, ErrorHandler } from '@angular/core';
3
3
  import { Subject, throwError } from 'rxjs';
4
- import * as i1 from '@vcomply/authorizer';
5
- import * as i4 from '@angular/common';
6
- import { CommonModule } from '@angular/common';
7
4
  import * as i3 from '@angular/router';
8
5
  import { NavigationStart, NavigationEnd, NavigationError } from '@angular/router';
9
- import { HTTP_INTERCEPTORS } from '@angular/common/http';
6
+ import * as i1 from '@vcomply/authorizer';
7
+ import * as i2 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import { HttpResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
10
10
  import * as Sentry from '@sentry/angular-ivy';
11
- import { timeout, catchError } from 'rxjs/operators';
11
+ import { timeout, tap, catchError } from 'rxjs/operators';
12
12
 
13
13
  class VcErrorHandlersService {
14
14
  constructor() { }
@@ -38,17 +38,182 @@ var ErrorStatusCode;
38
38
  ErrorStatusCode[ErrorStatusCode["JSChunkUnavailable"] = 600] = "JSChunkUnavailable";
39
39
  })(ErrorStatusCode || (ErrorStatusCode = {}));
40
40
 
41
- class GlobalErrorService {
41
+ const VCOMPLY_LOGO_URL = 'https://cdn.v-comply.com/logo/prod/v-logo.svg';
42
+ const API_TIMEOUT_TIME = 1000 * 15;
43
+ const ERROR_CONFIG = {
44
+ PAGE_NOT_FOUND: {
45
+ imageUrl: 'https://cdn.v-comply.com/application/images/Error-page-illustration.svg',
46
+ title: 'Oops!',
47
+ description: "The page you're looking for doesn't exist.",
48
+ details: 'Please check the URL or return to the homepage.',
49
+ buttonText: 'GO TO DASHBOARD',
50
+ },
51
+ UNAUTHORIZED: {
52
+ imageUrl: 'https://cdn.v-comply.com/application/images/Error-page-illustration.svg',
53
+ title: 'Oops!',
54
+ description: "You don't have permission to access this page.",
55
+ details: 'If you believe this is an error, please contact',
56
+ email: 'help@v-comply.com',
57
+ support: 'for support',
58
+ buttonText: 'CONTACT SUPPORT',
59
+ mail: 'mailto:help@v-comply.com',
60
+ },
61
+ SESSION_EXPIRED: {
62
+ heading: 'Session Expired!',
63
+ description: 'Your session has expired. Please log in again to continue using the app.',
64
+ buttonText: 'LOGIN',
65
+ },
66
+ CHUNK_UNAVAILABLE: {
67
+ heading: 'Oops!',
68
+ description: 'We are unable to load the data.',
69
+ buttonText: 'REFRESH',
70
+ },
71
+ SERVER_ERROR: {
72
+ imageUrl: 'https://cdn.v-comply.com/application/images/Error-page-illustration.svg',
73
+ title: 'Oops!',
74
+ description: 'We are unable to load the data.',
75
+ details: 'Please refresh this page or try again later.',
76
+ buttonText: 'REFRESH',
77
+ snackBarMessage: `Oops! Something went wrong. Please try again later.`,
78
+ },
79
+ NETWORK_UNAVAILABLE: {
80
+ offlineMessage: "You're currently offline.Please check your internet connection and try again.",
81
+ },
82
+ };
83
+
84
+ const PAGE_LEVEL_API_CONFIG = [
85
+ {
86
+ method: 'POST',
87
+ path: '/compliance_post',
88
+ query: { mode: 'xyz' },
89
+ body: { mode: 'abc' },
90
+ pageCodes: ['compliance:mr', 'risk:mr'],
91
+ },
92
+ {
93
+ method: 'GET',
94
+ path: '/compliance_post',
95
+ query: { mode: 'xyz' },
96
+ body: { mode: 'abc' },
97
+ pageCodes: ['compliance:mr', 'risk:mr'],
98
+ },
99
+ ];
100
+ const COMPONENT_LEVEL_API_CONFIG = [
101
+ {
102
+ method: 'GET',
103
+ path: '/organization/?mode=organisationUsersList',
104
+ query: { type: 'active' },
105
+ body: null,
106
+ },
107
+ {
108
+ method: 'GET',
109
+ path: '/organization/?mode=organisationUsersList',
110
+ query: { type: 'power_users' },
111
+ body: null,
112
+ },
113
+ {
114
+ method: 'GET',
115
+ path: '/organization/?mode=organisationUsersList',
116
+ query: { type: 'light_users' },
117
+ body: null,
118
+ },
119
+ {
120
+ method: 'GET',
121
+ path: '/organization/?mode=organisationUsersList',
122
+ query: { type: 'inactive' },
123
+ body: null,
124
+ },
125
+ ];
126
+
127
+ class SnackBarService {
42
128
  constructor() {
129
+ this.snackbarSubject = new Subject();
130
+ this.snackbarState = this.snackbarSubject.asObservable();
131
+ }
132
+ show(message, type) {
133
+ this.snackbarSubject.next({
134
+ show: true,
135
+ message,
136
+ icon: type,
137
+ });
138
+ }
139
+ hide() {
140
+ this.snackbarSubject.next({
141
+ show: false,
142
+ message: '',
143
+ icon: '',
144
+ });
145
+ }
146
+ }
147
+ SnackBarService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
148
+ SnackBarService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarService, providedIn: 'root' });
149
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarService, decorators: [{
150
+ type: Injectable,
151
+ args: [{
152
+ providedIn: 'root',
153
+ }]
154
+ }], ctorParameters: function () { return []; } });
155
+
156
+ class UtilsService {
157
+ isJsonSubset(parentJson, subsetJson) {
158
+ for (let key in subsetJson) {
159
+ if (!parentJson.hasOwnProperty(key) || parentJson[key] !== subsetJson[key]) {
160
+ return false;
161
+ }
162
+ }
163
+ return true;
164
+ }
165
+ }
166
+ UtilsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: UtilsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
167
+ UtilsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: UtilsService, providedIn: 'root' });
168
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: UtilsService, decorators: [{
169
+ type: Injectable,
170
+ args: [{
171
+ providedIn: 'root',
172
+ }]
173
+ }] });
174
+
175
+ class GlobalErrorService {
176
+ constructor(snackBarService, utilService, router) {
177
+ this.snackBarService = snackBarService;
178
+ this.utilService = utilService;
179
+ this.router = router;
43
180
  this.globalError$ = new Subject();
44
181
  this.localError$ = new Subject();
182
+ this.pageLevelApiConfig = PAGE_LEVEL_API_CONFIG;
183
+ this.componentLevelApiConfig = COMPONENT_LEVEL_API_CONFIG;
184
+ }
185
+ handleSoftErrors(event) {
186
+ const xData = event.headers.get('X-Data');
187
+ if (xData) {
188
+ const parsedData = JSON.parse(xData);
189
+ const statusCode = parsedData.statusCode;
190
+ const statusMessage = parsedData.message;
191
+ if (statusCode && statusCode !== 0) {
192
+ this.snackBarService.show(statusMessage || 'Error occurred', 'error');
193
+ }
194
+ }
45
195
  }
46
196
  handleError(error, request) {
47
197
  if (this.isUnauthenticated(error) ||
48
198
  this.isUnauthorizedAccess(error) ||
49
199
  this.isNetworkUnavailable(error)) {
50
- this.globalError$.next(error);
200
+ this.publishGlobalError(error);
51
201
  }
202
+ else if (this.isServerError(error)) {
203
+ this.handleServerError(error, request);
204
+ }
205
+ else {
206
+ this.handleSoftErrors(error);
207
+ }
208
+ }
209
+ isServerError(error) {
210
+ const serverErrorCodes = [
211
+ ErrorStatusCode.InternalServerError,
212
+ ErrorStatusCode.ServiceUnavailable,
213
+ ErrorStatusCode.BadGateway,
214
+ ErrorStatusCode.RequestTimeout,
215
+ ];
216
+ return serverErrorCodes.includes(error.status);
52
217
  }
53
218
  isUnauthenticated(error) {
54
219
  return error.status === ErrorStatusCode.Unauthenticated;
@@ -59,15 +224,90 @@ class GlobalErrorService {
59
224
  isNetworkUnavailable(error) {
60
225
  return error.status === ErrorStatusCode.NetworkUnavailable;
61
226
  }
227
+ handleServerError(error, request) {
228
+ if (this.isPageLevelError(error, request)) {
229
+ this.publishGlobalError(error);
230
+ }
231
+ else if (this.isComponentLevelError(error, request)) {
232
+ this.publishLocalError(error, request);
233
+ }
234
+ else {
235
+ this.showServerSnackBarError();
236
+ }
237
+ }
238
+ publishGlobalError(error) {
239
+ this.globalError$.next(error);
240
+ }
241
+ publishLocalError(error, request) {
242
+ this.localError$.next({ error, request });
243
+ }
244
+ showServerSnackBarError() {
245
+ const message = ERROR_CONFIG.SERVER_ERROR.snackBarMessage;
246
+ this.snackBarService.show(message, 'error');
247
+ }
248
+ isPageLevelError(error, request) {
249
+ const { method, path, query, body } = this.parseRequest(request);
250
+ const pageCode = this.getPageCode();
251
+ const isConfigMatched = this.pageLevelApiConfig.some((apiConfig) => {
252
+ if (apiConfig.method !== method)
253
+ return false;
254
+ if (apiConfig.path !== path)
255
+ return false;
256
+ const isQuerySubset = this.utilService.isJsonSubset(apiConfig.query, query);
257
+ if (!isQuerySubset)
258
+ return false;
259
+ const isBodyMatch = this.utilService.isJsonSubset(apiConfig.body, body);
260
+ if (!isBodyMatch)
261
+ return false;
262
+ return apiConfig.pageCodes.includes(pageCode);
263
+ });
264
+ return isConfigMatched;
265
+ }
266
+ isComponentLevelError(error, request) {
267
+ const { method, url: path, params, body } = request;
268
+ const query = {};
269
+ params.keys().forEach((key) => {
270
+ query[key] = params.get(key);
271
+ });
272
+ const isConfigFound = this.componentLevelApiConfig.some((apiConfig) => {
273
+ if (apiConfig.method !== method)
274
+ return false;
275
+ if (!path.includes(apiConfig.path))
276
+ return false;
277
+ const isQuerySubset = this.utilService.isJsonSubset(query, apiConfig.query);
278
+ if (!isQuerySubset)
279
+ return false;
280
+ if (apiConfig.body) {
281
+ const isBodyMatch = this.utilService.isJsonSubset(apiConfig.body, body);
282
+ if (!isBodyMatch)
283
+ return false;
284
+ }
285
+ return true;
286
+ });
287
+ return isConfigFound;
288
+ }
289
+ parseRequest(request) {
290
+ const { method, url: path, params, body } = request;
291
+ const query = {};
292
+ params.keys().forEach((key) => {
293
+ query[key] = params.get(key);
294
+ });
295
+ return { method, path, query, body };
296
+ }
297
+ getPageCode() {
298
+ var _a;
299
+ const currentRoute = this.router.routerState.snapshot.root.firstChild;
300
+ return (_a = currentRoute === null || currentRoute === void 0 ? void 0 : currentRoute.data) === null || _a === void 0 ? void 0 : _a.pageCode;
301
+ }
62
302
  }
63
- GlobalErrorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GlobalErrorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
303
+ GlobalErrorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GlobalErrorService, deps: [{ token: SnackBarService }, { token: UtilsService }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Injectable });
64
304
  GlobalErrorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GlobalErrorService, providedIn: 'root' });
65
305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GlobalErrorService, decorators: [{
66
306
  type: Injectable,
67
307
  args: [{
68
308
  providedIn: 'root',
69
309
  }]
70
- }] });
310
+ }], ctorParameters: function () { return [{ type: SnackBarService }, { type: UtilsService }, { type: i3.Router }]; } });
71
311
 
72
312
  class AuthService {
73
313
  constructor(authorizer) {
@@ -103,77 +343,111 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
103
343
  }]
104
344
  }] });
105
345
 
106
- const VCOMPLY_IMAGE_URL = 'https://cdn.v-comply.com/logo/prod/v-logo.svg';
107
- const API_TIMEOUT_TIME = 1000 * 15;
108
- const ERROR_CONFIG = {
109
- PAGE_NOT_FOUND: {
110
- imageUrl: 'https://cdn.v-comply.com/application/images/Error-page-illustration.svg',
111
- title: 'Oops!',
112
- description: "The page you're looking for doesn't exist.",
113
- details: 'Please check the URL or return to the homepage.',
114
- buttonText: 'GO TO DASHBOARD',
115
- },
116
- UNAUTHORIZED: {
117
- imageUrl: 'https://cdn.v-comply.com/application/images/Error-page-illustration.svg',
118
- title: 'Oops!',
119
- description: "You don't have permission to access this page.",
120
- details: 'If you believe this is an error, please contact',
121
- email: 'help@v-comply.com',
122
- support: 'for support',
123
- buttonText: 'CONTACT SUPPORT',
124
- },
125
- SESSION_EXPIRED: {
126
- heading: 'Session Expired!',
127
- description: 'Your session has expired. Please log in again to continue using the app.',
128
- buttonText: 'LOGIN',
129
- },
130
- };
346
+ class SnackBarComponent {
347
+ constructor(snackbarService) {
348
+ this.snackbarService = snackbarService;
349
+ this.show = false;
350
+ this.message = '--';
351
+ this.icon = '';
352
+ this.type = 'alert';
353
+ this.icons = {
354
+ success: '',
355
+ warning: '',
356
+ info: '',
357
+ alert: '',
358
+ error: '',
359
+ };
360
+ }
361
+ ngOnInit() {
362
+ this.snackbarSubscription = this.snackbarService.snackbarState.subscribe((state) => {
363
+ if (state.icon && Object.keys(this.icons).includes(state === null || state === void 0 ? void 0 : state.icon)) {
364
+ this.icon = this.icons[state.icon];
365
+ this.type = state === null || state === void 0 ? void 0 : state.icon;
366
+ }
367
+ this.message = state.message;
368
+ this.show = state.show;
369
+ });
370
+ }
371
+ setAutoClose() {
372
+ setTimeout(() => {
373
+ this.show = false;
374
+ this.close();
375
+ }, 3000);
376
+ }
377
+ close() {
378
+ this.show = false;
379
+ this.snackbarService.hide();
380
+ }
381
+ ngOnDestroy() {
382
+ this.snackbarSubscription.unsubscribe();
383
+ }
384
+ }
385
+ SnackBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarComponent, deps: [{ token: SnackBarService }], target: i0.ɵɵFactoryTarget.Component });
386
+ SnackBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: SnackBarComponent, selector: "app-snack-bar", ngImport: i0, template: "<div class=\"workflow-snackbar\" *ngIf=\"show\">\r\n <div class=\"workflow-snackbar-inner\">\r\n <div class=\"workflow-snackbarText\">\r\n <!-- &#xe914; -->\r\n <i class=\"icons\" [class]=\"type\" [innerHTML]=\"icon\"></i> <span [innerHTML]=\"message\">{{ message }}</span>\r\n </div>\r\n <button (click)=\"close()\">[ <span>Close</span> ]</button>\r\n </div>\r\n </div>", styles: ["::ng-deep .workflow-snackbar{position:fixed;top:20px;left:0;right:0;display:flex;align-items:center;justify-content:center;z-index:2147483647!important;pointer-events:none;animation:slide-top .3s cubic-bezier(.25,.46,.45,.94) both}::ng-deep .workflow-snackbar.white{background-color:#fff;color:#000;z-index:20}::ng-deep .workflow-snackbar.white button{color:#f6882f;font-size:11px;font-weight:400;pointer-events:all}::ng-deep .workflow-snackbar .workflow-snackbar-inner{display:flex;max-width:500px;min-width:450px;align-items:center;justify-content:space-between;padding:10px;background:#ffffff;border-radius:3px;box-shadow:0 0 10px #0003;min-height:55px;pointer-events:auto}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText{color:#161b2f;font-size:13px;display:flex;align-items:center;width:calc(100% - 70px)}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i{background:#f1f1f1;color:#d93b41;border-radius:50px;font-size:16px;width:30px;height:30px;text-align:center;line-height:28px;margin-right:10px;min-width:30px}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.success{color:#34aa44}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.warning{color:#f0b819}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.info{color:#1e5dd3}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.alert,::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.error{color:#d93b41}::ng-deep .workflow-snackbar .workflow-snackbar-inner button{background:transparent;border:none;font-size:11px;padding:0;position:relative;color:#747576;width:65px;text-align:right;cursor:pointer;text-transform:uppercase}::ng-deep .workflow-snackbar .workflow-snackbar-inner button span{color:#1e5dd3;font-weight:500}::ng-deep .workflow-snackbar .workflow-snackbar-inner button:focus{outline:none}@keyframes slide-top{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
387
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarComponent, decorators: [{
388
+ type: Component,
389
+ args: [{ selector: 'app-snack-bar', template: "<div class=\"workflow-snackbar\" *ngIf=\"show\">\r\n <div class=\"workflow-snackbar-inner\">\r\n <div class=\"workflow-snackbarText\">\r\n <!-- &#xe914; -->\r\n <i class=\"icons\" [class]=\"type\" [innerHTML]=\"icon\"></i> <span [innerHTML]=\"message\">{{ message }}</span>\r\n </div>\r\n <button (click)=\"close()\">[ <span>Close</span> ]</button>\r\n </div>\r\n </div>", styles: ["::ng-deep .workflow-snackbar{position:fixed;top:20px;left:0;right:0;display:flex;align-items:center;justify-content:center;z-index:2147483647!important;pointer-events:none;animation:slide-top .3s cubic-bezier(.25,.46,.45,.94) both}::ng-deep .workflow-snackbar.white{background-color:#fff;color:#000;z-index:20}::ng-deep .workflow-snackbar.white button{color:#f6882f;font-size:11px;font-weight:400;pointer-events:all}::ng-deep .workflow-snackbar .workflow-snackbar-inner{display:flex;max-width:500px;min-width:450px;align-items:center;justify-content:space-between;padding:10px;background:#ffffff;border-radius:3px;box-shadow:0 0 10px #0003;min-height:55px;pointer-events:auto}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText{color:#161b2f;font-size:13px;display:flex;align-items:center;width:calc(100% - 70px)}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i{background:#f1f1f1;color:#d93b41;border-radius:50px;font-size:16px;width:30px;height:30px;text-align:center;line-height:28px;margin-right:10px;min-width:30px}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.success{color:#34aa44}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.warning{color:#f0b819}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.info{color:#1e5dd3}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.alert,::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.error{color:#d93b41}::ng-deep .workflow-snackbar .workflow-snackbar-inner button{background:transparent;border:none;font-size:11px;padding:0;position:relative;color:#747576;width:65px;text-align:right;cursor:pointer;text-transform:uppercase}::ng-deep .workflow-snackbar .workflow-snackbar-inner button span{color:#1e5dd3;font-weight:500}::ng-deep .workflow-snackbar .workflow-snackbar-inner button:focus{outline:none}@keyframes slide-top{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}\n"] }]
390
+ }], ctorParameters: function () { return [{ type: SnackBarService }]; } });
131
391
 
132
392
  class DialogConfig {
133
393
  }
134
394
 
135
- class SessionExpiredModalComponent {
136
- constructor(dialogConfig, routerService) {
395
+ class ErrorModalComponent {
396
+ constructor(authService, dialogConfig, routerService) {
397
+ this.authService = authService;
137
398
  this.dialogConfig = dialogConfig;
138
399
  this.routerService = routerService;
139
- this.errorConfig = ERROR_CONFIG.SESSION_EXPIRED;
400
+ this.errorType = 'session_expired';
140
401
  this.data = {
141
- header: 'Message',
402
+ heading: 'Message',
142
403
  description: 'Description',
143
404
  buttonText: 'Click Action',
144
405
  };
145
- this.data = this.dialogConfig.data;
406
+ this.setDataConfig();
407
+ }
408
+ setDataConfig() {
409
+ var _a, _b;
410
+ this.data = (_a = this.dialogConfig.data) === null || _a === void 0 ? void 0 : _a.errorConfig;
411
+ this.errorType = (_b = this.dialogConfig.data) === null || _b === void 0 ? void 0 : _b.errorType;
146
412
  }
147
413
  onContinueAction() {
148
- this.routerService.redirectToLogin();
414
+ if (this.errorType === 'session_expired') {
415
+ this.authService.logoutUser();
416
+ this.routerService.redirectToLogin();
417
+ }
418
+ else if (this.errorType === 'chunk_not_found') {
419
+ window.location.reload();
420
+ }
149
421
  }
150
422
  }
151
- SessionExpiredModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SessionExpiredModalComponent, deps: [{ token: DialogConfig }, { token: RouterService }], target: i0.ɵɵFactoryTarget.Component });
152
- SessionExpiredModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: SessionExpiredModalComponent, selector: "lib-vc-error-session-expired-modal", ngImport: i0, template: ` <div class="error-dialog-box">
153
- <div class="error-dialog-box-top">{{ errorConfig.heading }}</div>
423
+ ErrorModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ErrorModalComponent, deps: [{ token: AuthService }, { token: DialogConfig }, { token: RouterService }], target: i0.ɵɵFactoryTarget.Component });
424
+ ErrorModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: ErrorModalComponent, selector: "lib-vc-error-modal", inputs: { errorType: "errorType" }, ngImport: i0, template: ` <div class="error-dialog-box">
425
+ <div class="error-dialog-box-top">{{ data.heading }}</div>
154
426
  <div class="error-dialog-box-mid">
155
- {{ errorConfig.description }}
427
+ {{ data.description }}
156
428
  </div>
157
429
  <div class="error-dialog-box-bottom">
158
430
  <button (click)="onContinueAction()" class="logIn-btn">
159
- {{ errorConfig.buttonText }}
431
+ {{ data.buttonText }}
160
432
  </button>
161
433
  </div>
162
434
  </div>`, isInline: true, styles: [".error-dialog-box{background:#fff;border-radius:.75rem;box-shadow:0 1px 10px #0003;width:27rem}.error-dialog-box-top{color:#000;font-size:16px;font-weight:500;border-radius:.75rem .75rem 0 0;display:flex;align-items:center;height:3.375rem;padding:0 1rem;margin-bottom:1rem}.error-dialog-box-mid{color:#565a6f;font-size:13px;min-height:5.5rem;padding:0 1rem}.error-dialog-box-bottom{display:flex;justify-content:end;padding:1rem}.error-dialog-box-bottom button.logIn-btn{background:#1e5dd3;border-radius:.125rem;border:none;color:#fff;cursor:pointer;font-size:11px;height:2rem;padding:.5rem .75rem}\n"] });
163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SessionExpiredModalComponent, decorators: [{
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ErrorModalComponent, decorators: [{
164
436
  type: Component,
165
- args: [{ selector: 'lib-vc-error-session-expired-modal', template: ` <div class="error-dialog-box">
166
- <div class="error-dialog-box-top">{{ errorConfig.heading }}</div>
437
+ args: [{ selector: 'lib-vc-error-modal', template: ` <div class="error-dialog-box">
438
+ <div class="error-dialog-box-top">{{ data.heading }}</div>
167
439
  <div class="error-dialog-box-mid">
168
- {{ errorConfig.description }}
440
+ {{ data.description }}
169
441
  </div>
170
442
  <div class="error-dialog-box-bottom">
171
443
  <button (click)="onContinueAction()" class="logIn-btn">
172
- {{ errorConfig.buttonText }}
444
+ {{ data.buttonText }}
173
445
  </button>
174
446
  </div>
175
447
  </div>`, styles: [".error-dialog-box{background:#fff;border-radius:.75rem;box-shadow:0 1px 10px #0003;width:27rem}.error-dialog-box-top{color:#000;font-size:16px;font-weight:500;border-radius:.75rem .75rem 0 0;display:flex;align-items:center;height:3.375rem;padding:0 1rem;margin-bottom:1rem}.error-dialog-box-mid{color:#565a6f;font-size:13px;min-height:5.5rem;padding:0 1rem}.error-dialog-box-bottom{display:flex;justify-content:end;padding:1rem}.error-dialog-box-bottom button.logIn-btn{background:#1e5dd3;border-radius:.125rem;border:none;color:#fff;cursor:pointer;font-size:11px;height:2rem;padding:.5rem .75rem}\n"] }]
176
- }], ctorParameters: function () { return [{ type: DialogConfig }, { type: RouterService }]; } });
448
+ }], ctorParameters: function () { return [{ type: AuthService }, { type: DialogConfig }, { type: RouterService }]; }, propDecorators: { errorType: [{
449
+ type: Input
450
+ }] } });
177
451
 
178
452
  class InsertionDirective {
179
453
  constructor(viewContainerRef) {
@@ -267,7 +541,7 @@ class DialogComponent {
267
541
  }
268
542
  }
269
543
  DialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: DialogComponent, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }, { token: DialogRef }, { token: DialogConfig }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
270
- DialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: DialogComponent, selector: "app-dialog", viewQueries: [{ propertyName: "insertionPoint", first: true, predicate: InsertionDirective, descendants: true, static: true }], ngImport: i0, template: "<div\r\n class=\"overlay\"\r\n (click)=\"onOverlayClicked($event)\"\r\n [ngClass]=\"{\r\n top: position === 'TOP',\r\n right: position === 'RIGHT',\r\n bottom: position === 'BOTTOM',\r\n left: position === 'LEFT',\r\n center: position === 'CENTER',\r\n black: background === 'black',\r\n whiteBlur: background === 'whiteBlur'\r\n }\" [class.pointer-none]=\"pointer === 'none'\"\r\n>\r\n <div\r\n class=\"dialog\"\r\n [class.animate]=\"animation\"\r\n (click)=\"onDialogClicked($event)\"\r\n [ngClass]=\"{\r\n top: position === 'TOP',\r\n right: position === 'RIGHT',\r\n bottom: position === 'BOTTOM',\r\n left: position === 'LEFT',\r\n center: position === 'CENTER'\r\n }\"\r\n >\r\n <ng-template appInsertion></ng-template>\r\n </div>\r\n</div>\r\n", styles: [".overlay{display:flex;position:fixed;top:0;bottom:0;left:0;right:0;align-items:center;justify-content:center;z-index:2147483009!important}.overlay.low{z-index:1}.overlay.black{background:#161b2fcc}.overlay.whiteBlur{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.overlay.top{align-items:flex-start}.overlay.right{justify-content:flex-end}.overlay.bottom{align-items:flex-end}.overlay.left{justify-content:flex-start}.dialog{position:relative}.dialog.animate.top{animation:animate-top .2s cubic-bezier(.25,.46,.45,.94) both}@keyframes animate-top{0%{transform:translateY(-100px)}to{transform:translateY(0)}}.dialog.animate.right{animation:animate-right .2s cubic-bezier(.25,.46,.45,.94) both}@keyframes animate-right{0%{transform:translate(100%)}to{transform:translate(0)}}.pointer-none{pointer-events:none}\n"], directives: [{ type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: InsertionDirective, selector: "[appInsertion]" }] });
544
+ DialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: DialogComponent, selector: "app-dialog", viewQueries: [{ propertyName: "insertionPoint", first: true, predicate: InsertionDirective, descendants: true, static: true }], ngImport: i0, template: "<div\r\n class=\"overlay\"\r\n (click)=\"onOverlayClicked($event)\"\r\n [ngClass]=\"{\r\n top: position === 'TOP',\r\n right: position === 'RIGHT',\r\n bottom: position === 'BOTTOM',\r\n left: position === 'LEFT',\r\n center: position === 'CENTER',\r\n black: background === 'black',\r\n whiteBlur: background === 'whiteBlur'\r\n }\" [class.pointer-none]=\"pointer === 'none'\"\r\n>\r\n <div\r\n class=\"dialog\"\r\n [class.animate]=\"animation\"\r\n (click)=\"onDialogClicked($event)\"\r\n [ngClass]=\"{\r\n top: position === 'TOP',\r\n right: position === 'RIGHT',\r\n bottom: position === 'BOTTOM',\r\n left: position === 'LEFT',\r\n center: position === 'CENTER'\r\n }\"\r\n >\r\n <ng-template appInsertion></ng-template>\r\n </div>\r\n</div>\r\n", styles: [".overlay{display:flex;position:fixed;top:0;bottom:0;left:0;right:0;align-items:center;justify-content:center;z-index:2147483009!important}.overlay.low{z-index:1}.overlay.black{background:#161b2fcc}.overlay.whiteBlur{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.overlay.top{align-items:flex-start}.overlay.right{justify-content:flex-end}.overlay.bottom{align-items:flex-end}.overlay.left{justify-content:flex-start}.dialog{position:relative}.dialog.animate.top{animation:animate-top .2s cubic-bezier(.25,.46,.45,.94) both}@keyframes animate-top{0%{transform:translateY(-100px)}to{transform:translateY(0)}}.dialog.animate.right{animation:animate-right .2s cubic-bezier(.25,.46,.45,.94) both}@keyframes animate-right{0%{transform:translate(100%)}to{transform:translate(0)}}.pointer-none{pointer-events:none}\n"], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: InsertionDirective, selector: "[appInsertion]" }] });
271
545
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: DialogComponent, decorators: [{
272
546
  type: Component,
273
547
  args: [{ selector: 'app-dialog', template: "<div\r\n class=\"overlay\"\r\n (click)=\"onOverlayClicked($event)\"\r\n [ngClass]=\"{\r\n top: position === 'TOP',\r\n right: position === 'RIGHT',\r\n bottom: position === 'BOTTOM',\r\n left: position === 'LEFT',\r\n center: position === 'CENTER',\r\n black: background === 'black',\r\n whiteBlur: background === 'whiteBlur'\r\n }\" [class.pointer-none]=\"pointer === 'none'\"\r\n>\r\n <div\r\n class=\"dialog\"\r\n [class.animate]=\"animation\"\r\n (click)=\"onDialogClicked($event)\"\r\n [ngClass]=\"{\r\n top: position === 'TOP',\r\n right: position === 'RIGHT',\r\n bottom: position === 'BOTTOM',\r\n left: position === 'LEFT',\r\n center: position === 'CENTER'\r\n }\"\r\n >\r\n <ng-template appInsertion></ng-template>\r\n </div>\r\n</div>\r\n", styles: [".overlay{display:flex;position:fixed;top:0;bottom:0;left:0;right:0;align-items:center;justify-content:center;z-index:2147483009!important}.overlay.low{z-index:1}.overlay.black{background:#161b2fcc}.overlay.whiteBlur{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.overlay.top{align-items:flex-start}.overlay.right{justify-content:flex-end}.overlay.bottom{align-items:flex-end}.overlay.left{justify-content:flex-start}.dialog{position:relative}.dialog.animate.top{animation:animate-top .2s cubic-bezier(.25,.46,.45,.94) both}@keyframes animate-top{0%{transform:translateY(-100px)}to{transform:translateY(0)}}.dialog.animate.right{animation:animate-right .2s cubic-bezier(.25,.46,.45,.94) both}@keyframes animate-right{0%{transform:translate(100%)}to{transform:translate(0)}}.pointer-none{pointer-events:none}\n"] }]
@@ -352,24 +626,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
352
626
  }], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }]; } });
353
627
 
354
628
  class SessionExpiredComponent {
355
- constructor(authService, dialogService) {
356
- this.authService = authService;
629
+ constructor(dialogService) {
357
630
  this.dialogService = dialogService;
358
631
  this.errorConfig = ERROR_CONFIG.SESSION_EXPIRED;
359
632
  }
360
633
  ngOnInit() {
361
- this.authService.logoutUser();
362
634
  this.openSessionExpiredModal();
363
635
  }
364
636
  openSessionExpiredModal() {
365
- this.dialogService.open(SessionExpiredModalComponent, {
366
- data: this.errorConfig,
637
+ this.dialogService.open(ErrorModalComponent, {
638
+ data: {
639
+ errorType: 'session_expired',
640
+ errorConfig: this.errorConfig,
641
+ },
367
642
  position: 'center',
368
643
  background: 'whiteBlur',
369
644
  });
370
645
  }
371
646
  }
372
- SessionExpiredComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SessionExpiredComponent, deps: [{ token: AuthService }, { token: DialogService }], target: i0.ɵɵFactoryTarget.Component });
647
+ SessionExpiredComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SessionExpiredComponent, deps: [{ token: DialogService }], target: i0.ɵɵFactoryTarget.Component });
373
648
  SessionExpiredComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: SessionExpiredComponent, selector: "lib-vc-error-session-expired", ngImport: i0, template: ``, isInline: true });
374
649
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SessionExpiredComponent, decorators: [{
375
650
  type: Component,
@@ -377,25 +652,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
377
652
  selector: 'lib-vc-error-session-expired',
378
653
  template: ``,
379
654
  }]
380
- }], ctorParameters: function () { return [{ type: AuthService }, { type: DialogService }]; } });
655
+ }], ctorParameters: function () { return [{ type: DialogService }]; } });
381
656
 
382
657
  class UnauthorizedComponent {
383
658
  constructor() {
659
+ this.currentYear = new Date().getFullYear();
384
660
  this.errorConfig = ERROR_CONFIG.UNAUTHORIZED;
385
- this.VcomplyImage = VCOMPLY_IMAGE_URL;
661
+ this.VcomplyLogo = VCOMPLY_LOGO_URL;
662
+ }
663
+ redirectToSupport() {
664
+ window.location.href = this.errorConfig.mail;
386
665
  }
387
- redirectToSupport() { }
388
666
  }
389
667
  UnauthorizedComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: UnauthorizedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
390
668
  UnauthorizedComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: UnauthorizedComponent, selector: "lib-vc-error-unauthorized", ngImport: i0, template: `
391
669
  <div class="errorPage">
392
670
  <div class="errorPage-top">
393
- <img
394
- src="https://cdn.v-comply.com/logo/prod/v-logo.svg"
395
- alt="VComply"
396
- width="24"
397
- height="24"
398
- />
671
+ <img [src]="VcomplyLogo" alt="VComply" width="24" height="24" />
399
672
  </div>
400
673
  <div class="errorPage-container">
401
674
  <div class="errorPage-inner">
@@ -403,8 +676,8 @@ UnauthorizedComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
403
676
  <img
404
677
  [src]="errorConfig.imageUrl"
405
678
  alt="Error Image"
406
- width="256"
407
- height="256"
679
+ width="246"
680
+ height="178"
408
681
  />
409
682
  </div>
410
683
  <div class="errorPage-inner-right">
@@ -420,20 +693,18 @@ UnauthorizedComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
420
693
  </button>
421
694
  </div>
422
695
  </div>
696
+ <div class="errorPage-copyright">
697
+ &copy;&nbsp;{{ currentYear }}, VCOMPLY TECHNOLOGIES, INC.
698
+ </div>
423
699
  </div>
424
700
  </div>
425
- `, isInline: true, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}\n"] });
701
+ `, isInline: true, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem;position:relative}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}.errorPage-copyright{font-size:11px;color:#787a8c;font-weight:500;position:absolute;bottom:8px;right:16px;line-height:16px}\n"] });
426
702
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: UnauthorizedComponent, decorators: [{
427
703
  type: Component,
428
704
  args: [{ selector: 'lib-vc-error-unauthorized', template: `
429
705
  <div class="errorPage">
430
706
  <div class="errorPage-top">
431
- <img
432
- src="https://cdn.v-comply.com/logo/prod/v-logo.svg"
433
- alt="VComply"
434
- width="24"
435
- height="24"
436
- />
707
+ <img [src]="VcomplyLogo" alt="VComply" width="24" height="24" />
437
708
  </div>
438
709
  <div class="errorPage-container">
439
710
  <div class="errorPage-inner">
@@ -441,8 +712,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
441
712
  <img
442
713
  [src]="errorConfig.imageUrl"
443
714
  alt="Error Image"
444
- width="256"
445
- height="256"
715
+ width="246"
716
+ height="178"
446
717
  />
447
718
  </div>
448
719
  <div class="errorPage-inner-right">
@@ -458,19 +729,138 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
458
729
  </button>
459
730
  </div>
460
731
  </div>
732
+ <div class="errorPage-copyright">
733
+ &copy;&nbsp;{{ currentYear }}, VCOMPLY TECHNOLOGIES, INC.
734
+ </div>
735
+ </div>
736
+ </div>
737
+ `, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem;position:relative}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}.errorPage-copyright{font-size:11px;color:#787a8c;font-weight:500;position:absolute;bottom:8px;right:16px;line-height:16px}\n"] }]
738
+ }] });
739
+
740
+ class ChunkUnavailableComponent {
741
+ constructor(dialogService) {
742
+ this.dialogService = dialogService;
743
+ this.errorConfig = ERROR_CONFIG.CHUNK_UNAVAILABLE;
744
+ }
745
+ ngOnInit() {
746
+ this.openSessionExpiredModal();
747
+ }
748
+ openSessionExpiredModal() {
749
+ this.dialogService.open(ErrorModalComponent, {
750
+ data: {
751
+ errorType: 'chunk_not_found',
752
+ errorConfig: this.errorConfig,
753
+ },
754
+ position: 'center',
755
+ background: 'whiteBlur',
756
+ });
757
+ }
758
+ }
759
+ ChunkUnavailableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChunkUnavailableComponent, deps: [{ token: DialogService }], target: i0.ɵɵFactoryTarget.Component });
760
+ ChunkUnavailableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: ChunkUnavailableComponent, selector: "lib-vc-error-chunk-unavailable", ngImport: i0, template: ``, isInline: true });
761
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChunkUnavailableComponent, decorators: [{
762
+ type: Component,
763
+ args: [{
764
+ selector: 'lib-vc-error-chunk-unavailable',
765
+ template: ``,
766
+ }]
767
+ }], ctorParameters: function () { return [{ type: DialogService }]; } });
768
+
769
+ class ServerErrorComponent {
770
+ constructor() {
771
+ this.errorConfig = ERROR_CONFIG.SERVER_ERROR;
772
+ this.VcomplyLogo = VCOMPLY_LOGO_URL;
773
+ }
774
+ refreshPage() {
775
+ window.location.reload();
776
+ }
777
+ }
778
+ ServerErrorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ServerErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
779
+ ServerErrorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: ServerErrorComponent, selector: "lib-vc-error-server-error", ngImport: i0, template: `
780
+ <div class="errorPage">
781
+ <div class="errorPage-top">
782
+ <img [src]="VcomplyLogo" alt="VComply" width="24" height="24" />
783
+ </div>
784
+ <div class="errorPage-container">
785
+ <div class="errorPage-inner">
786
+ <div class="errorPage-inner-image">
787
+ <img
788
+ [src]="errorConfig.imageUrl"
789
+ alt="Error Image"
790
+ width="246"
791
+ height="178"
792
+ />
793
+ </div>
794
+ <div class="errorPage-inner-right">
795
+ <div class="errorPage-heading">{{ errorConfig.title }}</div>
796
+ <div class="errorPage-text">{{ errorConfig.description }}</div>
797
+ <div class="errorPage-details">{{ errorConfig.details }}</div>
798
+ <button class="errorPage-btn" (click)="refreshPage()">
799
+ {{ errorConfig.buttonText }} <i class="icons">&#xe92b;</i>
800
+ </button>
801
+ </div>
802
+ </div>
461
803
  </div>
462
804
  </div>
463
- `, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}\n"] }]
805
+ `, isInline: true, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem;position:relative}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}.errorPage-copyright{font-size:11px;color:#787a8c;font-weight:500;position:absolute;bottom:8px;right:16px;line-height:16px}\n"] });
806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ServerErrorComponent, decorators: [{
807
+ type: Component,
808
+ args: [{ selector: 'lib-vc-error-server-error', template: `
809
+ <div class="errorPage">
810
+ <div class="errorPage-top">
811
+ <img [src]="VcomplyLogo" alt="VComply" width="24" height="24" />
812
+ </div>
813
+ <div class="errorPage-container">
814
+ <div class="errorPage-inner">
815
+ <div class="errorPage-inner-image">
816
+ <img
817
+ [src]="errorConfig.imageUrl"
818
+ alt="Error Image"
819
+ width="246"
820
+ height="178"
821
+ />
822
+ </div>
823
+ <div class="errorPage-inner-right">
824
+ <div class="errorPage-heading">{{ errorConfig.title }}</div>
825
+ <div class="errorPage-text">{{ errorConfig.description }}</div>
826
+ <div class="errorPage-details">{{ errorConfig.details }}</div>
827
+ <button class="errorPage-btn" (click)="refreshPage()">
828
+ {{ errorConfig.buttonText }} <i class="icons">&#xe92b;</i>
829
+ </button>
830
+ </div>
831
+ </div>
832
+ </div>
833
+ </div>
834
+ `, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem;position:relative}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}.errorPage-copyright{font-size:11px;color:#787a8c;font-weight:500;position:absolute;bottom:8px;right:16px;line-height:16px}\n"] }]
464
835
  }] });
465
836
 
466
837
  class VcErrorHandlersComponent {
467
- constructor(errorService) {
838
+ constructor(errorService, snackBarService) {
468
839
  this.errorService = errorService;
840
+ this.snackBarService = snackBarService;
841
+ this.errorConfig = ERROR_CONFIG.NETWORK_UNAVAILABLE;
469
842
  this.unauthorized = false;
470
843
  this.sessionExpired = false;
471
- this.networkUnavailable = false;
844
+ this.chunkUnavailable = false;
845
+ this.serverError = false;
846
+ this.isOnline = navigator.onLine;
847
+ this.onNetworkOnline = () => {
848
+ this.isOnline = true;
849
+ this.hideSnackBar();
850
+ };
851
+ this.onNetworkOffline = () => {
852
+ this.isOnline = false;
853
+ this.showOfflineSnackBar();
854
+ };
472
855
  this.subscribeGlobalError();
473
856
  }
857
+ ngOnInit() {
858
+ this.subscribeNetworkDetection();
859
+ }
860
+ ngOnDestroy() {
861
+ window.removeEventListener('online', this.onNetworkOnline);
862
+ window.removeEventListener('offline', this.onNetworkOffline);
863
+ }
474
864
  subscribeGlobalError() {
475
865
  this.errorService.globalError$.subscribe((error) => {
476
866
  this.handleError(error);
@@ -483,50 +873,81 @@ class VcErrorHandlersComponent {
483
873
  else if (error.status === ErrorStatusCode.UnauthorizedAccess) {
484
874
  this.unauthorized = true;
485
875
  }
876
+ else if (error.status === ErrorStatusCode.JSChunkUnavailable) {
877
+ this.chunkUnavailable = true;
878
+ }
486
879
  else if (error.status === ErrorStatusCode.NetworkUnavailable) {
487
- this.networkUnavailable = true;
880
+ this.handleNetworkError();
881
+ }
882
+ else if (this.errorService.isServerError(error)) {
883
+ this.serverError = true;
488
884
  }
489
885
  }
886
+ subscribeNetworkDetection() {
887
+ window.addEventListener('online', this.onNetworkOnline);
888
+ window.addEventListener('offline', this.onNetworkOffline);
889
+ }
890
+ handleNetworkError() {
891
+ if (!this.isOnline) {
892
+ this.showOfflineSnackBar();
893
+ }
894
+ }
895
+ showOfflineSnackBar() {
896
+ this.snackBarService.show(this.errorConfig.offlineMessage, 'error');
897
+ }
898
+ hideSnackBar() {
899
+ this.snackBarService.hide();
900
+ }
490
901
  }
491
- VcErrorHandlersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: VcErrorHandlersComponent, deps: [{ token: GlobalErrorService }], target: i0.ɵɵFactoryTarget.Component });
902
+ VcErrorHandlersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: VcErrorHandlersComponent, deps: [{ token: GlobalErrorService }, { token: SnackBarService }], target: i0.ɵɵFactoryTarget.Component });
492
903
  VcErrorHandlersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: VcErrorHandlersComponent, selector: "lib-vc-error-handlers", ngImport: i0, template: `
904
+ <app-snack-bar></app-snack-bar>
493
905
  <lib-vc-error-session-expired
494
906
  *ngIf="sessionExpired"
495
907
  ></lib-vc-error-session-expired>
496
908
  <lib-vc-error-unauthorized *ngIf="unauthorized"></lib-vc-error-unauthorized>
497
- `, isInline: true, components: [{ type: SessionExpiredComponent, selector: "lib-vc-error-session-expired" }, { type: UnauthorizedComponent, selector: "lib-vc-error-unauthorized" }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
909
+ <lib-vc-error-chunk-unavailable
910
+ *ngIf="chunkUnavailable"
911
+ ></lib-vc-error-chunk-unavailable>
912
+ <lib-vc-error-server-error *ngIf="serverError"></lib-vc-error-server-error>
913
+ `, isInline: true, components: [{ type: SnackBarComponent, selector: "app-snack-bar" }, { type: SessionExpiredComponent, selector: "lib-vc-error-session-expired" }, { type: UnauthorizedComponent, selector: "lib-vc-error-unauthorized" }, { type: ChunkUnavailableComponent, selector: "lib-vc-error-chunk-unavailable" }, { type: ServerErrorComponent, selector: "lib-vc-error-server-error" }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
498
914
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: VcErrorHandlersComponent, decorators: [{
499
915
  type: Component,
500
916
  args: [{
501
917
  selector: 'lib-vc-error-handlers',
502
918
  template: `
919
+ <app-snack-bar></app-snack-bar>
503
920
  <lib-vc-error-session-expired
504
921
  *ngIf="sessionExpired"
505
922
  ></lib-vc-error-session-expired>
506
923
  <lib-vc-error-unauthorized *ngIf="unauthorized"></lib-vc-error-unauthorized>
924
+ <lib-vc-error-chunk-unavailable
925
+ *ngIf="chunkUnavailable"
926
+ ></lib-vc-error-chunk-unavailable>
927
+ <lib-vc-error-server-error *ngIf="serverError"></lib-vc-error-server-error>
507
928
  `,
508
929
  }]
509
- }], ctorParameters: function () { return [{ type: GlobalErrorService }]; } });
930
+ }], ctorParameters: function () { return [{ type: GlobalErrorService }, { type: SnackBarService }]; } });
510
931
 
511
932
  class PageNotFoundComponent {
512
- constructor() {
933
+ constructor(router) {
934
+ this.router = router;
513
935
  this.errorConfig = ERROR_CONFIG.PAGE_NOT_FOUND;
514
- this.VcomplyImage = VCOMPLY_IMAGE_URL;
936
+ this.VcomplyLogo = VCOMPLY_LOGO_URL;
937
+ this.currentYear = new Date().getFullYear();
515
938
  }
516
939
  redirectToHome() {
517
- // Redirect to home page
940
+ const currentUrl = window.location.href;
941
+ if (currentUrl.includes('organization')) {
942
+ this.router.navigate(['/global-dashboard/compliance_dashboard']);
943
+ }
518
944
  }
519
945
  }
520
- PageNotFoundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: PageNotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
946
+ PageNotFoundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: PageNotFoundComponent, deps: [{ token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
521
947
  PageNotFoundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: PageNotFoundComponent, selector: "lib-vc-error-page-not-found", ngImport: i0, template: `
522
948
  <div class="errorPage">
523
949
  <div class="errorPage-top">
524
- <img
525
- src="https://cdn.v-comply.com/logo/prod/v-logo.svg"
526
- alt="VComply"
527
- width="24"
528
- height="24"
529
- />
950
+ <img [src]="VcomplyLogo" alt="VComply" width="24" height="24" />
530
951
  </div>
531
952
  <div class="errorPage-container">
532
953
  <div class="errorPage-inner">
@@ -534,8 +955,8 @@ PageNotFoundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
534
955
  <img
535
956
  [src]="errorConfig.imageUrl"
536
957
  alt="Error Image"
537
- width="256"
538
- height="256"
958
+ width="246"
959
+ height="178"
539
960
  />
540
961
  </div>
541
962
  <div class="errorPage-inner-right">
@@ -547,20 +968,18 @@ PageNotFoundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
547
968
  </button>
548
969
  </div>
549
970
  </div>
971
+ <div class="errorPage-copyright">
972
+ &copy;&nbsp;{{ currentYear }}, VCOMPLY TECHNOLOGIES, INC.
973
+ </div>
550
974
  </div>
551
975
  </div>
552
- `, isInline: true, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}\n"] });
976
+ `, isInline: true, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem;position:relative}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}.errorPage-copyright{font-size:11px;color:#787a8c;font-weight:500;position:absolute;bottom:8px;right:16px;line-height:16px}\n"] });
553
977
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: PageNotFoundComponent, decorators: [{
554
978
  type: Component,
555
979
  args: [{ selector: 'lib-vc-error-page-not-found', template: `
556
980
  <div class="errorPage">
557
981
  <div class="errorPage-top">
558
- <img
559
- src="https://cdn.v-comply.com/logo/prod/v-logo.svg"
560
- alt="VComply"
561
- width="24"
562
- height="24"
563
- />
982
+ <img [src]="VcomplyLogo" alt="VComply" width="24" height="24" />
564
983
  </div>
565
984
  <div class="errorPage-container">
566
985
  <div class="errorPage-inner">
@@ -568,8 +987,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
568
987
  <img
569
988
  [src]="errorConfig.imageUrl"
570
989
  alt="Error Image"
571
- width="256"
572
- height="256"
990
+ width="246"
991
+ height="178"
573
992
  />
574
993
  </div>
575
994
  <div class="errorPage-inner-right">
@@ -581,110 +1000,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
581
1000
  </button>
582
1001
  </div>
583
1002
  </div>
1003
+ <div class="errorPage-copyright">
1004
+ &copy;&nbsp;{{ currentYear }}, VCOMPLY TECHNOLOGIES, INC.
1005
+ </div>
584
1006
  </div>
585
1007
  </div>
586
- `, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}\n"] }]
587
- }] });
588
-
589
- class ChunkUnavailableComponent {
590
- constructor() { }
591
- ngOnInit() {
592
- }
593
- }
594
- ChunkUnavailableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChunkUnavailableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
595
- ChunkUnavailableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: ChunkUnavailableComponent, selector: "lib-chunk-unavailable", ngImport: i0, template: "<p>chunk-unavailable works!</p>\r\n", styles: [""] });
596
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChunkUnavailableComponent, decorators: [{
597
- type: Component,
598
- args: [{ selector: 'lib-chunk-unavailable', template: "<p>chunk-unavailable works!</p>\r\n", styles: [""] }]
599
- }], ctorParameters: function () { return []; } });
600
-
601
- class ServerErrorComponent {
602
- constructor() { }
603
- ngOnInit() {
604
- }
605
- }
606
- ServerErrorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ServerErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
607
- ServerErrorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: ServerErrorComponent, selector: "lib-server-error", ngImport: i0, template: "<p>server-error works!</p>\r\n", styles: [""] });
608
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ServerErrorComponent, decorators: [{
609
- type: Component,
610
- args: [{ selector: 'lib-server-error', template: "<p>server-error works!</p>\r\n", styles: [""] }]
611
- }], ctorParameters: function () { return []; } });
612
-
613
- class SnackBarService {
614
- constructor() {
615
- this.snackbarSubject = new Subject();
616
- this.snackbarState = this.snackbarSubject.asObservable();
617
- }
618
- show(message, type) {
619
- this.snackbarSubject.next({
620
- show: true,
621
- message,
622
- icon: type,
623
- });
624
- }
625
- hide() {
626
- this.snackbarSubject.next({
627
- show: false,
628
- message: '',
629
- icon: '',
630
- });
631
- }
632
- }
633
- SnackBarService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
634
- SnackBarService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarService, providedIn: 'root' });
635
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarService, decorators: [{
636
- type: Injectable,
637
- args: [{
638
- providedIn: 'root',
639
- }]
640
- }], ctorParameters: function () { return []; } });
641
-
642
- class SnackBarComponent {
643
- constructor(snackbarService) {
644
- this.snackbarService = snackbarService;
645
- this.show = false;
646
- this.message = '--';
647
- this.icon = '&#xe914;';
648
- this.type = 'alert';
649
- this.icons = {
650
- success: '&#xe93d;',
651
- warning: '&#xe914;',
652
- info: '&#xe932;',
653
- alert: '&#xe914;',
654
- error: '&#xeaae;',
655
- };
656
- }
657
- ngOnInit() {
658
- this.snackbarSubscription = this.snackbarService.snackbarState.subscribe((state) => {
659
- if (state.icon && Object.keys(this.icons).includes(state === null || state === void 0 ? void 0 : state.icon)) {
660
- this.icon = this.icons[state.icon];
661
- this.type = state === null || state === void 0 ? void 0 : state.icon;
662
- }
663
- this.message = state.message;
664
- this.show = state.show;
665
- this.setAutoClose();
666
- });
667
- }
668
- setAutoClose() {
669
- setTimeout(() => {
670
- this.show = false;
671
- this.close();
672
- }, 3000);
673
- }
674
- close() {
675
- this.show = false;
676
- this.snackbarService.hide();
677
- }
678
- ngOnDestroy() {
679
- this.snackbarSubscription.unsubscribe();
680
- }
681
- }
682
- SnackBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarComponent, deps: [{ token: SnackBarService }], target: i0.ɵɵFactoryTarget.Component });
683
- SnackBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: SnackBarComponent, selector: "app-snack-bar", ngImport: i0, template: "<div class=\"workflow-snackbar\" *ngIf=\"show\">\r\n <div class=\"workflow-snackbar-inner\">\r\n <div class=\"workflow-snackbarText\">\r\n <!-- &#xe914; -->\r\n <i class=\"icons\" [class]=\"type\" [innerHTML]=\"icon\"></i> <span [innerHTML]=\"message\">{{ message }}</span>\r\n </div>\r\n <button (click)=\"close()\">[ <span>Close</span> ]</button>\r\n </div>\r\n </div>", styles: ["::ng-deep .workflow-snackbar{position:fixed;top:20px;left:0;right:0;display:flex;align-items:center;justify-content:center;z-index:2147483647!important;pointer-events:none;animation:slide-top .3s cubic-bezier(.25,.46,.45,.94) both}::ng-deep .workflow-snackbar.white{background-color:#fff;color:#000;z-index:20}::ng-deep .workflow-snackbar.white button{color:#f6882f;font-size:11px;font-weight:400;pointer-events:all}::ng-deep .workflow-snackbar .workflow-snackbar-inner{display:flex;max-width:500px;min-width:450px;align-items:center;justify-content:space-between;padding:10px;background:#ffffff;border-radius:3px;box-shadow:0 0 10px #0003;min-height:55px;pointer-events:auto}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText{color:#161b2f;font-size:13px;display:flex;align-items:center;width:calc(100% - 70px)}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i{background:#f1f1f1;color:#d93b41;border-radius:50px;font-size:16px;width:30px;height:30px;text-align:center;line-height:28px;margin-right:10px;min-width:30px}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.success{color:#34aa44}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.warning{color:#f0b819}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.info{color:#1e5dd3}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.alert,::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.error{color:#d93b41}::ng-deep .workflow-snackbar .workflow-snackbar-inner button{background:transparent;border:none;font-size:11px;padding:0;position:relative;color:#747576;width:65px;text-align:right;cursor:pointer;text-transform:uppercase}::ng-deep .workflow-snackbar .workflow-snackbar-inner button span{color:#1e5dd3;font-weight:500}::ng-deep .workflow-snackbar .workflow-snackbar-inner button:focus{outline:none}@keyframes slide-top{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}\n"], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
684
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SnackBarComponent, decorators: [{
685
- type: Component,
686
- args: [{ selector: 'app-snack-bar', template: "<div class=\"workflow-snackbar\" *ngIf=\"show\">\r\n <div class=\"workflow-snackbar-inner\">\r\n <div class=\"workflow-snackbarText\">\r\n <!-- &#xe914; -->\r\n <i class=\"icons\" [class]=\"type\" [innerHTML]=\"icon\"></i> <span [innerHTML]=\"message\">{{ message }}</span>\r\n </div>\r\n <button (click)=\"close()\">[ <span>Close</span> ]</button>\r\n </div>\r\n </div>", styles: ["::ng-deep .workflow-snackbar{position:fixed;top:20px;left:0;right:0;display:flex;align-items:center;justify-content:center;z-index:2147483647!important;pointer-events:none;animation:slide-top .3s cubic-bezier(.25,.46,.45,.94) both}::ng-deep .workflow-snackbar.white{background-color:#fff;color:#000;z-index:20}::ng-deep .workflow-snackbar.white button{color:#f6882f;font-size:11px;font-weight:400;pointer-events:all}::ng-deep .workflow-snackbar .workflow-snackbar-inner{display:flex;max-width:500px;min-width:450px;align-items:center;justify-content:space-between;padding:10px;background:#ffffff;border-radius:3px;box-shadow:0 0 10px #0003;min-height:55px;pointer-events:auto}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText{color:#161b2f;font-size:13px;display:flex;align-items:center;width:calc(100% - 70px)}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i{background:#f1f1f1;color:#d93b41;border-radius:50px;font-size:16px;width:30px;height:30px;text-align:center;line-height:28px;margin-right:10px;min-width:30px}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.success{color:#34aa44}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.warning{color:#f0b819}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.info{color:#1e5dd3}::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.alert,::ng-deep .workflow-snackbar .workflow-snackbar-inner .workflow-snackbarText i.error{color:#d93b41}::ng-deep .workflow-snackbar .workflow-snackbar-inner button{background:transparent;border:none;font-size:11px;padding:0;position:relative;color:#747576;width:65px;text-align:right;cursor:pointer;text-transform:uppercase}::ng-deep .workflow-snackbar .workflow-snackbar-inner button span{color:#1e5dd3;font-weight:500}::ng-deep .workflow-snackbar .workflow-snackbar-inner button:focus{outline:none}@keyframes slide-top{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}\n"] }]
687
- }], ctorParameters: function () { return [{ type: SnackBarService }]; } });
1008
+ `, styles: ["@import\"https://cdn.v-comply.com/design-system/css/icons/icons.css\";.errorPage{background:#161b2f;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999}.errorPage-top{width:100%;height:3rem;display:flex;align-items:center;padding-left:.75rem}.errorPage-container{background:#f2f2f5;border-radius:.75rem;border:1px solid #e3e3e9;box-shadow:0 4px 8px #1d5dd31a;height:calc(100vh - 3.75rem);display:flex;align-items:center;justify-content:center;padding:0 4rem;margin:0 .75rem;position:relative}.errorPage-inner{display:flex;align-items:center}.errorPage-inner-image{width:16rem}.errorPage-inner-right{margin-left:2rem;width:calc(100% - 18rem)}.errorPage-inner-right .errorPage-heading{-webkit-text-fill-color:#e3e3e9;-webkit-text-stroke-color:#a9aab6;-webkit-text-stroke-width:1px;color:#e3e3e9;font-size:78px;font-weight:bold;line-height:110px;margin-bottom:1.5rem}.errorPage-inner-right .errorPage-text{color:#141724;font-size:19px;font-weight:500;line-height:1.75rem;margin-bottom:.5rem}.errorPage-inner-right .errorPage-details{color:#565a6f;font-size:13px;line-height:20px;margin-bottom:1.75rem}.errorPage-inner-right .errorPage-btn{background:#1e5dd3;border-radius:.25rem;border:none;color:#fff;display:inline-flex;align-items:center;font-size:11px;font-weight:500;line-height:2rem;padding:0 1rem}.errorPage-inner-right .errorPage-btn i{font-size:14px;margin-left:.25rem}.errorPage-copyright{font-size:11px;color:#787a8c;font-weight:500;position:absolute;bottom:8px;right:16px;line-height:16px}\n"] }]
1009
+ }], ctorParameters: function () { return [{ type: i3.Router }]; } });
688
1010
 
689
1011
  class SnackBarModule {
690
1012
  }
@@ -707,8 +1029,9 @@ class Configurations {
707
1029
  }
708
1030
 
709
1031
  class SentryErrorHandler {
710
- constructor(authorizerService, config) {
1032
+ constructor(authorizerService, errorService, config) {
711
1033
  this.authorizerService = authorizerService;
1034
+ this.errorService = errorService;
712
1035
  if (config === null || config === void 0 ? void 0 : config.sentryConfig) {
713
1036
  const SENTRY_CONFIG = config.sentryConfig;
714
1037
  Sentry.init({
@@ -728,22 +1051,24 @@ class SentryErrorHandler {
728
1051
  }
729
1052
  handleError(error) {
730
1053
  const ERROR = (error === null || error === void 0 ? void 0 : error.originalError) || error;
731
- this.handleChunkError(ERROR);
1054
+ this.handleChunkNotFoundError(ERROR);
732
1055
  Sentry.captureException(ERROR);
733
1056
  }
734
- handleChunkError(error) {
735
- const chunkFailedMessage = /Loading chunk [\d]+ failed/;
736
- if (chunkFailedMessage.test(error === null || error === void 0 ? void 0 : error.message)) {
737
- window.location.reload();
1057
+ handleChunkNotFoundError(error) {
1058
+ const failedMessage = /Loading chunk [\d]+ failed/;
1059
+ if (failedMessage.test(error.message)) {
1060
+ this.errorService.globalError$.next({
1061
+ status: ErrorStatusCode.JSChunkUnavailable,
1062
+ });
738
1063
  }
739
1064
  }
740
1065
  }
741
- SentryErrorHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SentryErrorHandler, deps: [{ token: i1.AuthorizerService }, { token: Configurations, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1066
+ SentryErrorHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SentryErrorHandler, deps: [{ token: i1.AuthorizerService }, { token: GlobalErrorService }, { token: Configurations, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
742
1067
  SentryErrorHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SentryErrorHandler });
743
1068
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: SentryErrorHandler, decorators: [{
744
1069
  type: Injectable
745
1070
  }], ctorParameters: function () {
746
- return [{ type: i1.AuthorizerService }, { type: Configurations, decorators: [{
1071
+ return [{ type: i1.AuthorizerService }, { type: GlobalErrorService }, { type: Configurations, decorators: [{
747
1072
  type: Optional
748
1073
  }] }];
749
1074
  } });
@@ -753,7 +1078,11 @@ class HttpReqInterceptor {
753
1078
  this.errorService = errorService;
754
1079
  }
755
1080
  intercept(req, next) {
756
- return next.handle(req).pipe(timeout(API_TIMEOUT_TIME), catchError((error) => {
1081
+ return next.handle(req).pipe(timeout(API_TIMEOUT_TIME), tap((event) => {
1082
+ if (event instanceof HttpResponse) {
1083
+ this.errorService.handleSoftErrors(event);
1084
+ }
1085
+ }), catchError((error) => {
757
1086
  this.errorService.handleError(error, req);
758
1087
  return throwError(error);
759
1088
  }));
@@ -781,13 +1110,13 @@ VcErrorHandlersModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", v
781
1110
  SessionExpiredComponent,
782
1111
  ChunkUnavailableComponent,
783
1112
  ServerErrorComponent,
784
- SessionExpiredModalComponent], imports: [CommonModule, DialogModule, SnackBarModule], exports: [VcErrorHandlersComponent,
1113
+ ErrorModalComponent], imports: [CommonModule, DialogModule, SnackBarModule], exports: [VcErrorHandlersComponent,
785
1114
  PageNotFoundComponent,
786
1115
  UnauthorizedComponent,
787
1116
  SessionExpiredComponent,
788
1117
  ChunkUnavailableComponent,
789
1118
  ServerErrorComponent,
790
- SessionExpiredModalComponent] });
1119
+ ErrorModalComponent] });
791
1120
  VcErrorHandlersModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: VcErrorHandlersModule, providers: [
792
1121
  { provide: ErrorHandler, useClass: SentryErrorHandler },
793
1122
  { provide: HTTP_INTERCEPTORS, useClass: HttpReqInterceptor, multi: true },
@@ -802,7 +1131,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
802
1131
  SessionExpiredComponent,
803
1132
  ChunkUnavailableComponent,
804
1133
  ServerErrorComponent,
805
- SessionExpiredModalComponent,
1134
+ ErrorModalComponent,
806
1135
  ],
807
1136
  imports: [CommonModule, DialogModule, SnackBarModule],
808
1137
  exports: [
@@ -812,7 +1141,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
812
1141
  SessionExpiredComponent,
813
1142
  ChunkUnavailableComponent,
814
1143
  ServerErrorComponent,
815
- SessionExpiredModalComponent,
1144
+ ErrorModalComponent,
816
1145
  ],
817
1146
  providers: [
818
1147
  { provide: ErrorHandler, useClass: SentryErrorHandler },
@@ -830,5 +1159,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
830
1159
  * Generated bundle index. Do not edit.
831
1160
  */
832
1161
 
833
- export { AuthService, ChunkUnavailableComponent, FOR_ROOT_SENTRY_OPTIONS_TOKEN, GlobalErrorService, HttpReqInterceptor, PageNotFoundComponent, RouterService, ServerErrorComponent, SessionExpiredComponent, SessionExpiredModalComponent, UnauthorizedComponent, VcErrorHandlersComponent, VcErrorHandlersModule, VcErrorHandlersService };
1162
+ export { AuthService, ChunkUnavailableComponent, ErrorModalComponent, FOR_ROOT_SENTRY_OPTIONS_TOKEN, GlobalErrorService, HttpReqInterceptor, PageNotFoundComponent, RouterService, ServerErrorComponent, SessionExpiredComponent, UnauthorizedComponent, VcErrorHandlersComponent, VcErrorHandlersModule, VcErrorHandlersService };
834
1163
  //# sourceMappingURL=vc-error-handlers.mjs.map