ngx-cho-common 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/esm2022/lib/guards/feature-guard.service.mjs +32 -0
- package/esm2022/lib/guards/unsaved-changes.guard.mjs +13 -0
- package/esm2022/lib/logging/console-logger.sink.mjs +27 -0
- package/esm2022/lib/logging/logger-sink-configuration.interface.mjs +2 -0
- package/esm2022/lib/logging/logger-sink.interface.mjs +2 -0
- package/esm2022/lib/logging/logger.model.mjs +3 -0
- package/esm2022/lib/logging/logger.service.mjs +127 -0
- package/esm2022/lib/logging/models/client-log-entry.interface.mjs +2 -0
- package/esm2022/lib/logging/models/severity-level.enum.mjs +9 -0
- package/esm2022/lib/logging/server-logger.sink.mjs +51 -0
- package/esm2022/lib/models/deactivatable.interface.mjs +2 -0
- package/esm2022/lib/models/uuid.model.mjs +32 -0
- package/esm2022/lib/security/auth-callback/auth-callback.component.mjs +18 -0
- package/esm2022/lib/security/models/auth-user.model.mjs +84 -0
- package/esm2022/lib/security/models/authorization-context.model.mjs +6 -0
- package/esm2022/lib/security/models/security-policy.model.mjs +15 -0
- package/esm2022/lib/security/security-policies.mjs +3 -0
- package/esm2022/lib/security/services/auth-guard.service.mjs +32 -0
- package/esm2022/lib/security/services/auth.service.mjs +131 -0
- package/esm2022/lib/security/signin/signin.component.mjs +18 -0
- package/esm2022/lib/security/signout/signout.component.mjs +18 -0
- package/esm2022/lib/services/date.service.mjs +40 -0
- package/esm2022/lib/services/download.service.mjs +49 -0
- package/esm2022/lib/services/feature.service.mjs +66 -0
- package/esm2022/lib/services/interval.service.mjs +115 -0
- package/esm2022/lib/services/local-storage.service.mjs +29 -0
- package/esm2022/lib/services/modal.service.mjs +34 -0
- package/esm2022/lib/services/navigation.service.mjs +45 -0
- package/esm2022/lib/services/object.service.mjs +33 -0
- package/esm2022/lib/services/rest-client.service.mjs +136 -0
- package/esm2022/lib/services/route-param.service.mjs +53 -0
- package/esm2022/lib/services/session-storage.service.mjs +29 -0
- package/esm2022/lib/types/indexable.type.mjs +2 -0
- package/esm2022/lib/types/name-value-item.type.mjs +2 -0
- package/esm2022/ngx-cho-common.mjs +5 -0
- package/esm2022/public-api.mjs +32 -0
- package/fesm2022/ngx-cho-common.mjs +1196 -0
- package/fesm2022/ngx-cho-common.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/guards/feature-guard.service.d.ts +14 -0
- package/lib/guards/unsaved-changes.guard.d.ts +11 -0
- package/lib/logging/console-logger.sink.d.ts +10 -0
- package/lib/logging/logger-sink-configuration.interface.d.ts +14 -0
- package/lib/logging/logger-sink.interface.d.ts +7 -0
- package/lib/logging/logger.model.d.ts +10 -0
- package/lib/logging/logger.service.d.ts +29 -0
- package/lib/logging/models/client-log-entry.interface.d.ts +10 -0
- package/lib/logging/models/severity-level.enum.d.ts +7 -0
- package/lib/logging/server-logger.sink.d.ts +27 -0
- package/lib/models/deactivatable.interface.d.ts +4 -0
- package/lib/models/uuid.model.d.ts +4 -0
- package/lib/security/auth-callback/auth-callback.component.d.ts +10 -0
- package/lib/security/models/auth-user.model.d.ts +57 -0
- package/lib/security/models/authorization-context.model.d.ts +5 -0
- package/lib/security/models/security-policy.model.d.ts +9 -0
- package/lib/security/security-policies.d.ts +3 -0
- package/lib/security/services/auth-guard.service.d.ts +12 -0
- package/lib/security/services/auth.service.d.ts +60 -0
- package/lib/security/signin/signin.component.d.ts +10 -0
- package/lib/security/signout/signout.component.d.ts +10 -0
- package/lib/services/date.service.d.ts +11 -0
- package/lib/services/download.service.d.ts +13 -0
- package/lib/services/feature.service.d.ts +40 -0
- package/lib/services/interval.service.d.ts +37 -0
- package/lib/services/local-storage.service.d.ts +9 -0
- package/lib/services/modal.service.d.ts +12 -0
- package/lib/services/navigation.service.d.ts +14 -0
- package/lib/services/object.service.d.ts +14 -0
- package/lib/services/rest-client.service.d.ts +88 -0
- package/lib/services/route-param.service.d.ts +17 -0
- package/lib/services/session-storage.service.d.ts +9 -0
- package/lib/types/indexable.type.d.ts +6 -0
- package/lib/types/name-value-item.type.d.ts +5 -0
- package/package.json +30 -0
- package/public-api.d.ts +33 -0
|
@@ -0,0 +1,1196 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Injectable, Inject, Component } from '@angular/core';
|
|
3
|
+
import { BehaviorSubject, lastValueFrom, take, retry, shareReplay } from 'rxjs';
|
|
4
|
+
import { UserManager } from 'oidc-client';
|
|
5
|
+
import * as i1 from '@angular/router';
|
|
6
|
+
import { NavigationEnd } from '@angular/router';
|
|
7
|
+
import * as i3 from 'ngx-spinner';
|
|
8
|
+
import * as i2 from 'ngx-toastr';
|
|
9
|
+
import { ZonedDateTime } from '@js-joda/core';
|
|
10
|
+
import * as i1$1 from '@angular/common/http';
|
|
11
|
+
import { HttpHeaders, HttpParams } from '@angular/common/http';
|
|
12
|
+
import moment from 'moment';
|
|
13
|
+
import { saveAs } from 'file-saver';
|
|
14
|
+
import * as i2$1 from '@angular/common';
|
|
15
|
+
import * as i1$2 from '@ng-bootstrap/ng-bootstrap';
|
|
16
|
+
|
|
17
|
+
class AuthUser {
|
|
18
|
+
static { this.anonymous = new AuthUser(); }
|
|
19
|
+
/**
|
|
20
|
+
* Constructs a user object from a given oidc user object.
|
|
21
|
+
*
|
|
22
|
+
* @param oidcUser The oidc user object.
|
|
23
|
+
*/
|
|
24
|
+
constructor(oidcUser = null) {
|
|
25
|
+
this.oidcUser = oidcUser;
|
|
26
|
+
this.oidcUser = oidcUser;
|
|
27
|
+
if (oidcUser == null) {
|
|
28
|
+
this.isAuthenticated = false;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
this.isAuthenticated = true;
|
|
32
|
+
this.authorizationHeader = `${oidcUser.token_type} ${oidcUser.access_token}`;
|
|
33
|
+
this.name = oidcUser.profile?.name;
|
|
34
|
+
this.firstName = oidcUser.profile?.given_name;
|
|
35
|
+
this.lastName = oidcUser.profile?.family_name;
|
|
36
|
+
this.fullName = `${this.firstName} ${this.lastName}`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Gets the raw claims associated with the user.
|
|
41
|
+
*/
|
|
42
|
+
get claims() {
|
|
43
|
+
return this.oidcUser?.profile || {};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Determines whether the currently authenticated user is in any of an
|
|
47
|
+
* array of roles.
|
|
48
|
+
*
|
|
49
|
+
* @param roles An array of required roles.
|
|
50
|
+
* @returns True if the user has any of the required roles, false otherwise.
|
|
51
|
+
*/
|
|
52
|
+
hasAnyRole(...roles) {
|
|
53
|
+
const roleClaim = this.claims['role'];
|
|
54
|
+
if (roleClaim == null) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const claimRoles = Array.isArray(roleClaim) ? roleClaim : [roleClaim];
|
|
58
|
+
return roles.some(r => claimRoles.some(cr => r.toLowerCase() === cr.toLowerCase()));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Determines whether the currently authenticated user has a claim,
|
|
62
|
+
* and optionally, whether the claim has a specific value.
|
|
63
|
+
*
|
|
64
|
+
* @param claimType Claim type to match
|
|
65
|
+
* @param claimValue Optional claim value to match
|
|
66
|
+
*
|
|
67
|
+
* @returns True if the user has the required claim, false otherwise.
|
|
68
|
+
*/
|
|
69
|
+
hasClaim(claimType, claimValue) {
|
|
70
|
+
const value = this.claims[claimType];
|
|
71
|
+
return !!value && (!claimValue || value === claimValue);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Determines whether the currently authenticated user is a customer.
|
|
75
|
+
*/
|
|
76
|
+
get isCustomer() {
|
|
77
|
+
return this.hasClaim('ch:customer');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Determines whether the currently authenticated user is an employee.
|
|
81
|
+
*/
|
|
82
|
+
get isEmployee() {
|
|
83
|
+
return this.hasAnyRole('ch:Employee');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Creates a user object given an oidc user object.
|
|
87
|
+
*
|
|
88
|
+
* @param oidcUser The oidc user object.
|
|
89
|
+
* @returns A user object for the given oidc user object. If no oidc
|
|
90
|
+
* user object is specified or it has expired, returns the anonymous
|
|
91
|
+
* user.
|
|
92
|
+
*/
|
|
93
|
+
static from(oidcUser) {
|
|
94
|
+
if (oidcUser === null || oidcUser.expired) {
|
|
95
|
+
return AuthUser.anonymous;
|
|
96
|
+
}
|
|
97
|
+
return new AuthUser(oidcUser);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
class AuthorizationContext {
|
|
102
|
+
constructor(user) {
|
|
103
|
+
this.user = user;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const SECURITY_POLICIES = new InjectionToken('');
|
|
108
|
+
|
|
109
|
+
class SessionStorageService {
|
|
110
|
+
checkIfKeyExists(key) {
|
|
111
|
+
return globalThis.sessionStorage.getItem(key) !== null;
|
|
112
|
+
}
|
|
113
|
+
getItem(key) {
|
|
114
|
+
const valueString = globalThis.sessionStorage.getItem(key);
|
|
115
|
+
if (valueString === null) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
const value = JSON.parse(valueString);
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
setItem(key, value) {
|
|
122
|
+
const valueString = JSON.stringify(value);
|
|
123
|
+
globalThis.sessionStorage.setItem(key, valueString);
|
|
124
|
+
}
|
|
125
|
+
removeItem(key) {
|
|
126
|
+
globalThis.sessionStorage.removeItem(key);
|
|
127
|
+
}
|
|
128
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SessionStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
129
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SessionStorageService, providedIn: 'root' }); }
|
|
130
|
+
}
|
|
131
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SessionStorageService, decorators: [{
|
|
132
|
+
type: Injectable,
|
|
133
|
+
args: [{ providedIn: 'root' }]
|
|
134
|
+
}] });
|
|
135
|
+
|
|
136
|
+
// function getClientSettings(): UserManagerSettings {
|
|
137
|
+
// return {
|
|
138
|
+
// authority: environment.auth.authority,
|
|
139
|
+
// client_id: environment.auth.clientId,
|
|
140
|
+
// redirect_uri: `${environment.webApp}/auth-callback`,
|
|
141
|
+
// post_logout_redirect_uri: environment.webApp,
|
|
142
|
+
// response_type: 'id_token token',
|
|
143
|
+
// scope: `openid profile ${environment.auth.resourceId}`,
|
|
144
|
+
// filterProtocolClaims: true,
|
|
145
|
+
// loadUserInfo: true,
|
|
146
|
+
// automaticSilentRenew: true,
|
|
147
|
+
// silent_redirect_uri: `${environment.webApp}/silent-refresh.html`,
|
|
148
|
+
// //extraQueryParams: { resource: environment.auth.resourceId }
|
|
149
|
+
// // This is useful for testing silent refresh. Don't set this any lower, otherwise
|
|
150
|
+
// // the token authority will likely block you.
|
|
151
|
+
// //accessTokenExpiringNotificationTime: 3545
|
|
152
|
+
// };
|
|
153
|
+
// }
|
|
154
|
+
class AuthService {
|
|
155
|
+
constructor(securityPolicies, webAppUrl, userManagerSettings, router, sessionStorage, spinnerService) {
|
|
156
|
+
this.securityPolicies = securityPolicies;
|
|
157
|
+
this.webAppUrl = webAppUrl;
|
|
158
|
+
this.userManagerSettings = userManagerSettings;
|
|
159
|
+
this.router = router;
|
|
160
|
+
this.sessionStorage = sessionStorage;
|
|
161
|
+
this.spinnerService = spinnerService;
|
|
162
|
+
this.returnUrlKey = 'AuthService.returnUrl';
|
|
163
|
+
this.userManager = new UserManager(this.userManagerSettings);
|
|
164
|
+
this._currentUser = AuthUser.anonymous;
|
|
165
|
+
this.userStream = new BehaviorSubject(AuthUser.anonymous);
|
|
166
|
+
this.userManager.events.addSilentRenewError(err => {
|
|
167
|
+
console.error(err);
|
|
168
|
+
});
|
|
169
|
+
this.checkIsAuthenticated();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Gets the current user.
|
|
173
|
+
*/
|
|
174
|
+
get currentUser() {
|
|
175
|
+
return this._currentUser;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Sets the current user.
|
|
179
|
+
*/
|
|
180
|
+
set currentUser(user) {
|
|
181
|
+
this._currentUser = user;
|
|
182
|
+
const authContext = new AuthorizationContext(user);
|
|
183
|
+
this.securityPolicies.forEach(p => p.evaluate(authContext));
|
|
184
|
+
this.userStream.next(user);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Checks that the specified security policy is satisfied.
|
|
188
|
+
*
|
|
189
|
+
* @param name
|
|
190
|
+
* @returns
|
|
191
|
+
*/
|
|
192
|
+
checkPolicy(name) {
|
|
193
|
+
return this.securityPolicies.some(p => p.name === name && p.succeeded);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Completes the authentication process, redirecting to the return URL if specified
|
|
197
|
+
* in the start authentication call.
|
|
198
|
+
*
|
|
199
|
+
* @returns A void promise.
|
|
200
|
+
*/
|
|
201
|
+
async completeAuthentication() {
|
|
202
|
+
this.currentUser = AuthUser.from(await this.userManager.signinRedirectCallback());
|
|
203
|
+
let returnUrl = this.sessionStorage.getItem(this.returnUrlKey) || this.webAppUrl;
|
|
204
|
+
this.sessionStorage.removeItem(this.returnUrlKey);
|
|
205
|
+
if (returnUrl.endsWith('login')) {
|
|
206
|
+
returnUrl = this.webAppUrl;
|
|
207
|
+
}
|
|
208
|
+
this.router.navigateByUrl(returnUrl, { replaceUrl: true });
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Determines whether the user is authenticated.
|
|
212
|
+
*/
|
|
213
|
+
async checkIsAuthenticated() {
|
|
214
|
+
this.currentUser = AuthUser.from(await this.userManager.getUser());
|
|
215
|
+
return this.currentUser.isAuthenticated;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Signs the current user out of the sytem.
|
|
219
|
+
*/
|
|
220
|
+
async signout() {
|
|
221
|
+
await this.userManager.signoutRedirect();
|
|
222
|
+
this.userManager.removeUser();
|
|
223
|
+
this.currentUser = AuthUser.anonymous;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Begins the authentication process.
|
|
227
|
+
*
|
|
228
|
+
* @param returnUrl Optional. Destination after authentication is complete.
|
|
229
|
+
* @returns A void promise.
|
|
230
|
+
*/
|
|
231
|
+
startAuthentication(returnUrl) {
|
|
232
|
+
if (returnUrl) {
|
|
233
|
+
this.sessionStorage.setItem(this.returnUrlKey, returnUrl);
|
|
234
|
+
}
|
|
235
|
+
this.spinnerService.show();
|
|
236
|
+
return this.userManager.signinRedirect().then(() => {
|
|
237
|
+
this.spinnerService.hide();
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthService, deps: [{ token: SECURITY_POLICIES }, { token: 'webAppUrl' }, { token: 'userManagerSettings' }, { token: i1.Router }, { token: SessionStorageService }, { token: i3.NgxSpinnerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
241
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthService, providedIn: 'root' }); }
|
|
242
|
+
}
|
|
243
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthService, decorators: [{
|
|
244
|
+
type: Injectable,
|
|
245
|
+
args: [{ providedIn: 'root' }]
|
|
246
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
247
|
+
type: Inject,
|
|
248
|
+
args: [SECURITY_POLICIES]
|
|
249
|
+
}] }, { type: undefined, decorators: [{
|
|
250
|
+
type: Inject,
|
|
251
|
+
args: ['webAppUrl']
|
|
252
|
+
}] }, { type: undefined, decorators: [{
|
|
253
|
+
type: Inject,
|
|
254
|
+
args: ['userManagerSettings']
|
|
255
|
+
}] }, { type: i1.Router }, { type: SessionStorageService }, { type: i3.NgxSpinnerService }] });
|
|
256
|
+
|
|
257
|
+
class AuthCallbackComponent {
|
|
258
|
+
constructor(authService) {
|
|
259
|
+
this.authService = authService;
|
|
260
|
+
}
|
|
261
|
+
ngOnInit() {
|
|
262
|
+
return this.authService.completeAuthentication();
|
|
263
|
+
}
|
|
264
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthCallbackComponent, deps: [{ token: AuthService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
265
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuthCallbackComponent, selector: "app-auth-callback", ngImport: i0, template: "" }); }
|
|
266
|
+
}
|
|
267
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthCallbackComponent, decorators: [{
|
|
268
|
+
type: Component,
|
|
269
|
+
args: [{ selector: 'app-auth-callback', template: "" }]
|
|
270
|
+
}], ctorParameters: () => [{ type: AuthService }] });
|
|
271
|
+
|
|
272
|
+
class AuthGuardService {
|
|
273
|
+
constructor(authService, toastr) {
|
|
274
|
+
this.authService = authService;
|
|
275
|
+
this.toastr = toastr;
|
|
276
|
+
}
|
|
277
|
+
async canActivate(route, state) {
|
|
278
|
+
if (await this.authService.checkIsAuthenticated()) {
|
|
279
|
+
const routePolicy = route.data['policy'];
|
|
280
|
+
if (!routePolicy) {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
if (!this.authService.checkPolicy(routePolicy)) {
|
|
284
|
+
this.toastr.error("Oops! It doesn't look like you are authorized to access this page.");
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
await this.authService.startAuthentication(state.url);
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthGuardService, deps: [{ token: AuthService }, { token: i2.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
293
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthGuardService, providedIn: 'root' }); }
|
|
294
|
+
}
|
|
295
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthGuardService, decorators: [{
|
|
296
|
+
type: Injectable,
|
|
297
|
+
args: [{ providedIn: 'root' }]
|
|
298
|
+
}], ctorParameters: () => [{ type: AuthService }, { type: i2.ToastrService }] });
|
|
299
|
+
|
|
300
|
+
class SecurityPolicy {
|
|
301
|
+
constructor(name, requirement) {
|
|
302
|
+
this.name = name;
|
|
303
|
+
this.requirement = requirement;
|
|
304
|
+
this._succeeded = false;
|
|
305
|
+
}
|
|
306
|
+
get succeeded() {
|
|
307
|
+
return this._succeeded;
|
|
308
|
+
}
|
|
309
|
+
evaluate(context) {
|
|
310
|
+
this._succeeded = this.requirement(context);
|
|
311
|
+
return this._succeeded;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
class SigninComponent {
|
|
316
|
+
constructor(authService) {
|
|
317
|
+
this.authService = authService;
|
|
318
|
+
}
|
|
319
|
+
ngOnInit() {
|
|
320
|
+
this.authService.startAuthentication('/');
|
|
321
|
+
}
|
|
322
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SigninComponent, deps: [{ token: AuthService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
323
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SigninComponent, selector: "app-signin", ngImport: i0, template: "<section class=\"container-fluid\">\n <p>Redirecting to sign in page...</p>\n</section>\n" }); }
|
|
324
|
+
}
|
|
325
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SigninComponent, decorators: [{
|
|
326
|
+
type: Component,
|
|
327
|
+
args: [{ selector: 'app-signin', template: "<section class=\"container-fluid\">\n <p>Redirecting to sign in page...</p>\n</section>\n" }]
|
|
328
|
+
}], ctorParameters: () => [{ type: AuthService }] });
|
|
329
|
+
|
|
330
|
+
class SignoutComponent {
|
|
331
|
+
constructor(authService) {
|
|
332
|
+
this.authService = authService;
|
|
333
|
+
}
|
|
334
|
+
ngOnInit() {
|
|
335
|
+
this.authService.signout();
|
|
336
|
+
}
|
|
337
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignoutComponent, deps: [{ token: AuthService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
338
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SignoutComponent, selector: "app-signout", ngImport: i0, template: "<section class=\"container-fluid\">\n <p>Signing out...</p>\n</section>\n" }); }
|
|
339
|
+
}
|
|
340
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignoutComponent, decorators: [{
|
|
341
|
+
type: Component,
|
|
342
|
+
args: [{ selector: 'app-signout', template: "<section class=\"container-fluid\">\n <p>Signing out...</p>\n</section>\n" }]
|
|
343
|
+
}], ctorParameters: () => [{ type: AuthService }] });
|
|
344
|
+
|
|
345
|
+
var SeverityLevel;
|
|
346
|
+
(function (SeverityLevel) {
|
|
347
|
+
SeverityLevel[SeverityLevel["verbose"] = 0] = "verbose";
|
|
348
|
+
SeverityLevel[SeverityLevel["information"] = 1] = "information";
|
|
349
|
+
SeverityLevel[SeverityLevel["warning"] = 2] = "warning";
|
|
350
|
+
SeverityLevel[SeverityLevel["error"] = 3] = "error";
|
|
351
|
+
SeverityLevel[SeverityLevel["critical"] = 4] = "critical";
|
|
352
|
+
})(SeverityLevel || (SeverityLevel = {}));
|
|
353
|
+
|
|
354
|
+
class ConsoleLoggerSink {
|
|
355
|
+
constructor(name, level) {
|
|
356
|
+
this.name = name;
|
|
357
|
+
this.level = level;
|
|
358
|
+
this.consoleMethods = new Map([
|
|
359
|
+
[SeverityLevel.verbose, console.log],
|
|
360
|
+
[SeverityLevel.information, console.info || console.log],
|
|
361
|
+
[SeverityLevel.warning, console.warn || console.log],
|
|
362
|
+
[SeverityLevel.error, console.error || console.log],
|
|
363
|
+
[SeverityLevel.critical, console.error || console.log],
|
|
364
|
+
]);
|
|
365
|
+
}
|
|
366
|
+
write(logEntry) {
|
|
367
|
+
const consoleMethod = this.consoleMethods.get(logEntry.severityLevel) || console.log;
|
|
368
|
+
if (logEntry.stackTrace) {
|
|
369
|
+
const error = new Error(logEntry.message);
|
|
370
|
+
error.stack = logEntry.stackTrace;
|
|
371
|
+
consoleMethod(error);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
consoleMethod(logEntry.message);
|
|
375
|
+
}
|
|
376
|
+
return Promise.resolve();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
class Logger {
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
class Uuid {
|
|
384
|
+
static create() {
|
|
385
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
386
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
387
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
388
|
+
let index = 0;
|
|
389
|
+
return (Uuid.toHex(bytes[index++]) +
|
|
390
|
+
Uuid.toHex(bytes[index++]) +
|
|
391
|
+
Uuid.toHex(bytes[index++]) +
|
|
392
|
+
Uuid.toHex(bytes[index++]) +
|
|
393
|
+
'-' +
|
|
394
|
+
Uuid.toHex(bytes[index++]) +
|
|
395
|
+
Uuid.toHex(bytes[index++]) +
|
|
396
|
+
'-' +
|
|
397
|
+
Uuid.toHex(bytes[index++]) +
|
|
398
|
+
Uuid.toHex(bytes[index++]) +
|
|
399
|
+
'-' +
|
|
400
|
+
Uuid.toHex(bytes[index++]) +
|
|
401
|
+
Uuid.toHex(bytes[index++]) +
|
|
402
|
+
'-' +
|
|
403
|
+
Uuid.toHex(bytes[index++]) +
|
|
404
|
+
Uuid.toHex(bytes[index++]) +
|
|
405
|
+
Uuid.toHex(bytes[index++]) +
|
|
406
|
+
Uuid.toHex(bytes[index++]) +
|
|
407
|
+
Uuid.toHex(bytes[index++]) +
|
|
408
|
+
Uuid.toHex(bytes[index++]));
|
|
409
|
+
}
|
|
410
|
+
static toHex(byte) {
|
|
411
|
+
return (0x100 | byte).toString(16).substr(1);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
class LoggerService {
|
|
416
|
+
static { this.overrideQueryStringRegex = /log\.(\w+)/; }
|
|
417
|
+
constructor(loggerSinkConfiguration, activatedRoute, authService, injector) {
|
|
418
|
+
this.loggerSinkConfiguration = loggerSinkConfiguration;
|
|
419
|
+
this.activatedRoute = activatedRoute;
|
|
420
|
+
this.authService = authService;
|
|
421
|
+
this.injector = injector;
|
|
422
|
+
this.sessionId = Uuid.create();
|
|
423
|
+
this.sinks = new Array();
|
|
424
|
+
this.minimumLevel = SeverityLevel.error;
|
|
425
|
+
this.readConfiguration();
|
|
426
|
+
this.activatedRoute.queryParams.subscribe(async (params) => {
|
|
427
|
+
const isDebug = this.authService.checkPolicy('debug');
|
|
428
|
+
if (isDebug) {
|
|
429
|
+
let updated = false;
|
|
430
|
+
for (const key of Object.keys(params)) {
|
|
431
|
+
const match = key.match(LoggerService.overrideQueryStringRegex);
|
|
432
|
+
if (match?.length === 2) {
|
|
433
|
+
const [paramName, sinkName] = match;
|
|
434
|
+
const sink = this.sinks.find(s => s.name === sinkName);
|
|
435
|
+
if (!sink) {
|
|
436
|
+
throw new Error(`Cannot find sink with name '${sinkName}'.`);
|
|
437
|
+
}
|
|
438
|
+
const value = params[paramName];
|
|
439
|
+
let level;
|
|
440
|
+
if (!value) {
|
|
441
|
+
throw new Error(`Missing value for query string parameter '${paramName}'.`);
|
|
442
|
+
}
|
|
443
|
+
else if (!(level = parseInt(value))) {
|
|
444
|
+
level =
|
|
445
|
+
SeverityLevel[value.toLowerCase()];
|
|
446
|
+
}
|
|
447
|
+
sink.level = level;
|
|
448
|
+
updated = true;
|
|
449
|
+
console.log(`Logging sink '${sinkName}' set to '${value}'.`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (updated) {
|
|
453
|
+
this.refreshSinks();
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
logError(message, options) {
|
|
459
|
+
if (typeof message === 'string') {
|
|
460
|
+
this.logWrite(SeverityLevel.error, message, options);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const error = message;
|
|
464
|
+
this.logWrite(SeverityLevel.error, error.message, Object.assign({ stackTrace: error.stack }, options));
|
|
465
|
+
}
|
|
466
|
+
logInfo(message, options) {
|
|
467
|
+
this.logWrite(SeverityLevel.information, message, options);
|
|
468
|
+
}
|
|
469
|
+
logVerbose(message, options) {
|
|
470
|
+
this.logWrite(SeverityLevel.verbose, message, options);
|
|
471
|
+
}
|
|
472
|
+
logWarning(message, options) {
|
|
473
|
+
this.logWrite(SeverityLevel.warning, message, options);
|
|
474
|
+
}
|
|
475
|
+
logWrite(level, message, options) {
|
|
476
|
+
if (level < this.minimumLevel) {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const logEntry = {
|
|
480
|
+
createdDateTime: ZonedDateTime.now().withFixedOffsetZone().toString(),
|
|
481
|
+
sessionId: this.sessionId,
|
|
482
|
+
severityLevel: level,
|
|
483
|
+
message: message,
|
|
484
|
+
stackTrace: options?.stackTrace,
|
|
485
|
+
url: window.location.href,
|
|
486
|
+
userAgent: navigator.userAgent,
|
|
487
|
+
jsonData: options?.data ? JSON.stringify(options.data) : undefined,
|
|
488
|
+
};
|
|
489
|
+
for (const sink of this.sinks) {
|
|
490
|
+
if (level >= sink.level) {
|
|
491
|
+
try {
|
|
492
|
+
sink.write(logEntry);
|
|
493
|
+
}
|
|
494
|
+
catch (error) {
|
|
495
|
+
this.logError(`Error writing log entry to sink '${sink.name}'.`, {
|
|
496
|
+
stackTrace: error.stack,
|
|
497
|
+
data: { sink: sink.name },
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
readConfiguration() {
|
|
504
|
+
const sinkConfigs = this.loggerSinkConfiguration;
|
|
505
|
+
if (sinkConfigs) {
|
|
506
|
+
for (const sinkConfig of sinkConfigs) {
|
|
507
|
+
this.requiredProperty(sinkConfig, 'name');
|
|
508
|
+
this.requiredProperty(sinkConfig, 'type');
|
|
509
|
+
this.requiredProperty(sinkConfig, 'level');
|
|
510
|
+
const sink = new sinkConfig.type(sinkConfig.name, sinkConfig.level, sinkConfig.args, this, this.injector);
|
|
511
|
+
this.sinks.push(sink);
|
|
512
|
+
}
|
|
513
|
+
this.refreshSinks();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
refreshSinks() {
|
|
517
|
+
this.minimumLevel = this.sinks.reduce((l, s) => Math.min(l, s.level), SeverityLevel.critical);
|
|
518
|
+
}
|
|
519
|
+
requiredProperty(obj, propertyName) {
|
|
520
|
+
if (obj[propertyName] == null) {
|
|
521
|
+
throw new Error(`Missing required property '${propertyName}' in the logger section of environment.ts.`);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LoggerService, deps: [{ token: 'loggerSinkConfiguration' }, { token: i1.ActivatedRoute }, { token: AuthService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
525
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LoggerService, providedIn: 'root' }); }
|
|
526
|
+
}
|
|
527
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LoggerService, decorators: [{
|
|
528
|
+
type: Injectable,
|
|
529
|
+
args: [{ providedIn: 'root' }]
|
|
530
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
531
|
+
type: Inject,
|
|
532
|
+
args: ['loggerSinkConfiguration']
|
|
533
|
+
}] }, { type: i1.ActivatedRoute }, { type: AuthService }, { type: i0.Injector }] });
|
|
534
|
+
|
|
535
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
536
|
+
class RestClient {
|
|
537
|
+
constructor(httpClient) {
|
|
538
|
+
this.httpClient = httpClient;
|
|
539
|
+
this.defaultRetry = { count: 0, delay: 1000 };
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Sends a delete request to the specified REST service
|
|
543
|
+
*
|
|
544
|
+
* @param url The service endpoint
|
|
545
|
+
* @param options Additional options
|
|
546
|
+
*/
|
|
547
|
+
delete(url, options) {
|
|
548
|
+
return lastValueFrom(this.request('DELETE', url, options));
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Retrieves data from the specified REST service
|
|
552
|
+
*
|
|
553
|
+
* @param url The service endpoint
|
|
554
|
+
* @param options Additional options
|
|
555
|
+
*/
|
|
556
|
+
get(url, options) {
|
|
557
|
+
return lastValueFrom(this.request('GET', url, options));
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Sends a patch request to the specified REST service
|
|
561
|
+
*
|
|
562
|
+
* @param url The service endpoint
|
|
563
|
+
* @param options Additional options
|
|
564
|
+
*/
|
|
565
|
+
patch(url, options) {
|
|
566
|
+
return lastValueFrom(this.request('PATCH', url, options));
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Sends a post request to the specified REST service
|
|
570
|
+
*
|
|
571
|
+
* @param url The service endpoint
|
|
572
|
+
* @param options Additional options
|
|
573
|
+
*/
|
|
574
|
+
post(url, options) {
|
|
575
|
+
return lastValueFrom(this.request('POST', url, options));
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Sends a put request to the specified REST service
|
|
579
|
+
*
|
|
580
|
+
* @param url The service endpoint
|
|
581
|
+
* @param options Additional options
|
|
582
|
+
*/
|
|
583
|
+
put(url, options) {
|
|
584
|
+
return lastValueFrom(this.request('PUT', url, options));
|
|
585
|
+
}
|
|
586
|
+
request(method, url, options) {
|
|
587
|
+
return this.httpClient
|
|
588
|
+
.request(method, url, {
|
|
589
|
+
body: options?.body ? JSON.stringify(options.body) : undefined,
|
|
590
|
+
headers: this.createRequestHeaders(options),
|
|
591
|
+
params: this.createRequestParams(options?.queryParameters),
|
|
592
|
+
})
|
|
593
|
+
.pipe(take(1), retry(options?.retry || this.defaultRetry));
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
*
|
|
597
|
+
* @param url
|
|
598
|
+
* @param options
|
|
599
|
+
* @returns
|
|
600
|
+
*/
|
|
601
|
+
getResponse(method, url, options) {
|
|
602
|
+
return this.httpClient
|
|
603
|
+
.request(method, url, {
|
|
604
|
+
observe: 'response',
|
|
605
|
+
body: options?.body ? JSON.stringify(options.body) : undefined,
|
|
606
|
+
headers: this.createRequestHeaders(options),
|
|
607
|
+
params: this.createRequestParams(options?.queryParameters),
|
|
608
|
+
})
|
|
609
|
+
.pipe(take(1), retry(options?.retry || this.defaultRetry));
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Creates request headers based on the provided options.
|
|
613
|
+
*
|
|
614
|
+
* @param options
|
|
615
|
+
* @returns
|
|
616
|
+
*/
|
|
617
|
+
createRequestHeaders(options) {
|
|
618
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
619
|
+
const headers = Object.assign({
|
|
620
|
+
Accept: 'application/json',
|
|
621
|
+
'Content-Type': 'application/json',
|
|
622
|
+
}, options?.headers);
|
|
623
|
+
if (options?.apiVersion) {
|
|
624
|
+
const versionString = `; version=${options.apiVersion}`;
|
|
625
|
+
headers.Accept += versionString;
|
|
626
|
+
headers['Content-Type'] += versionString;
|
|
627
|
+
}
|
|
628
|
+
if (options?.showSpinner === false) {
|
|
629
|
+
headers['x-spinner'] = 'false';
|
|
630
|
+
}
|
|
631
|
+
if (options?.cacheLifetimeSeconds) {
|
|
632
|
+
headers['x-cache-ttl'] = options?.cacheLifetimeSeconds;
|
|
633
|
+
}
|
|
634
|
+
return new HttpHeaders(headers);
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Converts one or more objects to an HttpParams object.
|
|
638
|
+
*
|
|
639
|
+
* @param sources The objects to convert
|
|
640
|
+
* @returns
|
|
641
|
+
*/
|
|
642
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
643
|
+
createRequestParams(...sources) {
|
|
644
|
+
let params = new HttpParams();
|
|
645
|
+
for (const source of sources) {
|
|
646
|
+
if (source == null) {
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
for (const key of Object.keys(source)) {
|
|
650
|
+
const value = source[key];
|
|
651
|
+
if (value != null) {
|
|
652
|
+
params = params.set(key, value.toString());
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return params;
|
|
657
|
+
}
|
|
658
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RestClient, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
659
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RestClient, providedIn: 'any' }); }
|
|
660
|
+
}
|
|
661
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RestClient, decorators: [{
|
|
662
|
+
type: Injectable,
|
|
663
|
+
args: [{ providedIn: 'any' }]
|
|
664
|
+
}], ctorParameters: () => [{ type: i1$1.HttpClient }] });
|
|
665
|
+
|
|
666
|
+
var FireImmediately;
|
|
667
|
+
(function (FireImmediately) {
|
|
668
|
+
FireImmediately[FireImmediately["never"] = 0] = "never";
|
|
669
|
+
FireImmediately[FireImmediately["whenShown"] = 1] = "whenShown";
|
|
670
|
+
FireImmediately[FireImmediately["whenFocused"] = 2] = "whenFocused";
|
|
671
|
+
})(FireImmediately || (FireImmediately = {}));
|
|
672
|
+
class IntervalService {
|
|
673
|
+
static { this.defaultOptions = { fireImmediately: FireImmediately.never }; }
|
|
674
|
+
create(action, interval, options = IntervalService.defaultOptions) {
|
|
675
|
+
const timer = new IntervalTimer(action, interval, options);
|
|
676
|
+
timer.initialize();
|
|
677
|
+
return timer;
|
|
678
|
+
}
|
|
679
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IntervalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
680
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IntervalService, providedIn: 'root' }); }
|
|
681
|
+
}
|
|
682
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IntervalService, decorators: [{
|
|
683
|
+
type: Injectable,
|
|
684
|
+
args: [{ providedIn: 'root' }]
|
|
685
|
+
}] });
|
|
686
|
+
class IntervalTimer {
|
|
687
|
+
constructor(action, interval, options) {
|
|
688
|
+
this.action = action;
|
|
689
|
+
this.interval = interval;
|
|
690
|
+
this.options = options;
|
|
691
|
+
this.currentInterval = 0;
|
|
692
|
+
this.isStopped = true;
|
|
693
|
+
}
|
|
694
|
+
initialize() {
|
|
695
|
+
if (this.options.hiddenInterval != null) {
|
|
696
|
+
document.addEventListener('visibilitychange', () => {
|
|
697
|
+
if (document.hidden) {
|
|
698
|
+
this.onHidden();
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
this.onShown();
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
if (this.options.blurInterval != null) {
|
|
706
|
+
window.addEventListener('blur', () => this.onBlur());
|
|
707
|
+
window.addEventListener('focus', () => this.onFocus());
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
start() {
|
|
711
|
+
if (this.isStopped) {
|
|
712
|
+
if (!document.hidden) {
|
|
713
|
+
this.isStopped = false;
|
|
714
|
+
this.onShown();
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
this.setInterval(this.interval);
|
|
718
|
+
this.isStopped = false;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
stop() {
|
|
723
|
+
this.setInterval(0);
|
|
724
|
+
this.isStopped = true;
|
|
725
|
+
}
|
|
726
|
+
async callActionAndScheduleNext(nextInterval) {
|
|
727
|
+
this.setInterval(0); // pause while the action runs
|
|
728
|
+
await this.action();
|
|
729
|
+
this.setInterval(nextInterval);
|
|
730
|
+
}
|
|
731
|
+
onBlur() {
|
|
732
|
+
if (this.isStopped) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
this.setInterval(this.options?.blurInterval);
|
|
736
|
+
}
|
|
737
|
+
onFocus() {
|
|
738
|
+
if (this.isStopped) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
if (this.options?.fireImmediately === FireImmediately.whenFocused) {
|
|
742
|
+
this.callActionAndScheduleNext(this.interval);
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
this.setInterval(this.interval);
|
|
746
|
+
}
|
|
747
|
+
onHidden() {
|
|
748
|
+
if (this.isStopped) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
this.setInterval(this.options?.hiddenInterval);
|
|
752
|
+
}
|
|
753
|
+
onShown() {
|
|
754
|
+
if (this.isStopped) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
if (this.options.fireImmediately === FireImmediately.whenShown) {
|
|
758
|
+
this.callActionAndScheduleNext(this.interval);
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
this.setInterval(this.interval);
|
|
762
|
+
}
|
|
763
|
+
setInterval(interval) {
|
|
764
|
+
if (this.$handle) {
|
|
765
|
+
if (interval === this.currentInterval) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
window.clearTimeout(this.$handle);
|
|
769
|
+
this.$handle = undefined;
|
|
770
|
+
}
|
|
771
|
+
if (!interval) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
this.$handle = window.setTimeout(() => this.callActionAndScheduleNext(interval), interval);
|
|
775
|
+
this.currentInterval = interval;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
class ServerLoggerSink {
|
|
780
|
+
constructor(name, level, args, logger, injector) {
|
|
781
|
+
this.name = name;
|
|
782
|
+
this.level = level;
|
|
783
|
+
this.args = args;
|
|
784
|
+
this.logger = logger;
|
|
785
|
+
this.injector = injector;
|
|
786
|
+
this.retryCount = 10;
|
|
787
|
+
this.postFrequency = 15 * 1000 /*15 seconds*/;
|
|
788
|
+
this.entryBuffer = new Array();
|
|
789
|
+
this.errorCount = 0;
|
|
790
|
+
if (!args?.url) {
|
|
791
|
+
throw new Error(`Missing required argument 'url' for sink ${this.constructor.name}.`);
|
|
792
|
+
}
|
|
793
|
+
const intervalService = injector.get(IntervalService);
|
|
794
|
+
this.$interval = intervalService.create(() => this.flush(), this.postFrequency);
|
|
795
|
+
this.$interval.start();
|
|
796
|
+
}
|
|
797
|
+
write(logEntry) {
|
|
798
|
+
this.entryBuffer.push(logEntry);
|
|
799
|
+
}
|
|
800
|
+
async flush() {
|
|
801
|
+
if (this.entryBuffer.length === 0) {
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
const mark = this.entryBuffer.length;
|
|
805
|
+
try {
|
|
806
|
+
await this.postLogEntries(this.entryBuffer);
|
|
807
|
+
this.entryBuffer = this.entryBuffer.slice(mark);
|
|
808
|
+
this.errorCount = 0;
|
|
809
|
+
}
|
|
810
|
+
catch (error) {
|
|
811
|
+
this.logger.logError(error);
|
|
812
|
+
if (this.errorCount++ > this.retryCount) {
|
|
813
|
+
this.$interval.stop();
|
|
814
|
+
throw new Error(`Error posting log entries to server. Retried ${this.retryCount} times and giving up.`);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
postLogEntries(entries) {
|
|
819
|
+
const restClient = this.injector.get(RestClient);
|
|
820
|
+
const restOptions = Object.assign({}, this.args, {
|
|
821
|
+
body: entries,
|
|
822
|
+
showSpinner: false,
|
|
823
|
+
});
|
|
824
|
+
return restClient.post(this.args.url, restOptions);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
class DateService {
|
|
829
|
+
getMonthItems(startMonth = 1, endMonth = 12) {
|
|
830
|
+
const items = [];
|
|
831
|
+
const d = moment().startOf('year');
|
|
832
|
+
let i = startMonth;
|
|
833
|
+
while (i <= endMonth) {
|
|
834
|
+
d.set('month', i - 1);
|
|
835
|
+
items.push({ value: i, name: d.format('MMMM') });
|
|
836
|
+
i++;
|
|
837
|
+
}
|
|
838
|
+
return items;
|
|
839
|
+
}
|
|
840
|
+
getYearItems(startYear, endYear) {
|
|
841
|
+
startYear = startYear || moment().year();
|
|
842
|
+
endYear = endYear || moment().year();
|
|
843
|
+
const items = [];
|
|
844
|
+
let i = startYear;
|
|
845
|
+
while (i <= endYear) {
|
|
846
|
+
items.push({ value: i, name: i.toString() });
|
|
847
|
+
i++;
|
|
848
|
+
}
|
|
849
|
+
return items;
|
|
850
|
+
}
|
|
851
|
+
toDateString(input) {
|
|
852
|
+
return moment(input).format('yyyy-MM-DD');
|
|
853
|
+
}
|
|
854
|
+
toISOString(input) {
|
|
855
|
+
return moment(input).toISOString();
|
|
856
|
+
}
|
|
857
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
858
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DateService, providedIn: 'root' }); }
|
|
859
|
+
}
|
|
860
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DateService, decorators: [{
|
|
861
|
+
type: Injectable,
|
|
862
|
+
args: [{ providedIn: 'root' }]
|
|
863
|
+
}] });
|
|
864
|
+
|
|
865
|
+
class DownloadService {
|
|
866
|
+
constructor(httpClient) {
|
|
867
|
+
this.httpClient = httpClient;
|
|
868
|
+
this.octetStreamMime = 'application/octet-stream';
|
|
869
|
+
}
|
|
870
|
+
downloadFile(url, params) {
|
|
871
|
+
const download$ = this.httpClient
|
|
872
|
+
.get(url, {
|
|
873
|
+
responseType: 'arraybuffer',
|
|
874
|
+
observe: 'response',
|
|
875
|
+
params: params,
|
|
876
|
+
})
|
|
877
|
+
.pipe(shareReplay());
|
|
878
|
+
download$.subscribe(r => this.processDownload(r));
|
|
879
|
+
return download$;
|
|
880
|
+
}
|
|
881
|
+
processDownload(response) {
|
|
882
|
+
const filename = this.getFileNameFromResponse(response);
|
|
883
|
+
const contentType = response.headers.get('content-type') || this.octetStreamMime;
|
|
884
|
+
if (response.body) {
|
|
885
|
+
const blob = new Blob([response.body], { type: contentType });
|
|
886
|
+
saveAs(blob, filename);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
getFileNameFromResponse(response) {
|
|
890
|
+
// attempt to get from response headers
|
|
891
|
+
let fileName = response.headers.get('x-filename') || response.headers.get('filename');
|
|
892
|
+
if (!fileName) {
|
|
893
|
+
// attempt to get from content disposition
|
|
894
|
+
const disposition = response.headers.get('content-disposition');
|
|
895
|
+
if (disposition) {
|
|
896
|
+
fileName = disposition.split(';')[1].split('=')[1].replace(/"/g, '');
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
return fileName || 'download.bin';
|
|
900
|
+
}
|
|
901
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DownloadService, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
902
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DownloadService, providedIn: 'any' }); }
|
|
903
|
+
}
|
|
904
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DownloadService, decorators: [{
|
|
905
|
+
type: Injectable,
|
|
906
|
+
args: [{ providedIn: 'any' }]
|
|
907
|
+
}], ctorParameters: () => [{ type: i1$1.HttpClient }] });
|
|
908
|
+
|
|
909
|
+
class FeatureService {
|
|
910
|
+
constructor(webApiUrl, restClient) {
|
|
911
|
+
this.webApiUrl = webApiUrl;
|
|
912
|
+
this.restClient = restClient;
|
|
913
|
+
this.featureStream = new BehaviorSubject([]);
|
|
914
|
+
this._enabledFeatures = [];
|
|
915
|
+
this._isInitialized = false;
|
|
916
|
+
this.routePrefix = `${this.webApiUrl}/common/features`;
|
|
917
|
+
this.checkEnabledFeatures();
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Gets the enabled features.
|
|
921
|
+
*/
|
|
922
|
+
get enabledFeatures() {
|
|
923
|
+
return this._enabledFeatures;
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Sets the enabled features.
|
|
927
|
+
*/
|
|
928
|
+
set enabledFeatures(enabledFeatures) {
|
|
929
|
+
this._enabledFeatures = enabledFeatures;
|
|
930
|
+
this._isInitialized = true;
|
|
931
|
+
this.featureStream.next(enabledFeatures);
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Gets whether features have been initialized
|
|
935
|
+
*/
|
|
936
|
+
get isInitialized() {
|
|
937
|
+
return this._isInitialized;
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Checks that the enabled features are set and returns the list.
|
|
941
|
+
*
|
|
942
|
+
* @param name
|
|
943
|
+
* @returns
|
|
944
|
+
*/
|
|
945
|
+
async checkEnabledFeatures() {
|
|
946
|
+
if (!this._enabledFeatures) {
|
|
947
|
+
this.enabledFeatures = await this.restClient.get(`${this.routePrefix}/enabled`);
|
|
948
|
+
}
|
|
949
|
+
return this.enabledFeatures;
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Checks that the specified feature is enabled.
|
|
953
|
+
*
|
|
954
|
+
* @param name
|
|
955
|
+
* @returns
|
|
956
|
+
*/
|
|
957
|
+
checkFeatureIsEnabled(name) {
|
|
958
|
+
return this._enabledFeatures?.some(p => p === name);
|
|
959
|
+
}
|
|
960
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FeatureService, deps: [{ token: 'webApiUrl' }, { token: RestClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
961
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FeatureService, providedIn: 'root' }); }
|
|
962
|
+
}
|
|
963
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FeatureService, decorators: [{
|
|
964
|
+
type: Injectable,
|
|
965
|
+
args: [{ providedIn: 'root' }]
|
|
966
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
967
|
+
type: Inject,
|
|
968
|
+
args: ['webApiUrl']
|
|
969
|
+
}] }, { type: RestClient }] });
|
|
970
|
+
|
|
971
|
+
// from https://nils-mehlhorn.de/posts/angular-navigate-back-previous-page
|
|
972
|
+
class NavigationService {
|
|
973
|
+
constructor(router, location) {
|
|
974
|
+
this.router = router;
|
|
975
|
+
this.location = location;
|
|
976
|
+
this.history = [];
|
|
977
|
+
this.router.events.subscribe(event => {
|
|
978
|
+
if (event instanceof NavigationEnd) {
|
|
979
|
+
this.history.push(event.urlAfterRedirects);
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
goBack() {
|
|
984
|
+
this.goBackOrDefault('/');
|
|
985
|
+
}
|
|
986
|
+
goBackOrDefault(defaultUrl) {
|
|
987
|
+
if (this.history.length > 0) {
|
|
988
|
+
this.history.pop();
|
|
989
|
+
this.location.back();
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
this.router.navigateByUrl(defaultUrl);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
setQueryParams(params) {
|
|
996
|
+
this.router.navigate([], {
|
|
997
|
+
queryParams: params,
|
|
998
|
+
queryParamsHandling: 'merge',
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavigationService, deps: [{ token: i1.Router }, { token: i2$1.Location }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1002
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavigationService, providedIn: 'root' }); }
|
|
1003
|
+
}
|
|
1004
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavigationService, decorators: [{
|
|
1005
|
+
type: Injectable,
|
|
1006
|
+
args: [{
|
|
1007
|
+
providedIn: 'root',
|
|
1008
|
+
}]
|
|
1009
|
+
}], ctorParameters: () => [{ type: i1.Router }, { type: i2$1.Location }] });
|
|
1010
|
+
|
|
1011
|
+
class FeatureGuardService {
|
|
1012
|
+
constructor(featureService, navigationService, toastr) {
|
|
1013
|
+
this.featureService = featureService;
|
|
1014
|
+
this.navigationService = navigationService;
|
|
1015
|
+
this.toastr = toastr;
|
|
1016
|
+
}
|
|
1017
|
+
async canActivate(route) {
|
|
1018
|
+
const routeFeature = route.data['feature'];
|
|
1019
|
+
if (!routeFeature) {
|
|
1020
|
+
return true;
|
|
1021
|
+
}
|
|
1022
|
+
await this.featureService.checkEnabledFeatures();
|
|
1023
|
+
if (!this.featureService.checkFeatureIsEnabled(routeFeature)) {
|
|
1024
|
+
this.toastr.error("Oops! It doesn't look like this feature has been enabled.");
|
|
1025
|
+
this.navigationService.goBack();
|
|
1026
|
+
return false;
|
|
1027
|
+
}
|
|
1028
|
+
return true;
|
|
1029
|
+
}
|
|
1030
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FeatureGuardService, deps: [{ token: FeatureService }, { token: NavigationService }, { token: i2.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1031
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FeatureGuardService, providedIn: 'root' }); }
|
|
1032
|
+
}
|
|
1033
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FeatureGuardService, decorators: [{
|
|
1034
|
+
type: Injectable,
|
|
1035
|
+
args: [{ providedIn: 'root' }]
|
|
1036
|
+
}], ctorParameters: () => [{ type: FeatureService }, { type: NavigationService }, { type: i2.ToastrService }] });
|
|
1037
|
+
|
|
1038
|
+
class LocalStorageService {
|
|
1039
|
+
checkIfKeyExists(key) {
|
|
1040
|
+
return globalThis.localStorage.getItem(key) !== null;
|
|
1041
|
+
}
|
|
1042
|
+
getItem(key) {
|
|
1043
|
+
const valueString = globalThis.localStorage.getItem(key);
|
|
1044
|
+
if (valueString === null) {
|
|
1045
|
+
return undefined;
|
|
1046
|
+
}
|
|
1047
|
+
const value = JSON.parse(valueString);
|
|
1048
|
+
return value;
|
|
1049
|
+
}
|
|
1050
|
+
setItem(key, value) {
|
|
1051
|
+
const valueString = JSON.stringify(value);
|
|
1052
|
+
globalThis.localStorage.setItem(key, valueString);
|
|
1053
|
+
}
|
|
1054
|
+
removeItem(key) {
|
|
1055
|
+
globalThis.localStorage.removeItem(key);
|
|
1056
|
+
}
|
|
1057
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1058
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocalStorageService, providedIn: 'root' }); }
|
|
1059
|
+
}
|
|
1060
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocalStorageService, decorators: [{
|
|
1061
|
+
type: Injectable,
|
|
1062
|
+
args: [{ providedIn: 'root' }]
|
|
1063
|
+
}] });
|
|
1064
|
+
|
|
1065
|
+
class ModalService {
|
|
1066
|
+
constructor(ngbModal) {
|
|
1067
|
+
this.ngbModal = ngbModal;
|
|
1068
|
+
}
|
|
1069
|
+
async showModal(component, componentParameters, modalOptions = { backdrop: 'static' }) {
|
|
1070
|
+
const modal = this.ngbModal.open(component, modalOptions);
|
|
1071
|
+
const componentInstance = modal.componentInstance;
|
|
1072
|
+
Object.assign(componentInstance, componentParameters);
|
|
1073
|
+
let result;
|
|
1074
|
+
try {
|
|
1075
|
+
result = await modal.result;
|
|
1076
|
+
}
|
|
1077
|
+
catch (error) {
|
|
1078
|
+
result = null;
|
|
1079
|
+
if (error === undefined) {
|
|
1080
|
+
throw 'modal dismiss';
|
|
1081
|
+
}
|
|
1082
|
+
throw error;
|
|
1083
|
+
}
|
|
1084
|
+
return { result, componentInstance };
|
|
1085
|
+
}
|
|
1086
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalService, deps: [{ token: i1$2.NgbModal }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1087
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalService, providedIn: 'root' }); }
|
|
1088
|
+
}
|
|
1089
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalService, decorators: [{
|
|
1090
|
+
type: Injectable,
|
|
1091
|
+
args: [{
|
|
1092
|
+
providedIn: 'root',
|
|
1093
|
+
}]
|
|
1094
|
+
}], ctorParameters: () => [{ type: i1$2.NgbModal }] });
|
|
1095
|
+
|
|
1096
|
+
class ObjectService {
|
|
1097
|
+
toValueObject(obj) {
|
|
1098
|
+
const result = Object.getOwnPropertyNames(obj).reduce((p, key) => {
|
|
1099
|
+
if (obj[key]) {
|
|
1100
|
+
p[key] = obj[key];
|
|
1101
|
+
}
|
|
1102
|
+
return p;
|
|
1103
|
+
}, new Object());
|
|
1104
|
+
return result;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Convert Object to HttpParams
|
|
1108
|
+
* @param {object} obj
|
|
1109
|
+
* @returns {HttpParams}
|
|
1110
|
+
* see: https://stackoverflow.com/questions/45210406/angular-4-3-httpclient-set-params
|
|
1111
|
+
*/
|
|
1112
|
+
toHttpParams(obj) {
|
|
1113
|
+
const temp = Object.getOwnPropertyNames(obj).reduce((p, key) => (obj[key] == null || obj[key].length === 0 ? p : p.set(key, obj[key])), new HttpParams());
|
|
1114
|
+
return temp;
|
|
1115
|
+
}
|
|
1116
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ObjectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1117
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ObjectService, providedIn: 'root' }); }
|
|
1118
|
+
}
|
|
1119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ObjectService, decorators: [{
|
|
1120
|
+
type: Injectable,
|
|
1121
|
+
args: [{
|
|
1122
|
+
providedIn: 'root',
|
|
1123
|
+
}]
|
|
1124
|
+
}] });
|
|
1125
|
+
|
|
1126
|
+
class RouteParamService {
|
|
1127
|
+
constructor(route) {
|
|
1128
|
+
this.route = route;
|
|
1129
|
+
}
|
|
1130
|
+
getParameterBoolean(params, paramKey) {
|
|
1131
|
+
const value = this.getParameterValue(params, paramKey);
|
|
1132
|
+
if (value) {
|
|
1133
|
+
return !!value;
|
|
1134
|
+
}
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
getParameterNumber(params, paramKey) {
|
|
1138
|
+
const value = this.getParameterValue(params, paramKey);
|
|
1139
|
+
if (value) {
|
|
1140
|
+
return parseInt(value);
|
|
1141
|
+
}
|
|
1142
|
+
return null;
|
|
1143
|
+
}
|
|
1144
|
+
getParameterValue(params, paramKey) {
|
|
1145
|
+
const value = params[paramKey];
|
|
1146
|
+
return value || null;
|
|
1147
|
+
}
|
|
1148
|
+
getQueryParameterBoolean(paramKey) {
|
|
1149
|
+
return this.getParameterBoolean(this.route.snapshot.queryParams, paramKey);
|
|
1150
|
+
}
|
|
1151
|
+
getQueryParameterNumber(paramKey) {
|
|
1152
|
+
return this.getParameterNumber(this.route.snapshot.queryParams, paramKey);
|
|
1153
|
+
}
|
|
1154
|
+
getQueryParameterValue(paramKey) {
|
|
1155
|
+
return this.getParameterValue(this.route.snapshot.queryParams, paramKey);
|
|
1156
|
+
}
|
|
1157
|
+
getRouteParameterBoolean(route, paramKey) {
|
|
1158
|
+
return this.getParameterBoolean(route.snapshot.params, paramKey);
|
|
1159
|
+
}
|
|
1160
|
+
getRouteParameterNumber(route, paramKey) {
|
|
1161
|
+
return this.getParameterNumber(route.snapshot.params, paramKey);
|
|
1162
|
+
}
|
|
1163
|
+
getRouteParameterValue(route, paramKey) {
|
|
1164
|
+
return this.getParameterValue(route.snapshot.params, paramKey);
|
|
1165
|
+
}
|
|
1166
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RouteParamService, deps: [{ token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1167
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RouteParamService, providedIn: 'root' }); }
|
|
1168
|
+
}
|
|
1169
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RouteParamService, decorators: [{
|
|
1170
|
+
type: Injectable,
|
|
1171
|
+
args: [{
|
|
1172
|
+
providedIn: 'root',
|
|
1173
|
+
}]
|
|
1174
|
+
}], ctorParameters: () => [{ type: i1.ActivatedRoute }] });
|
|
1175
|
+
|
|
1176
|
+
class UnsavedChangesGuard {
|
|
1177
|
+
canDeactivate(component) {
|
|
1178
|
+
return component.onDeactivate ? component.onDeactivate() : true;
|
|
1179
|
+
}
|
|
1180
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UnsavedChangesGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1181
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UnsavedChangesGuard }); }
|
|
1182
|
+
}
|
|
1183
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UnsavedChangesGuard, decorators: [{
|
|
1184
|
+
type: Injectable
|
|
1185
|
+
}] });
|
|
1186
|
+
|
|
1187
|
+
/*
|
|
1188
|
+
* Public API Surface of ngx-cho-common
|
|
1189
|
+
*/
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Generated bundle index. Do not edit.
|
|
1193
|
+
*/
|
|
1194
|
+
|
|
1195
|
+
export { AuthCallbackComponent, AuthGuardService, AuthService, AuthUser, AuthorizationContext, ConsoleLoggerSink, DateService, DownloadService, FeatureGuardService, FeatureService, IntervalService, IntervalTimer, LocalStorageService, Logger, LoggerService, ModalService, NavigationService, ObjectService, RestClient, RouteParamService, SECURITY_POLICIES, SecurityPolicy, ServerLoggerSink, SessionStorageService, SeverityLevel, SigninComponent, SignoutComponent, UnsavedChangesGuard, Uuid };
|
|
1196
|
+
//# sourceMappingURL=ngx-cho-common.mjs.map
|