@codex-ts/core-lib 1.0.15 → 1.0.17
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/fesm2022/codex-ts-core-lib.mjs +218 -42
- package/fesm2022/codex-ts-core-lib.mjs.map +1 -1
- package/lib/keycloak/keycloak-config.interface.d.ts +56 -7
- package/lib/keycloak/keycloak.guard.d.ts +11 -0
- package/lib/keycloak/keycloak.interceptor.d.ts +11 -0
- package/lib/keycloak/keycloak.providers.d.ts +25 -0
- package/lib/keycloak/keycloak.service.d.ts +52 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, PLATFORM_ID, signal, computed, Injectable, importProvidersFrom, Component, NgModule, Directive, Input, ViewChild, Pipe } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, PLATFORM_ID, signal, computed, Injectable, importProvidersFrom, APP_INITIALIZER, Component, NgModule, Directive, Input, ViewChild, Pipe } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common/http';
|
|
4
|
-
import { HttpClient, HttpClientModule, HttpParams } from '@angular/common/http';
|
|
4
|
+
import { HttpClient, HTTP_INTERCEPTORS, HttpClientModule, HttpParams } from '@angular/common/http';
|
|
5
5
|
import * as i1$2 from '@angular/common';
|
|
6
6
|
import { isPlatformBrowser, CommonModule, formatDate } from '@angular/common';
|
|
7
|
-
import { BehaviorSubject, finalize, Observable, forkJoin,
|
|
8
|
-
import
|
|
7
|
+
import { from, mergeMap, catchError, throwError, map, BehaviorSubject, finalize, Observable, forkJoin, of, isObservable, Subject, take as take$1, tap as tap$1, takeUntil as takeUntil$1, ReplaySubject, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs';
|
|
8
|
+
import * as i1$3 from '@angular/router';
|
|
9
|
+
import { Router } from '@angular/router';
|
|
10
|
+
import { toObservable } from '@angular/core/rxjs-interop';
|
|
11
|
+
import { retry, timeout, catchError as catchError$1, take, map as map$1, finalize as finalize$1, switchMap, takeUntil, mergeMap as mergeMap$1, tap, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
9
12
|
import * as i4 from 'primeng/api';
|
|
10
13
|
import * as i1$1 from '@angular/forms';
|
|
11
14
|
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
@@ -29,7 +32,6 @@ import * as i3$4 from 'primeng/inputtextarea';
|
|
|
29
32
|
import { Textarea } from 'primeng/inputtextarea';
|
|
30
33
|
import * as i2$1 from 'primeng/tooltip';
|
|
31
34
|
import { TooltipModule } from 'primeng/tooltip';
|
|
32
|
-
import * as i1$3 from '@angular/router';
|
|
33
35
|
|
|
34
36
|
class AppConstants {
|
|
35
37
|
static FORM = {
|
|
@@ -136,6 +138,28 @@ var TaskRole;
|
|
|
136
138
|
|
|
137
139
|
const KEYCLOAK_CONFIG = new InjectionToken('KEYCLOAK_CONFIG');
|
|
138
140
|
|
|
141
|
+
/** Keycloak error types */
|
|
142
|
+
var KeycloakErrorType;
|
|
143
|
+
(function (KeycloakErrorType) {
|
|
144
|
+
KeycloakErrorType["SCRIPT_LOAD"] = "SCRIPT_LOAD_ERROR";
|
|
145
|
+
KeycloakErrorType["INIT"] = "INIT_ERROR";
|
|
146
|
+
KeycloakErrorType["TOKEN_REFRESH"] = "TOKEN_REFRESH_ERROR";
|
|
147
|
+
KeycloakErrorType["PROFILE_LOAD"] = "PROFILE_LOAD_ERROR";
|
|
148
|
+
})(KeycloakErrorType || (KeycloakErrorType = {}));
|
|
149
|
+
/** Keycloak error with type and details */
|
|
150
|
+
class KeycloakError extends Error {
|
|
151
|
+
type;
|
|
152
|
+
originalError;
|
|
153
|
+
constructor(type, message, originalError) {
|
|
154
|
+
super(message);
|
|
155
|
+
this.type = type;
|
|
156
|
+
this.originalError = originalError;
|
|
157
|
+
this.name = 'KeycloakError';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Service for handling Keycloak authentication and authorization
|
|
162
|
+
*/
|
|
139
163
|
class KeycloakService {
|
|
140
164
|
http = inject(HttpClient);
|
|
141
165
|
platformId = inject(PLATFORM_ID);
|
|
@@ -146,6 +170,22 @@ class KeycloakService {
|
|
|
146
170
|
#userProfile = signal(null);
|
|
147
171
|
isAuthenticated$ = computed(() => this.#isAuthenticated());
|
|
148
172
|
userProfile$ = computed(() => this.#userProfile());
|
|
173
|
+
/** Check if URL should be excluded from bearer token */
|
|
174
|
+
isUrlExcluded(url) {
|
|
175
|
+
return this.config.bearerExcludedUrls?.some(excluded => url.startsWith(excluded) || new RegExp(excluded).test(url)) ?? false;
|
|
176
|
+
}
|
|
177
|
+
/** Validate Keycloak configuration */
|
|
178
|
+
validateConfig() {
|
|
179
|
+
if (!this.config.authServerUrl) {
|
|
180
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Auth server URL is required');
|
|
181
|
+
}
|
|
182
|
+
if (!this.config.realm) {
|
|
183
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Realm is required');
|
|
184
|
+
}
|
|
185
|
+
if (!this.config.clientId) {
|
|
186
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Client ID is required');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
149
189
|
loadKeycloakScript() {
|
|
150
190
|
if (!this.isBrowser)
|
|
151
191
|
return Promise.resolve();
|
|
@@ -165,17 +205,26 @@ class KeycloakService {
|
|
|
165
205
|
return '';
|
|
166
206
|
return `${window.location.origin}/node_modules/@codex-ts/core-lib/assets/keycloak/silent-check-sso.html`;
|
|
167
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Initialize Keycloak authentication
|
|
210
|
+
* @returns Promise resolving to true if initialization is successful
|
|
211
|
+
* @throws KeycloakError if initialization fails
|
|
212
|
+
*/
|
|
168
213
|
async initialize() {
|
|
169
214
|
if (!this.isBrowser)
|
|
170
215
|
return false;
|
|
171
216
|
try {
|
|
217
|
+
this.validateConfig();
|
|
172
218
|
await this.loadKeycloakScript();
|
|
173
219
|
const keycloak = new Keycloak(this.config);
|
|
174
220
|
this.#keycloakInstance.set(keycloak);
|
|
175
|
-
const
|
|
176
|
-
onLoad: '
|
|
177
|
-
silentCheckSsoRedirectUri: this.getSilentCheckUrl()
|
|
178
|
-
|
|
221
|
+
const initOptions = {
|
|
222
|
+
onLoad: 'login-required',
|
|
223
|
+
silentCheckSsoRedirectUri: this.getSilentCheckUrl(),
|
|
224
|
+
checkLoginIframe: false,
|
|
225
|
+
...this.config.initOptions
|
|
226
|
+
};
|
|
227
|
+
const authenticated = await keycloak.init(initOptions);
|
|
179
228
|
this.#isAuthenticated.set(authenticated);
|
|
180
229
|
if (authenticated) {
|
|
181
230
|
await this.loadUserProfile();
|
|
@@ -183,45 +232,78 @@ class KeycloakService {
|
|
|
183
232
|
return authenticated;
|
|
184
233
|
}
|
|
185
234
|
catch (error) {
|
|
186
|
-
|
|
187
|
-
return false;
|
|
235
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Failed to initialize Keycloak', error);
|
|
188
236
|
}
|
|
189
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Redirect to Keycloak login page
|
|
240
|
+
* @param options Additional login options
|
|
241
|
+
* @returns Promise resolving when login is complete
|
|
242
|
+
*/
|
|
190
243
|
login(options = {}) {
|
|
244
|
+
const instance = this.#keycloakInstance();
|
|
245
|
+
if (!instance) {
|
|
246
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Keycloak not initialized');
|
|
247
|
+
}
|
|
191
248
|
const loginOptions = {
|
|
192
249
|
...this.config.loginOptions,
|
|
193
250
|
...options
|
|
194
251
|
};
|
|
195
|
-
return
|
|
252
|
+
return instance.login(loginOptions);
|
|
196
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Logout the current user
|
|
256
|
+
* @returns Promise resolving when logout is complete
|
|
257
|
+
*/
|
|
197
258
|
logout() {
|
|
198
|
-
|
|
259
|
+
const instance = this.#keycloakInstance();
|
|
260
|
+
if (!instance) {
|
|
261
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Keycloak not initialized');
|
|
262
|
+
}
|
|
263
|
+
return instance.logout();
|
|
199
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Get the current access token
|
|
267
|
+
* @returns Promise resolving to the access token or null
|
|
268
|
+
*/
|
|
200
269
|
async getToken() {
|
|
201
270
|
try {
|
|
202
271
|
await this.updateToken(this.config.tokenValidityInSeconds || 60);
|
|
203
|
-
return this.#keycloakInstance()?.token;
|
|
272
|
+
return this.#keycloakInstance()?.token ?? null;
|
|
204
273
|
}
|
|
205
274
|
catch (error) {
|
|
206
|
-
|
|
207
|
-
return null;
|
|
275
|
+
throw new KeycloakError(KeycloakErrorType.TOKEN_REFRESH, 'Failed to get token', error);
|
|
208
276
|
}
|
|
209
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Get the current user's roles
|
|
280
|
+
* @returns Array of role names
|
|
281
|
+
*/
|
|
210
282
|
getRoles() {
|
|
211
283
|
const keycloak = this.#keycloakInstance();
|
|
212
|
-
if (!keycloak
|
|
213
|
-
|
|
284
|
+
if (!keycloak) {
|
|
285
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Keycloak not initialized');
|
|
214
286
|
}
|
|
215
|
-
return keycloak.realmAccess
|
|
287
|
+
return keycloak.realmAccess?.roles ?? [];
|
|
216
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Check if the current user has a specific role
|
|
291
|
+
* @param role Role name to check
|
|
292
|
+
* @returns true if user has the role
|
|
293
|
+
*/
|
|
217
294
|
hasRole(role) {
|
|
218
295
|
return this.getRoles().includes(role);
|
|
219
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Update the access token if it's close to expiring
|
|
299
|
+
* @param minValidity Minimum validity time in seconds
|
|
300
|
+
* @returns Promise resolving to true if token was refreshed
|
|
301
|
+
*/
|
|
220
302
|
updateToken(minValidity = 60) {
|
|
221
303
|
return new Promise((resolve, reject) => {
|
|
222
304
|
const keycloak = this.#keycloakInstance();
|
|
223
305
|
if (!keycloak?.token) {
|
|
224
|
-
|
|
306
|
+
reject(new KeycloakError(KeycloakErrorType.TOKEN_REFRESH, 'No token available'));
|
|
225
307
|
return;
|
|
226
308
|
}
|
|
227
309
|
keycloak.updateToken(minValidity)
|
|
@@ -229,8 +311,7 @@ class KeycloakService {
|
|
|
229
311
|
resolve(refreshed);
|
|
230
312
|
})
|
|
231
313
|
.catch((error) => {
|
|
232
|
-
|
|
233
|
-
reject(error);
|
|
314
|
+
reject(new KeycloakError(KeycloakErrorType.TOKEN_REFRESH, 'Failed to refresh token', error));
|
|
234
315
|
});
|
|
235
316
|
});
|
|
236
317
|
}
|
|
@@ -254,6 +335,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
|
|
|
254
335
|
args: [{ providedIn: 'root' }]
|
|
255
336
|
}] });
|
|
256
337
|
|
|
338
|
+
class KeycloakAuthInterceptor {
|
|
339
|
+
keycloakService;
|
|
340
|
+
constructor(keycloakService) {
|
|
341
|
+
this.keycloakService = keycloakService;
|
|
342
|
+
}
|
|
343
|
+
intercept(req, next) {
|
|
344
|
+
// Skip bearer token for excluded URLs
|
|
345
|
+
if (this.keycloakService.isUrlExcluded(req.url)) {
|
|
346
|
+
return next.handle(req);
|
|
347
|
+
}
|
|
348
|
+
return from(this.keycloakService.getToken()).pipe(mergeMap(token => {
|
|
349
|
+
if (token) {
|
|
350
|
+
const authReq = req.clone({
|
|
351
|
+
headers: req.headers.set('Authorization', `Bearer ${token}`)
|
|
352
|
+
});
|
|
353
|
+
return next.handle(authReq);
|
|
354
|
+
}
|
|
355
|
+
return next.handle(req);
|
|
356
|
+
}), catchError((error) => {
|
|
357
|
+
// Handle 401/403 errors by refreshing token or redirecting to login
|
|
358
|
+
if (error.status === 401 || error.status === 403) {
|
|
359
|
+
return from(this.keycloakService.updateToken()).pipe(mergeMap(refreshed => {
|
|
360
|
+
if (refreshed) {
|
|
361
|
+
return from(this.keycloakService.getToken()).pipe(mergeMap(newToken => {
|
|
362
|
+
const authReq = req.clone({
|
|
363
|
+
headers: req.headers.set('Authorization', `Bearer ${newToken}`)
|
|
364
|
+
});
|
|
365
|
+
return next.handle(authReq);
|
|
366
|
+
}));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
// Token refresh failed, redirect to login
|
|
370
|
+
this.keycloakService.login();
|
|
371
|
+
return throwError(() => error);
|
|
372
|
+
}
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
return throwError(() => error);
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthInterceptor, deps: [{ token: KeycloakService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
379
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthInterceptor });
|
|
380
|
+
}
|
|
381
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthInterceptor, decorators: [{
|
|
382
|
+
type: Injectable
|
|
383
|
+
}], ctorParameters: () => [{ type: KeycloakService }] });
|
|
384
|
+
|
|
385
|
+
function initializeKeycloak(keycloak) {
|
|
386
|
+
return () => keycloak.initialize();
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Provides Keycloak authentication and authorization services
|
|
390
|
+
* @param config Keycloak configuration
|
|
391
|
+
* @returns Array of providers for Keycloak integration
|
|
392
|
+
*/
|
|
257
393
|
function provideKeycloak(config) {
|
|
258
394
|
return [
|
|
259
395
|
importProvidersFrom(HttpClientModule),
|
|
@@ -261,10 +397,50 @@ function provideKeycloak(config) {
|
|
|
261
397
|
provide: KEYCLOAK_CONFIG,
|
|
262
398
|
useValue: config
|
|
263
399
|
},
|
|
264
|
-
KeycloakService
|
|
400
|
+
KeycloakService,
|
|
401
|
+
{
|
|
402
|
+
provide: APP_INITIALIZER,
|
|
403
|
+
useFactory: initializeKeycloak,
|
|
404
|
+
multi: true,
|
|
405
|
+
deps: [KeycloakService]
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
provide: HTTP_INTERCEPTORS,
|
|
409
|
+
useClass: KeycloakAuthInterceptor,
|
|
410
|
+
multi: true
|
|
411
|
+
}
|
|
265
412
|
];
|
|
266
413
|
}
|
|
267
414
|
|
|
415
|
+
class KeycloakAuthGuard {
|
|
416
|
+
keycloakService = inject(KeycloakService);
|
|
417
|
+
router = inject(Router);
|
|
418
|
+
canActivate(route, state) {
|
|
419
|
+
return toObservable(this.keycloakService.isAuthenticated$).pipe(map(authenticated => {
|
|
420
|
+
if (!authenticated) {
|
|
421
|
+
this.keycloakService.login({
|
|
422
|
+
redirectUri: window.location.origin + state.url
|
|
423
|
+
});
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
const requiredRoles = route.data['roles'];
|
|
427
|
+
if (requiredRoles && !this.hasRequiredRoles(requiredRoles)) {
|
|
428
|
+
return this.router.createUrlTree(['/unauthorized']);
|
|
429
|
+
}
|
|
430
|
+
return true;
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
hasRequiredRoles(requiredRoles) {
|
|
434
|
+
return requiredRoles.every(role => this.keycloakService.getRoles().includes(role));
|
|
435
|
+
}
|
|
436
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
437
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthGuard, providedIn: 'root' });
|
|
438
|
+
}
|
|
439
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthGuard, decorators: [{
|
|
440
|
+
type: Injectable,
|
|
441
|
+
args: [{ providedIn: 'root' }]
|
|
442
|
+
}] });
|
|
443
|
+
|
|
268
444
|
/**
|
|
269
445
|
* A general-purpose HTTP utility service that provides enhanced HTTP operations
|
|
270
446
|
* beyond the standard Angular HttpClient. This service includes features such as:
|
|
@@ -303,7 +479,7 @@ class HttpUtilityService {
|
|
|
303
479
|
if (options?.timeoutMs) {
|
|
304
480
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
305
481
|
}
|
|
306
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
482
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
307
483
|
}
|
|
308
484
|
/**
|
|
309
485
|
* Perform a POST request with enhanced options
|
|
@@ -326,7 +502,7 @@ class HttpUtilityService {
|
|
|
326
502
|
if (options?.timeoutMs) {
|
|
327
503
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
328
504
|
}
|
|
329
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
505
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
330
506
|
}
|
|
331
507
|
/**
|
|
332
508
|
* Perform a PUT request with enhanced options
|
|
@@ -349,7 +525,7 @@ class HttpUtilityService {
|
|
|
349
525
|
if (options?.timeoutMs) {
|
|
350
526
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
351
527
|
}
|
|
352
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
528
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
353
529
|
}
|
|
354
530
|
/**
|
|
355
531
|
* Perform a DELETE request with enhanced options
|
|
@@ -371,7 +547,7 @@ class HttpUtilityService {
|
|
|
371
547
|
if (options?.timeoutMs) {
|
|
372
548
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
373
549
|
}
|
|
374
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
550
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
375
551
|
}
|
|
376
552
|
/**
|
|
377
553
|
* Upload a file with optional additional data
|
|
@@ -434,7 +610,7 @@ class HttpUtilityService {
|
|
|
434
610
|
});
|
|
435
611
|
}
|
|
436
612
|
// Standard request without progress tracking
|
|
437
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
613
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
438
614
|
}
|
|
439
615
|
/**
|
|
440
616
|
* Execute multiple HTTP requests in parallel
|
|
@@ -443,7 +619,7 @@ class HttpUtilityService {
|
|
|
443
619
|
*/
|
|
444
620
|
batchRequests(requests) {
|
|
445
621
|
this.loading.next(true);
|
|
446
|
-
return forkJoin(requests).pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
622
|
+
return forkJoin(requests).pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
447
623
|
}
|
|
448
624
|
/**
|
|
449
625
|
* Download a file from the server
|
|
@@ -462,7 +638,7 @@ class HttpUtilityService {
|
|
|
462
638
|
if (options?.timeoutMs) {
|
|
463
639
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
464
640
|
}
|
|
465
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
641
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
466
642
|
}
|
|
467
643
|
/**
|
|
468
644
|
* Create parameter string from an object
|
|
@@ -1017,7 +1193,7 @@ class FormService {
|
|
|
1017
1193
|
return of(void 0);
|
|
1018
1194
|
}
|
|
1019
1195
|
this.formState.loading = true;
|
|
1020
|
-
return this.entityService.getById(uuid).pipe(take(1), map(data => {
|
|
1196
|
+
return this.entityService.getById(uuid).pipe(take(1), map$1(data => {
|
|
1021
1197
|
this.updateFormState(data);
|
|
1022
1198
|
}), finalize$1(() => this.formState.loading = false));
|
|
1023
1199
|
}
|
|
@@ -1037,7 +1213,7 @@ class FormService {
|
|
|
1037
1213
|
}
|
|
1038
1214
|
this.formState.loading = true;
|
|
1039
1215
|
const operation$ = this.getSubmitOperation();
|
|
1040
|
-
return operation$.pipe(finalize$1(() => this.formState.loading = false), map(result => {
|
|
1216
|
+
return operation$.pipe(finalize$1(() => this.formState.loading = false), map$1(result => {
|
|
1041
1217
|
this.notificationService.showSuccess(`${this.entityName} ${AppMessages.FORM.SUCCESS.SAVE}`);
|
|
1042
1218
|
return result;
|
|
1043
1219
|
}));
|
|
@@ -1776,14 +1952,14 @@ class BaseFormComponent extends BasePageComponent {
|
|
|
1776
1952
|
});
|
|
1777
1953
|
}
|
|
1778
1954
|
initializeForm() {
|
|
1779
|
-
return this.route.queryParams.pipe(take(1), map(params => {
|
|
1955
|
+
return this.route.queryParams.pipe(take(1), map$1(params => {
|
|
1780
1956
|
this.initializeFormMode(params[AppConstants.FORM.MODE]);
|
|
1781
1957
|
this.setupFormState();
|
|
1782
1958
|
this.initializeFormSubscriptions();
|
|
1783
1959
|
}));
|
|
1784
1960
|
}
|
|
1785
1961
|
loadFormData() {
|
|
1786
|
-
return this.route.queryParams.pipe(take(1), mergeMap(params => {
|
|
1962
|
+
return this.route.queryParams.pipe(take(1), mergeMap$1(params => {
|
|
1787
1963
|
const state = this.getRouterState();
|
|
1788
1964
|
if (this.state.mode === AppConstants.PAGE_MODE.CREATE) {
|
|
1789
1965
|
return of(void 0);
|
|
@@ -1797,7 +1973,7 @@ class BaseFormComponent extends BasePageComponent {
|
|
|
1797
1973
|
throw new Error(`UUID is required for ${this.state.mode} mode`);
|
|
1798
1974
|
}
|
|
1799
1975
|
return this.getEntityOperations().getById(uuid)
|
|
1800
|
-
.pipe(tap(data => this.updateFormState(data)), map(() => void 0));
|
|
1976
|
+
.pipe(tap(data => this.updateFormState(data)), map$1(() => void 0));
|
|
1801
1977
|
}));
|
|
1802
1978
|
}
|
|
1803
1979
|
getRouterState() {
|
|
@@ -2376,7 +2552,7 @@ class BaseTabbedFormComponent extends BasePageComponent {
|
|
|
2376
2552
|
activeTab: tabs[0]?.value || ''
|
|
2377
2553
|
};
|
|
2378
2554
|
// Then initialize form
|
|
2379
|
-
this.route.queryParams.pipe(take$1(1), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(params => this.initializeForm(params)), map
|
|
2555
|
+
this.route.queryParams.pipe(take$1(1), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(params => this.initializeForm(params)), map(() => void 0), catchError(error => {
|
|
2380
2556
|
console.error('Error initializing form:', error);
|
|
2381
2557
|
this.showError(AppMessages.FORM.ERROR.INIT);
|
|
2382
2558
|
return of(void 0);
|
|
@@ -2432,13 +2608,13 @@ class BaseTabbedFormComponent extends BasePageComponent {
|
|
|
2432
2608
|
}
|
|
2433
2609
|
}
|
|
2434
2610
|
loadFromUuid() {
|
|
2435
|
-
this.route.queryParams.pipe(take$1(1), map
|
|
2611
|
+
this.route.queryParams.pipe(take$1(1), map((params) => {
|
|
2436
2612
|
const uuid = params[AppConstants.FORM.UUID];
|
|
2437
2613
|
if (!uuid) {
|
|
2438
2614
|
throw new Error(`UUID is required for ${this.state.mode} mode when no formData is provided`);
|
|
2439
2615
|
}
|
|
2440
2616
|
return uuid;
|
|
2441
|
-
}), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(uuid => this.loadEntity(uuid)), catchError
|
|
2617
|
+
}), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(uuid => this.loadEntity(uuid)), catchError(error => {
|
|
2442
2618
|
console.error('Error loading UUID:', error);
|
|
2443
2619
|
this.showError(`${AppMessages.FORM.ERROR.LOAD} UUID`);
|
|
2444
2620
|
return of(void 0);
|
|
@@ -2639,7 +2815,7 @@ class BaseListTabbedFormComponent extends BasePageComponent {
|
|
|
2639
2815
|
this.setupRouteParamsSubscription();
|
|
2640
2816
|
}
|
|
2641
2817
|
initializeFormFromQueryParams() {
|
|
2642
|
-
this.route.queryParams.pipe(take$1(1), catchError
|
|
2818
|
+
this.route.queryParams.pipe(take$1(1), catchError(error => {
|
|
2643
2819
|
console.error('Error initializing form:', error);
|
|
2644
2820
|
this.showError(AppMessages.FORM.ERROR.INIT);
|
|
2645
2821
|
throw error;
|
|
@@ -2820,7 +2996,7 @@ class BaseTaskDetailsComponent extends BasePageComponent {
|
|
|
2820
2996
|
this.formlyConfigService = formlyConfigService;
|
|
2821
2997
|
}
|
|
2822
2998
|
initializeServices() {
|
|
2823
|
-
return of(void 0).pipe(map(() => {
|
|
2999
|
+
return of(void 0).pipe(map$1(() => {
|
|
2824
3000
|
this.formService = new FormService(this.getEntityService(), this.formlyConfigService, this.notificationService, this.getEntityName(), this.getJsonFields(), this.getDropdownOptions());
|
|
2825
3001
|
this.state = this.formService.getState();
|
|
2826
3002
|
this.loading = this.state.loading;
|
|
@@ -2835,7 +3011,7 @@ class BaseTaskDetailsComponent extends BasePageComponent {
|
|
|
2835
3011
|
});
|
|
2836
3012
|
}
|
|
2837
3013
|
initializeFromRoute() {
|
|
2838
|
-
return this.route.queryParams.pipe(map(params => {
|
|
3014
|
+
return this.route.queryParams.pipe(map$1(params => {
|
|
2839
3015
|
const mode = params[AppConstants.FORM.MODE];
|
|
2840
3016
|
if (mode) {
|
|
2841
3017
|
this.formService.setMode(mode);
|
|
@@ -3089,5 +3265,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
|
|
|
3089
3265
|
* Generated bundle index. Do not edit.
|
|
3090
3266
|
*/
|
|
3091
3267
|
|
|
3092
|
-
export { AppConstants, AppMessages, BaseCrudService, BaseFormComponent, BaseListPageComponent, BaseListTabbedFormComponent, BasePageComponent, BaseTabbedFormComponent, BaseTaskDashboardComponent, BaseTaskDetailsComponent, BaseTaskService, ComponentContext, CoreFormlyModule, FormService, FormlyConfigService, HttpUtilityService, IndianDatePipe, KEYCLOAK_CONFIG, KeycloakService, NotificationService, TabbedFormType, TaskRole, UtilsService, provideKeycloak };
|
|
3268
|
+
export { AppConstants, AppMessages, BaseCrudService, BaseFormComponent, BaseListPageComponent, BaseListTabbedFormComponent, BasePageComponent, BaseTabbedFormComponent, BaseTaskDashboardComponent, BaseTaskDetailsComponent, BaseTaskService, ComponentContext, CoreFormlyModule, FormService, FormlyConfigService, HttpUtilityService, IndianDatePipe, KEYCLOAK_CONFIG, KeycloakAuthGuard, KeycloakError, KeycloakErrorType, KeycloakService, NotificationService, TabbedFormType, TaskRole, UtilsService, provideKeycloak };
|
|
3093
3269
|
//# sourceMappingURL=codex-ts-core-lib.mjs.map
|