@flusys/ng-auth 3.0.0-rc → 3.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 +676 -365
- package/fesm2022/flusys-ng-auth.mjs +1566 -474
- package/fesm2022/flusys-ng-auth.mjs.map +1 -1
- package/package.json +12 -12
- package/types/flusys-ng-auth.d.ts +217 -35
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import * as i1 from '@angular/common/http';
|
|
2
1
|
import { HttpClient } from '@angular/common/http';
|
|
3
2
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { inject, Injectable, signal, computed, effect, PLATFORM_ID, ChangeDetectionStrategy, Component, untracked, DestroyRef, input, output, makeStateKey, TransferState } from '@angular/core';
|
|
5
|
-
import { APP_CONFIG, getServiceUrl, isCompanyFeatureEnabled, isFeatureEnabled, getPermissionMode } from '@flusys/ng-core';
|
|
3
|
+
import { inject, Injectable, signal, computed, effect, PLATFORM_ID, InjectionToken, ChangeDetectionStrategy, Component, untracked, DestroyRef, input, Injector, output, makeStateKey, TransferState } from '@angular/core';
|
|
4
|
+
import { APP_CONFIG, getServiceUrl, isCompanyFeatureEnabled, isEmailFeatureEnabled, isSignUpEnabled, isFeatureEnabled, getPermissionMode, getDefaultCompanySlug, getDefaultBranchSlug } from '@flusys/ng-core';
|
|
6
5
|
import * as i2$1 from '@angular/router';
|
|
7
6
|
import { Router, RouterOutlet, RouterLink, RouterLinkActive, ActivatedRoute } from '@angular/router';
|
|
8
|
-
import { of, timeout, switchMap, map, tap, catchError, shareReplay, finalize, BehaviorSubject, throwError, filter, take, firstValueFrom } from 'rxjs';
|
|
7
|
+
import { of, timeout, switchMap, map, tap, catchError, shareReplay, finalize, BehaviorSubject, throwError, filter, take, forkJoin, firstValueFrom } from 'rxjs';
|
|
9
8
|
import { PlatformService, ApiResourceService, CookieService, permissionGuard, USER_PERMISSIONS, COMPANY_PERMISSIONS, BRANCH_PERMISSIONS, USER_PROVIDER, COMPANY_API_PROVIDER, USER_PERMISSION_PROVIDER, AUTH_STATE_PROVIDER, PermissionValidatorService, AngularModule, PrimeModule, HasPermissionDirective, FileUrlService, PROFILE_UPLOAD_PROVIDER, PROFILE_PERMISSION_PROVIDER, FileUploaderComponent } from '@flusys/ng-shared';
|
|
10
9
|
import { map as map$1, catchError as catchError$1, tap as tap$1 } from 'rxjs/operators';
|
|
10
|
+
import * as i1$1 from '@angular/common';
|
|
11
11
|
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
12
12
|
import { MessageService, ConfirmationService } from 'primeng/api';
|
|
13
13
|
import { LAYOUT_AUTH_STATE, LAYOUT_AUTH_API, AppFloatingConfigurator } from '@flusys/ng-layout';
|
|
14
14
|
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
15
15
|
import { form, required, FormField, email, minLength } from '@angular/forms/signals';
|
|
16
|
-
import * as i1
|
|
16
|
+
import * as i1 from '@angular/forms';
|
|
17
17
|
import * as i2 from 'primeng/button';
|
|
18
18
|
import * as i3 from 'primeng/card';
|
|
19
19
|
import * as i4 from 'primeng/inputtext';
|
|
20
|
-
import * as
|
|
20
|
+
import * as i6 from 'primeng/tag';
|
|
21
21
|
import { TagModule } from 'primeng/tag';
|
|
22
22
|
import * as i4$1 from 'primeng/select';
|
|
23
|
-
import * as
|
|
24
|
-
import * as
|
|
25
|
-
import * as
|
|
26
|
-
import * as
|
|
27
|
-
import * as
|
|
28
|
-
import * as
|
|
23
|
+
import * as i5 from 'primeng/table';
|
|
24
|
+
import * as i7 from 'primeng/tooltip';
|
|
25
|
+
import * as i3$1 from 'primeng/avatar';
|
|
26
|
+
import * as i6$1 from 'primeng/password';
|
|
27
|
+
import * as i7$1 from 'primeng/skeleton';
|
|
28
|
+
import * as i9 from 'primeng/textarea';
|
|
29
|
+
import * as i4$2 from 'primeng/dialog';
|
|
29
30
|
import { DialogModule } from 'primeng/dialog';
|
|
30
|
-
import * as i5$
|
|
31
|
+
import * as i5$1 from 'primeng/progressspinner';
|
|
31
32
|
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
|
32
33
|
import * as i3$2 from 'primeng/checkbox';
|
|
33
34
|
|
|
@@ -144,10 +145,10 @@ class AuthApiService {
|
|
|
144
145
|
token,
|
|
145
146
|
});
|
|
146
147
|
}
|
|
147
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
148
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
148
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
149
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthApiService, providedIn: 'root' });
|
|
149
150
|
}
|
|
150
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthApiService, decorators: [{
|
|
151
152
|
type: Injectable,
|
|
152
153
|
args: [{ providedIn: 'root' }]
|
|
153
154
|
}], ctorParameters: () => [] });
|
|
@@ -347,10 +348,10 @@ class AuthStateService {
|
|
|
347
348
|
if (!this.platform.isServer)
|
|
348
349
|
localStorage.removeItem(key);
|
|
349
350
|
}
|
|
350
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
351
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
351
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
352
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthStateService, providedIn: 'root' });
|
|
352
353
|
}
|
|
353
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthStateService, decorators: [{
|
|
354
355
|
type: Injectable,
|
|
355
356
|
args: [{ providedIn: 'root' }]
|
|
356
357
|
}], ctorParameters: () => [] });
|
|
@@ -457,10 +458,10 @@ class AuthInitService {
|
|
|
457
458
|
}));
|
|
458
459
|
return this.initializationCache$;
|
|
459
460
|
}
|
|
460
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
461
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
461
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthInitService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
462
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthInitService, providedIn: 'root' });
|
|
462
463
|
}
|
|
463
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
464
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthInitService, decorators: [{
|
|
464
465
|
type: Injectable,
|
|
465
466
|
args: [{ providedIn: 'root' }]
|
|
466
467
|
}] });
|
|
@@ -471,8 +472,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
471
472
|
*/
|
|
472
473
|
class BranchApiService extends ApiResourceService {
|
|
473
474
|
_currentCompanyId = signal(null, ...(ngDevMode ? [{ debugName: "_currentCompanyId" }] : []));
|
|
474
|
-
constructor(
|
|
475
|
-
super('
|
|
475
|
+
constructor() {
|
|
476
|
+
super('branch', inject(HttpClient), 'administration');
|
|
476
477
|
}
|
|
477
478
|
setCurrentCompanyId(companyId) {
|
|
478
479
|
this._currentCompanyId.set(companyId);
|
|
@@ -481,29 +482,29 @@ class BranchApiService extends ApiResourceService {
|
|
|
481
482
|
this.setCurrentCompanyId(companyId);
|
|
482
483
|
this.fetchList(search, { filter: { companyId } });
|
|
483
484
|
}
|
|
484
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
485
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
485
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
486
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchApiService, providedIn: 'root' });
|
|
486
487
|
}
|
|
487
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
488
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchApiService, decorators: [{
|
|
488
489
|
type: Injectable,
|
|
489
490
|
args: [{ providedIn: 'root' }]
|
|
490
|
-
}], ctorParameters: () => [
|
|
491
|
+
}], ctorParameters: () => [] });
|
|
491
492
|
|
|
492
493
|
/**
|
|
493
494
|
* Company API Service
|
|
494
495
|
* Signal-based service for company CRUD operations
|
|
495
496
|
*/
|
|
496
497
|
class CompanyApiService extends ApiResourceService {
|
|
497
|
-
constructor(
|
|
498
|
-
super('
|
|
498
|
+
constructor() {
|
|
499
|
+
super('company', inject(HttpClient), 'administration');
|
|
499
500
|
}
|
|
500
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
501
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
501
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
502
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyApiService, providedIn: 'root' });
|
|
502
503
|
}
|
|
503
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyApiService, decorators: [{
|
|
504
505
|
type: Injectable,
|
|
505
506
|
args: [{ providedIn: 'root' }]
|
|
506
|
-
}], ctorParameters: () => [
|
|
507
|
+
}], ctorParameters: () => [] });
|
|
507
508
|
|
|
508
509
|
/**
|
|
509
510
|
* Token Refresh State Service
|
|
@@ -526,10 +527,10 @@ class TokenRefreshStateService {
|
|
|
526
527
|
failRefresh() {
|
|
527
528
|
this._isRefreshing.set(false);
|
|
528
529
|
}
|
|
529
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
530
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
530
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TokenRefreshStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
531
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TokenRefreshStateService, providedIn: 'root' });
|
|
531
532
|
}
|
|
532
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
533
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TokenRefreshStateService, decorators: [{
|
|
533
534
|
type: Injectable,
|
|
534
535
|
args: [{ providedIn: 'root' }]
|
|
535
536
|
}] });
|
|
@@ -539,28 +540,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
539
540
|
* Signal-based service for user CRUD operations
|
|
540
541
|
*/
|
|
541
542
|
class UserApiService extends ApiResourceService {
|
|
542
|
-
constructor(
|
|
543
|
-
super('
|
|
543
|
+
constructor() {
|
|
544
|
+
super('users', inject(HttpClient), 'administration');
|
|
544
545
|
}
|
|
545
546
|
updateProfile(data) {
|
|
546
547
|
return this.http.post(`${this.baseUrl}/profile`, data);
|
|
547
548
|
}
|
|
548
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
549
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
549
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
550
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserApiService, providedIn: 'root' });
|
|
550
551
|
}
|
|
551
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
552
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserApiService, decorators: [{
|
|
552
553
|
type: Injectable,
|
|
553
554
|
args: [{ providedIn: 'root' }]
|
|
554
|
-
}], ctorParameters: () => [
|
|
555
|
+
}], ctorParameters: () => [] });
|
|
555
556
|
|
|
556
557
|
/**
|
|
557
558
|
* User Permission API Service
|
|
558
559
|
* Handles user-company and user-branch permission assignments.
|
|
560
|
+
* Endpoint: POST /administration/permissions/*
|
|
559
561
|
*/
|
|
560
562
|
class UserPermissionApiService {
|
|
561
563
|
appConfig = inject(APP_CONFIG);
|
|
562
564
|
http = inject(HttpClient);
|
|
563
|
-
baseUrl = this.appConfig
|
|
565
|
+
baseUrl = `${getServiceUrl(this.appConfig, 'administration')}/permissions`;
|
|
564
566
|
// Company Permissions
|
|
565
567
|
assignUserCompanies(data) {
|
|
566
568
|
return this.http.post(`${this.baseUrl}/user-company/assign`, data);
|
|
@@ -590,10 +592,10 @@ class UserPermissionApiService {
|
|
|
590
592
|
...(companyId && { companyId }),
|
|
591
593
|
});
|
|
592
594
|
}
|
|
593
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
594
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
595
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserPermissionApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
596
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserPermissionApiService, providedIn: 'root' });
|
|
595
597
|
}
|
|
596
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
598
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserPermissionApiService, decorators: [{
|
|
597
599
|
type: Injectable,
|
|
598
600
|
args: [{ providedIn: 'root' }]
|
|
599
601
|
}] });
|
|
@@ -672,6 +674,22 @@ const companyFeatureGuard = () => {
|
|
|
672
674
|
return router.createUrlTree(['/']);
|
|
673
675
|
return true;
|
|
674
676
|
};
|
|
677
|
+
/** Protects routes requiring email feature to be enabled */
|
|
678
|
+
const emailFeatureGuard = () => {
|
|
679
|
+
const router = inject(Router);
|
|
680
|
+
const appConfig = inject(APP_CONFIG);
|
|
681
|
+
if (!appConfig.services.email?.enabled)
|
|
682
|
+
return router.createUrlTree([AUTH_ENDPOINTS.LOGIN]);
|
|
683
|
+
return true;
|
|
684
|
+
};
|
|
685
|
+
/** Protects routes requiring sign-up feature to be enabled */
|
|
686
|
+
const signUpFeatureGuard = () => {
|
|
687
|
+
const router = inject(Router);
|
|
688
|
+
const appConfig = inject(APP_CONFIG);
|
|
689
|
+
if (appConfig.enableSignUp === false)
|
|
690
|
+
return router.createUrlTree([AUTH_ENDPOINTS.LOGIN]);
|
|
691
|
+
return true;
|
|
692
|
+
};
|
|
675
693
|
|
|
676
694
|
/** Endpoints that need withCredentials for cookie handling */
|
|
677
695
|
const COOKIE_ENDPOINTS = [
|
|
@@ -789,21 +807,22 @@ const AUTH_ROUTES = [
|
|
|
789
807
|
{
|
|
790
808
|
path: 'register',
|
|
791
809
|
loadComponent: () => Promise.resolve().then(function () { return registerPage_component; }).then((m) => m.RegisterPageComponent),
|
|
792
|
-
canActivate: [guestGuard],
|
|
810
|
+
canActivate: [signUpFeatureGuard, guestGuard],
|
|
793
811
|
},
|
|
794
812
|
{
|
|
795
813
|
path: 'forgot-password',
|
|
796
814
|
loadComponent: () => Promise.resolve().then(function () { return forgotPasswordPage_component; }).then((m) => m.ForgotPasswordPageComponent),
|
|
797
|
-
canActivate: [guestGuard],
|
|
815
|
+
canActivate: [emailFeatureGuard, guestGuard],
|
|
798
816
|
},
|
|
799
817
|
{
|
|
800
818
|
path: 'reset-password',
|
|
801
819
|
loadComponent: () => Promise.resolve().then(function () { return resetPasswordPage_component; }).then((m) => m.ResetPasswordPageComponent),
|
|
802
|
-
canActivate: [guestGuard],
|
|
820
|
+
canActivate: [emailFeatureGuard, guestGuard],
|
|
803
821
|
},
|
|
804
822
|
{
|
|
805
823
|
path: 'verify-email',
|
|
806
824
|
loadComponent: () => Promise.resolve().then(function () { return verifyEmailPage_component; }).then((m) => m.VerifyEmailPageComponent),
|
|
825
|
+
canActivate: [emailFeatureGuard],
|
|
807
826
|
},
|
|
808
827
|
{
|
|
809
828
|
path: '',
|
|
@@ -953,10 +972,10 @@ class AuthLayoutStateAdapter {
|
|
|
953
972
|
}
|
|
954
973
|
return null;
|
|
955
974
|
}, ...(ngDevMode ? [{ debugName: "loginUserData" }] : []));
|
|
956
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
957
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
975
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthLayoutStateAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
976
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthLayoutStateAdapter, providedIn: 'root' });
|
|
958
977
|
}
|
|
959
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
978
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthLayoutStateAdapter, decorators: [{
|
|
960
979
|
type: Injectable,
|
|
961
980
|
args: [{ providedIn: 'root' }]
|
|
962
981
|
}] });
|
|
@@ -1010,10 +1029,10 @@ class AuthLayoutApiAdapter {
|
|
|
1010
1029
|
slug: permission.branchSlug ?? '',
|
|
1011
1030
|
}))));
|
|
1012
1031
|
}
|
|
1013
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1014
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
1032
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthLayoutApiAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1033
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthLayoutApiAdapter, providedIn: 'root' });
|
|
1015
1034
|
}
|
|
1016
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1035
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthLayoutApiAdapter, decorators: [{
|
|
1017
1036
|
type: Injectable,
|
|
1018
1037
|
args: [{ providedIn: 'root' }]
|
|
1019
1038
|
}] });
|
|
@@ -1059,10 +1078,10 @@ class AuthUserProviderAdapter {
|
|
|
1059
1078
|
meta: response.meta,
|
|
1060
1079
|
})));
|
|
1061
1080
|
}
|
|
1062
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1063
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
1081
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthUserProviderAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1082
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthUserProviderAdapter });
|
|
1064
1083
|
}
|
|
1065
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1084
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthUserProviderAdapter, decorators: [{
|
|
1066
1085
|
type: Injectable
|
|
1067
1086
|
}] });
|
|
1068
1087
|
// =============================================================================
|
|
@@ -1089,10 +1108,10 @@ class AuthCompanyApiProviderAdapter {
|
|
|
1089
1108
|
meta: response.meta,
|
|
1090
1109
|
})));
|
|
1091
1110
|
}
|
|
1092
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1093
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
1111
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthCompanyApiProviderAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1112
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthCompanyApiProviderAdapter });
|
|
1094
1113
|
}
|
|
1095
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthCompanyApiProviderAdapter, decorators: [{
|
|
1096
1115
|
type: Injectable
|
|
1097
1116
|
}] });
|
|
1098
1117
|
// =============================================================================
|
|
@@ -1103,10 +1122,10 @@ class AuthUserPermissionProviderAdapter {
|
|
|
1103
1122
|
getUserBranchPermissions(userId, companyId) {
|
|
1104
1123
|
return this.userPermissionApi.getUserBranches(userId, companyId);
|
|
1105
1124
|
}
|
|
1106
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1107
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
1125
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthUserPermissionProviderAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1126
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthUserPermissionProviderAdapter });
|
|
1108
1127
|
}
|
|
1109
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1128
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthUserPermissionProviderAdapter, decorators: [{
|
|
1110
1129
|
type: Injectable
|
|
1111
1130
|
}] });
|
|
1112
1131
|
// =============================================================================
|
|
@@ -1121,10 +1140,10 @@ class AuthStateProviderAdapter {
|
|
|
1121
1140
|
initialize() {
|
|
1122
1141
|
return this.authInit.initialize().pipe(map(() => undefined));
|
|
1123
1142
|
}
|
|
1124
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1125
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.
|
|
1143
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthStateProviderAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1144
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthStateProviderAdapter });
|
|
1126
1145
|
}
|
|
1127
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1146
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AuthStateProviderAdapter, decorators: [{
|
|
1128
1147
|
type: Injectable
|
|
1129
1148
|
}] });
|
|
1130
1149
|
|
|
@@ -1146,6 +1165,51 @@ function provideAuthProviders() {
|
|
|
1146
1165
|
];
|
|
1147
1166
|
}
|
|
1148
1167
|
|
|
1168
|
+
const AUTH_VALIDATION_CONFIG = new InjectionToken('AUTH_VALIDATION_CONFIG');
|
|
1169
|
+
const REGISTRATION_FIELD_CONTEXT = new InjectionToken('REGISTRATION_FIELD_CONTEXT');
|
|
1170
|
+
const AUTH_REGISTRATION_EXTENSION = new InjectionToken('AUTH_REGISTRATION_EXTENSION');
|
|
1171
|
+
const AUTH_USER_LIST_EXTENSION = new InjectionToken('AUTH_USER_LIST_EXTENSION');
|
|
1172
|
+
const PROFILE_FIELD_CONTEXT = new InjectionToken('PROFILE_FIELD_CONTEXT');
|
|
1173
|
+
const AUTH_PROFILE_EXTENSION = new InjectionToken('AUTH_PROFILE_EXTENSION');
|
|
1174
|
+
const AUTH_USER_DETAIL_CONFIG = new InjectionToken('AUTH_USER_DETAIL_CONFIG');
|
|
1175
|
+
function validatePassword(password, config) {
|
|
1176
|
+
const minLen = config.minLength ?? 8;
|
|
1177
|
+
const maxLen = config.maxLength;
|
|
1178
|
+
if (password.length < minLen) {
|
|
1179
|
+
return config.message ?? `Password must be at least ${minLen} characters`;
|
|
1180
|
+
}
|
|
1181
|
+
if (maxLen && password.length > maxLen) {
|
|
1182
|
+
return config.message ?? `Password must be at most ${maxLen} characters`;
|
|
1183
|
+
}
|
|
1184
|
+
if (config.pattern) {
|
|
1185
|
+
if (!config.pattern.test(password)) {
|
|
1186
|
+
return config.message ?? 'Password does not meet requirements';
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
else {
|
|
1190
|
+
if (config.requireUppercase && !/[A-Z]/.test(password)) {
|
|
1191
|
+
return config.message ?? 'Password must contain at least one uppercase letter';
|
|
1192
|
+
}
|
|
1193
|
+
if (config.requireLowercase && !/[a-z]/.test(password)) {
|
|
1194
|
+
return config.message ?? 'Password must contain at least one lowercase letter';
|
|
1195
|
+
}
|
|
1196
|
+
if (config.requireNumbers && !/\d/.test(password)) {
|
|
1197
|
+
return config.message ?? 'Password must contain at least one number';
|
|
1198
|
+
}
|
|
1199
|
+
if (config.requireSpecialChars && !/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
|
|
1200
|
+
return config.message ?? 'Password must contain at least one special character';
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
function validateEmail(email, config) {
|
|
1206
|
+
const pattern = config?.pattern ?? /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1207
|
+
const message = config?.message ?? 'Please enter a valid email address';
|
|
1208
|
+
if (!pattern.test(email))
|
|
1209
|
+
return message;
|
|
1210
|
+
return null;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1149
1213
|
/**
|
|
1150
1214
|
* Administration Page Component
|
|
1151
1215
|
* Unified administration page with tabs for:
|
|
@@ -1199,8 +1263,8 @@ class AdministrationPageComponent {
|
|
|
1199
1263
|
return 'No permissions available';
|
|
1200
1264
|
return `Manage ${tabs.map((t) => t.label.toLowerCase()).join(', ')}`;
|
|
1201
1265
|
}, ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
|
|
1202
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1203
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
1266
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AdministrationPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1267
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: AdministrationPageComponent, isStandalone: true, selector: "lib-administration-page", ngImport: i0, template: `
|
|
1204
1268
|
<div class="p-4">
|
|
1205
1269
|
<div class="mb-4">
|
|
1206
1270
|
<h1 class="text-2xl font-bold m-0">Administration</h1>
|
|
@@ -1225,7 +1289,7 @@ class AdministrationPageComponent {
|
|
|
1225
1289
|
</div>
|
|
1226
1290
|
`, isInline: true, styles: [".scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1227
1291
|
}
|
|
1228
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1292
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AdministrationPageComponent, decorators: [{
|
|
1229
1293
|
type: Component,
|
|
1230
1294
|
args: [{ selector: 'lib-administration-page', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive], template: `
|
|
1231
1295
|
<div class="p-4">
|
|
@@ -1441,8 +1505,8 @@ class BranchFormComponent {
|
|
|
1441
1505
|
onCancel() {
|
|
1442
1506
|
this.navigateToList();
|
|
1443
1507
|
}
|
|
1444
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1445
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
1508
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1509
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: BranchFormComponent, isStandalone: true, selector: "lib-branch-form", ngImport: i0, template: `
|
|
1446
1510
|
<p-card>
|
|
1447
1511
|
<ng-template #header>
|
|
1448
1512
|
<div class="flex justify-between items-center p-4">
|
|
@@ -1553,9 +1617,9 @@ class BranchFormComponent {
|
|
|
1553
1617
|
</div>
|
|
1554
1618
|
</form>
|
|
1555
1619
|
</p-card>
|
|
1556
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
1620
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1557
1621
|
}
|
|
1558
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1622
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchFormComponent, decorators: [{
|
|
1559
1623
|
type: Component,
|
|
1560
1624
|
args: [{
|
|
1561
1625
|
selector: 'lib-branch-form',
|
|
@@ -1783,8 +1847,8 @@ class BranchListComponent {
|
|
|
1783
1847
|
},
|
|
1784
1848
|
});
|
|
1785
1849
|
}
|
|
1786
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
1787
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
1850
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1851
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: BranchListComponent, isStandalone: true, selector: "lib-branch-list", ngImport: i0, template: `
|
|
1788
1852
|
<p-card>
|
|
1789
1853
|
<ng-template #header>
|
|
1790
1854
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4">
|
|
@@ -1881,9 +1945,9 @@ class BranchListComponent {
|
|
|
1881
1945
|
</p-table>
|
|
1882
1946
|
</div>
|
|
1883
1947
|
</p-card>
|
|
1884
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
1948
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: i4$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: TagModule }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1885
1949
|
}
|
|
1886
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
1950
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BranchListComponent, decorators: [{
|
|
1887
1951
|
type: Component,
|
|
1888
1952
|
args: [{
|
|
1889
1953
|
selector: 'lib-branch-list',
|
|
@@ -2134,8 +2198,8 @@ class CompanyFormComponent {
|
|
|
2134
2198
|
isActive: model.isActive,
|
|
2135
2199
|
};
|
|
2136
2200
|
}
|
|
2137
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
2138
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.
|
|
2201
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2202
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.5", type: CompanyFormComponent, isStandalone: true, selector: "lib-company-form", ngImport: i0, template: `
|
|
2139
2203
|
<p-card>
|
|
2140
2204
|
<ng-template #header>
|
|
2141
2205
|
<div class="flex justify-between items-center p-4">
|
|
@@ -2241,9 +2305,9 @@ class CompanyFormComponent {
|
|
|
2241
2305
|
</div>
|
|
2242
2306
|
</form>
|
|
2243
2307
|
</p-card>
|
|
2244
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
2308
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2245
2309
|
}
|
|
2246
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
2310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyFormComponent, decorators: [{
|
|
2247
2311
|
type: Component,
|
|
2248
2312
|
args: [{
|
|
2249
2313
|
selector: 'lib-company-form',
|
|
@@ -2424,8 +2488,8 @@ class CompanyListComponent {
|
|
|
2424
2488
|
},
|
|
2425
2489
|
});
|
|
2426
2490
|
}
|
|
2427
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
2428
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
2491
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2492
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: CompanyListComponent, isStandalone: true, selector: "lib-company-list", ngImport: i0, template: `
|
|
2429
2493
|
<p-card>
|
|
2430
2494
|
<ng-template #header>
|
|
2431
2495
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4">
|
|
@@ -2513,9 +2577,9 @@ class CompanyListComponent {
|
|
|
2513
2577
|
</p-table>
|
|
2514
2578
|
</div>
|
|
2515
2579
|
</p-card>
|
|
2516
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type:
|
|
2580
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: i5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: TagModule }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2517
2581
|
}
|
|
2518
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
2582
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyListComponent, decorators: [{
|
|
2519
2583
|
type: Component,
|
|
2520
2584
|
args: [{
|
|
2521
2585
|
selector: 'lib-company-list',
|
|
@@ -2657,8 +2721,8 @@ class ForgotPasswordPageComponent {
|
|
|
2657
2721
|
this.submittedEmail.set('');
|
|
2658
2722
|
this.formModel.set({ email: '' });
|
|
2659
2723
|
}
|
|
2660
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
2661
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
2724
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ForgotPasswordPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2725
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ForgotPasswordPageComponent, isStandalone: true, selector: "lib-forgot-password-page", ngImport: i0, template: `
|
|
2662
2726
|
<app-floating-configurator />
|
|
2663
2727
|
<div class="bg-surface-ground flex items-center justify-center min-h-screen">
|
|
2664
2728
|
<div class="flex flex-col items-center justify-center w-full max-w-[32rem] px-4">
|
|
@@ -2735,9 +2799,9 @@ class ForgotPasswordPageComponent {
|
|
|
2735
2799
|
</div>
|
|
2736
2800
|
</div>
|
|
2737
2801
|
</div>
|
|
2738
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
2802
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: AppFloatingConfigurator, selector: "app-floating-configurator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2739
2803
|
}
|
|
2740
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
2804
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ForgotPasswordPageComponent, decorators: [{
|
|
2741
2805
|
type: Component,
|
|
2742
2806
|
args: [{
|
|
2743
2807
|
selector: 'lib-forgot-password-page',
|
|
@@ -2835,6 +2899,7 @@ class LoginPageComponent {
|
|
|
2835
2899
|
messageService = inject(MessageService);
|
|
2836
2900
|
authApi = inject(AuthApiService);
|
|
2837
2901
|
authState = inject(AuthStateService);
|
|
2902
|
+
validationConfig = inject(AUTH_VALIDATION_CONFIG, { optional: true });
|
|
2838
2903
|
returnUrl = input('', ...(ngDevMode ? [{ debugName: "returnUrl" }] : []));
|
|
2839
2904
|
currentStep = signal('credentials', ...(ngDevMode ? [{ debugName: "currentStep" }] : []));
|
|
2840
2905
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
@@ -2844,13 +2909,35 @@ class LoginPageComponent {
|
|
|
2844
2909
|
password: '',
|
|
2845
2910
|
rememberMe: true,
|
|
2846
2911
|
}, ...(ngDevMode ? [{ debugName: "loginFormModel" }] : []));
|
|
2912
|
+
emailErrorMessage = computed(() => this.validationConfig?.email?.message ?? 'Please enter a valid email address', ...(ngDevMode ? [{ debugName: "emailErrorMessage" }] : []));
|
|
2913
|
+
passwordMinLength = computed(() => this.validationConfig?.password?.minLength ?? 8, ...(ngDevMode ? [{ debugName: "passwordMinLength" }] : []));
|
|
2914
|
+
passwordErrorMessage = computed(() => this.validationConfig?.password?.message ?? `Password must be at least ${this.passwordMinLength()} characters`, ...(ngDevMode ? [{ debugName: "passwordErrorMessage" }] : []));
|
|
2847
2915
|
loginForm = form(this.loginFormModel, (f) => {
|
|
2848
2916
|
required(f.email, { message: 'Email is required' });
|
|
2849
|
-
email(f.email, { message:
|
|
2917
|
+
email(f.email, { message: this.emailErrorMessage() });
|
|
2850
2918
|
required(f.password, { message: 'Password is required' });
|
|
2851
|
-
minLength(f.password,
|
|
2919
|
+
minLength(f.password, this.passwordMinLength(), { message: this.passwordErrorMessage() });
|
|
2852
2920
|
});
|
|
2853
|
-
|
|
2921
|
+
emailValidationError = computed(() => {
|
|
2922
|
+
const email = this.loginFormModel().email;
|
|
2923
|
+
if (!email)
|
|
2924
|
+
return null;
|
|
2925
|
+
return validateEmail(email, this.validationConfig?.email ?? undefined);
|
|
2926
|
+
}, ...(ngDevMode ? [{ debugName: "emailValidationError" }] : []));
|
|
2927
|
+
passwordValidationError = computed(() => {
|
|
2928
|
+
const password = this.loginFormModel().password;
|
|
2929
|
+
if (!password)
|
|
2930
|
+
return null;
|
|
2931
|
+
if (!this.validationConfig?.password)
|
|
2932
|
+
return null;
|
|
2933
|
+
return validatePassword(password, this.validationConfig.password);
|
|
2934
|
+
}, ...(ngDevMode ? [{ debugName: "passwordValidationError" }] : []));
|
|
2935
|
+
isLoginFormValid = computed(() => {
|
|
2936
|
+
const formValid = this.loginForm().valid();
|
|
2937
|
+
const emailError = this.emailValidationError();
|
|
2938
|
+
const passwordError = this.passwordValidationError();
|
|
2939
|
+
return formValid && !emailError && !passwordError;
|
|
2940
|
+
}, ...(ngDevMode ? [{ debugName: "isLoginFormValid" }] : []));
|
|
2854
2941
|
selectionFormModel = signal({
|
|
2855
2942
|
companyId: '',
|
|
2856
2943
|
branchId: '',
|
|
@@ -2862,6 +2949,8 @@ class LoginPageComponent {
|
|
|
2862
2949
|
});
|
|
2863
2950
|
isSelectionFormValid = computed(() => this.selectionForm().valid(), ...(ngDevMode ? [{ debugName: "isSelectionFormValid" }] : []));
|
|
2864
2951
|
companyFeatureEnabled = computed(() => isCompanyFeatureEnabled(this.appConfig), ...(ngDevMode ? [{ debugName: "companyFeatureEnabled" }] : []));
|
|
2952
|
+
emailFeatureEnabled = computed(() => isEmailFeatureEnabled(this.appConfig), ...(ngDevMode ? [{ debugName: "emailFeatureEnabled" }] : []));
|
|
2953
|
+
signUpEnabled = computed(() => isSignUpEnabled(this.appConfig), ...(ngDevMode ? [{ debugName: "signUpEnabled" }] : []));
|
|
2865
2954
|
sessionId = null;
|
|
2866
2955
|
companies = signal([], ...(ngDevMode ? [{ debugName: "companies" }] : []));
|
|
2867
2956
|
userName = signal('', ...(ngDevMode ? [{ debugName: "userName" }] : []));
|
|
@@ -3066,8 +3155,8 @@ class LoginPageComponent {
|
|
|
3066
3155
|
}
|
|
3067
3156
|
}
|
|
3068
3157
|
}
|
|
3069
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
3070
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
3158
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LoginPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3159
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: LoginPageComponent, isStandalone: true, selector: "lib-login-page", inputs: { returnUrl: { classPropertyName: "returnUrl", publicName: "returnUrl", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
3071
3160
|
<app-floating-configurator />
|
|
3072
3161
|
<div class="bg-surface-ground flex items-center justify-center min-h-screen">
|
|
3073
3162
|
<div class="flex flex-col items-center justify-center w-full max-w-[32rem] px-4">
|
|
@@ -3119,9 +3208,13 @@ class LoginPageComponent {
|
|
|
3119
3208
|
id="email"
|
|
3120
3209
|
type="email"
|
|
3121
3210
|
placeholder="Email address"
|
|
3122
|
-
class="w-full md:w-[25rem]
|
|
3211
|
+
class="w-full md:w-[25rem]"
|
|
3123
3212
|
[formField]="loginForm.email"
|
|
3124
3213
|
autocomplete="email" />
|
|
3214
|
+
@if (emailValidationError() && loginFormModel().email) {
|
|
3215
|
+
<small class="text-danger block mt-1">{{ emailValidationError() }}</small>
|
|
3216
|
+
}
|
|
3217
|
+
<div class="mb-4"></div>
|
|
3125
3218
|
|
|
3126
3219
|
<label for="password" class="block font-medium text-lg mb-2 text-color">
|
|
3127
3220
|
Password
|
|
@@ -3135,6 +3228,9 @@ class LoginPageComponent {
|
|
|
3135
3228
|
class="w-full md:w-[25rem]"
|
|
3136
3229
|
[formField]="loginForm.password"
|
|
3137
3230
|
autocomplete="current-password" />
|
|
3231
|
+
@if (passwordValidationError() && loginFormModel().password) {
|
|
3232
|
+
<small class="text-danger block mt-1">{{ passwordValidationError() }}</small>
|
|
3233
|
+
}
|
|
3138
3234
|
</div>
|
|
3139
3235
|
|
|
3140
3236
|
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between mt-2 mb-8 gap-4">
|
|
@@ -3144,11 +3240,13 @@ class LoginPageComponent {
|
|
|
3144
3240
|
[formField]="loginForm.rememberMe" />
|
|
3145
3241
|
<span>Remember me</span>
|
|
3146
3242
|
</label>
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3243
|
+
@if (emailFeatureEnabled()) {
|
|
3244
|
+
<span
|
|
3245
|
+
class="font-medium no-underline ml-2 text-right cursor-pointer text-primary"
|
|
3246
|
+
routerLink="/auth/forgot-password">
|
|
3247
|
+
Forgot password?
|
|
3248
|
+
</span>
|
|
3249
|
+
}
|
|
3152
3250
|
</div>
|
|
3153
3251
|
|
|
3154
3252
|
<p-button
|
|
@@ -3158,12 +3256,14 @@ class LoginPageComponent {
|
|
|
3158
3256
|
[loading]="isLoading()"
|
|
3159
3257
|
[disabled]="!isLoginFormValid() || isLoading()" />
|
|
3160
3258
|
|
|
3161
|
-
|
|
3162
|
-
<
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3259
|
+
@if (signUpEnabled()) {
|
|
3260
|
+
<div class="flex items-center justify-center mt-4 gap-2">
|
|
3261
|
+
<span class="font-medium">Don't have an account?</span>
|
|
3262
|
+
<a routerLink="/auth/register" class="font-semibold text-primary cursor-pointer">
|
|
3263
|
+
Sign Up
|
|
3264
|
+
</a>
|
|
3265
|
+
</div>
|
|
3266
|
+
}
|
|
3167
3267
|
</form>
|
|
3168
3268
|
}
|
|
3169
3269
|
|
|
@@ -3263,9 +3363,9 @@ class LoginPageComponent {
|
|
|
3263
3363
|
</div>
|
|
3264
3364
|
</div>
|
|
3265
3365
|
</div>
|
|
3266
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
3366
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: AppFloatingConfigurator, selector: "app-floating-configurator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3267
3367
|
}
|
|
3268
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
3368
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LoginPageComponent, decorators: [{
|
|
3269
3369
|
type: Component,
|
|
3270
3370
|
args: [{
|
|
3271
3371
|
selector: 'lib-login-page',
|
|
@@ -3323,9 +3423,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
3323
3423
|
id="email"
|
|
3324
3424
|
type="email"
|
|
3325
3425
|
placeholder="Email address"
|
|
3326
|
-
class="w-full md:w-[25rem]
|
|
3426
|
+
class="w-full md:w-[25rem]"
|
|
3327
3427
|
[formField]="loginForm.email"
|
|
3328
3428
|
autocomplete="email" />
|
|
3429
|
+
@if (emailValidationError() && loginFormModel().email) {
|
|
3430
|
+
<small class="text-danger block mt-1">{{ emailValidationError() }}</small>
|
|
3431
|
+
}
|
|
3432
|
+
<div class="mb-4"></div>
|
|
3329
3433
|
|
|
3330
3434
|
<label for="password" class="block font-medium text-lg mb-2 text-color">
|
|
3331
3435
|
Password
|
|
@@ -3339,6 +3443,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
3339
3443
|
class="w-full md:w-[25rem]"
|
|
3340
3444
|
[formField]="loginForm.password"
|
|
3341
3445
|
autocomplete="current-password" />
|
|
3446
|
+
@if (passwordValidationError() && loginFormModel().password) {
|
|
3447
|
+
<small class="text-danger block mt-1">{{ passwordValidationError() }}</small>
|
|
3448
|
+
}
|
|
3342
3449
|
</div>
|
|
3343
3450
|
|
|
3344
3451
|
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between mt-2 mb-8 gap-4">
|
|
@@ -3348,11 +3455,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
3348
3455
|
[formField]="loginForm.rememberMe" />
|
|
3349
3456
|
<span>Remember me</span>
|
|
3350
3457
|
</label>
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3458
|
+
@if (emailFeatureEnabled()) {
|
|
3459
|
+
<span
|
|
3460
|
+
class="font-medium no-underline ml-2 text-right cursor-pointer text-primary"
|
|
3461
|
+
routerLink="/auth/forgot-password">
|
|
3462
|
+
Forgot password?
|
|
3463
|
+
</span>
|
|
3464
|
+
}
|
|
3356
3465
|
</div>
|
|
3357
3466
|
|
|
3358
3467
|
<p-button
|
|
@@ -3362,12 +3471,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
3362
3471
|
[loading]="isLoading()"
|
|
3363
3472
|
[disabled]="!isLoginFormValid() || isLoading()" />
|
|
3364
3473
|
|
|
3365
|
-
|
|
3366
|
-
<
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3474
|
+
@if (signUpEnabled()) {
|
|
3475
|
+
<div class="flex items-center justify-center mt-4 gap-2">
|
|
3476
|
+
<span class="font-medium">Don't have an account?</span>
|
|
3477
|
+
<a routerLink="/auth/register" class="font-semibold text-primary cursor-pointer">
|
|
3478
|
+
Sign Up
|
|
3479
|
+
</a>
|
|
3480
|
+
</div>
|
|
3481
|
+
}
|
|
3371
3482
|
</form>
|
|
3372
3483
|
}
|
|
3373
3484
|
|
|
@@ -3476,20 +3587,6 @@ var loginPage_component = /*#__PURE__*/Object.freeze({
|
|
|
3476
3587
|
LoginPageComponent: LoginPageComponent
|
|
3477
3588
|
});
|
|
3478
3589
|
|
|
3479
|
-
/**
|
|
3480
|
-
* Profile Page Component
|
|
3481
|
-
*
|
|
3482
|
-
* Allows users to view and update their profile information.
|
|
3483
|
-
* Features:
|
|
3484
|
-
* - Update name, phone, profile picture (if storage enabled)
|
|
3485
|
-
* - View company/branch info (read-only, if company feature enabled)
|
|
3486
|
-
* - View roles/actions (read-only, if IAM enabled via optional injection)
|
|
3487
|
-
*
|
|
3488
|
-
* Package Independence:
|
|
3489
|
-
* - Uses PROFILE_UPLOAD_PROVIDER (optional) for storage functionality
|
|
3490
|
-
* - Uses PROFILE_PERMISSION_PROVIDER (optional) for IAM functionality
|
|
3491
|
-
* - No direct imports from ng-storage or ng-iam
|
|
3492
|
-
*/
|
|
3493
3590
|
class ProfilePageComponent {
|
|
3494
3591
|
destroyRef = inject(DestroyRef);
|
|
3495
3592
|
appConfig = inject(APP_CONFIG);
|
|
@@ -3498,44 +3595,56 @@ class ProfilePageComponent {
|
|
|
3498
3595
|
userService = inject(UserApiService);
|
|
3499
3596
|
authApiService = inject(AuthApiService);
|
|
3500
3597
|
fileUrlService = inject(FileUrlService);
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
});
|
|
3505
|
-
// Optional injection - null if IAM not configured
|
|
3506
|
-
permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, {
|
|
3507
|
-
optional: true,
|
|
3508
|
-
});
|
|
3509
|
-
// State
|
|
3598
|
+
uploadProvider = inject(PROFILE_UPLOAD_PROVIDER, { optional: true });
|
|
3599
|
+
permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, { optional: true });
|
|
3600
|
+
profileExtension = inject(AUTH_PROFILE_EXTENSION, { optional: true });
|
|
3510
3601
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
3511
3602
|
isLoadingPermissions = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingPermissions" }] : []));
|
|
3603
|
+
isLoadingExtraFields = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingExtraFields" }] : []));
|
|
3512
3604
|
_profilePictureUrl = signal(null, ...(ngDevMode ? [{ debugName: "_profilePictureUrl" }] : []));
|
|
3513
3605
|
profilePictureUrl = this._profilePictureUrl.asReadonly();
|
|
3514
|
-
// Permission data
|
|
3515
3606
|
_userRoles = signal([], ...(ngDevMode ? [{ debugName: "_userRoles" }] : []));
|
|
3516
3607
|
userRoles = this._userRoles.asReadonly();
|
|
3517
3608
|
_userActions = signal([], ...(ngDevMode ? [{ debugName: "_userActions" }] : []));
|
|
3518
3609
|
userActions = this._userActions.asReadonly();
|
|
3519
|
-
|
|
3610
|
+
extraSections = computed(() => {
|
|
3611
|
+
if (!this.profileExtension?.getExtraSections)
|
|
3612
|
+
return [];
|
|
3613
|
+
const sections = this.profileExtension.getExtraSections();
|
|
3614
|
+
return sections.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
|
|
3615
|
+
}, ...(ngDevMode ? [{ debugName: "extraSections" }] : []));
|
|
3616
|
+
extraFields = computed(() => {
|
|
3617
|
+
if (!this.profileExtension?.getExtraFields)
|
|
3618
|
+
return [];
|
|
3619
|
+
const fields = this.profileExtension.getExtraFields();
|
|
3620
|
+
return fields.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
|
|
3621
|
+
}, ...(ngDevMode ? [{ debugName: "extraFields" }] : []));
|
|
3622
|
+
viewOnlyFields = computed(() => this.extraFields().filter(f => f.editable === false), ...(ngDevMode ? [{ debugName: "viewOnlyFields" }] : []));
|
|
3623
|
+
editableFields = computed(() => this.extraFields().filter(f => f.editable !== false), ...(ngDevMode ? [{ debugName: "editableFields" }] : []));
|
|
3624
|
+
hasExtraContent = computed(() => this.extraSections().length > 0 || this.extraFields().length > 0, ...(ngDevMode ? [{ debugName: "hasExtraContent" }] : []));
|
|
3625
|
+
extraFieldsModel = signal({}, ...(ngDevMode ? [{ debugName: "extraFieldsModel" }] : []));
|
|
3626
|
+
originalExtraFieldsModel = signal({}, ...(ngDevMode ? [{ debugName: "originalExtraFieldsModel" }] : []));
|
|
3627
|
+
isExtraFieldsDirty = computed(() => {
|
|
3628
|
+
const current = this.extraFieldsModel();
|
|
3629
|
+
const original = this.originalExtraFieldsModel();
|
|
3630
|
+
return JSON.stringify(current) !== JSON.stringify(original);
|
|
3631
|
+
}, ...(ngDevMode ? [{ debugName: "isExtraFieldsDirty" }] : []));
|
|
3632
|
+
extraFieldsValidationError = computed(() => {
|
|
3633
|
+
if (!this.profileExtension?.validateExtraFields)
|
|
3634
|
+
return null;
|
|
3635
|
+
return this.profileExtension.validateExtraFields(this.extraFieldsModel());
|
|
3636
|
+
}, ...(ngDevMode ? [{ debugName: "extraFieldsValidationError" }] : []));
|
|
3520
3637
|
userEmail = computed(() => this.authState.user()?.email ?? '', ...(ngDevMode ? [{ debugName: "userEmail" }] : []));
|
|
3521
3638
|
userName = computed(() => this.authState.user()?.name ?? 'User', ...(ngDevMode ? [{ debugName: "userName" }] : []));
|
|
3522
3639
|
userInitials = computed(() => {
|
|
3523
3640
|
const name = this.authState.user()?.name ?? '';
|
|
3524
|
-
return name
|
|
3525
|
-
.split(' ')
|
|
3526
|
-
.map((n) => n[0])
|
|
3527
|
-
.join('')
|
|
3528
|
-
.toUpperCase()
|
|
3529
|
-
.slice(0, 2);
|
|
3641
|
+
return name.split(' ').map((n) => n[0]).join('').toUpperCase().slice(0, 2);
|
|
3530
3642
|
}, ...(ngDevMode ? [{ debugName: "userInitials" }] : []));
|
|
3531
3643
|
companyName = computed(() => this.authState.companyName(), ...(ngDevMode ? [{ debugName: "companyName" }] : []));
|
|
3532
3644
|
branchName = computed(() => this.authState.branchName(), ...(ngDevMode ? [{ debugName: "branchName" }] : []));
|
|
3533
|
-
|
|
3534
|
-
showUploadSection = computed(() => isFeatureEnabled(this.appConfig, 'storage') &&
|
|
3535
|
-
this.uploadProvider !== null, ...(ngDevMode ? [{ debugName: "showUploadSection" }] : []));
|
|
3645
|
+
showUploadSection = computed(() => isFeatureEnabled(this.appConfig, 'storage') && this.uploadProvider !== null, ...(ngDevMode ? [{ debugName: "showUploadSection" }] : []));
|
|
3536
3646
|
showCompanySection = computed(() => isCompanyFeatureEnabled(this.appConfig), ...(ngDevMode ? [{ debugName: "showCompanySection" }] : []));
|
|
3537
|
-
showPermissionsSection = computed(() => isFeatureEnabled(this.appConfig, 'iam') &&
|
|
3538
|
-
this.permissionProvider !== null, ...(ngDevMode ? [{ debugName: "showPermissionsSection" }] : []));
|
|
3647
|
+
showPermissionsSection = computed(() => isFeatureEnabled(this.appConfig, 'iam') && this.permissionProvider !== null, ...(ngDevMode ? [{ debugName: "showPermissionsSection" }] : []));
|
|
3539
3648
|
permissionMode = computed(() => getPermissionMode(this.appConfig), ...(ngDevMode ? [{ debugName: "permissionMode" }] : []));
|
|
3540
3649
|
showRoles = computed(() => {
|
|
3541
3650
|
const mode = this.permissionMode();
|
|
@@ -3545,30 +3654,45 @@ class ProfilePageComponent {
|
|
|
3545
3654
|
const mode = this.permissionMode();
|
|
3546
3655
|
return mode === 'direct' || mode === 'full';
|
|
3547
3656
|
}, ...(ngDevMode ? [{ debugName: "showActions" }] : []));
|
|
3548
|
-
// Show bottom row only if at least one section is visible
|
|
3549
3657
|
showBottomRow = computed(() => this.showCompanySection() || this.showPermissionsSection(), ...(ngDevMode ? [{ debugName: "showBottomRow" }] : []));
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
name: '',
|
|
3553
|
-
phone: '',
|
|
3554
|
-
}, ...(ngDevMode ? [{ debugName: "originalFormModel" }] : []));
|
|
3555
|
-
formModel = signal({
|
|
3556
|
-
name: '',
|
|
3557
|
-
phone: '',
|
|
3558
|
-
}, ...(ngDevMode ? [{ debugName: "formModel" }] : []));
|
|
3658
|
+
originalFormModel = signal({ name: '', phone: '' }, ...(ngDevMode ? [{ debugName: "originalFormModel" }] : []));
|
|
3659
|
+
formModel = signal({ name: '', phone: '' }, ...(ngDevMode ? [{ debugName: "formModel" }] : []));
|
|
3559
3660
|
formTree = form(this.formModel, (f) => {
|
|
3560
3661
|
required(f.name, { message: 'Name is required' });
|
|
3561
3662
|
});
|
|
3562
|
-
isFormValid = computed(() => {
|
|
3563
|
-
const model = this.formModel();
|
|
3564
|
-
return model.name.trim().length > 0;
|
|
3565
|
-
}, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
|
|
3663
|
+
isFormValid = computed(() => this.formModel().name.trim().length > 0, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
|
|
3566
3664
|
isFormDirty = computed(() => {
|
|
3567
3665
|
const current = this.formModel();
|
|
3568
3666
|
const original = this.originalFormModel();
|
|
3569
|
-
|
|
3667
|
+
const basicDirty = current.name !== original.name || current.phone !== original.phone;
|
|
3668
|
+
return basicDirty || this.isExtraFieldsDirty();
|
|
3570
3669
|
}, ...(ngDevMode ? [{ debugName: "isFormDirty" }] : []));
|
|
3571
|
-
|
|
3670
|
+
updateExtraField(key, value) {
|
|
3671
|
+
this.extraFieldsModel.update((model) => ({ ...model, [key]: value }));
|
|
3672
|
+
}
|
|
3673
|
+
getExtraFieldValue(key) {
|
|
3674
|
+
return this.extraFieldsModel()[key];
|
|
3675
|
+
}
|
|
3676
|
+
getSelectLabel(field, value) {
|
|
3677
|
+
if (!value || !field.options)
|
|
3678
|
+
return '-';
|
|
3679
|
+
const option = field.options.find(opt => opt.value === value);
|
|
3680
|
+
return option?.label ?? String(value);
|
|
3681
|
+
}
|
|
3682
|
+
getFieldTemplateContext(field) {
|
|
3683
|
+
return {
|
|
3684
|
+
field,
|
|
3685
|
+
value: this.extraFieldsModel()[field.key],
|
|
3686
|
+
updateValue: (value) => this.updateExtraField(field.key, value),
|
|
3687
|
+
};
|
|
3688
|
+
}
|
|
3689
|
+
parentInjector = inject(Injector);
|
|
3690
|
+
getFieldInjector(field) {
|
|
3691
|
+
return Injector.create({
|
|
3692
|
+
providers: [{ provide: PROFILE_FIELD_CONTEXT, useValue: this.getFieldTemplateContext(field) }],
|
|
3693
|
+
parent: field.injector ?? this.parentInjector,
|
|
3694
|
+
});
|
|
3695
|
+
}
|
|
3572
3696
|
passwordModel = signal({
|
|
3573
3697
|
currentPassword: '',
|
|
3574
3698
|
newPassword: '',
|
|
@@ -3577,19 +3701,15 @@ class ProfilePageComponent {
|
|
|
3577
3701
|
isPasswordLoading = signal(false, ...(ngDevMode ? [{ debugName: "isPasswordLoading" }] : []));
|
|
3578
3702
|
isPasswordFormValid = computed(() => {
|
|
3579
3703
|
const model = this.passwordModel();
|
|
3580
|
-
return
|
|
3581
|
-
model.newPassword.length >= 6 &&
|
|
3582
|
-
model.newPassword === model.confirmPassword);
|
|
3704
|
+
return model.currentPassword.length > 0 && model.newPassword.length >= 6 && model.newPassword === model.confirmPassword;
|
|
3583
3705
|
}, ...(ngDevMode ? [{ debugName: "isPasswordFormValid" }] : []));
|
|
3584
3706
|
passwordsMatch = computed(() => {
|
|
3585
3707
|
const model = this.passwordModel();
|
|
3586
3708
|
return model.confirmPassword.length === 0 || model.newPassword === model.confirmPassword;
|
|
3587
3709
|
}, ...(ngDevMode ? [{ debugName: "passwordsMatch" }] : []));
|
|
3588
|
-
// Upload function for FileUploader - uses provider if available
|
|
3589
3710
|
uploadFileFn = (file, options) => {
|
|
3590
|
-
if (!this.uploadProvider)
|
|
3711
|
+
if (!this.uploadProvider)
|
|
3591
3712
|
throw new Error('Upload provider not available');
|
|
3592
|
-
}
|
|
3593
3713
|
return this.uploadProvider
|
|
3594
3714
|
.uploadProfilePicture(file, {
|
|
3595
3715
|
folderPath: options?.folderPath ?? 'profile-pictures',
|
|
@@ -3600,15 +3720,12 @@ class ProfilePageComponent {
|
|
|
3600
3720
|
.pipe(map((response) => ({
|
|
3601
3721
|
success: response.success,
|
|
3602
3722
|
message: response.message,
|
|
3603
|
-
data: response.data
|
|
3604
|
-
? this.mapUploadResultToUploadedFile(response.data)
|
|
3605
|
-
: undefined,
|
|
3723
|
+
data: response.data ? this.mapUploadResultToUploadedFile(response.data) : undefined,
|
|
3606
3724
|
})));
|
|
3607
3725
|
};
|
|
3608
|
-
/** Map upload result to IUploadedFile format */
|
|
3609
3726
|
mapUploadResultToUploadedFile(result) {
|
|
3610
3727
|
return {
|
|
3611
|
-
id: result.id,
|
|
3728
|
+
id: result.id,
|
|
3612
3729
|
name: result.name,
|
|
3613
3730
|
key: result.key,
|
|
3614
3731
|
size: result.size,
|
|
@@ -3616,32 +3733,28 @@ class ProfilePageComponent {
|
|
|
3616
3733
|
};
|
|
3617
3734
|
}
|
|
3618
3735
|
constructor() {
|
|
3619
|
-
// Initialize user data on construction
|
|
3620
3736
|
this.loadUserData();
|
|
3621
|
-
// Effect for permissions loading when section is visible
|
|
3622
3737
|
effect(() => {
|
|
3623
|
-
if (this.showPermissionsSection())
|
|
3738
|
+
if (this.showPermissionsSection())
|
|
3624
3739
|
this.loadPermissions();
|
|
3625
|
-
|
|
3740
|
+
});
|
|
3741
|
+
effect(() => {
|
|
3742
|
+
const user = this.authState.user();
|
|
3743
|
+
if (user && this.hasExtraContent())
|
|
3744
|
+
this.loadExtraFields();
|
|
3626
3745
|
});
|
|
3627
3746
|
}
|
|
3628
3747
|
loadUserData() {
|
|
3629
3748
|
const user = this.authState.user();
|
|
3630
3749
|
if (user) {
|
|
3631
|
-
const initialValues = {
|
|
3632
|
-
name: user.name ?? '',
|
|
3633
|
-
phone: user.phone ?? '',
|
|
3634
|
-
};
|
|
3750
|
+
const initialValues = { name: user.name ?? '', phone: user.phone ?? '' };
|
|
3635
3751
|
this.originalFormModel.set(initialValues);
|
|
3636
3752
|
this.formModel.set(initialValues);
|
|
3637
|
-
// Load profile picture URL (only if storage is enabled)
|
|
3638
3753
|
if (user.profilePictureId && isFeatureEnabled(this.appConfig, 'storage')) {
|
|
3639
3754
|
this.fileUrlService
|
|
3640
3755
|
.fetchSingleFileUrl(user.profilePictureId)
|
|
3641
3756
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3642
|
-
.subscribe((file) =>
|
|
3643
|
-
this._profilePictureUrl.set(file?.url ?? null);
|
|
3644
|
-
});
|
|
3757
|
+
.subscribe((file) => this._profilePictureUrl.set(file?.url ?? null));
|
|
3645
3758
|
}
|
|
3646
3759
|
}
|
|
3647
3760
|
}
|
|
@@ -3655,52 +3768,44 @@ class ProfilePageComponent {
|
|
|
3655
3768
|
if (!loadRoles && !loadActions)
|
|
3656
3769
|
return;
|
|
3657
3770
|
this.isLoadingPermissions.set(true);
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
}
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
this.
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
.
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
error: () => {
|
|
3695
|
-
this._userActions.set([]);
|
|
3696
|
-
actionsLoaded = true;
|
|
3697
|
-
checkComplete();
|
|
3698
|
-
},
|
|
3699
|
-
});
|
|
3700
|
-
}
|
|
3771
|
+
const roles$ = loadRoles
|
|
3772
|
+
? this.permissionProvider.getUserRoles(user.id, branch?.id).pipe(catchError(() => of({ data: [] })))
|
|
3773
|
+
: of({ data: [] });
|
|
3774
|
+
const actions$ = loadActions
|
|
3775
|
+
? this.permissionProvider.getUserActions(user.id, branch?.id).pipe(catchError(() => of({ data: [] })))
|
|
3776
|
+
: of({ data: [] });
|
|
3777
|
+
forkJoin([roles$, actions$])
|
|
3778
|
+
.pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.isLoadingPermissions.set(false)))
|
|
3779
|
+
.subscribe(([rolesResponse, actionsResponse]) => {
|
|
3780
|
+
this._userRoles.set(rolesResponse.data ?? []);
|
|
3781
|
+
this._userActions.set(actionsResponse.data ?? []);
|
|
3782
|
+
});
|
|
3783
|
+
}
|
|
3784
|
+
loadExtraFields() {
|
|
3785
|
+
const user = this.authState.user();
|
|
3786
|
+
if (!user || !this.profileExtension?.getExtraFieldValues)
|
|
3787
|
+
return;
|
|
3788
|
+
this.isLoadingExtraFields.set(true);
|
|
3789
|
+
this.profileExtension
|
|
3790
|
+
.getExtraFieldValues(user.id)
|
|
3791
|
+
.pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.isLoadingExtraFields.set(false)))
|
|
3792
|
+
.subscribe({
|
|
3793
|
+
next: (values) => {
|
|
3794
|
+
this.extraFieldsModel.set(values);
|
|
3795
|
+
this.originalExtraFieldsModel.set(values);
|
|
3796
|
+
},
|
|
3797
|
+
error: () => {
|
|
3798
|
+
const defaults = {};
|
|
3799
|
+
for (const field of this.extraFields()) {
|
|
3800
|
+
if (field.key)
|
|
3801
|
+
defaults[field.key] = undefined;
|
|
3802
|
+
}
|
|
3803
|
+
this.extraFieldsModel.set(defaults);
|
|
3804
|
+
this.originalExtraFieldsModel.set(defaults);
|
|
3805
|
+
},
|
|
3806
|
+
});
|
|
3701
3807
|
}
|
|
3702
3808
|
onProfilePictureUploaded(file) {
|
|
3703
|
-
// Update user with new profile picture ID (file.id is the FileManager UUID)
|
|
3704
3809
|
const user = this.authState.user();
|
|
3705
3810
|
if (!user || !file.id)
|
|
3706
3811
|
return;
|
|
@@ -3711,33 +3816,25 @@ class ProfilePageComponent {
|
|
|
3711
3816
|
.subscribe({
|
|
3712
3817
|
next: (response) => {
|
|
3713
3818
|
if (response.success && response.data) {
|
|
3714
|
-
|
|
3715
|
-
this.authState.setUser({
|
|
3716
|
-
...user,
|
|
3717
|
-
profilePictureId: fileManagerId,
|
|
3718
|
-
});
|
|
3719
|
-
// Fetch new profile picture URL (force refresh to get fresh URL)
|
|
3819
|
+
this.authState.setUser({ ...user, profilePictureId: fileManagerId });
|
|
3720
3820
|
this.fileUrlService
|
|
3721
3821
|
.fetchSingleFileUrl(fileManagerId, true)
|
|
3722
3822
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3723
|
-
.subscribe((fileInfo) =>
|
|
3724
|
-
|
|
3725
|
-
});
|
|
3726
|
-
this.messageService.add({
|
|
3727
|
-
severity: 'success',
|
|
3728
|
-
summary: 'Success',
|
|
3729
|
-
detail: 'Profile picture updated',
|
|
3730
|
-
});
|
|
3823
|
+
.subscribe((fileInfo) => this._profilePictureUrl.set(fileInfo?.url ?? null));
|
|
3824
|
+
this.messageService.add({ severity: 'success', summary: 'Success', detail: 'Profile picture updated' });
|
|
3731
3825
|
}
|
|
3732
3826
|
},
|
|
3733
|
-
error: () => {
|
|
3734
|
-
// Error toast handled by global interceptor
|
|
3735
|
-
},
|
|
3827
|
+
error: () => { },
|
|
3736
3828
|
});
|
|
3737
3829
|
}
|
|
3738
3830
|
onSubmit() {
|
|
3739
3831
|
if (!this.isFormValid())
|
|
3740
3832
|
return;
|
|
3833
|
+
const extraFieldsError = this.extraFieldsValidationError();
|
|
3834
|
+
if (extraFieldsError) {
|
|
3835
|
+
this.messageService.add({ severity: 'error', summary: 'Validation Error', detail: extraFieldsError });
|
|
3836
|
+
return;
|
|
3837
|
+
}
|
|
3741
3838
|
const user = this.authState.user();
|
|
3742
3839
|
if (!user)
|
|
3743
3840
|
return;
|
|
@@ -3748,33 +3845,22 @@ class ProfilePageComponent {
|
|
|
3748
3845
|
name: model.name,
|
|
3749
3846
|
phone: model.phone || undefined,
|
|
3750
3847
|
};
|
|
3751
|
-
this.userService
|
|
3752
|
-
|
|
3848
|
+
const profileUpdate$ = this.userService.updateProfile(updateData);
|
|
3849
|
+
const extraFieldsUpdate$ = this.isExtraFieldsDirty() && this.profileExtension?.saveExtraFieldValues
|
|
3850
|
+
? this.profileExtension.saveExtraFieldValues(user.id, this.extraFieldsModel())
|
|
3851
|
+
: of(undefined);
|
|
3852
|
+
forkJoin([profileUpdate$, extraFieldsUpdate$])
|
|
3753
3853
|
.pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.isLoading.set(false)))
|
|
3754
3854
|
.subscribe({
|
|
3755
|
-
next: (response) => {
|
|
3855
|
+
next: ([response]) => {
|
|
3756
3856
|
if (response.success && response.data) {
|
|
3757
|
-
|
|
3758
|
-
this.
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
phone: response.data.phone ?? null,
|
|
3762
|
-
});
|
|
3763
|
-
// Update original form model to reset dirty state
|
|
3764
|
-
this.originalFormModel.set({
|
|
3765
|
-
name: response.data.name,
|
|
3766
|
-
phone: response.data.phone ?? '',
|
|
3767
|
-
});
|
|
3768
|
-
this.messageService.add({
|
|
3769
|
-
severity: 'success',
|
|
3770
|
-
summary: 'Success',
|
|
3771
|
-
detail: 'Profile updated successfully',
|
|
3772
|
-
});
|
|
3857
|
+
this.authState.setUser({ ...user, name: response.data.name, phone: response.data.phone ?? null });
|
|
3858
|
+
this.originalFormModel.set({ name: response.data.name, phone: response.data.phone ?? '' });
|
|
3859
|
+
this.originalExtraFieldsModel.set({ ...this.extraFieldsModel() });
|
|
3860
|
+
this.messageService.add({ severity: 'success', summary: 'Success', detail: 'Profile updated successfully' });
|
|
3773
3861
|
}
|
|
3774
3862
|
},
|
|
3775
|
-
error: () => {
|
|
3776
|
-
// Error toast handled by global interceptor
|
|
3777
|
-
},
|
|
3863
|
+
error: () => { },
|
|
3778
3864
|
});
|
|
3779
3865
|
}
|
|
3780
3866
|
updatePasswordField(field, value) {
|
|
@@ -3786,42 +3872,25 @@ class ProfilePageComponent {
|
|
|
3786
3872
|
this.isPasswordLoading.set(true);
|
|
3787
3873
|
const model = this.passwordModel();
|
|
3788
3874
|
this.authApiService
|
|
3789
|
-
.changePassword({
|
|
3790
|
-
currentPassword: model.currentPassword,
|
|
3791
|
-
newPassword: model.newPassword,
|
|
3792
|
-
})
|
|
3875
|
+
.changePassword({ currentPassword: model.currentPassword, newPassword: model.newPassword })
|
|
3793
3876
|
.pipe(takeUntilDestroyed(this.destroyRef), finalize(() => this.isPasswordLoading.set(false)))
|
|
3794
3877
|
.subscribe({
|
|
3795
3878
|
next: () => {
|
|
3796
|
-
this.messageService.add({
|
|
3797
|
-
|
|
3798
|
-
summary: 'Success',
|
|
3799
|
-
detail: 'Password changed successfully',
|
|
3800
|
-
});
|
|
3801
|
-
// Reset password form
|
|
3802
|
-
this.passwordModel.set({
|
|
3803
|
-
currentPassword: '',
|
|
3804
|
-
newPassword: '',
|
|
3805
|
-
confirmPassword: '',
|
|
3806
|
-
});
|
|
3807
|
-
},
|
|
3808
|
-
error: () => {
|
|
3809
|
-
// Error toast handled by global interceptor
|
|
3879
|
+
this.messageService.add({ severity: 'success', summary: 'Success', detail: 'Password changed successfully' });
|
|
3880
|
+
this.passwordModel.set({ currentPassword: '', newPassword: '', confirmPassword: '' });
|
|
3810
3881
|
},
|
|
3882
|
+
error: () => { },
|
|
3811
3883
|
});
|
|
3812
3884
|
}
|
|
3813
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
3814
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
3815
|
-
<!-- Page Header -->
|
|
3885
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ProfilePageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3886
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ProfilePageComponent, isStandalone: true, selector: "lib-profile-page", ngImport: i0, template: `
|
|
3816
3887
|
<div class="mb-4 md:mb-6">
|
|
3817
3888
|
<h1 class="text-2xl font-bold text-color mb-2">My Profile</h1>
|
|
3818
3889
|
<p class="text-muted-color">Manage your account settings and preferences.</p>
|
|
3819
3890
|
</div>
|
|
3820
3891
|
|
|
3821
|
-
<!-- Profile Form Card (full width) -->
|
|
3822
3892
|
<div class="card mb-2 md:mb-4">
|
|
3823
3893
|
<div class="flex flex-col md:flex-row gap-4 md:gap-6">
|
|
3824
|
-
<!-- Avatar Section -->
|
|
3825
3894
|
<div class="flex flex-col items-center gap-4 md:w-72 lg:w-80 md:border-r md:border-surface-200 md:pr-6">
|
|
3826
3895
|
@if (profilePictureUrl()) {
|
|
3827
3896
|
<p-avatar
|
|
@@ -3840,7 +3909,6 @@ class ProfilePageComponent {
|
|
|
3840
3909
|
<div class="font-semibold text-color">{{ userName() }}</div>
|
|
3841
3910
|
<div class="text-muted-color text-sm">{{ userEmail() }}</div>
|
|
3842
3911
|
</div>
|
|
3843
|
-
<!-- Upload section - only show if storage is enabled and provider is available -->
|
|
3844
3912
|
@if (showUploadSection()) {
|
|
3845
3913
|
<lib-file-uploader
|
|
3846
3914
|
[uploadFile]="uploadFileFn"
|
|
@@ -3858,10 +3926,8 @@ class ProfilePageComponent {
|
|
|
3858
3926
|
}
|
|
3859
3927
|
</div>
|
|
3860
3928
|
|
|
3861
|
-
<!-- Form Section -->
|
|
3862
3929
|
<div class="flex-1">
|
|
3863
3930
|
<form (ngSubmit)="onSubmit()" class="flex flex-col gap-4">
|
|
3864
|
-
<!-- Email (read-only) -->
|
|
3865
3931
|
<div class="flex flex-col gap-2">
|
|
3866
3932
|
<label class="font-medium text-color">Email</label>
|
|
3867
3933
|
<input
|
|
@@ -3871,7 +3937,6 @@ class ProfilePageComponent {
|
|
|
3871
3937
|
class="bg-surface-50" />
|
|
3872
3938
|
</div>
|
|
3873
3939
|
|
|
3874
|
-
<!-- Name -->
|
|
3875
3940
|
<div class="flex flex-col gap-2">
|
|
3876
3941
|
<label for="name" class="font-medium text-color">Name *</label>
|
|
3877
3942
|
<input
|
|
@@ -3881,7 +3946,6 @@ class ProfilePageComponent {
|
|
|
3881
3946
|
placeholder="Your full name" />
|
|
3882
3947
|
</div>
|
|
3883
3948
|
|
|
3884
|
-
<!-- Phone -->
|
|
3885
3949
|
<div class="flex flex-col gap-2">
|
|
3886
3950
|
<label for="phone" class="font-medium text-color">Phone</label>
|
|
3887
3951
|
<input
|
|
@@ -3891,7 +3955,140 @@ class ProfilePageComponent {
|
|
|
3891
3955
|
placeholder="+1 234 567 8900" />
|
|
3892
3956
|
</div>
|
|
3893
3957
|
|
|
3894
|
-
|
|
3958
|
+
@if (editableFields().length > 0) {
|
|
3959
|
+
<div class="border-t border-surface pt-4 mt-2">
|
|
3960
|
+
<div class="text-sm font-medium text-muted-color mb-4">
|
|
3961
|
+
<i class="pi pi-pencil mr-2"></i>Additional Information
|
|
3962
|
+
</div>
|
|
3963
|
+
@if (isLoadingExtraFields()) {
|
|
3964
|
+
<p-skeleton height="2rem" styleClass="mb-2" />
|
|
3965
|
+
<p-skeleton height="2rem" />
|
|
3966
|
+
} @else {
|
|
3967
|
+
<div class="flex flex-col gap-4">
|
|
3968
|
+
@for (field of editableFields(); track field.key) {
|
|
3969
|
+
<div class="flex flex-col gap-2">
|
|
3970
|
+
<label [for]="field.key" class="font-medium text-color">
|
|
3971
|
+
{{ field.label }}{{ field.required ? ' *' : '' }}
|
|
3972
|
+
</label>
|
|
3973
|
+
@if (field.component) {
|
|
3974
|
+
<ng-container *ngComponentOutlet="field.component; injector: getFieldInjector(field)" />
|
|
3975
|
+
} @else if (field.template) {
|
|
3976
|
+
<ng-container [ngTemplateOutlet]="field.template" [ngTemplateOutletContext]="getFieldTemplateContext(field)" />
|
|
3977
|
+
} @else {
|
|
3978
|
+
<ng-container [ngTemplateOutlet]="fieldTemplate" [ngTemplateOutletContext]="{ field: field }" />
|
|
3979
|
+
}
|
|
3980
|
+
</div>
|
|
3981
|
+
}
|
|
3982
|
+
</div>
|
|
3983
|
+
@if (extraFieldsValidationError()) {
|
|
3984
|
+
<small class="text-danger block mt-2">{{ extraFieldsValidationError() }}</small>
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
</div>
|
|
3988
|
+
}
|
|
3989
|
+
|
|
3990
|
+
@if (viewOnlyFields().length > 0) {
|
|
3991
|
+
<div class="border-t border-surface pt-4 mt-2">
|
|
3992
|
+
<div class="flex items-center justify-between mb-4">
|
|
3993
|
+
<div class="text-sm font-medium text-muted-color">
|
|
3994
|
+
<i class="pi pi-eye mr-2"></i>Employment Information
|
|
3995
|
+
</div>
|
|
3996
|
+
<p-tag value="Managed by Admin" severity="secondary" />
|
|
3997
|
+
</div>
|
|
3998
|
+
@if (isLoadingExtraFields()) {
|
|
3999
|
+
<p-skeleton height="2rem" styleClass="mb-2" />
|
|
4000
|
+
<p-skeleton height="2rem" />
|
|
4001
|
+
} @else {
|
|
4002
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
4003
|
+
@for (field of viewOnlyFields(); track field.key) {
|
|
4004
|
+
<div class="flex flex-col gap-1">
|
|
4005
|
+
<label class="text-sm text-muted-color">{{ field.label }}</label>
|
|
4006
|
+
<span class="text-color font-medium">
|
|
4007
|
+
@if (field.type === 'select') {
|
|
4008
|
+
{{ getSelectLabel(field, getExtraFieldValue(field.key)) }}
|
|
4009
|
+
} @else {
|
|
4010
|
+
{{ getExtraFieldValue(field.key) || '-' }}
|
|
4011
|
+
}
|
|
4012
|
+
</span>
|
|
4013
|
+
</div>
|
|
4014
|
+
}
|
|
4015
|
+
</div>
|
|
4016
|
+
}
|
|
4017
|
+
</div>
|
|
4018
|
+
}
|
|
4019
|
+
|
|
4020
|
+
<ng-template #fieldTemplate let-field="field">
|
|
4021
|
+
@switch (field.type) {
|
|
4022
|
+
@case ('text') {
|
|
4023
|
+
<input
|
|
4024
|
+
pInputText
|
|
4025
|
+
[id]="field.key"
|
|
4026
|
+
[placeholder]="field.placeholder ?? ''"
|
|
4027
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4028
|
+
[disabled]="field.editable === false"
|
|
4029
|
+
(input)="updateExtraField(field.key, $any($event.target).value)"
|
|
4030
|
+
class="w-full" />
|
|
4031
|
+
}
|
|
4032
|
+
@case ('number') {
|
|
4033
|
+
<input
|
|
4034
|
+
pInputText
|
|
4035
|
+
type="number"
|
|
4036
|
+
[id]="field.key"
|
|
4037
|
+
[placeholder]="field.placeholder ?? ''"
|
|
4038
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4039
|
+
[disabled]="field.editable === false"
|
|
4040
|
+
(input)="updateExtraField(field.key, $any($event.target).valueAsNumber)"
|
|
4041
|
+
class="w-full" />
|
|
4042
|
+
}
|
|
4043
|
+
@case ('textarea') {
|
|
4044
|
+
<textarea
|
|
4045
|
+
pInputTextarea
|
|
4046
|
+
[id]="field.key"
|
|
4047
|
+
[placeholder]="field.placeholder ?? ''"
|
|
4048
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4049
|
+
[disabled]="field.editable === false"
|
|
4050
|
+
(input)="updateExtraField(field.key, $any($event.target).value)"
|
|
4051
|
+
class="w-full"
|
|
4052
|
+
rows="3"></textarea>
|
|
4053
|
+
}
|
|
4054
|
+
@case ('select') {
|
|
4055
|
+
<select
|
|
4056
|
+
[id]="field.key"
|
|
4057
|
+
class="p-select-native w-full"
|
|
4058
|
+
[ngModel]="getExtraFieldValue(field.key) ?? ''"
|
|
4059
|
+
[ngModelOptions]="{standalone: true}"
|
|
4060
|
+
[disabled]="field.editable === false"
|
|
4061
|
+
(ngModelChange)="updateExtraField(field.key, $event)">
|
|
4062
|
+
<option value="">{{ field.placeholder ?? 'Select...' }}</option>
|
|
4063
|
+
@for (opt of field.options; track opt.value) {
|
|
4064
|
+
<option [value]="opt.value">{{ opt.label }}</option>
|
|
4065
|
+
}
|
|
4066
|
+
</select>
|
|
4067
|
+
}
|
|
4068
|
+
@case ('checkbox') {
|
|
4069
|
+
<label class="p-checkbox-native">
|
|
4070
|
+
<input
|
|
4071
|
+
type="checkbox"
|
|
4072
|
+
[id]="field.key"
|
|
4073
|
+
[checked]="getExtraFieldValue(field.key) ?? false"
|
|
4074
|
+
[disabled]="field.editable === false"
|
|
4075
|
+
(change)="updateExtraField(field.key, $any($event.target).checked)" />
|
|
4076
|
+
<span>{{ field.placeholder ?? field.label }}</span>
|
|
4077
|
+
</label>
|
|
4078
|
+
}
|
|
4079
|
+
@case ('date') {
|
|
4080
|
+
<input
|
|
4081
|
+
pInputText
|
|
4082
|
+
type="date"
|
|
4083
|
+
[id]="field.key"
|
|
4084
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4085
|
+
[disabled]="field.editable === false"
|
|
4086
|
+
(input)="updateExtraField(field.key, $any($event.target).value)"
|
|
4087
|
+
class="w-full" />
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
</ng-template>
|
|
4091
|
+
|
|
3895
4092
|
<div class="flex justify-end pt-4">
|
|
3896
4093
|
<p-button
|
|
3897
4094
|
label="Save Changes"
|
|
@@ -3905,7 +4102,6 @@ class ProfilePageComponent {
|
|
|
3905
4102
|
</div>
|
|
3906
4103
|
</div>
|
|
3907
4104
|
|
|
3908
|
-
<!-- Security Card -->
|
|
3909
4105
|
<div class="card mb-2 md:mb-4">
|
|
3910
4106
|
<div class="flex items-center gap-2 mb-4">
|
|
3911
4107
|
<i class="pi pi-lock text-primary"></i>
|
|
@@ -3913,7 +4109,6 @@ class ProfilePageComponent {
|
|
|
3913
4109
|
</div>
|
|
3914
4110
|
<form (ngSubmit)="onChangePassword()" class="flex flex-col gap-4">
|
|
3915
4111
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
3916
|
-
<!-- Current Password -->
|
|
3917
4112
|
<div class="flex flex-col gap-2">
|
|
3918
4113
|
<label for="currentPassword" class="font-medium text-color">Current Password *</label>
|
|
3919
4114
|
<p-password
|
|
@@ -3928,7 +4123,6 @@ class ProfilePageComponent {
|
|
|
3928
4123
|
inputStyleClass="w-full" />
|
|
3929
4124
|
</div>
|
|
3930
4125
|
|
|
3931
|
-
<!-- New Password -->
|
|
3932
4126
|
<div class="flex flex-col gap-2">
|
|
3933
4127
|
<label for="newPassword" class="font-medium text-color">New Password *</label>
|
|
3934
4128
|
<p-password
|
|
@@ -3943,7 +4137,6 @@ class ProfilePageComponent {
|
|
|
3943
4137
|
inputStyleClass="w-full" />
|
|
3944
4138
|
</div>
|
|
3945
4139
|
|
|
3946
|
-
<!-- Confirm Password -->
|
|
3947
4140
|
<div class="flex flex-col gap-2">
|
|
3948
4141
|
<label for="confirmPassword" class="font-medium text-color">Confirm Password *</label>
|
|
3949
4142
|
<p-password
|
|
@@ -3962,7 +4155,6 @@ class ProfilePageComponent {
|
|
|
3962
4155
|
</div>
|
|
3963
4156
|
</div>
|
|
3964
4157
|
|
|
3965
|
-
<!-- Submit -->
|
|
3966
4158
|
<div class="flex justify-end">
|
|
3967
4159
|
<p-button
|
|
3968
4160
|
label="Change Password"
|
|
@@ -3974,10 +4166,40 @@ class ProfilePageComponent {
|
|
|
3974
4166
|
</form>
|
|
3975
4167
|
</div>
|
|
3976
4168
|
|
|
3977
|
-
|
|
4169
|
+
@for (section of extraSections(); track section.key) {
|
|
4170
|
+
@if (section.editPermission) {
|
|
4171
|
+
<div *hasPermission="section.editPermission" class="card mb-2 md:mb-4">
|
|
4172
|
+
<div class="flex items-center gap-2 mb-4">
|
|
4173
|
+
@if (section.icon) {
|
|
4174
|
+
<i [class]="section.icon + ' text-primary'"></i>
|
|
4175
|
+
}
|
|
4176
|
+
<span class="font-semibold text-color">{{ section.title }}</span>
|
|
4177
|
+
</div>
|
|
4178
|
+
<div class="section-content">
|
|
4179
|
+
@if (section.component) {
|
|
4180
|
+
<ng-container *ngComponentOutlet="section.component" />
|
|
4181
|
+
}
|
|
4182
|
+
</div>
|
|
4183
|
+
</div>
|
|
4184
|
+
} @else {
|
|
4185
|
+
<div class="card mb-2 md:mb-4">
|
|
4186
|
+
<div class="flex items-center gap-2 mb-4">
|
|
4187
|
+
@if (section.icon) {
|
|
4188
|
+
<i [class]="section.icon + ' text-primary'"></i>
|
|
4189
|
+
}
|
|
4190
|
+
<span class="font-semibold text-color">{{ section.title }}</span>
|
|
4191
|
+
</div>
|
|
4192
|
+
<div class="section-content">
|
|
4193
|
+
@if (section.component) {
|
|
4194
|
+
<ng-container *ngComponentOutlet="section.component" />
|
|
4195
|
+
}
|
|
4196
|
+
</div>
|
|
4197
|
+
</div>
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
|
|
3978
4201
|
@if (showBottomRow()) {
|
|
3979
4202
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4 flex-1">
|
|
3980
|
-
<!-- Company/Branch Info -->
|
|
3981
4203
|
@if (showCompanySection()) {
|
|
3982
4204
|
<div class="card h-48 md:h-56 flex flex-col">
|
|
3983
4205
|
<div class="flex items-center gap-2 mb-4">
|
|
@@ -4007,7 +4229,6 @@ class ProfilePageComponent {
|
|
|
4007
4229
|
</div>
|
|
4008
4230
|
}
|
|
4009
4231
|
|
|
4010
|
-
<!-- Permissions -->
|
|
4011
4232
|
@if (showPermissionsSection()) {
|
|
4012
4233
|
<div class="card h-48 md:h-56 flex flex-col">
|
|
4013
4234
|
<div class="flex items-center justify-between mb-4">
|
|
@@ -4018,7 +4239,6 @@ class ProfilePageComponent {
|
|
|
4018
4239
|
<p-tag value="Read-only" severity="secondary" />
|
|
4019
4240
|
</div>
|
|
4020
4241
|
<div class="flex flex-col gap-4 flex-1 overflow-auto">
|
|
4021
|
-
<!-- Roles -->
|
|
4022
4242
|
@if (showRoles()) {
|
|
4023
4243
|
<div>
|
|
4024
4244
|
<div class="text-sm text-muted-color mb-2 flex items-center gap-2">
|
|
@@ -4038,7 +4258,6 @@ class ProfilePageComponent {
|
|
|
4038
4258
|
</div>
|
|
4039
4259
|
}
|
|
4040
4260
|
|
|
4041
|
-
<!-- Actions -->
|
|
4042
4261
|
@if (showActions()) {
|
|
4043
4262
|
<div>
|
|
4044
4263
|
<div class="text-sm text-muted-color mb-2 flex items-center gap-2">
|
|
@@ -4062,24 +4281,21 @@ class ProfilePageComponent {
|
|
|
4062
4281
|
}
|
|
4063
4282
|
</div>
|
|
4064
4283
|
}
|
|
4065
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1
|
|
4284
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i3$1.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i6$1.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }, { kind: "component", type: i7$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i9.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: FileUploaderComponent, selector: "lib-file-uploader", inputs: ["uploadFile", "acceptTypes", "multiple", "maxFiles", "maxSizeMb", "uploadOptions", "disabled", "showPreview", "autoUpload"], outputs: ["fileUploaded", "filesUploaded", "onError", "fileSelected"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4066
4285
|
}
|
|
4067
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
4286
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ProfilePageComponent, decorators: [{
|
|
4068
4287
|
type: Component,
|
|
4069
4288
|
args: [{
|
|
4070
4289
|
selector: 'lib-profile-page',
|
|
4071
|
-
imports: [AngularModule, PrimeModule, FormField, FileUploaderComponent],
|
|
4290
|
+
imports: [AngularModule, PrimeModule, FormField, FileUploaderComponent, HasPermissionDirective],
|
|
4072
4291
|
template: `
|
|
4073
|
-
<!-- Page Header -->
|
|
4074
4292
|
<div class="mb-4 md:mb-6">
|
|
4075
4293
|
<h1 class="text-2xl font-bold text-color mb-2">My Profile</h1>
|
|
4076
4294
|
<p class="text-muted-color">Manage your account settings and preferences.</p>
|
|
4077
4295
|
</div>
|
|
4078
4296
|
|
|
4079
|
-
<!-- Profile Form Card (full width) -->
|
|
4080
4297
|
<div class="card mb-2 md:mb-4">
|
|
4081
4298
|
<div class="flex flex-col md:flex-row gap-4 md:gap-6">
|
|
4082
|
-
<!-- Avatar Section -->
|
|
4083
4299
|
<div class="flex flex-col items-center gap-4 md:w-72 lg:w-80 md:border-r md:border-surface-200 md:pr-6">
|
|
4084
4300
|
@if (profilePictureUrl()) {
|
|
4085
4301
|
<p-avatar
|
|
@@ -4098,7 +4314,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4098
4314
|
<div class="font-semibold text-color">{{ userName() }}</div>
|
|
4099
4315
|
<div class="text-muted-color text-sm">{{ userEmail() }}</div>
|
|
4100
4316
|
</div>
|
|
4101
|
-
<!-- Upload section - only show if storage is enabled and provider is available -->
|
|
4102
4317
|
@if (showUploadSection()) {
|
|
4103
4318
|
<lib-file-uploader
|
|
4104
4319
|
[uploadFile]="uploadFileFn"
|
|
@@ -4116,10 +4331,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4116
4331
|
}
|
|
4117
4332
|
</div>
|
|
4118
4333
|
|
|
4119
|
-
<!-- Form Section -->
|
|
4120
4334
|
<div class="flex-1">
|
|
4121
4335
|
<form (ngSubmit)="onSubmit()" class="flex flex-col gap-4">
|
|
4122
|
-
<!-- Email (read-only) -->
|
|
4123
4336
|
<div class="flex flex-col gap-2">
|
|
4124
4337
|
<label class="font-medium text-color">Email</label>
|
|
4125
4338
|
<input
|
|
@@ -4129,7 +4342,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4129
4342
|
class="bg-surface-50" />
|
|
4130
4343
|
</div>
|
|
4131
4344
|
|
|
4132
|
-
<!-- Name -->
|
|
4133
4345
|
<div class="flex flex-col gap-2">
|
|
4134
4346
|
<label for="name" class="font-medium text-color">Name *</label>
|
|
4135
4347
|
<input
|
|
@@ -4139,7 +4351,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4139
4351
|
placeholder="Your full name" />
|
|
4140
4352
|
</div>
|
|
4141
4353
|
|
|
4142
|
-
<!-- Phone -->
|
|
4143
4354
|
<div class="flex flex-col gap-2">
|
|
4144
4355
|
<label for="phone" class="font-medium text-color">Phone</label>
|
|
4145
4356
|
<input
|
|
@@ -4149,7 +4360,140 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4149
4360
|
placeholder="+1 234 567 8900" />
|
|
4150
4361
|
</div>
|
|
4151
4362
|
|
|
4152
|
-
|
|
4363
|
+
@if (editableFields().length > 0) {
|
|
4364
|
+
<div class="border-t border-surface pt-4 mt-2">
|
|
4365
|
+
<div class="text-sm font-medium text-muted-color mb-4">
|
|
4366
|
+
<i class="pi pi-pencil mr-2"></i>Additional Information
|
|
4367
|
+
</div>
|
|
4368
|
+
@if (isLoadingExtraFields()) {
|
|
4369
|
+
<p-skeleton height="2rem" styleClass="mb-2" />
|
|
4370
|
+
<p-skeleton height="2rem" />
|
|
4371
|
+
} @else {
|
|
4372
|
+
<div class="flex flex-col gap-4">
|
|
4373
|
+
@for (field of editableFields(); track field.key) {
|
|
4374
|
+
<div class="flex flex-col gap-2">
|
|
4375
|
+
<label [for]="field.key" class="font-medium text-color">
|
|
4376
|
+
{{ field.label }}{{ field.required ? ' *' : '' }}
|
|
4377
|
+
</label>
|
|
4378
|
+
@if (field.component) {
|
|
4379
|
+
<ng-container *ngComponentOutlet="field.component; injector: getFieldInjector(field)" />
|
|
4380
|
+
} @else if (field.template) {
|
|
4381
|
+
<ng-container [ngTemplateOutlet]="field.template" [ngTemplateOutletContext]="getFieldTemplateContext(field)" />
|
|
4382
|
+
} @else {
|
|
4383
|
+
<ng-container [ngTemplateOutlet]="fieldTemplate" [ngTemplateOutletContext]="{ field: field }" />
|
|
4384
|
+
}
|
|
4385
|
+
</div>
|
|
4386
|
+
}
|
|
4387
|
+
</div>
|
|
4388
|
+
@if (extraFieldsValidationError()) {
|
|
4389
|
+
<small class="text-danger block mt-2">{{ extraFieldsValidationError() }}</small>
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
</div>
|
|
4393
|
+
}
|
|
4394
|
+
|
|
4395
|
+
@if (viewOnlyFields().length > 0) {
|
|
4396
|
+
<div class="border-t border-surface pt-4 mt-2">
|
|
4397
|
+
<div class="flex items-center justify-between mb-4">
|
|
4398
|
+
<div class="text-sm font-medium text-muted-color">
|
|
4399
|
+
<i class="pi pi-eye mr-2"></i>Employment Information
|
|
4400
|
+
</div>
|
|
4401
|
+
<p-tag value="Managed by Admin" severity="secondary" />
|
|
4402
|
+
</div>
|
|
4403
|
+
@if (isLoadingExtraFields()) {
|
|
4404
|
+
<p-skeleton height="2rem" styleClass="mb-2" />
|
|
4405
|
+
<p-skeleton height="2rem" />
|
|
4406
|
+
} @else {
|
|
4407
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
4408
|
+
@for (field of viewOnlyFields(); track field.key) {
|
|
4409
|
+
<div class="flex flex-col gap-1">
|
|
4410
|
+
<label class="text-sm text-muted-color">{{ field.label }}</label>
|
|
4411
|
+
<span class="text-color font-medium">
|
|
4412
|
+
@if (field.type === 'select') {
|
|
4413
|
+
{{ getSelectLabel(field, getExtraFieldValue(field.key)) }}
|
|
4414
|
+
} @else {
|
|
4415
|
+
{{ getExtraFieldValue(field.key) || '-' }}
|
|
4416
|
+
}
|
|
4417
|
+
</span>
|
|
4418
|
+
</div>
|
|
4419
|
+
}
|
|
4420
|
+
</div>
|
|
4421
|
+
}
|
|
4422
|
+
</div>
|
|
4423
|
+
}
|
|
4424
|
+
|
|
4425
|
+
<ng-template #fieldTemplate let-field="field">
|
|
4426
|
+
@switch (field.type) {
|
|
4427
|
+
@case ('text') {
|
|
4428
|
+
<input
|
|
4429
|
+
pInputText
|
|
4430
|
+
[id]="field.key"
|
|
4431
|
+
[placeholder]="field.placeholder ?? ''"
|
|
4432
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4433
|
+
[disabled]="field.editable === false"
|
|
4434
|
+
(input)="updateExtraField(field.key, $any($event.target).value)"
|
|
4435
|
+
class="w-full" />
|
|
4436
|
+
}
|
|
4437
|
+
@case ('number') {
|
|
4438
|
+
<input
|
|
4439
|
+
pInputText
|
|
4440
|
+
type="number"
|
|
4441
|
+
[id]="field.key"
|
|
4442
|
+
[placeholder]="field.placeholder ?? ''"
|
|
4443
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4444
|
+
[disabled]="field.editable === false"
|
|
4445
|
+
(input)="updateExtraField(field.key, $any($event.target).valueAsNumber)"
|
|
4446
|
+
class="w-full" />
|
|
4447
|
+
}
|
|
4448
|
+
@case ('textarea') {
|
|
4449
|
+
<textarea
|
|
4450
|
+
pInputTextarea
|
|
4451
|
+
[id]="field.key"
|
|
4452
|
+
[placeholder]="field.placeholder ?? ''"
|
|
4453
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4454
|
+
[disabled]="field.editable === false"
|
|
4455
|
+
(input)="updateExtraField(field.key, $any($event.target).value)"
|
|
4456
|
+
class="w-full"
|
|
4457
|
+
rows="3"></textarea>
|
|
4458
|
+
}
|
|
4459
|
+
@case ('select') {
|
|
4460
|
+
<select
|
|
4461
|
+
[id]="field.key"
|
|
4462
|
+
class="p-select-native w-full"
|
|
4463
|
+
[ngModel]="getExtraFieldValue(field.key) ?? ''"
|
|
4464
|
+
[ngModelOptions]="{standalone: true}"
|
|
4465
|
+
[disabled]="field.editable === false"
|
|
4466
|
+
(ngModelChange)="updateExtraField(field.key, $event)">
|
|
4467
|
+
<option value="">{{ field.placeholder ?? 'Select...' }}</option>
|
|
4468
|
+
@for (opt of field.options; track opt.value) {
|
|
4469
|
+
<option [value]="opt.value">{{ opt.label }}</option>
|
|
4470
|
+
}
|
|
4471
|
+
</select>
|
|
4472
|
+
}
|
|
4473
|
+
@case ('checkbox') {
|
|
4474
|
+
<label class="p-checkbox-native">
|
|
4475
|
+
<input
|
|
4476
|
+
type="checkbox"
|
|
4477
|
+
[id]="field.key"
|
|
4478
|
+
[checked]="getExtraFieldValue(field.key) ?? false"
|
|
4479
|
+
[disabled]="field.editable === false"
|
|
4480
|
+
(change)="updateExtraField(field.key, $any($event.target).checked)" />
|
|
4481
|
+
<span>{{ field.placeholder ?? field.label }}</span>
|
|
4482
|
+
</label>
|
|
4483
|
+
}
|
|
4484
|
+
@case ('date') {
|
|
4485
|
+
<input
|
|
4486
|
+
pInputText
|
|
4487
|
+
type="date"
|
|
4488
|
+
[id]="field.key"
|
|
4489
|
+
[value]="getExtraFieldValue(field.key) ?? ''"
|
|
4490
|
+
[disabled]="field.editable === false"
|
|
4491
|
+
(input)="updateExtraField(field.key, $any($event.target).value)"
|
|
4492
|
+
class="w-full" />
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
</ng-template>
|
|
4496
|
+
|
|
4153
4497
|
<div class="flex justify-end pt-4">
|
|
4154
4498
|
<p-button
|
|
4155
4499
|
label="Save Changes"
|
|
@@ -4163,7 +4507,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4163
4507
|
</div>
|
|
4164
4508
|
</div>
|
|
4165
4509
|
|
|
4166
|
-
<!-- Security Card -->
|
|
4167
4510
|
<div class="card mb-2 md:mb-4">
|
|
4168
4511
|
<div class="flex items-center gap-2 mb-4">
|
|
4169
4512
|
<i class="pi pi-lock text-primary"></i>
|
|
@@ -4171,7 +4514,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4171
4514
|
</div>
|
|
4172
4515
|
<form (ngSubmit)="onChangePassword()" class="flex flex-col gap-4">
|
|
4173
4516
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
4174
|
-
<!-- Current Password -->
|
|
4175
4517
|
<div class="flex flex-col gap-2">
|
|
4176
4518
|
<label for="currentPassword" class="font-medium text-color">Current Password *</label>
|
|
4177
4519
|
<p-password
|
|
@@ -4186,7 +4528,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4186
4528
|
inputStyleClass="w-full" />
|
|
4187
4529
|
</div>
|
|
4188
4530
|
|
|
4189
|
-
<!-- New Password -->
|
|
4190
4531
|
<div class="flex flex-col gap-2">
|
|
4191
4532
|
<label for="newPassword" class="font-medium text-color">New Password *</label>
|
|
4192
4533
|
<p-password
|
|
@@ -4201,7 +4542,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4201
4542
|
inputStyleClass="w-full" />
|
|
4202
4543
|
</div>
|
|
4203
4544
|
|
|
4204
|
-
<!-- Confirm Password -->
|
|
4205
4545
|
<div class="flex flex-col gap-2">
|
|
4206
4546
|
<label for="confirmPassword" class="font-medium text-color">Confirm Password *</label>
|
|
4207
4547
|
<p-password
|
|
@@ -4220,7 +4560,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4220
4560
|
</div>
|
|
4221
4561
|
</div>
|
|
4222
4562
|
|
|
4223
|
-
<!-- Submit -->
|
|
4224
4563
|
<div class="flex justify-end">
|
|
4225
4564
|
<p-button
|
|
4226
4565
|
label="Change Password"
|
|
@@ -4232,10 +4571,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4232
4571
|
</form>
|
|
4233
4572
|
</div>
|
|
4234
4573
|
|
|
4235
|
-
|
|
4574
|
+
@for (section of extraSections(); track section.key) {
|
|
4575
|
+
@if (section.editPermission) {
|
|
4576
|
+
<div *hasPermission="section.editPermission" class="card mb-2 md:mb-4">
|
|
4577
|
+
<div class="flex items-center gap-2 mb-4">
|
|
4578
|
+
@if (section.icon) {
|
|
4579
|
+
<i [class]="section.icon + ' text-primary'"></i>
|
|
4580
|
+
}
|
|
4581
|
+
<span class="font-semibold text-color">{{ section.title }}</span>
|
|
4582
|
+
</div>
|
|
4583
|
+
<div class="section-content">
|
|
4584
|
+
@if (section.component) {
|
|
4585
|
+
<ng-container *ngComponentOutlet="section.component" />
|
|
4586
|
+
}
|
|
4587
|
+
</div>
|
|
4588
|
+
</div>
|
|
4589
|
+
} @else {
|
|
4590
|
+
<div class="card mb-2 md:mb-4">
|
|
4591
|
+
<div class="flex items-center gap-2 mb-4">
|
|
4592
|
+
@if (section.icon) {
|
|
4593
|
+
<i [class]="section.icon + ' text-primary'"></i>
|
|
4594
|
+
}
|
|
4595
|
+
<span class="font-semibold text-color">{{ section.title }}</span>
|
|
4596
|
+
</div>
|
|
4597
|
+
<div class="section-content">
|
|
4598
|
+
@if (section.component) {
|
|
4599
|
+
<ng-container *ngComponentOutlet="section.component" />
|
|
4600
|
+
}
|
|
4601
|
+
</div>
|
|
4602
|
+
</div>
|
|
4603
|
+
}
|
|
4604
|
+
}
|
|
4605
|
+
|
|
4236
4606
|
@if (showBottomRow()) {
|
|
4237
4607
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4 flex-1">
|
|
4238
|
-
<!-- Company/Branch Info -->
|
|
4239
4608
|
@if (showCompanySection()) {
|
|
4240
4609
|
<div class="card h-48 md:h-56 flex flex-col">
|
|
4241
4610
|
<div class="flex items-center gap-2 mb-4">
|
|
@@ -4265,7 +4634,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4265
4634
|
</div>
|
|
4266
4635
|
}
|
|
4267
4636
|
|
|
4268
|
-
<!-- Permissions -->
|
|
4269
4637
|
@if (showPermissionsSection()) {
|
|
4270
4638
|
<div class="card h-48 md:h-56 flex flex-col">
|
|
4271
4639
|
<div class="flex items-center justify-between mb-4">
|
|
@@ -4276,7 +4644,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4276
4644
|
<p-tag value="Read-only" severity="secondary" />
|
|
4277
4645
|
</div>
|
|
4278
4646
|
<div class="flex flex-col gap-4 flex-1 overflow-auto">
|
|
4279
|
-
<!-- Roles -->
|
|
4280
4647
|
@if (showRoles()) {
|
|
4281
4648
|
<div>
|
|
4282
4649
|
<div class="text-sm text-muted-color mb-2 flex items-center gap-2">
|
|
@@ -4296,7 +4663,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4296
4663
|
</div>
|
|
4297
4664
|
}
|
|
4298
4665
|
|
|
4299
|
-
<!-- Actions -->
|
|
4300
4666
|
@if (showActions()) {
|
|
4301
4667
|
<div>
|
|
4302
4668
|
<div class="text-sm text-muted-color mb-2 flex items-center gap-2">
|
|
@@ -4338,11 +4704,33 @@ class RegisterPageComponent {
|
|
|
4338
4704
|
authState = inject(AuthStateService);
|
|
4339
4705
|
route = inject(ActivatedRoute);
|
|
4340
4706
|
router = inject(Router);
|
|
4707
|
+
validationConfig = inject(AUTH_VALIDATION_CONFIG, {
|
|
4708
|
+
optional: true,
|
|
4709
|
+
});
|
|
4710
|
+
registrationExtension = inject(AUTH_REGISTRATION_EXTENSION, {
|
|
4711
|
+
optional: true,
|
|
4712
|
+
});
|
|
4341
4713
|
queryParamMap = toSignal(this.route.queryParamMap);
|
|
4342
4714
|
companySlugInitialized = false;
|
|
4343
4715
|
returnUrl = input('', ...(ngDevMode ? [{ debugName: "returnUrl" }] : []));
|
|
4344
4716
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
4345
4717
|
companyFeatureEnabled = computed(() => isCompanyFeatureEnabled(this.appConfig), ...(ngDevMode ? [{ debugName: "companyFeatureEnabled" }] : []));
|
|
4718
|
+
defaultCompanySlug = computed(() => getDefaultCompanySlug(this.appConfig), ...(ngDevMode ? [{ debugName: "defaultCompanySlug" }] : []));
|
|
4719
|
+
defaultBranchSlug = computed(() => getDefaultBranchSlug(this.appConfig), ...(ngDevMode ? [{ debugName: "defaultBranchSlug" }] : []));
|
|
4720
|
+
hasDefaultCompany = computed(() => !!this.defaultCompanySlug(), ...(ngDevMode ? [{ debugName: "hasDefaultCompany" }] : []));
|
|
4721
|
+
hasDefaultBranch = computed(() => !!this.defaultBranchSlug(), ...(ngDevMode ? [{ debugName: "hasDefaultBranch" }] : []));
|
|
4722
|
+
extraFields = computed(() => {
|
|
4723
|
+
if (!this.registrationExtension)
|
|
4724
|
+
return [];
|
|
4725
|
+
const fields = this.registrationExtension.getExtraFields();
|
|
4726
|
+
return fields.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
|
|
4727
|
+
}, ...(ngDevMode ? [{ debugName: "extraFields" }] : []));
|
|
4728
|
+
extraFieldsModel = signal({}, ...(ngDevMode ? [{ debugName: "extraFieldsModel" }] : []));
|
|
4729
|
+
emailErrorMessage = computed(() => this.validationConfig?.email?.message ??
|
|
4730
|
+
'Please enter a valid email address', ...(ngDevMode ? [{ debugName: "emailErrorMessage" }] : []));
|
|
4731
|
+
passwordMinLength = computed(() => this.validationConfig?.password?.minLength ?? 8, ...(ngDevMode ? [{ debugName: "passwordMinLength" }] : []));
|
|
4732
|
+
passwordErrorMessage = computed(() => this.validationConfig?.password?.message ??
|
|
4733
|
+
`Password must be at least ${this.passwordMinLength()} characters`, ...(ngDevMode ? [{ debugName: "passwordErrorMessage" }] : []));
|
|
4346
4734
|
userFormModel = signal({
|
|
4347
4735
|
name: '',
|
|
4348
4736
|
email: '',
|
|
@@ -4354,10 +4742,10 @@ class RegisterPageComponent {
|
|
|
4354
4742
|
required(f.name, { message: 'Name is required' });
|
|
4355
4743
|
minLength(f.name, 2, { message: 'Name must be at least 2 characters' });
|
|
4356
4744
|
required(f.email, { message: 'Email is required' });
|
|
4357
|
-
email(f.email, { message:
|
|
4745
|
+
email(f.email, { message: this.emailErrorMessage() });
|
|
4358
4746
|
required(f.password, { message: 'Password is required' });
|
|
4359
|
-
minLength(f.password,
|
|
4360
|
-
message:
|
|
4747
|
+
minLength(f.password, this.passwordMinLength(), {
|
|
4748
|
+
message: this.passwordErrorMessage(),
|
|
4361
4749
|
});
|
|
4362
4750
|
required(f.confirmPassword, { message: 'Please confirm your password' });
|
|
4363
4751
|
});
|
|
@@ -4369,35 +4757,106 @@ class RegisterPageComponent {
|
|
|
4369
4757
|
newCompanyPhone: '',
|
|
4370
4758
|
newCompanyAddress: '',
|
|
4371
4759
|
}, ...(ngDevMode ? [{ debugName: "companyFormModel" }] : []));
|
|
4372
|
-
companyForm = form(this.companyFormModel
|
|
4760
|
+
companyForm = form(this.companyFormModel);
|
|
4761
|
+
emailValidationError = computed(() => {
|
|
4762
|
+
const email = this.userFormModel().email;
|
|
4763
|
+
if (!email)
|
|
4764
|
+
return null;
|
|
4765
|
+
return validateEmail(email, this.validationConfig?.email ?? undefined);
|
|
4766
|
+
}, ...(ngDevMode ? [{ debugName: "emailValidationError" }] : []));
|
|
4767
|
+
passwordValidationError = computed(() => {
|
|
4768
|
+
const password = this.userFormModel().password;
|
|
4769
|
+
if (!password)
|
|
4770
|
+
return null;
|
|
4771
|
+
if (!this.validationConfig?.password)
|
|
4772
|
+
return null;
|
|
4773
|
+
return validatePassword(password, this.validationConfig.password);
|
|
4774
|
+
}, ...(ngDevMode ? [{ debugName: "passwordValidationError" }] : []));
|
|
4775
|
+
extraFieldsValidationError = computed(() => {
|
|
4776
|
+
if (!this.registrationExtension?.validateExtraFields)
|
|
4777
|
+
return null;
|
|
4778
|
+
return this.registrationExtension.validateExtraFields(this.extraFieldsModel());
|
|
4779
|
+
}, ...(ngDevMode ? [{ debugName: "extraFieldsValidationError" }] : []));
|
|
4373
4780
|
passwordsMatch = computed(() => {
|
|
4374
4781
|
const model = this.userFormModel();
|
|
4375
4782
|
return model.password === model.confirmPassword;
|
|
4376
4783
|
}, ...(ngDevMode ? [{ debugName: "passwordsMatch" }] : []));
|
|
4377
4784
|
isFormValid = computed(() => {
|
|
4378
4785
|
const userModel = this.userFormModel();
|
|
4786
|
+
const emailError = this.emailValidationError();
|
|
4787
|
+
const passwordError = this.passwordValidationError();
|
|
4788
|
+
const extraFieldsError = this.extraFieldsValidationError();
|
|
4379
4789
|
const userValid = userModel.name.trim().length >= 2 &&
|
|
4380
4790
|
userModel.email.includes('@') &&
|
|
4381
|
-
|
|
4791
|
+
!emailError &&
|
|
4792
|
+
userModel.password.length >= this.passwordMinLength() &&
|
|
4793
|
+
!passwordError &&
|
|
4382
4794
|
userModel.confirmPassword.length > 0 &&
|
|
4383
|
-
this.passwordsMatch()
|
|
4795
|
+
this.passwordsMatch() &&
|
|
4796
|
+
!extraFieldsError;
|
|
4797
|
+
const extraFieldsValid = this.validateRequiredExtraFields();
|
|
4384
4798
|
if (!isCompanyFeatureEnabled(this.appConfig))
|
|
4385
|
-
return userValid;
|
|
4799
|
+
return userValid && extraFieldsValid;
|
|
4386
4800
|
const companyModel = this.companyFormModel();
|
|
4387
4801
|
if (companyModel.createNewCompany) {
|
|
4388
|
-
return userValid &&
|
|
4802
|
+
return (userValid &&
|
|
4803
|
+
extraFieldsValid &&
|
|
4804
|
+
companyModel.newCompanyName.trim().length > 0);
|
|
4389
4805
|
}
|
|
4390
|
-
return userValid;
|
|
4806
|
+
return userValid && extraFieldsValid;
|
|
4391
4807
|
}, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
|
|
4808
|
+
validateRequiredExtraFields() {
|
|
4809
|
+
const fields = this.extraFields();
|
|
4810
|
+
const values = this.extraFieldsModel();
|
|
4811
|
+
for (const field of fields) {
|
|
4812
|
+
if (field.required) {
|
|
4813
|
+
const value = values[field.key];
|
|
4814
|
+
if (value === undefined || value === null || value === '') {
|
|
4815
|
+
return false;
|
|
4816
|
+
}
|
|
4817
|
+
}
|
|
4818
|
+
}
|
|
4819
|
+
return true;
|
|
4820
|
+
}
|
|
4821
|
+
updateExtraField(key, value) {
|
|
4822
|
+
this.extraFieldsModel.update((model) => ({ ...model, [key]: value }));
|
|
4823
|
+
}
|
|
4824
|
+
getFieldTemplateContext(field) {
|
|
4825
|
+
return {
|
|
4826
|
+
field,
|
|
4827
|
+
value: this.extraFieldsModel()[field.key] ?? field.defaultValue,
|
|
4828
|
+
updateValue: (value) => this.updateExtraField(field.key, value),
|
|
4829
|
+
};
|
|
4830
|
+
}
|
|
4831
|
+
parentInjector = inject(Injector);
|
|
4832
|
+
getFieldInjector(field) {
|
|
4833
|
+
return Injector.create({
|
|
4834
|
+
providers: [
|
|
4835
|
+
{
|
|
4836
|
+
provide: REGISTRATION_FIELD_CONTEXT,
|
|
4837
|
+
useValue: this.getFieldTemplateContext(field),
|
|
4838
|
+
},
|
|
4839
|
+
],
|
|
4840
|
+
parent: field.injector ?? this.parentInjector,
|
|
4841
|
+
});
|
|
4842
|
+
}
|
|
4392
4843
|
constructor() {
|
|
4393
4844
|
effect(() => {
|
|
4394
4845
|
const params = this.queryParamMap();
|
|
4395
4846
|
if (!params || this.companySlugInitialized)
|
|
4396
4847
|
return;
|
|
4397
4848
|
this.companySlugInitialized = true;
|
|
4398
|
-
const
|
|
4399
|
-
|
|
4400
|
-
|
|
4849
|
+
const configCompanySlug = this.defaultCompanySlug();
|
|
4850
|
+
const configBranchSlug = this.defaultBranchSlug();
|
|
4851
|
+
const queryCompanySlug = params.get('companySlug');
|
|
4852
|
+
const companySlug = configCompanySlug || queryCompanySlug || '';
|
|
4853
|
+
const branchSlug = configBranchSlug || '';
|
|
4854
|
+
if (companySlug || branchSlug) {
|
|
4855
|
+
this.companyFormModel.update((model) => ({
|
|
4856
|
+
...model,
|
|
4857
|
+
companySlug,
|
|
4858
|
+
branchSlug,
|
|
4859
|
+
}));
|
|
4401
4860
|
}
|
|
4402
4861
|
});
|
|
4403
4862
|
}
|
|
@@ -4433,24 +4892,32 @@ class RegisterPageComponent {
|
|
|
4433
4892
|
this.isLoading.set(true);
|
|
4434
4893
|
const userModel = this.userFormModel();
|
|
4435
4894
|
const companyModel = this.companyFormModel();
|
|
4436
|
-
|
|
4895
|
+
let registrationData = {
|
|
4437
4896
|
name: userModel.name,
|
|
4438
4897
|
email: userModel.email,
|
|
4439
4898
|
password: userModel.password,
|
|
4440
4899
|
phone: userModel.phone || undefined,
|
|
4441
4900
|
};
|
|
4901
|
+
const extraFieldsData = this.extraFieldsModel();
|
|
4902
|
+
if (Object.keys(extraFieldsData).length > 0) {
|
|
4903
|
+
registrationData['additionalFields'] = extraFieldsData;
|
|
4904
|
+
}
|
|
4905
|
+
if (this.registrationExtension?.transformRegistrationData) {
|
|
4906
|
+
registrationData =
|
|
4907
|
+
this.registrationExtension.transformRegistrationData(registrationData);
|
|
4908
|
+
}
|
|
4442
4909
|
if (isCompanyFeatureEnabled(this.appConfig)) {
|
|
4443
4910
|
if (companyModel.createNewCompany) {
|
|
4444
|
-
registrationData
|
|
4911
|
+
registrationData['newCompanyName'] =
|
|
4445
4912
|
companyModel.newCompanyName || undefined;
|
|
4446
|
-
registrationData
|
|
4913
|
+
registrationData['newCompanyPhone'] =
|
|
4447
4914
|
companyModel.newCompanyPhone || undefined;
|
|
4448
|
-
registrationData
|
|
4915
|
+
registrationData['newCompanyAddress'] =
|
|
4449
4916
|
companyModel.newCompanyAddress || undefined;
|
|
4450
4917
|
}
|
|
4451
4918
|
else {
|
|
4452
|
-
registrationData
|
|
4453
|
-
registrationData
|
|
4919
|
+
registrationData['companySlug'] = companyModel.companySlug || undefined;
|
|
4920
|
+
registrationData['branchSlug'] = companyModel.branchSlug || undefined;
|
|
4454
4921
|
}
|
|
4455
4922
|
}
|
|
4456
4923
|
this.authApi
|
|
@@ -4490,8 +4957,8 @@ class RegisterPageComponent {
|
|
|
4490
4957
|
},
|
|
4491
4958
|
});
|
|
4492
4959
|
}
|
|
4493
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
4494
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
4960
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: RegisterPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4961
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: RegisterPageComponent, isStandalone: true, selector: "lib-register-page", inputs: { returnUrl: { classPropertyName: "returnUrl", publicName: "returnUrl", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
4495
4962
|
<app-floating-configurator />
|
|
4496
4963
|
<div
|
|
4497
4964
|
class="bg-surface-ground flex items-center justify-center min-h-screen py-8"
|
|
@@ -4557,6 +5024,11 @@ class RegisterPageComponent {
|
|
|
4557
5024
|
class="w-full"
|
|
4558
5025
|
autocomplete="email"
|
|
4559
5026
|
/>
|
|
5027
|
+
@if (emailValidationError() && userFormModel().email) {
|
|
5028
|
+
<small class="text-danger block mt-1">{{
|
|
5029
|
+
emailValidationError()
|
|
5030
|
+
}}</small>
|
|
5031
|
+
}
|
|
4560
5032
|
</div>
|
|
4561
5033
|
|
|
4562
5034
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
@@ -4569,10 +5041,15 @@ class RegisterPageComponent {
|
|
|
4569
5041
|
id="password"
|
|
4570
5042
|
type="password"
|
|
4571
5043
|
[formField]="userForm.password"
|
|
4572
|
-
placeholder="Min.
|
|
5044
|
+
placeholder="Min. {{ passwordMinLength() }} characters"
|
|
4573
5045
|
class="w-full"
|
|
4574
5046
|
autocomplete="new-password"
|
|
4575
5047
|
/>
|
|
5048
|
+
@if (passwordValidationError() && userFormModel().password) {
|
|
5049
|
+
<small class="text-danger block mt-1">{{
|
|
5050
|
+
passwordValidationError()
|
|
5051
|
+
}}</small>
|
|
5052
|
+
}
|
|
4576
5053
|
</div>
|
|
4577
5054
|
|
|
4578
5055
|
<div>
|
|
@@ -4596,29 +5073,193 @@ class RegisterPageComponent {
|
|
|
4596
5073
|
</div>
|
|
4597
5074
|
</div>
|
|
4598
5075
|
|
|
5076
|
+
@if (extraFields().length > 0) {
|
|
5077
|
+
<div class="border-t border-surface pt-4 mt-4 mb-4">
|
|
5078
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
5079
|
+
@for (field of extraFields(); track field.key) {
|
|
5080
|
+
<div [class]="field.containerClass ?? ''">
|
|
5081
|
+
<label [for]="field.key" class="block font-medium mb-2">
|
|
5082
|
+
{{ field.label }}{{ field.required ? ' *' : '' }}
|
|
5083
|
+
</label>
|
|
5084
|
+
@if (field.component) {
|
|
5085
|
+
<ng-container
|
|
5086
|
+
*ngComponentOutlet="field.component; injector: getFieldInjector(field)"
|
|
5087
|
+
></ng-container>
|
|
5088
|
+
} @else if (field.template) {
|
|
5089
|
+
<ng-container
|
|
5090
|
+
[ngTemplateOutlet]="field.template"
|
|
5091
|
+
[ngTemplateOutletContext]="getFieldTemplateContext(field)"
|
|
5092
|
+
></ng-container>
|
|
5093
|
+
} @else {
|
|
5094
|
+
@switch (field.type) {
|
|
5095
|
+
@case ('text') {
|
|
5096
|
+
<input
|
|
5097
|
+
pInputText
|
|
5098
|
+
[id]="field.key"
|
|
5099
|
+
[placeholder]="field.placeholder ?? ''"
|
|
5100
|
+
[value]="
|
|
5101
|
+
extraFieldsModel()[field.key] ??
|
|
5102
|
+
field.defaultValue ??
|
|
5103
|
+
''
|
|
5104
|
+
"
|
|
5105
|
+
(input)="
|
|
5106
|
+
updateExtraField(
|
|
5107
|
+
field.key,
|
|
5108
|
+
$any($event.target).value
|
|
5109
|
+
)
|
|
5110
|
+
"
|
|
5111
|
+
class="w-full"
|
|
5112
|
+
/>
|
|
5113
|
+
}
|
|
5114
|
+
@case ('number') {
|
|
5115
|
+
<input
|
|
5116
|
+
pInputText
|
|
5117
|
+
type="number"
|
|
5118
|
+
[id]="field.key"
|
|
5119
|
+
[placeholder]="field.placeholder ?? ''"
|
|
5120
|
+
[value]="
|
|
5121
|
+
extraFieldsModel()[field.key] ??
|
|
5122
|
+
field.defaultValue ??
|
|
5123
|
+
''
|
|
5124
|
+
"
|
|
5125
|
+
(input)="
|
|
5126
|
+
updateExtraField(
|
|
5127
|
+
field.key,
|
|
5128
|
+
$any($event.target).valueAsNumber
|
|
5129
|
+
)
|
|
5130
|
+
"
|
|
5131
|
+
class="w-full"
|
|
5132
|
+
/>
|
|
5133
|
+
}
|
|
5134
|
+
@case ('textarea') {
|
|
5135
|
+
<textarea
|
|
5136
|
+
pInputTextarea
|
|
5137
|
+
[id]="field.key"
|
|
5138
|
+
[placeholder]="field.placeholder ?? ''"
|
|
5139
|
+
[value]="
|
|
5140
|
+
extraFieldsModel()[field.key] ??
|
|
5141
|
+
field.defaultValue ??
|
|
5142
|
+
''
|
|
5143
|
+
"
|
|
5144
|
+
(input)="
|
|
5145
|
+
updateExtraField(
|
|
5146
|
+
field.key,
|
|
5147
|
+
$any($event.target).value
|
|
5148
|
+
)
|
|
5149
|
+
"
|
|
5150
|
+
class="w-full"
|
|
5151
|
+
rows="3"
|
|
5152
|
+
></textarea>
|
|
5153
|
+
}
|
|
5154
|
+
@case ('select') {
|
|
5155
|
+
<select
|
|
5156
|
+
[id]="field.key"
|
|
5157
|
+
class="p-select-native w-full"
|
|
5158
|
+
[value]="
|
|
5159
|
+
extraFieldsModel()[field.key] ??
|
|
5160
|
+
field.defaultValue ??
|
|
5161
|
+
''
|
|
5162
|
+
"
|
|
5163
|
+
(change)="
|
|
5164
|
+
updateExtraField(
|
|
5165
|
+
field.key,
|
|
5166
|
+
$any($event.target).value
|
|
5167
|
+
)
|
|
5168
|
+
"
|
|
5169
|
+
>
|
|
5170
|
+
<option value="">
|
|
5171
|
+
{{ field.placeholder ?? 'Select...' }}
|
|
5172
|
+
</option>
|
|
5173
|
+
@for (opt of field.options; track opt.value) {
|
|
5174
|
+
<option [value]="opt.value">
|
|
5175
|
+
{{ opt.label }}
|
|
5176
|
+
</option>
|
|
5177
|
+
}
|
|
5178
|
+
</select>
|
|
5179
|
+
}
|
|
5180
|
+
@case ('checkbox') {
|
|
5181
|
+
<label class="p-checkbox-native">
|
|
5182
|
+
<input
|
|
5183
|
+
type="checkbox"
|
|
5184
|
+
[id]="field.key"
|
|
5185
|
+
[checked]="
|
|
5186
|
+
extraFieldsModel()[field.key] ??
|
|
5187
|
+
field.defaultValue ??
|
|
5188
|
+
false
|
|
5189
|
+
"
|
|
5190
|
+
(change)="
|
|
5191
|
+
updateExtraField(
|
|
5192
|
+
field.key,
|
|
5193
|
+
$any($event.target).checked
|
|
5194
|
+
)
|
|
5195
|
+
"
|
|
5196
|
+
/>
|
|
5197
|
+
<span>{{
|
|
5198
|
+
field.placeholder ?? field.label
|
|
5199
|
+
}}</span>
|
|
5200
|
+
</label>
|
|
5201
|
+
}
|
|
5202
|
+
@case ('date') {
|
|
5203
|
+
<input
|
|
5204
|
+
pInputText
|
|
5205
|
+
type="date"
|
|
5206
|
+
[id]="field.key"
|
|
5207
|
+
[value]="
|
|
5208
|
+
extraFieldsModel()[field.key] ??
|
|
5209
|
+
field.defaultValue ??
|
|
5210
|
+
''
|
|
5211
|
+
"
|
|
5212
|
+
(input)="
|
|
5213
|
+
updateExtraField(
|
|
5214
|
+
field.key,
|
|
5215
|
+
$any($event.target).value
|
|
5216
|
+
)
|
|
5217
|
+
"
|
|
5218
|
+
class="w-full"
|
|
5219
|
+
/>
|
|
5220
|
+
}
|
|
5221
|
+
}
|
|
5222
|
+
}
|
|
5223
|
+
</div>
|
|
5224
|
+
}
|
|
5225
|
+
</div>
|
|
5226
|
+
@if (extraFieldsValidationError()) {
|
|
5227
|
+
<small class="text-danger block mt-2">{{
|
|
5228
|
+
extraFieldsValidationError()
|
|
5229
|
+
}}</small>
|
|
5230
|
+
}
|
|
5231
|
+
</div>
|
|
5232
|
+
}
|
|
5233
|
+
|
|
4599
5234
|
@if (companyFeatureEnabled()) {
|
|
4600
5235
|
<div class="border-t border-surface pt-6 mt-6">
|
|
4601
5236
|
<div class="text-center mb-6">
|
|
4602
5237
|
<div class="text-2xl font-medium mb-2 text-color">
|
|
4603
5238
|
Company Details
|
|
4604
5239
|
</div>
|
|
4605
|
-
<span class="text-muted-color font-medium"
|
|
4606
|
-
|
|
4607
|
-
|
|
5240
|
+
<span class="text-muted-color font-medium">
|
|
5241
|
+
@if (hasDefaultCompany()) {
|
|
5242
|
+
You will join the default company
|
|
5243
|
+
} @else {
|
|
5244
|
+
Join existing or create new company
|
|
5245
|
+
}
|
|
5246
|
+
</span>
|
|
4608
5247
|
</div>
|
|
4609
5248
|
|
|
4610
|
-
|
|
4611
|
-
<
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
5249
|
+
@if (!hasDefaultCompany()) {
|
|
5250
|
+
<div class="mb-4">
|
|
5251
|
+
<label
|
|
5252
|
+
class="p-checkbox-native"
|
|
5253
|
+
(click)="onCreateCompanyToggle()"
|
|
5254
|
+
>
|
|
5255
|
+
<input
|
|
5256
|
+
type="checkbox"
|
|
5257
|
+
[formField]="companyForm.createNewCompany"
|
|
5258
|
+
/>
|
|
5259
|
+
<span>Create new company</span>
|
|
5260
|
+
</label>
|
|
5261
|
+
</div>
|
|
5262
|
+
}
|
|
4622
5263
|
|
|
4623
5264
|
@if (!companyFormModel().createNewCompany) {
|
|
4624
5265
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
@@ -4626,29 +5267,55 @@ class RegisterPageComponent {
|
|
|
4626
5267
|
<label for="companySlug" class="block font-medium mb-2"
|
|
4627
5268
|
>Company Code</label
|
|
4628
5269
|
>
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
5270
|
+
@if (hasDefaultCompany()) {
|
|
5271
|
+
<input
|
|
5272
|
+
pInputText
|
|
5273
|
+
id="companySlug"
|
|
5274
|
+
[value]="defaultCompanySlug()"
|
|
5275
|
+
class="w-full bg-surface-100"
|
|
5276
|
+
readonly
|
|
5277
|
+
/>
|
|
5278
|
+
<small class="text-muted-color"
|
|
5279
|
+
>Pre-configured company</small
|
|
5280
|
+
>
|
|
5281
|
+
} @else {
|
|
5282
|
+
<input
|
|
5283
|
+
pInputText
|
|
5284
|
+
id="companySlug"
|
|
5285
|
+
[formField]="companyForm.companySlug"
|
|
5286
|
+
placeholder="Company code/slug"
|
|
5287
|
+
class="w-full"
|
|
5288
|
+
/>
|
|
5289
|
+
<small class="text-muted-color"
|
|
5290
|
+
>Enter company code to join</small
|
|
5291
|
+
>
|
|
5292
|
+
}
|
|
4639
5293
|
</div>
|
|
4640
5294
|
|
|
4641
5295
|
<div>
|
|
4642
5296
|
<label for="branchSlug" class="block font-medium mb-2"
|
|
4643
5297
|
>Branch Code</label
|
|
4644
5298
|
>
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
5299
|
+
@if (hasDefaultBranch()) {
|
|
5300
|
+
<input
|
|
5301
|
+
pInputText
|
|
5302
|
+
id="branchSlug"
|
|
5303
|
+
[value]="defaultBranchSlug()"
|
|
5304
|
+
class="w-full bg-surface-100"
|
|
5305
|
+
readonly
|
|
5306
|
+
/>
|
|
5307
|
+
<small class="text-muted-color"
|
|
5308
|
+
>Pre-configured branch</small
|
|
5309
|
+
>
|
|
5310
|
+
} @else {
|
|
5311
|
+
<input
|
|
5312
|
+
pInputText
|
|
5313
|
+
id="branchSlug"
|
|
5314
|
+
[formField]="companyForm.branchSlug"
|
|
5315
|
+
placeholder="Branch code (optional)"
|
|
5316
|
+
class="w-full"
|
|
5317
|
+
/>
|
|
5318
|
+
}
|
|
4652
5319
|
</div>
|
|
4653
5320
|
</div>
|
|
4654
5321
|
} @else {
|
|
@@ -4722,9 +5389,9 @@ class RegisterPageComponent {
|
|
|
4722
5389
|
</div>
|
|
4723
5390
|
</div>
|
|
4724
5391
|
</div>
|
|
4725
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1
|
|
5392
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: i9.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: AppFloatingConfigurator, selector: "app-floating-configurator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4726
5393
|
}
|
|
4727
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
5394
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: RegisterPageComponent, decorators: [{
|
|
4728
5395
|
type: Component,
|
|
4729
5396
|
args: [{
|
|
4730
5397
|
selector: 'lib-register-page',
|
|
@@ -4796,6 +5463,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4796
5463
|
class="w-full"
|
|
4797
5464
|
autocomplete="email"
|
|
4798
5465
|
/>
|
|
5466
|
+
@if (emailValidationError() && userFormModel().email) {
|
|
5467
|
+
<small class="text-danger block mt-1">{{
|
|
5468
|
+
emailValidationError()
|
|
5469
|
+
}}</small>
|
|
5470
|
+
}
|
|
4799
5471
|
</div>
|
|
4800
5472
|
|
|
4801
5473
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
@@ -4808,10 +5480,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4808
5480
|
id="password"
|
|
4809
5481
|
type="password"
|
|
4810
5482
|
[formField]="userForm.password"
|
|
4811
|
-
placeholder="Min.
|
|
5483
|
+
placeholder="Min. {{ passwordMinLength() }} characters"
|
|
4812
5484
|
class="w-full"
|
|
4813
5485
|
autocomplete="new-password"
|
|
4814
5486
|
/>
|
|
5487
|
+
@if (passwordValidationError() && userFormModel().password) {
|
|
5488
|
+
<small class="text-danger block mt-1">{{
|
|
5489
|
+
passwordValidationError()
|
|
5490
|
+
}}</small>
|
|
5491
|
+
}
|
|
4815
5492
|
</div>
|
|
4816
5493
|
|
|
4817
5494
|
<div>
|
|
@@ -4835,29 +5512,193 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4835
5512
|
</div>
|
|
4836
5513
|
</div>
|
|
4837
5514
|
|
|
5515
|
+
@if (extraFields().length > 0) {
|
|
5516
|
+
<div class="border-t border-surface pt-4 mt-4 mb-4">
|
|
5517
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
5518
|
+
@for (field of extraFields(); track field.key) {
|
|
5519
|
+
<div [class]="field.containerClass ?? ''">
|
|
5520
|
+
<label [for]="field.key" class="block font-medium mb-2">
|
|
5521
|
+
{{ field.label }}{{ field.required ? ' *' : '' }}
|
|
5522
|
+
</label>
|
|
5523
|
+
@if (field.component) {
|
|
5524
|
+
<ng-container
|
|
5525
|
+
*ngComponentOutlet="field.component; injector: getFieldInjector(field)"
|
|
5526
|
+
></ng-container>
|
|
5527
|
+
} @else if (field.template) {
|
|
5528
|
+
<ng-container
|
|
5529
|
+
[ngTemplateOutlet]="field.template"
|
|
5530
|
+
[ngTemplateOutletContext]="getFieldTemplateContext(field)"
|
|
5531
|
+
></ng-container>
|
|
5532
|
+
} @else {
|
|
5533
|
+
@switch (field.type) {
|
|
5534
|
+
@case ('text') {
|
|
5535
|
+
<input
|
|
5536
|
+
pInputText
|
|
5537
|
+
[id]="field.key"
|
|
5538
|
+
[placeholder]="field.placeholder ?? ''"
|
|
5539
|
+
[value]="
|
|
5540
|
+
extraFieldsModel()[field.key] ??
|
|
5541
|
+
field.defaultValue ??
|
|
5542
|
+
''
|
|
5543
|
+
"
|
|
5544
|
+
(input)="
|
|
5545
|
+
updateExtraField(
|
|
5546
|
+
field.key,
|
|
5547
|
+
$any($event.target).value
|
|
5548
|
+
)
|
|
5549
|
+
"
|
|
5550
|
+
class="w-full"
|
|
5551
|
+
/>
|
|
5552
|
+
}
|
|
5553
|
+
@case ('number') {
|
|
5554
|
+
<input
|
|
5555
|
+
pInputText
|
|
5556
|
+
type="number"
|
|
5557
|
+
[id]="field.key"
|
|
5558
|
+
[placeholder]="field.placeholder ?? ''"
|
|
5559
|
+
[value]="
|
|
5560
|
+
extraFieldsModel()[field.key] ??
|
|
5561
|
+
field.defaultValue ??
|
|
5562
|
+
''
|
|
5563
|
+
"
|
|
5564
|
+
(input)="
|
|
5565
|
+
updateExtraField(
|
|
5566
|
+
field.key,
|
|
5567
|
+
$any($event.target).valueAsNumber
|
|
5568
|
+
)
|
|
5569
|
+
"
|
|
5570
|
+
class="w-full"
|
|
5571
|
+
/>
|
|
5572
|
+
}
|
|
5573
|
+
@case ('textarea') {
|
|
5574
|
+
<textarea
|
|
5575
|
+
pInputTextarea
|
|
5576
|
+
[id]="field.key"
|
|
5577
|
+
[placeholder]="field.placeholder ?? ''"
|
|
5578
|
+
[value]="
|
|
5579
|
+
extraFieldsModel()[field.key] ??
|
|
5580
|
+
field.defaultValue ??
|
|
5581
|
+
''
|
|
5582
|
+
"
|
|
5583
|
+
(input)="
|
|
5584
|
+
updateExtraField(
|
|
5585
|
+
field.key,
|
|
5586
|
+
$any($event.target).value
|
|
5587
|
+
)
|
|
5588
|
+
"
|
|
5589
|
+
class="w-full"
|
|
5590
|
+
rows="3"
|
|
5591
|
+
></textarea>
|
|
5592
|
+
}
|
|
5593
|
+
@case ('select') {
|
|
5594
|
+
<select
|
|
5595
|
+
[id]="field.key"
|
|
5596
|
+
class="p-select-native w-full"
|
|
5597
|
+
[value]="
|
|
5598
|
+
extraFieldsModel()[field.key] ??
|
|
5599
|
+
field.defaultValue ??
|
|
5600
|
+
''
|
|
5601
|
+
"
|
|
5602
|
+
(change)="
|
|
5603
|
+
updateExtraField(
|
|
5604
|
+
field.key,
|
|
5605
|
+
$any($event.target).value
|
|
5606
|
+
)
|
|
5607
|
+
"
|
|
5608
|
+
>
|
|
5609
|
+
<option value="">
|
|
5610
|
+
{{ field.placeholder ?? 'Select...' }}
|
|
5611
|
+
</option>
|
|
5612
|
+
@for (opt of field.options; track opt.value) {
|
|
5613
|
+
<option [value]="opt.value">
|
|
5614
|
+
{{ opt.label }}
|
|
5615
|
+
</option>
|
|
5616
|
+
}
|
|
5617
|
+
</select>
|
|
5618
|
+
}
|
|
5619
|
+
@case ('checkbox') {
|
|
5620
|
+
<label class="p-checkbox-native">
|
|
5621
|
+
<input
|
|
5622
|
+
type="checkbox"
|
|
5623
|
+
[id]="field.key"
|
|
5624
|
+
[checked]="
|
|
5625
|
+
extraFieldsModel()[field.key] ??
|
|
5626
|
+
field.defaultValue ??
|
|
5627
|
+
false
|
|
5628
|
+
"
|
|
5629
|
+
(change)="
|
|
5630
|
+
updateExtraField(
|
|
5631
|
+
field.key,
|
|
5632
|
+
$any($event.target).checked
|
|
5633
|
+
)
|
|
5634
|
+
"
|
|
5635
|
+
/>
|
|
5636
|
+
<span>{{
|
|
5637
|
+
field.placeholder ?? field.label
|
|
5638
|
+
}}</span>
|
|
5639
|
+
</label>
|
|
5640
|
+
}
|
|
5641
|
+
@case ('date') {
|
|
5642
|
+
<input
|
|
5643
|
+
pInputText
|
|
5644
|
+
type="date"
|
|
5645
|
+
[id]="field.key"
|
|
5646
|
+
[value]="
|
|
5647
|
+
extraFieldsModel()[field.key] ??
|
|
5648
|
+
field.defaultValue ??
|
|
5649
|
+
''
|
|
5650
|
+
"
|
|
5651
|
+
(input)="
|
|
5652
|
+
updateExtraField(
|
|
5653
|
+
field.key,
|
|
5654
|
+
$any($event.target).value
|
|
5655
|
+
)
|
|
5656
|
+
"
|
|
5657
|
+
class="w-full"
|
|
5658
|
+
/>
|
|
5659
|
+
}
|
|
5660
|
+
}
|
|
5661
|
+
}
|
|
5662
|
+
</div>
|
|
5663
|
+
}
|
|
5664
|
+
</div>
|
|
5665
|
+
@if (extraFieldsValidationError()) {
|
|
5666
|
+
<small class="text-danger block mt-2">{{
|
|
5667
|
+
extraFieldsValidationError()
|
|
5668
|
+
}}</small>
|
|
5669
|
+
}
|
|
5670
|
+
</div>
|
|
5671
|
+
}
|
|
5672
|
+
|
|
4838
5673
|
@if (companyFeatureEnabled()) {
|
|
4839
5674
|
<div class="border-t border-surface pt-6 mt-6">
|
|
4840
5675
|
<div class="text-center mb-6">
|
|
4841
5676
|
<div class="text-2xl font-medium mb-2 text-color">
|
|
4842
5677
|
Company Details
|
|
4843
5678
|
</div>
|
|
4844
|
-
<span class="text-muted-color font-medium"
|
|
4845
|
-
|
|
4846
|
-
|
|
5679
|
+
<span class="text-muted-color font-medium">
|
|
5680
|
+
@if (hasDefaultCompany()) {
|
|
5681
|
+
You will join the default company
|
|
5682
|
+
} @else {
|
|
5683
|
+
Join existing or create new company
|
|
5684
|
+
}
|
|
5685
|
+
</span>
|
|
4847
5686
|
</div>
|
|
4848
5687
|
|
|
4849
|
-
|
|
4850
|
-
<
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
5688
|
+
@if (!hasDefaultCompany()) {
|
|
5689
|
+
<div class="mb-4">
|
|
5690
|
+
<label
|
|
5691
|
+
class="p-checkbox-native"
|
|
5692
|
+
(click)="onCreateCompanyToggle()"
|
|
5693
|
+
>
|
|
5694
|
+
<input
|
|
5695
|
+
type="checkbox"
|
|
5696
|
+
[formField]="companyForm.createNewCompany"
|
|
5697
|
+
/>
|
|
5698
|
+
<span>Create new company</span>
|
|
5699
|
+
</label>
|
|
5700
|
+
</div>
|
|
5701
|
+
}
|
|
4861
5702
|
|
|
4862
5703
|
@if (!companyFormModel().createNewCompany) {
|
|
4863
5704
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
@@ -4865,29 +5706,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
4865
5706
|
<label for="companySlug" class="block font-medium mb-2"
|
|
4866
5707
|
>Company Code</label
|
|
4867
5708
|
>
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
5709
|
+
@if (hasDefaultCompany()) {
|
|
5710
|
+
<input
|
|
5711
|
+
pInputText
|
|
5712
|
+
id="companySlug"
|
|
5713
|
+
[value]="defaultCompanySlug()"
|
|
5714
|
+
class="w-full bg-surface-100"
|
|
5715
|
+
readonly
|
|
5716
|
+
/>
|
|
5717
|
+
<small class="text-muted-color"
|
|
5718
|
+
>Pre-configured company</small
|
|
5719
|
+
>
|
|
5720
|
+
} @else {
|
|
5721
|
+
<input
|
|
5722
|
+
pInputText
|
|
5723
|
+
id="companySlug"
|
|
5724
|
+
[formField]="companyForm.companySlug"
|
|
5725
|
+
placeholder="Company code/slug"
|
|
5726
|
+
class="w-full"
|
|
5727
|
+
/>
|
|
5728
|
+
<small class="text-muted-color"
|
|
5729
|
+
>Enter company code to join</small
|
|
5730
|
+
>
|
|
5731
|
+
}
|
|
4878
5732
|
</div>
|
|
4879
5733
|
|
|
4880
5734
|
<div>
|
|
4881
5735
|
<label for="branchSlug" class="block font-medium mb-2"
|
|
4882
5736
|
>Branch Code</label
|
|
4883
5737
|
>
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
5738
|
+
@if (hasDefaultBranch()) {
|
|
5739
|
+
<input
|
|
5740
|
+
pInputText
|
|
5741
|
+
id="branchSlug"
|
|
5742
|
+
[value]="defaultBranchSlug()"
|
|
5743
|
+
class="w-full bg-surface-100"
|
|
5744
|
+
readonly
|
|
5745
|
+
/>
|
|
5746
|
+
<small class="text-muted-color"
|
|
5747
|
+
>Pre-configured branch</small
|
|
5748
|
+
>
|
|
5749
|
+
} @else {
|
|
5750
|
+
<input
|
|
5751
|
+
pInputText
|
|
5752
|
+
id="branchSlug"
|
|
5753
|
+
[formField]="companyForm.branchSlug"
|
|
5754
|
+
placeholder="Branch code (optional)"
|
|
5755
|
+
class="w-full"
|
|
5756
|
+
/>
|
|
5757
|
+
}
|
|
4891
5758
|
</div>
|
|
4892
5759
|
</div>
|
|
4893
5760
|
} @else {
|
|
@@ -5036,8 +5903,8 @@ class ResetPasswordPageComponent {
|
|
|
5036
5903
|
},
|
|
5037
5904
|
});
|
|
5038
5905
|
}
|
|
5039
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
5040
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
5906
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ResetPasswordPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5907
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ResetPasswordPageComponent, isStandalone: true, selector: "lib-reset-password-page", ngImport: i0, template: `
|
|
5041
5908
|
<app-floating-configurator />
|
|
5042
5909
|
<div class="bg-surface-ground flex items-center justify-center min-h-screen">
|
|
5043
5910
|
<div class="flex flex-col items-center justify-center w-full max-w-[32rem] px-4">
|
|
@@ -5148,9 +6015,9 @@ class ResetPasswordPageComponent {
|
|
|
5148
6015
|
</div>
|
|
5149
6016
|
</div>
|
|
5150
6017
|
</div>
|
|
5151
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
6018
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: AppFloatingConfigurator, selector: "app-floating-configurator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5152
6019
|
}
|
|
5153
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
6020
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ResetPasswordPageComponent, decorators: [{
|
|
5154
6021
|
type: Component,
|
|
5155
6022
|
args: [{
|
|
5156
6023
|
selector: 'lib-reset-password-page',
|
|
@@ -5458,8 +6325,8 @@ class UserFormComponent {
|
|
|
5458
6325
|
onCancel() {
|
|
5459
6326
|
this.router.navigate(['/administration/users']);
|
|
5460
6327
|
}
|
|
5461
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
5462
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
6328
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6329
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: UserFormComponent, isStandalone: true, selector: "lib-user-form", ngImport: i0, template: `
|
|
5463
6330
|
<p-card>
|
|
5464
6331
|
<ng-template #header>
|
|
5465
6332
|
<div class="flex justify-between items-center p-4">
|
|
@@ -5561,9 +6428,9 @@ class UserFormComponent {
|
|
|
5561
6428
|
</div>
|
|
5562
6429
|
</form>
|
|
5563
6430
|
</p-card>
|
|
5564
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
6431
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5565
6432
|
}
|
|
5566
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
6433
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserFormComponent, decorators: [{
|
|
5567
6434
|
type: Component,
|
|
5568
6435
|
args: [{
|
|
5569
6436
|
selector: 'lib-user-form',
|
|
@@ -5771,8 +6638,8 @@ class UserCompanyPermissionDialogComponent {
|
|
|
5771
6638
|
onClose() {
|
|
5772
6639
|
this.closed.emit();
|
|
5773
6640
|
}
|
|
5774
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
5775
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
6641
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserCompanyPermissionDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6642
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: UserCompanyPermissionDialogComponent, isStandalone: true, selector: "lib-user-company-permission-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed", permissionsChanged: "permissionsChanged" }, ngImport: i0, template: `
|
|
5776
6643
|
<p-dialog
|
|
5777
6644
|
[visible]="visible()"
|
|
5778
6645
|
[modal]="true"
|
|
@@ -5823,9 +6690,9 @@ class UserCompanyPermissionDialogComponent {
|
|
|
5823
6690
|
[disabled]="isSaving()" />
|
|
5824
6691
|
</ng-template>
|
|
5825
6692
|
</p-dialog>
|
|
5826
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
6693
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3$2.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i5$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: ProgressSpinnerModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5827
6694
|
}
|
|
5828
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
6695
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserCompanyPermissionDialogComponent, decorators: [{
|
|
5829
6696
|
type: Component,
|
|
5830
6697
|
args: [{
|
|
5831
6698
|
selector: 'lib-user-company-permission-dialog',
|
|
@@ -6003,8 +6870,8 @@ class UserBranchPermissionDialogComponent {
|
|
|
6003
6870
|
onClose() {
|
|
6004
6871
|
this.closed.emit();
|
|
6005
6872
|
}
|
|
6006
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
6007
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
6873
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserBranchPermissionDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6874
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: UserBranchPermissionDialogComponent, isStandalone: true, selector: "lib-user-branch-permission-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed", permissionsChanged: "permissionsChanged" }, ngImport: i0, template: `
|
|
6008
6875
|
<p-dialog
|
|
6009
6876
|
[visible]="visible()"
|
|
6010
6877
|
[modal]="true"
|
|
@@ -6074,9 +6941,9 @@ class UserBranchPermissionDialogComponent {
|
|
|
6074
6941
|
[disabled]="isSaving()" />
|
|
6075
6942
|
</ng-template>
|
|
6076
6943
|
</p-dialog>
|
|
6077
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
6944
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3$2.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i4$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: ProgressSpinnerModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6078
6945
|
}
|
|
6079
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
6946
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserBranchPermissionDialogComponent, decorators: [{
|
|
6080
6947
|
type: Component,
|
|
6081
6948
|
args: [{
|
|
6082
6949
|
selector: 'lib-user-branch-permission-dialog',
|
|
@@ -6156,31 +7023,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6156
7023
|
}]
|
|
6157
7024
|
}], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: true }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], closed: [{ type: i0.Output, args: ["closed"] }], permissionsChanged: [{ type: i0.Output, args: ["permissionsChanged"] }] } });
|
|
6158
7025
|
|
|
6159
|
-
/**
|
|
6160
|
-
* User List Component
|
|
6161
|
-
* Displays a list of users with CRUD operations.
|
|
6162
|
-
*/
|
|
6163
7026
|
class UserListComponent {
|
|
6164
|
-
// Permission constants for template
|
|
6165
7027
|
USER_PERMISSIONS = USER_PERMISSIONS;
|
|
6166
7028
|
router = inject(Router);
|
|
6167
7029
|
appConfig = inject(APP_CONFIG);
|
|
6168
7030
|
messageService = inject(MessageService);
|
|
6169
7031
|
confirmationService = inject(ConfirmationService);
|
|
6170
7032
|
userService = inject(UserApiService);
|
|
6171
|
-
|
|
7033
|
+
userListExtension = inject(AUTH_USER_LIST_EXTENSION, { optional: true });
|
|
7034
|
+
userDetailConfig = inject(AUTH_USER_DETAIL_CONFIG, { optional: true });
|
|
6172
7035
|
users = this.userService.data;
|
|
6173
|
-
/** Loading state from service */
|
|
6174
7036
|
isLoading = this.userService.isLoading;
|
|
6175
|
-
/** Total count from service */
|
|
6176
7037
|
total = this.userService.total;
|
|
6177
|
-
/** Whether company feature is enabled */
|
|
6178
7038
|
companyFeatureEnabled = computed(() => isCompanyFeatureEnabled(this.appConfig), ...(ngDevMode ? [{ debugName: "companyFeatureEnabled" }] : []));
|
|
6179
|
-
|
|
7039
|
+
extraColumns = computed(() => {
|
|
7040
|
+
if (!this.userListExtension)
|
|
7041
|
+
return [];
|
|
7042
|
+
const columns = this.userListExtension.getExtraColumns();
|
|
7043
|
+
return columns.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
|
|
7044
|
+
}, ...(ngDevMode ? [{ debugName: "extraColumns" }] : []));
|
|
7045
|
+
extraActions = computed(() => {
|
|
7046
|
+
if (!this.userListExtension)
|
|
7047
|
+
return [];
|
|
7048
|
+
const actions = this.userListExtension.getExtraActions();
|
|
7049
|
+
return actions.sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
|
|
7050
|
+
}, ...(ngDevMode ? [{ debugName: "extraActions" }] : []));
|
|
7051
|
+
hasUserDetailView = computed(() => !!this.userDetailConfig, ...(ngDevMode ? [{ debugName: "hasUserDetailView" }] : []));
|
|
7052
|
+
tableColspan = computed(() => 6 + this.extraColumns().length, ...(ngDevMode ? [{ debugName: "tableColspan" }] : []));
|
|
6180
7053
|
showCompanyDialog = signal(false, ...(ngDevMode ? [{ debugName: "showCompanyDialog" }] : []));
|
|
6181
7054
|
showBranchDialog = signal(false, ...(ngDevMode ? [{ debugName: "showBranchDialog" }] : []));
|
|
6182
|
-
|
|
7055
|
+
showUserDetailDialog = signal(false, ...(ngDevMode ? [{ debugName: "showUserDetailDialog" }] : []));
|
|
6183
7056
|
selectedUser = signal(null, ...(ngDevMode ? [{ debugName: "selectedUser" }] : []));
|
|
7057
|
+
getFieldValue(user, field) {
|
|
7058
|
+
const parts = field.split('.');
|
|
7059
|
+
let value = user;
|
|
7060
|
+
for (const part of parts) {
|
|
7061
|
+
if (value === null || value === undefined)
|
|
7062
|
+
return undefined;
|
|
7063
|
+
value = value[part];
|
|
7064
|
+
}
|
|
7065
|
+
return value;
|
|
7066
|
+
}
|
|
7067
|
+
isActionVisible(action, user) {
|
|
7068
|
+
return action.isVisible ? action.isVisible(user) : true;
|
|
7069
|
+
}
|
|
7070
|
+
isActionDisabled(action, user) {
|
|
7071
|
+
return action.isDisabled ? action.isDisabled(user) : false;
|
|
7072
|
+
}
|
|
7073
|
+
onExtraAction(action, user) {
|
|
7074
|
+
action.onClick(user);
|
|
7075
|
+
}
|
|
7076
|
+
onViewDetails(user) {
|
|
7077
|
+
if (!this.userDetailConfig)
|
|
7078
|
+
return;
|
|
7079
|
+
if (this.userDetailConfig.viewMode === 'page') {
|
|
7080
|
+
this.router.navigate(['/administration/users', user.id]);
|
|
7081
|
+
}
|
|
7082
|
+
else {
|
|
7083
|
+
this.selectedUser.set(user);
|
|
7084
|
+
this.showUserDetailDialog.set(true);
|
|
7085
|
+
}
|
|
7086
|
+
}
|
|
7087
|
+
closeUserDetailDialog() {
|
|
7088
|
+
this.showUserDetailDialog.set(false);
|
|
7089
|
+
this.selectedUser.set(null);
|
|
7090
|
+
}
|
|
6184
7091
|
loadUsers() {
|
|
6185
7092
|
this.userService.fetchList('', {
|
|
6186
7093
|
pagination: { currentPage: 0, pageSize: 10 },
|
|
@@ -6232,8 +7139,8 @@ class UserListComponent {
|
|
|
6232
7139
|
},
|
|
6233
7140
|
});
|
|
6234
7141
|
}
|
|
6235
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
6236
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
7142
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7143
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: UserListComponent, isStandalone: true, selector: "lib-user-list", ngImport: i0, template: `
|
|
6237
7144
|
<p-card>
|
|
6238
7145
|
<ng-template #header>
|
|
6239
7146
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4">
|
|
@@ -6261,7 +7168,12 @@ class UserListComponent {
|
|
|
6261
7168
|
<th>Phone</th>
|
|
6262
7169
|
<th>Email Verified</th>
|
|
6263
7170
|
<th>Status</th>
|
|
6264
|
-
|
|
7171
|
+
@for (col of extraColumns(); track col.key) {
|
|
7172
|
+
<th [class]="col.styleClass ?? ''" [style.width]="col.width ?? 'auto'">
|
|
7173
|
+
{{ col.header }}
|
|
7174
|
+
</th>
|
|
7175
|
+
}
|
|
7176
|
+
<th class="w-[180px]">Actions</th>
|
|
6265
7177
|
</tr>
|
|
6266
7178
|
</ng-template>
|
|
6267
7179
|
<ng-template #body let-user>
|
|
@@ -6279,8 +7191,26 @@ class UserListComponent {
|
|
|
6279
7191
|
[value]="user.isActive ? 'Active' : 'Inactive'"
|
|
6280
7192
|
[severity]="user.isActive ? 'success' : 'danger'" />
|
|
6281
7193
|
</td>
|
|
7194
|
+
@for (col of extraColumns(); track col.key) {
|
|
7195
|
+
<td [class]="col.styleClass ?? ''">
|
|
7196
|
+
@if (col.template) {
|
|
7197
|
+
<ng-container [ngTemplateOutlet]="col.template" [ngTemplateOutletContext]="{ $implicit: user }" />
|
|
7198
|
+
} @else if (col.field) {
|
|
7199
|
+
{{ getFieldValue(user, col.field) ?? '-' }}
|
|
7200
|
+
}
|
|
7201
|
+
</td>
|
|
7202
|
+
}
|
|
6282
7203
|
<td>
|
|
6283
|
-
<div class="flex gap-
|
|
7204
|
+
<div class="flex gap-1 flex-wrap">
|
|
7205
|
+
@if (hasUserDetailView()) {
|
|
7206
|
+
<p-button
|
|
7207
|
+
icon="pi pi-eye"
|
|
7208
|
+
[rounded]="true"
|
|
7209
|
+
[text]="true"
|
|
7210
|
+
severity="info"
|
|
7211
|
+
pTooltip="View Details"
|
|
7212
|
+
(onClick)="onViewDetails(user)" />
|
|
7213
|
+
}
|
|
6284
7214
|
<p-button
|
|
6285
7215
|
*hasPermission="USER_PERMISSIONS.UPDATE"
|
|
6286
7216
|
icon="pi pi-pencil"
|
|
@@ -6307,6 +7237,18 @@ class UserListComponent {
|
|
|
6307
7237
|
pTooltip="Branch Permissions"
|
|
6308
7238
|
(onClick)="onManageBranchPermissions(user)" />
|
|
6309
7239
|
}
|
|
7240
|
+
@for (action of extraActions(); track action.key) {
|
|
7241
|
+
@if (isActionVisible(action, user)) {
|
|
7242
|
+
<p-button
|
|
7243
|
+
[icon]="action.icon"
|
|
7244
|
+
[rounded]="true"
|
|
7245
|
+
[text]="true"
|
|
7246
|
+
[severity]="action.severity ?? 'secondary'"
|
|
7247
|
+
[pTooltip]="action.label"
|
|
7248
|
+
[disabled]="isActionDisabled(action, user)"
|
|
7249
|
+
(onClick)="onExtraAction(action, user)" />
|
|
7250
|
+
}
|
|
7251
|
+
}
|
|
6310
7252
|
<p-button
|
|
6311
7253
|
*hasPermission="USER_PERMISSIONS.DELETE"
|
|
6312
7254
|
icon="pi pi-trash"
|
|
@@ -6321,7 +7263,7 @@ class UserListComponent {
|
|
|
6321
7263
|
</ng-template>
|
|
6322
7264
|
<ng-template #emptymessage>
|
|
6323
7265
|
<tr>
|
|
6324
|
-
<td colspan="
|
|
7266
|
+
<td [attr.colspan]="tableColspan()" class="text-center py-8">
|
|
6325
7267
|
No users found. Click "Add User" to create one.
|
|
6326
7268
|
</td>
|
|
6327
7269
|
</tr>
|
|
@@ -6330,7 +7272,6 @@ class UserListComponent {
|
|
|
6330
7272
|
</div>
|
|
6331
7273
|
</p-card>
|
|
6332
7274
|
|
|
6333
|
-
<!-- Permission Dialogs -->
|
|
6334
7275
|
@if (companyFeatureEnabled()) {
|
|
6335
7276
|
<lib-user-company-permission-dialog
|
|
6336
7277
|
[visible]="showCompanyDialog()"
|
|
@@ -6344,9 +7285,68 @@ class UserListComponent {
|
|
|
6344
7285
|
(closed)="showBranchDialog.set(false)"
|
|
6345
7286
|
(permissionsChanged)="loadUsers()" />
|
|
6346
7287
|
}
|
|
6347
|
-
|
|
7288
|
+
|
|
7289
|
+
@if (hasUserDetailView() && showUserDetailDialog()) {
|
|
7290
|
+
<p-dialog
|
|
7291
|
+
header="User Details"
|
|
7292
|
+
[visible]="showUserDetailDialog()"
|
|
7293
|
+
[modal]="true"
|
|
7294
|
+
[style]="{ width: userDetailConfig?.width ?? '600px' }"
|
|
7295
|
+
[draggable]="false"
|
|
7296
|
+
[resizable]="false"
|
|
7297
|
+
(onHide)="closeUserDetailDialog()">
|
|
7298
|
+
@if (selectedUser(); as user) {
|
|
7299
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
7300
|
+
<div class="flex flex-col gap-2">
|
|
7301
|
+
<label class="font-medium text-muted-color">Name</label>
|
|
7302
|
+
<span class="text-color">{{ user.name }}</span>
|
|
7303
|
+
</div>
|
|
7304
|
+
<div class="flex flex-col gap-2">
|
|
7305
|
+
<label class="font-medium text-muted-color">Email</label>
|
|
7306
|
+
<span class="text-color">{{ user.email }}</span>
|
|
7307
|
+
</div>
|
|
7308
|
+
<div class="flex flex-col gap-2">
|
|
7309
|
+
<label class="font-medium text-muted-color">Phone</label>
|
|
7310
|
+
<span class="text-color">{{ user.phone || '-' }}</span>
|
|
7311
|
+
</div>
|
|
7312
|
+
<div class="flex flex-col gap-2">
|
|
7313
|
+
<label class="font-medium text-muted-color">Status</label>
|
|
7314
|
+
<p-tag
|
|
7315
|
+
[value]="user.isActive ? 'Active' : 'Inactive'"
|
|
7316
|
+
[severity]="user.isActive ? 'success' : 'danger'" />
|
|
7317
|
+
</div>
|
|
7318
|
+
<div class="flex flex-col gap-2">
|
|
7319
|
+
<label class="font-medium text-muted-color">Email Verified</label>
|
|
7320
|
+
<p-tag
|
|
7321
|
+
[value]="user.emailVerified ? 'Verified' : 'Unverified'"
|
|
7322
|
+
[severity]="user.emailVerified ? 'success' : 'warn'" />
|
|
7323
|
+
</div>
|
|
7324
|
+
@for (col of extraColumns(); track col.key) {
|
|
7325
|
+
<div class="flex flex-col gap-2">
|
|
7326
|
+
<label class="font-medium text-muted-color">{{ col.header }}</label>
|
|
7327
|
+
<span class="text-color">{{ getFieldValue(user, col.field ?? col.key) ?? '-' }}</span>
|
|
7328
|
+
</div>
|
|
7329
|
+
}
|
|
7330
|
+
</div>
|
|
7331
|
+
<div class="flex justify-end gap-2 mt-6">
|
|
7332
|
+
@if (userDetailConfig?.allowEdit) {
|
|
7333
|
+
<p-button
|
|
7334
|
+
label="Edit"
|
|
7335
|
+
icon="pi pi-pencil"
|
|
7336
|
+
(onClick)="onEdit(user); closeUserDetailDialog()" />
|
|
7337
|
+
}
|
|
7338
|
+
<p-button
|
|
7339
|
+
label="Close"
|
|
7340
|
+
severity="secondary"
|
|
7341
|
+
[outlined]="true"
|
|
7342
|
+
(onClick)="closeUserDetailDialog()" />
|
|
7343
|
+
</div>
|
|
7344
|
+
}
|
|
7345
|
+
</p-dialog>
|
|
7346
|
+
}
|
|
7347
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: i4$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserCompanyPermissionDialogComponent, selector: "lib-user-company-permission-dialog", inputs: ["visible", "user"], outputs: ["closed", "permissionsChanged"] }, { kind: "component", type: UserBranchPermissionDialogComponent, selector: "lib-user-branch-permission-dialog", inputs: ["visible", "user"], outputs: ["closed", "permissionsChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6348
7348
|
}
|
|
6349
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
7349
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserListComponent, decorators: [{
|
|
6350
7350
|
type: Component,
|
|
6351
7351
|
args: [{
|
|
6352
7352
|
selector: 'lib-user-list',
|
|
@@ -6354,7 +7354,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6354
7354
|
imports: [
|
|
6355
7355
|
AngularModule,
|
|
6356
7356
|
PrimeModule,
|
|
6357
|
-
TagModule,
|
|
6358
7357
|
HasPermissionDirective,
|
|
6359
7358
|
UserCompanyPermissionDialogComponent,
|
|
6360
7359
|
UserBranchPermissionDialogComponent,
|
|
@@ -6387,7 +7386,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6387
7386
|
<th>Phone</th>
|
|
6388
7387
|
<th>Email Verified</th>
|
|
6389
7388
|
<th>Status</th>
|
|
6390
|
-
|
|
7389
|
+
@for (col of extraColumns(); track col.key) {
|
|
7390
|
+
<th [class]="col.styleClass ?? ''" [style.width]="col.width ?? 'auto'">
|
|
7391
|
+
{{ col.header }}
|
|
7392
|
+
</th>
|
|
7393
|
+
}
|
|
7394
|
+
<th class="w-[180px]">Actions</th>
|
|
6391
7395
|
</tr>
|
|
6392
7396
|
</ng-template>
|
|
6393
7397
|
<ng-template #body let-user>
|
|
@@ -6405,8 +7409,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6405
7409
|
[value]="user.isActive ? 'Active' : 'Inactive'"
|
|
6406
7410
|
[severity]="user.isActive ? 'success' : 'danger'" />
|
|
6407
7411
|
</td>
|
|
7412
|
+
@for (col of extraColumns(); track col.key) {
|
|
7413
|
+
<td [class]="col.styleClass ?? ''">
|
|
7414
|
+
@if (col.template) {
|
|
7415
|
+
<ng-container [ngTemplateOutlet]="col.template" [ngTemplateOutletContext]="{ $implicit: user }" />
|
|
7416
|
+
} @else if (col.field) {
|
|
7417
|
+
{{ getFieldValue(user, col.field) ?? '-' }}
|
|
7418
|
+
}
|
|
7419
|
+
</td>
|
|
7420
|
+
}
|
|
6408
7421
|
<td>
|
|
6409
|
-
<div class="flex gap-
|
|
7422
|
+
<div class="flex gap-1 flex-wrap">
|
|
7423
|
+
@if (hasUserDetailView()) {
|
|
7424
|
+
<p-button
|
|
7425
|
+
icon="pi pi-eye"
|
|
7426
|
+
[rounded]="true"
|
|
7427
|
+
[text]="true"
|
|
7428
|
+
severity="info"
|
|
7429
|
+
pTooltip="View Details"
|
|
7430
|
+
(onClick)="onViewDetails(user)" />
|
|
7431
|
+
}
|
|
6410
7432
|
<p-button
|
|
6411
7433
|
*hasPermission="USER_PERMISSIONS.UPDATE"
|
|
6412
7434
|
icon="pi pi-pencil"
|
|
@@ -6433,6 +7455,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6433
7455
|
pTooltip="Branch Permissions"
|
|
6434
7456
|
(onClick)="onManageBranchPermissions(user)" />
|
|
6435
7457
|
}
|
|
7458
|
+
@for (action of extraActions(); track action.key) {
|
|
7459
|
+
@if (isActionVisible(action, user)) {
|
|
7460
|
+
<p-button
|
|
7461
|
+
[icon]="action.icon"
|
|
7462
|
+
[rounded]="true"
|
|
7463
|
+
[text]="true"
|
|
7464
|
+
[severity]="action.severity ?? 'secondary'"
|
|
7465
|
+
[pTooltip]="action.label"
|
|
7466
|
+
[disabled]="isActionDisabled(action, user)"
|
|
7467
|
+
(onClick)="onExtraAction(action, user)" />
|
|
7468
|
+
}
|
|
7469
|
+
}
|
|
6436
7470
|
<p-button
|
|
6437
7471
|
*hasPermission="USER_PERMISSIONS.DELETE"
|
|
6438
7472
|
icon="pi pi-trash"
|
|
@@ -6447,7 +7481,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6447
7481
|
</ng-template>
|
|
6448
7482
|
<ng-template #emptymessage>
|
|
6449
7483
|
<tr>
|
|
6450
|
-
<td colspan="
|
|
7484
|
+
<td [attr.colspan]="tableColspan()" class="text-center py-8">
|
|
6451
7485
|
No users found. Click "Add User" to create one.
|
|
6452
7486
|
</td>
|
|
6453
7487
|
</tr>
|
|
@@ -6456,7 +7490,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6456
7490
|
</div>
|
|
6457
7491
|
</p-card>
|
|
6458
7492
|
|
|
6459
|
-
<!-- Permission Dialogs -->
|
|
6460
7493
|
@if (companyFeatureEnabled()) {
|
|
6461
7494
|
<lib-user-company-permission-dialog
|
|
6462
7495
|
[visible]="showCompanyDialog()"
|
|
@@ -6470,6 +7503,65 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6470
7503
|
(closed)="showBranchDialog.set(false)"
|
|
6471
7504
|
(permissionsChanged)="loadUsers()" />
|
|
6472
7505
|
}
|
|
7506
|
+
|
|
7507
|
+
@if (hasUserDetailView() && showUserDetailDialog()) {
|
|
7508
|
+
<p-dialog
|
|
7509
|
+
header="User Details"
|
|
7510
|
+
[visible]="showUserDetailDialog()"
|
|
7511
|
+
[modal]="true"
|
|
7512
|
+
[style]="{ width: userDetailConfig?.width ?? '600px' }"
|
|
7513
|
+
[draggable]="false"
|
|
7514
|
+
[resizable]="false"
|
|
7515
|
+
(onHide)="closeUserDetailDialog()">
|
|
7516
|
+
@if (selectedUser(); as user) {
|
|
7517
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
7518
|
+
<div class="flex flex-col gap-2">
|
|
7519
|
+
<label class="font-medium text-muted-color">Name</label>
|
|
7520
|
+
<span class="text-color">{{ user.name }}</span>
|
|
7521
|
+
</div>
|
|
7522
|
+
<div class="flex flex-col gap-2">
|
|
7523
|
+
<label class="font-medium text-muted-color">Email</label>
|
|
7524
|
+
<span class="text-color">{{ user.email }}</span>
|
|
7525
|
+
</div>
|
|
7526
|
+
<div class="flex flex-col gap-2">
|
|
7527
|
+
<label class="font-medium text-muted-color">Phone</label>
|
|
7528
|
+
<span class="text-color">{{ user.phone || '-' }}</span>
|
|
7529
|
+
</div>
|
|
7530
|
+
<div class="flex flex-col gap-2">
|
|
7531
|
+
<label class="font-medium text-muted-color">Status</label>
|
|
7532
|
+
<p-tag
|
|
7533
|
+
[value]="user.isActive ? 'Active' : 'Inactive'"
|
|
7534
|
+
[severity]="user.isActive ? 'success' : 'danger'" />
|
|
7535
|
+
</div>
|
|
7536
|
+
<div class="flex flex-col gap-2">
|
|
7537
|
+
<label class="font-medium text-muted-color">Email Verified</label>
|
|
7538
|
+
<p-tag
|
|
7539
|
+
[value]="user.emailVerified ? 'Verified' : 'Unverified'"
|
|
7540
|
+
[severity]="user.emailVerified ? 'success' : 'warn'" />
|
|
7541
|
+
</div>
|
|
7542
|
+
@for (col of extraColumns(); track col.key) {
|
|
7543
|
+
<div class="flex flex-col gap-2">
|
|
7544
|
+
<label class="font-medium text-muted-color">{{ col.header }}</label>
|
|
7545
|
+
<span class="text-color">{{ getFieldValue(user, col.field ?? col.key) ?? '-' }}</span>
|
|
7546
|
+
</div>
|
|
7547
|
+
}
|
|
7548
|
+
</div>
|
|
7549
|
+
<div class="flex justify-end gap-2 mt-6">
|
|
7550
|
+
@if (userDetailConfig?.allowEdit) {
|
|
7551
|
+
<p-button
|
|
7552
|
+
label="Edit"
|
|
7553
|
+
icon="pi pi-pencil"
|
|
7554
|
+
(onClick)="onEdit(user); closeUserDetailDialog()" />
|
|
7555
|
+
}
|
|
7556
|
+
<p-button
|
|
7557
|
+
label="Close"
|
|
7558
|
+
severity="secondary"
|
|
7559
|
+
[outlined]="true"
|
|
7560
|
+
(onClick)="closeUserDetailDialog()" />
|
|
7561
|
+
</div>
|
|
7562
|
+
}
|
|
7563
|
+
</p-dialog>
|
|
7564
|
+
}
|
|
6473
7565
|
`,
|
|
6474
7566
|
}]
|
|
6475
7567
|
}] });
|
|
@@ -6586,8 +7678,8 @@ class VerifyEmailPageComponent {
|
|
|
6586
7678
|
this.submittedEmail.set(email);
|
|
6587
7679
|
this.resendSuccess.set(true);
|
|
6588
7680
|
}
|
|
6589
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
6590
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
7681
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: VerifyEmailPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7682
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: VerifyEmailPageComponent, isStandalone: true, selector: "lib-verify-email-page", ngImport: i0, template: `
|
|
6591
7683
|
<app-floating-configurator />
|
|
6592
7684
|
<div class="bg-surface-ground flex items-center justify-center min-h-screen">
|
|
6593
7685
|
<div class="flex flex-col items-center justify-center w-full max-w-[32rem] px-4">
|
|
@@ -6711,9 +7803,9 @@ class VerifyEmailPageComponent {
|
|
|
6711
7803
|
</div>
|
|
6712
7804
|
</div>
|
|
6713
7805
|
</div>
|
|
6714
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1
|
|
7806
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: AppFloatingConfigurator, selector: "app-floating-configurator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6715
7807
|
}
|
|
6716
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
7808
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: VerifyEmailPageComponent, decorators: [{
|
|
6717
7809
|
type: Component,
|
|
6718
7810
|
args: [{
|
|
6719
7811
|
selector: 'lib-verify-email-page',
|
|
@@ -6861,5 +7953,5 @@ var verifyEmailPage_component = /*#__PURE__*/Object.freeze({
|
|
|
6861
7953
|
* Generated bundle index. Do not edit.
|
|
6862
7954
|
*/
|
|
6863
7955
|
|
|
6864
|
-
export { ADMINISTRATION_ROUTES, AUTH_ENDPOINTS, AUTH_ROUTES, AdministrationPageComponent, AuthApiService, AuthCompanyApiProviderAdapter, AuthInitService, AuthLayoutApiAdapter, AuthLayoutStateAdapter, AuthStateProviderAdapter, AuthStateService, AuthUserPermissionProviderAdapter, AuthUserProviderAdapter, BranchApiService, BranchFormComponent, BranchListComponent, CompanyApiService, CompanyFormComponent, CompanyListComponent, ForgotPasswordPageComponent, LoginPageComponent, PROFILE_ROUTES, ProfilePageComponent, RegisterPageComponent, ResetPasswordPageComponent, TokenRefreshStateService, UserApiService, UserBranchPermissionDialogComponent, UserCompanyPermissionDialogComponent, UserFormComponent, UserListComponent, UserPermissionApiService, VerifyEmailPageComponent, authGuard, authInterceptor, companyFeatureGuard, guestGuard, isCompanySelectionResponse, isEmailVerificationRequired, isEndpoint, isLoginResponse, provideAuthLayoutIntegration, provideAuthProviders, tokenRefreshInterceptor };
|
|
7956
|
+
export { ADMINISTRATION_ROUTES, AUTH_ENDPOINTS, AUTH_PROFILE_EXTENSION, AUTH_REGISTRATION_EXTENSION, AUTH_ROUTES, AUTH_USER_DETAIL_CONFIG, AUTH_USER_LIST_EXTENSION, AUTH_VALIDATION_CONFIG, AdministrationPageComponent, AuthApiService, AuthCompanyApiProviderAdapter, AuthInitService, AuthLayoutApiAdapter, AuthLayoutStateAdapter, AuthStateProviderAdapter, AuthStateService, AuthUserPermissionProviderAdapter, AuthUserProviderAdapter, BranchApiService, BranchFormComponent, BranchListComponent, CompanyApiService, CompanyFormComponent, CompanyListComponent, ForgotPasswordPageComponent, LoginPageComponent, PROFILE_FIELD_CONTEXT, PROFILE_ROUTES, ProfilePageComponent, REGISTRATION_FIELD_CONTEXT, RegisterPageComponent, ResetPasswordPageComponent, TokenRefreshStateService, UserApiService, UserBranchPermissionDialogComponent, UserCompanyPermissionDialogComponent, UserFormComponent, UserListComponent, UserPermissionApiService, VerifyEmailPageComponent, authGuard, authInterceptor, companyFeatureGuard, emailFeatureGuard, guestGuard, isCompanySelectionResponse, isEmailVerificationRequired, isEndpoint, isLoginResponse, provideAuthLayoutIntegration, provideAuthProviders, signUpFeatureGuard, tokenRefreshInterceptor, validateEmail, validatePassword };
|
|
6865
7957
|
//# sourceMappingURL=flusys-ng-auth.mjs.map
|