@flusys/ng-auth 9.2.2 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/fesm2022/{flusys-ng-auth-administration-page.component-C9cMjTFU.mjs → flusys-ng-auth-administration-page.component-CxQYkCc1.mjs} +4 -4
  2. package/fesm2022/{flusys-ng-auth-administration-page.component-C9cMjTFU.mjs.map → flusys-ng-auth-administration-page.component-CxQYkCc1.mjs.map} +1 -1
  3. package/fesm2022/{flusys-ng-auth-branch-form.component-xttRMwxT.mjs → flusys-ng-auth-branch-form.component-DtoM4SET.mjs} +4 -4
  4. package/fesm2022/{flusys-ng-auth-branch-form.component-xttRMwxT.mjs.map → flusys-ng-auth-branch-form.component-DtoM4SET.mjs.map} +1 -1
  5. package/fesm2022/{flusys-ng-auth-branch-list.component-SeGvWdUO.mjs → flusys-ng-auth-branch-list.component-CP9VFx_8.mjs} +4 -4
  6. package/fesm2022/{flusys-ng-auth-branch-list.component-SeGvWdUO.mjs.map → flusys-ng-auth-branch-list.component-CP9VFx_8.mjs.map} +1 -1
  7. package/fesm2022/{flusys-ng-auth-company-form.component-BPrFxqto.mjs → flusys-ng-auth-company-form.component-C1HXjgn-.mjs} +4 -4
  8. package/fesm2022/{flusys-ng-auth-company-form.component-BPrFxqto.mjs.map → flusys-ng-auth-company-form.component-C1HXjgn-.mjs.map} +1 -1
  9. package/fesm2022/{flusys-ng-auth-company-list.component-jEtVFxYE.mjs → flusys-ng-auth-company-list.component-jkyaG-hS.mjs} +4 -4
  10. package/fesm2022/{flusys-ng-auth-company-list.component-jEtVFxYE.mjs.map → flusys-ng-auth-company-list.component-jkyaG-hS.mjs.map} +1 -1
  11. package/fesm2022/{flusys-ng-auth-forgot-password-page.component-JnLtR304.mjs → flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs} +4 -4
  12. package/fesm2022/{flusys-ng-auth-forgot-password-page.component-JnLtR304.mjs.map → flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs.map} +1 -1
  13. package/fesm2022/{flusys-ng-auth-login-page.component-R8gMWdLZ.mjs → flusys-ng-auth-login-page.component-Bz-bbY3U.mjs} +4 -4
  14. package/fesm2022/{flusys-ng-auth-login-page.component-R8gMWdLZ.mjs.map → flusys-ng-auth-login-page.component-Bz-bbY3U.mjs.map} +1 -1
  15. package/fesm2022/{flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs → flusys-ng-auth-profile-page.component-Dg25DA0i.mjs} +4 -4
  16. package/fesm2022/{flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs.map → flusys-ng-auth-profile-page.component-Dg25DA0i.mjs.map} +1 -1
  17. package/fesm2022/{flusys-ng-auth-register-page.component-B0me9tCm.mjs → flusys-ng-auth-register-page.component-Cb-ycJHR.mjs} +4 -4
  18. package/fesm2022/{flusys-ng-auth-register-page.component-B0me9tCm.mjs.map → flusys-ng-auth-register-page.component-Cb-ycJHR.mjs.map} +1 -1
  19. package/fesm2022/{flusys-ng-auth-reset-password-page.component-DnULwTow.mjs → flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs} +4 -4
  20. package/fesm2022/{flusys-ng-auth-reset-password-page.component-DnULwTow.mjs.map → flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs.map} +1 -1
  21. package/fesm2022/{flusys-ng-auth-social-callback-page.component-DTrdtpbR.mjs → flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs} +4 -4
  22. package/fesm2022/{flusys-ng-auth-social-callback-page.component-DTrdtpbR.mjs.map → flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs.map} +1 -1
  23. package/fesm2022/{flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs → flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs} +4 -4
  24. package/fesm2022/{flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs.map → flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs.map} +1 -1
  25. package/fesm2022/{flusys-ng-auth-user-form.component-cY4cmjV_.mjs → flusys-ng-auth-user-form.component-o0MbxMQn.mjs} +4 -4
  26. package/fesm2022/{flusys-ng-auth-user-form.component-cY4cmjV_.mjs.map → flusys-ng-auth-user-form.component-o0MbxMQn.mjs.map} +1 -1
  27. package/fesm2022/{flusys-ng-auth-user-list.component-Dhq8Hygo.mjs → flusys-ng-auth-user-list.component-MHHsLH9r.mjs} +4 -4
  28. package/fesm2022/{flusys-ng-auth-user-list.component-Dhq8Hygo.mjs.map → flusys-ng-auth-user-list.component-MHHsLH9r.mjs.map} +1 -1
  29. package/fesm2022/{flusys-ng-auth-verify-email-page.component-C3CLhAip.mjs → flusys-ng-auth-verify-email-page.component-3qcv2X_u.mjs} +4 -4
  30. package/fesm2022/{flusys-ng-auth-verify-email-page.component-C3CLhAip.mjs.map → flusys-ng-auth-verify-email-page.component-3qcv2X_u.mjs.map} +1 -1
  31. package/fesm2022/flusys-ng-auth.mjs +87 -87
  32. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"flusys-ng-auth-login-page.component-R8gMWdLZ.mjs","names":[],"sources":["../../../projects/ng-auth/pages/login/login-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { RouterLink } from '@angular/router';\nimport {\n APP_CONFIG,\n isCompanyFeatureEnabled,\n isServiceEnabled,\n isSignUpEnabled,\n} from '@flusys/ng-core';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport {\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n buildBranchTreeNodes,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n IBranchSelectionInfo,\n ICompanyWithBranches,\n ILoginRequest,\n isCompanySelectionResponse,\n ISelectRequest,\n isEmailVerificationRequired,\n isLoginResponse,\n} from '../../interfaces/auth.interface';\nimport { SocialLoginButtonsComponent } from '../../components/social-login-buttons.component';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { EmailPolicyService } from '../../services/email-policy.service';\n\ninterface ILoginFormModel {\n email: string;\n password: string;\n rememberMe: boolean;\n}\n\ninterface ISelectionFormModel {\n companyId: string;\n branchId: string;\n rememberSelection: boolean;\n}\n\ntype LoginStep = 'credentials' | 'company-selection' | 'email-verification';\n\n@Component({\n selector: 'lib-login-page',\n imports: [\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n RouterLink,\n FormField,\n AppFloatingConfigurator,\n SocialLoginButtonsComponent,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen\"\n >\n <div\n class=\"flex flex-col items-center justify-center w-full max-w-[32rem] px-4\"\n >\n <div\n class=\"w-full\"\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"w-full py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n <!-- Step Indicator (only when company feature enabled) -->\n @if (companyFeatureEnabled()) {\n <div class=\"flex items-center justify-center mb-6 gap-2\">\n <div\n class=\"flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold transition-colors\"\n [class.bg-primary]=\"currentStep() === 'credentials'\"\n [class.text-primary-contrast]=\"\n currentStep() === 'credentials'\n \"\n [class.bg-surface-200]=\"currentStep() !== 'credentials'\"\n [class.dark:bg-surface-700]=\"currentStep() !== 'credentials'\"\n [class.text-muted-color]=\"currentStep() !== 'credentials'\"\n >\n 1\n </div>\n <div class=\"w-12 h-0.5 bg-surface-200 dark:bg-surface-700\"></div>\n <div\n class=\"flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold transition-colors\"\n [class.bg-primary]=\"currentStep() === 'company-selection'\"\n [class.text-primary-contrast]=\"\n currentStep() === 'company-selection'\n \"\n [class.bg-surface-200]=\"currentStep() !== 'company-selection'\"\n [class.dark:bg-surface-700]=\"currentStep() !== 'company-selection'\"\n [class.text-muted-color]=\"\n currentStep() !== 'company-selection'\n \"\n >\n 2\n </div>\n </div>\n }\n\n <!-- Step 1: Credentials -->\n @if (currentStep() === 'credentials') {\n <div class=\"text-center mb-8\">\n <div\n class=\"text-3xl font-medium mb-4 text-color truncate\"\n [title]=\"savedUserName() ? welcomeBackText() : null\"\n >\n @if (savedUserName()) {\n {{ welcomeBackText() }}\n } @else {\n {{ 'auth.login.welcome' | translate }}\n }\n </div>\n <span class=\"text-muted-color font-medium\">{{\n 'auth.login.sign.in.to.continue' | translate\n }}</span>\n </div>\n\n <form (submit)=\"onSubmit($event)\">\n <label\n for=\"email\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.email.label' | translate }}\n </label>\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n class=\"w-full\"\n [formField]=\"loginForm.email\"\n autocomplete=\"email\"\n />\n @if (emailValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n emailValidationError()\n }}</small>\n }\n <div class=\"mb-4\"></div>\n\n <label\n for=\"password\"\n class=\"block font-medium text-lg mb-2 text-color\"\n >\n {{ 'auth.password.label' | translate }}\n </label>\n <div class=\"mb-4\">\n <f-password\n [inputId]=\"'password'\"\n [placeholder]=\"'auth.password.placeholder' | translate\"\n class=\"w-full\"\n [formField]=\"loginForm.password\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div\n class=\"flex flex-col sm:flex-row items-start sm:items-center justify-between mt-2 mb-8 gap-4\"\n >\n <f-checkbox [formField]=\"loginForm.rememberMe\" [label]=\"'auth.field.remember.me' | translate\" />\n @if (emailFeatureEnabled()) {\n <span\n class=\"font-medium no-underline cursor-pointer text-primary\"\n style=\"margin-inline-start: 0.5rem;\"\n routerLink=\"/auth/forgot-password\"\n >\n {{ 'auth.password.forgot' | translate }}\n </span>\n }\n </div>\n\n <button\n fButton\n class=\"w-full\"\n type=\"submit\"\n [disabled]=\"!isLoginFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.login.sign.in' | translate }}</span>\n </button>\n\n <lib-social-login-buttons [returnUrl]=\"returnUrl()\" />\n\n @if (signUpEnabled()) {\n <div class=\"flex items-center justify-center mt-4 gap-2\">\n <span class=\"font-medium\">{{\n 'auth.login.no.account' | translate\n }}</span>\n <a\n routerLink=\"/auth/register\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.sign.up' | translate }}\n </a>\n </div>\n }\n </form>\n }\n\n <!-- Email Verification Required -->\n @if (currentStep() === 'email-verification') {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"envelope\" class=\"text-6xl text-warn\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.login.email.not.verified' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{ 'auth.login.verify.email.message' | translate }}\n </p>\n <button\n fButton\n class=\"w-full mb-4\"\n (click)=\"onResendVerification()\"\n [disabled]=\"isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.verify.resend' | translate }}</span>\n </button>\n <div class=\"mt-4\">\n <span\n class=\"font-semibold text-primary cursor-pointer\"\n (click)=\"goBackToCredentials()\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </span>\n </div>\n </div>\n }\n\n <!-- Step 2: Company Selection -->\n @if (currentStep() === 'company-selection') {\n <div class=\"text-center mb-8\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.login.select.company' | translate }}\n </div>\n <div class=\"text-muted-color font-medium\">\n {{ 'auth.login.select.company.message' | translate }}\n </div>\n </div>\n\n <form (submit)=\"onSelectCompany($event)\">\n <label\n for=\"company\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'shared.company' | translate }}\n </label>\n <f-select\n inputId=\"company\"\n class=\"w-full mb-4\"\n [options]=\"companies()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [formField]=\"selectionForm.companyId\"\n [placeholder]=\"'auth.login.select.company.option' | translate\"\n (onChange)=\"onCompanyChange()\"\n />\n\n <label\n for=\"branch\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.login.branch.label' | translate }}\n </label>\n <f-treeselect\n inputId=\"branch\"\n class=\"w-full mb-4\"\n [options]=\"branchTreeNodes()\"\n [formField]=\"selectionForm.branchId\"\n [placeholder]=\"'auth.login.select.branch.option' | translate\"\n [filter]=\"true\"\n [filterPlaceholder]=\"'shared.search' | translate\"\n [emptyMessage]=\"'shared.no.results' | translate\"\n />\n\n <div class=\"flex items-center mt-2 mb-8\">\n <f-checkbox\n [formField]=\"selectionForm.rememberSelection\"\n [label]=\"'auth.login.remember.selection' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col sm:flex-row gap-4\">\n <button\n fButton\n class=\"w-full\"\n severity=\"secondary\"\n [outlined]=\"true\"\n type=\"button\"\n (click)=\"goBackToCredentials()\"\n >\n <span pButtonLabel>{{ 'shared.back' | translate }}</span>\n </button>\n <button\n fButton\n class=\"w-full\"\n type=\"submit\"\n [disabled]=\"!isSelectionFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'shared.continue' | translate }}</span>\n </button>\n </div>\n </form>\n }\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class LoginPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly authState = inject(AuthStateService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private readonly emailPolicy = inject(EmailPolicyService);\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly returnUrl = input<string>('');\n readonly currentStep = signal<LoginStep>('credentials');\n readonly isLoading = signal(false);\n readonly unverifiedEmail = signal('');\n readonly savedUserName = signal(this.authState.getSavedUserName());\n readonly welcomeBackText = computed(() =>\n this.translate('auth.login.welcome.back', { name: this.savedUserName()! }),\n );\n\n readonly loginFormModel = signal<ILoginFormModel>({\n email: '',\n password: '',\n rememberMe: true,\n });\n\n readonly loginForm = form(this.loginFormModel, (f) => {\n required(f.email, {\n message: this.translate('auth.validation.email.required'),\n });\n required(f.password, {\n message: this.translate('auth.validation.password.required'),\n });\n });\n\n readonly emailValidationError = computed(() =>\n this.emailPolicy.validate(this.loginFormModel().email),\n );\n\n readonly isLoginFormValid = computed(() => {\n const formValid = this.loginForm().valid();\n return formValid && !this.emailValidationError();\n });\n\n readonly selectionFormModel = signal<ISelectionFormModel>({\n companyId: '',\n branchId: '',\n rememberSelection: true,\n });\n\n readonly selectionForm = form(this.selectionFormModel, (f) => {\n required(f.companyId, {\n message: this.translate('auth.validation.company.required'),\n });\n required(f.branchId, {\n message: this.translate('auth.validation.branch.required'),\n });\n });\n\n readonly isSelectionFormValid = computed(() => this.selectionForm().valid());\n readonly companyFeatureEnabled = computed(() =>\n isCompanyFeatureEnabled(this.appConfig),\n );\n readonly emailFeatureEnabled = computed(() =>\n isServiceEnabled(this.appConfig, 'email'),\n );\n readonly signUpEnabled = computed(() => isSignUpEnabled(this.appConfig));\n\n private sessionId: string | null = null;\n readonly companies = signal<ICompanyWithBranches[]>([]);\n readonly userName = signal<string>('');\n\n readonly branches = computed<IBranchSelectionInfo[]>(() => {\n const companyId = this.selectionFormModel().companyId;\n if (!companyId) return [];\n const company = this.companies().find((c) => c.id === companyId);\n return company?.branches ?? [];\n });\n\n readonly branchTreeNodes = computed(() =>\n buildBranchTreeNodes(this.branches()),\n );\n\n constructor() {\n effect(() => {\n if (this.authState.requiresCompanySelection()) {\n this.restorePendingSelectionState();\n }\n });\n }\n\n private restorePendingSelectionState(): void {\n const availableCompanies = this.authState.availableCompanies();\n const sessionId = this.authState.selectionSessionId();\n const name = this.authState.userName();\n\n if (availableCompanies.length > 0 && sessionId) {\n this.companies.set(availableCompanies);\n this.sessionId = sessionId;\n this.userName.set(name);\n this.currentStep.set('company-selection');\n this.autoSelectIfSingle();\n }\n }\n\n onSubmit(event: Event): void {\n event.preventDefault();\n\n if (!this.isLoginFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n const formData = this.loginFormModel();\n const loginData: ILoginRequest = {\n email: formData.email,\n password: formData.password,\n rememberMe: formData.rememberMe,\n };\n\n this.authApi\n .login(loginData)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n\n if (isEmailVerificationRequired(response)) {\n if (!response.data) return;\n this.unverifiedEmail.set(response.data.email);\n this.currentStep.set('email-verification');\n return;\n }\n\n if (isCompanySelectionResponse(response)) {\n if (!response.data) return;\n this.sessionId = response.data.sessionId;\n this.companies.set(response.data.companies);\n this.userName.set(\n response.data.user.name ?? response.data.user.email,\n );\n this.authState.setSelectionState(response.data);\n this.currentStep.set('company-selection');\n this.autoSelectIfSingle();\n } else if (isLoginResponse(response)) {\n if (!response.data) return;\n this.authState.setLoginState(response.data);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : (response.message ?? this.translate('auth.login.success')),\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n }\n },\n error: (error) => {\n this.isLoading.set(false);\n const messageKey = error?.error?.messageKey;\n const detail = messageKey\n ? this.translate(messageKey, error?.error?.messageVariables)\n : error?.error?.message;\n this.messageService.add({\n severity: 'error',\n summary: this.translate('auth.login.title'),\n detail,\n });\n },\n });\n }\n\n onCompanyChange(): void {\n this.selectionFormModel.update((model) => ({\n ...model,\n branchId: '',\n }));\n\n const branches = this.branches();\n if (branches.length === 1) {\n this.selectionFormModel.update((model) => ({\n ...model,\n branchId: branches[0].id,\n }));\n }\n }\n\n onSelectCompany(event: Event): void {\n event.preventDefault();\n\n if (!this.isSelectionFormValid()) {\n this.messageService.add({\n severity: 'warn',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('auth.login.requires.selection'),\n });\n return;\n }\n\n if (!this.sessionId) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.error'),\n detail: this.translate('auth.session.expired'),\n });\n this.goBackToCredentials();\n return;\n }\n\n this.isLoading.set(true);\n\n const formData = this.selectionFormModel();\n const selectData: ISelectRequest = {\n sessionId: this.sessionId,\n companyId: formData.companyId!,\n branchId: formData.branchId!,\n rememberMe: this.loginFormModel().rememberMe,\n };\n\n this.authApi\n .select(selectData)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n if (!response.data) return;\n this.authState.setLoginState(response.data);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n\n goBackToCredentials(): void {\n this.sessionId = null;\n this.companies.set([]);\n this.unverifiedEmail.set('');\n this.selectionFormModel.set({\n companyId: '',\n branchId: '',\n rememberSelection: true,\n });\n this.authState.resetState();\n this.currentStep.set('credentials');\n }\n\n onResendVerification(): void {\n const email = this.unverifiedEmail();\n if (!email) return;\n\n this.isLoading.set(true);\n\n this.authApi\n .resendVerification(email)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n });\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n\n private autoSelectIfSingle(): void {\n if (this.companies().length === 1) {\n this.selectionFormModel.update((model) => ({\n ...model,\n companyId: this.companies()[0].id,\n }));\n this.onCompanyChange();\n }\n\n const storedCompanyId = this.authState.getStoredCompanyId();\n const storedBranchId = this.authState.getStoredBranchId();\n\n if (storedCompanyId) {\n const company = this.companies().find((c) => c.id === storedCompanyId);\n if (company) {\n this.selectionFormModel.update((model) => ({\n ...model,\n companyId: storedCompanyId,\n }));\n if (storedBranchId) {\n const branch = company.branches.find((b) => b.id === storedBranchId);\n if (branch) {\n this.selectionFormModel.update((model) => ({\n ...model,\n branchId: storedBranchId,\n }));\n }\n }\n }\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"flusys-ng-auth-login-page.component-Bz-bbY3U.mjs","names":[],"sources":["../../../projects/ng-auth/pages/login/login-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { RouterLink } from '@angular/router';\nimport {\n APP_CONFIG,\n isCompanyFeatureEnabled,\n isServiceEnabled,\n isSignUpEnabled,\n} from '@flusys/ng-core';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport {\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n buildBranchTreeNodes,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n IBranchSelectionInfo,\n ICompanyWithBranches,\n ILoginRequest,\n isCompanySelectionResponse,\n ISelectRequest,\n isEmailVerificationRequired,\n isLoginResponse,\n} from '../../interfaces/auth.interface';\nimport { SocialLoginButtonsComponent } from '../../components/social-login-buttons.component';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { EmailPolicyService } from '../../services/email-policy.service';\n\ninterface ILoginFormModel {\n email: string;\n password: string;\n rememberMe: boolean;\n}\n\ninterface ISelectionFormModel {\n companyId: string;\n branchId: string;\n rememberSelection: boolean;\n}\n\ntype LoginStep = 'credentials' | 'company-selection' | 'email-verification';\n\n@Component({\n selector: 'lib-login-page',\n imports: [\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n RouterLink,\n FormField,\n AppFloatingConfigurator,\n SocialLoginButtonsComponent,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen\"\n >\n <div\n class=\"flex flex-col items-center justify-center w-full max-w-[32rem] px-4\"\n >\n <div\n class=\"w-full\"\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"w-full py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n <!-- Step Indicator (only when company feature enabled) -->\n @if (companyFeatureEnabled()) {\n <div class=\"flex items-center justify-center mb-6 gap-2\">\n <div\n class=\"flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold transition-colors\"\n [class.bg-primary]=\"currentStep() === 'credentials'\"\n [class.text-primary-contrast]=\"\n currentStep() === 'credentials'\n \"\n [class.bg-surface-200]=\"currentStep() !== 'credentials'\"\n [class.dark:bg-surface-700]=\"currentStep() !== 'credentials'\"\n [class.text-muted-color]=\"currentStep() !== 'credentials'\"\n >\n 1\n </div>\n <div class=\"w-12 h-0.5 bg-surface-200 dark:bg-surface-700\"></div>\n <div\n class=\"flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold transition-colors\"\n [class.bg-primary]=\"currentStep() === 'company-selection'\"\n [class.text-primary-contrast]=\"\n currentStep() === 'company-selection'\n \"\n [class.bg-surface-200]=\"currentStep() !== 'company-selection'\"\n [class.dark:bg-surface-700]=\"currentStep() !== 'company-selection'\"\n [class.text-muted-color]=\"\n currentStep() !== 'company-selection'\n \"\n >\n 2\n </div>\n </div>\n }\n\n <!-- Step 1: Credentials -->\n @if (currentStep() === 'credentials') {\n <div class=\"text-center mb-8\">\n <div\n class=\"text-3xl font-medium mb-4 text-color truncate\"\n [title]=\"savedUserName() ? welcomeBackText() : null\"\n >\n @if (savedUserName()) {\n {{ welcomeBackText() }}\n } @else {\n {{ 'auth.login.welcome' | translate }}\n }\n </div>\n <span class=\"text-muted-color font-medium\">{{\n 'auth.login.sign.in.to.continue' | translate\n }}</span>\n </div>\n\n <form (submit)=\"onSubmit($event)\">\n <label\n for=\"email\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.email.label' | translate }}\n </label>\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n class=\"w-full\"\n [formField]=\"loginForm.email\"\n autocomplete=\"email\"\n />\n @if (emailValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n emailValidationError()\n }}</small>\n }\n <div class=\"mb-4\"></div>\n\n <label\n for=\"password\"\n class=\"block font-medium text-lg mb-2 text-color\"\n >\n {{ 'auth.password.label' | translate }}\n </label>\n <div class=\"mb-4\">\n <f-password\n [inputId]=\"'password'\"\n [placeholder]=\"'auth.password.placeholder' | translate\"\n class=\"w-full\"\n [formField]=\"loginForm.password\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div\n class=\"flex flex-col sm:flex-row items-start sm:items-center justify-between mt-2 mb-8 gap-4\"\n >\n <f-checkbox [formField]=\"loginForm.rememberMe\" [label]=\"'auth.field.remember.me' | translate\" />\n @if (emailFeatureEnabled()) {\n <span\n class=\"font-medium no-underline cursor-pointer text-primary\"\n style=\"margin-inline-start: 0.5rem;\"\n routerLink=\"/auth/forgot-password\"\n >\n {{ 'auth.password.forgot' | translate }}\n </span>\n }\n </div>\n\n <button\n fButton\n class=\"w-full\"\n type=\"submit\"\n [disabled]=\"!isLoginFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.login.sign.in' | translate }}</span>\n </button>\n\n <lib-social-login-buttons [returnUrl]=\"returnUrl()\" />\n\n @if (signUpEnabled()) {\n <div class=\"flex items-center justify-center mt-4 gap-2\">\n <span class=\"font-medium\">{{\n 'auth.login.no.account' | translate\n }}</span>\n <a\n routerLink=\"/auth/register\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.sign.up' | translate }}\n </a>\n </div>\n }\n </form>\n }\n\n <!-- Email Verification Required -->\n @if (currentStep() === 'email-verification') {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"envelope\" class=\"text-6xl text-warn\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.login.email.not.verified' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{ 'auth.login.verify.email.message' | translate }}\n </p>\n <button\n fButton\n class=\"w-full mb-4\"\n (click)=\"onResendVerification()\"\n [disabled]=\"isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.verify.resend' | translate }}</span>\n </button>\n <div class=\"mt-4\">\n <span\n class=\"font-semibold text-primary cursor-pointer\"\n (click)=\"goBackToCredentials()\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </span>\n </div>\n </div>\n }\n\n <!-- Step 2: Company Selection -->\n @if (currentStep() === 'company-selection') {\n <div class=\"text-center mb-8\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.login.select.company' | translate }}\n </div>\n <div class=\"text-muted-color font-medium\">\n {{ 'auth.login.select.company.message' | translate }}\n </div>\n </div>\n\n <form (submit)=\"onSelectCompany($event)\">\n <label\n for=\"company\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'shared.company' | translate }}\n </label>\n <f-select\n inputId=\"company\"\n class=\"w-full mb-4\"\n [options]=\"companies()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [formField]=\"selectionForm.companyId\"\n [placeholder]=\"'auth.login.select.company.option' | translate\"\n (onChange)=\"onCompanyChange()\"\n />\n\n <label\n for=\"branch\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.login.branch.label' | translate }}\n </label>\n <f-treeselect\n inputId=\"branch\"\n class=\"w-full mb-4\"\n [options]=\"branchTreeNodes()\"\n [formField]=\"selectionForm.branchId\"\n [placeholder]=\"'auth.login.select.branch.option' | translate\"\n [filter]=\"true\"\n [filterPlaceholder]=\"'shared.search' | translate\"\n [emptyMessage]=\"'shared.no.results' | translate\"\n />\n\n <div class=\"flex items-center mt-2 mb-8\">\n <f-checkbox\n [formField]=\"selectionForm.rememberSelection\"\n [label]=\"'auth.login.remember.selection' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col sm:flex-row gap-4\">\n <button\n fButton\n class=\"w-full\"\n severity=\"secondary\"\n [outlined]=\"true\"\n type=\"button\"\n (click)=\"goBackToCredentials()\"\n >\n <span pButtonLabel>{{ 'shared.back' | translate }}</span>\n </button>\n <button\n fButton\n class=\"w-full\"\n type=\"submit\"\n [disabled]=\"!isSelectionFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'shared.continue' | translate }}</span>\n </button>\n </div>\n </form>\n }\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class LoginPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly authState = inject(AuthStateService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private readonly emailPolicy = inject(EmailPolicyService);\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly returnUrl = input<string>('');\n readonly currentStep = signal<LoginStep>('credentials');\n readonly isLoading = signal(false);\n readonly unverifiedEmail = signal('');\n readonly savedUserName = signal(this.authState.getSavedUserName());\n readonly welcomeBackText = computed(() =>\n this.translate('auth.login.welcome.back', { name: this.savedUserName()! }),\n );\n\n readonly loginFormModel = signal<ILoginFormModel>({\n email: '',\n password: '',\n rememberMe: true,\n });\n\n readonly loginForm = form(this.loginFormModel, (f) => {\n required(f.email, {\n message: this.translate('auth.validation.email.required'),\n });\n required(f.password, {\n message: this.translate('auth.validation.password.required'),\n });\n });\n\n readonly emailValidationError = computed(() =>\n this.emailPolicy.validate(this.loginFormModel().email),\n );\n\n readonly isLoginFormValid = computed(() => {\n const formValid = this.loginForm().valid();\n return formValid && !this.emailValidationError();\n });\n\n readonly selectionFormModel = signal<ISelectionFormModel>({\n companyId: '',\n branchId: '',\n rememberSelection: true,\n });\n\n readonly selectionForm = form(this.selectionFormModel, (f) => {\n required(f.companyId, {\n message: this.translate('auth.validation.company.required'),\n });\n required(f.branchId, {\n message: this.translate('auth.validation.branch.required'),\n });\n });\n\n readonly isSelectionFormValid = computed(() => this.selectionForm().valid());\n readonly companyFeatureEnabled = computed(() =>\n isCompanyFeatureEnabled(this.appConfig),\n );\n readonly emailFeatureEnabled = computed(() =>\n isServiceEnabled(this.appConfig, 'email'),\n );\n readonly signUpEnabled = computed(() => isSignUpEnabled(this.appConfig));\n\n private sessionId: string | null = null;\n readonly companies = signal<ICompanyWithBranches[]>([]);\n readonly userName = signal<string>('');\n\n readonly branches = computed<IBranchSelectionInfo[]>(() => {\n const companyId = this.selectionFormModel().companyId;\n if (!companyId) return [];\n const company = this.companies().find((c) => c.id === companyId);\n return company?.branches ?? [];\n });\n\n readonly branchTreeNodes = computed(() =>\n buildBranchTreeNodes(this.branches()),\n );\n\n constructor() {\n effect(() => {\n if (this.authState.requiresCompanySelection()) {\n this.restorePendingSelectionState();\n }\n });\n }\n\n private restorePendingSelectionState(): void {\n const availableCompanies = this.authState.availableCompanies();\n const sessionId = this.authState.selectionSessionId();\n const name = this.authState.userName();\n\n if (availableCompanies.length > 0 && sessionId) {\n this.companies.set(availableCompanies);\n this.sessionId = sessionId;\n this.userName.set(name);\n this.currentStep.set('company-selection');\n this.autoSelectIfSingle();\n }\n }\n\n onSubmit(event: Event): void {\n event.preventDefault();\n\n if (!this.isLoginFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n const formData = this.loginFormModel();\n const loginData: ILoginRequest = {\n email: formData.email,\n password: formData.password,\n rememberMe: formData.rememberMe,\n };\n\n this.authApi\n .login(loginData)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n\n if (isEmailVerificationRequired(response)) {\n if (!response.data) return;\n this.unverifiedEmail.set(response.data.email);\n this.currentStep.set('email-verification');\n return;\n }\n\n if (isCompanySelectionResponse(response)) {\n if (!response.data) return;\n this.sessionId = response.data.sessionId;\n this.companies.set(response.data.companies);\n this.userName.set(\n response.data.user.name ?? response.data.user.email,\n );\n this.authState.setSelectionState(response.data);\n this.currentStep.set('company-selection');\n this.autoSelectIfSingle();\n } else if (isLoginResponse(response)) {\n if (!response.data) return;\n this.authState.setLoginState(response.data);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : (response.message ?? this.translate('auth.login.success')),\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n }\n },\n error: (error) => {\n this.isLoading.set(false);\n const messageKey = error?.error?.messageKey;\n const detail = messageKey\n ? this.translate(messageKey, error?.error?.messageVariables)\n : error?.error?.message;\n this.messageService.add({\n severity: 'error',\n summary: this.translate('auth.login.title'),\n detail,\n });\n },\n });\n }\n\n onCompanyChange(): void {\n this.selectionFormModel.update((model) => ({\n ...model,\n branchId: '',\n }));\n\n const branches = this.branches();\n if (branches.length === 1) {\n this.selectionFormModel.update((model) => ({\n ...model,\n branchId: branches[0].id,\n }));\n }\n }\n\n onSelectCompany(event: Event): void {\n event.preventDefault();\n\n if (!this.isSelectionFormValid()) {\n this.messageService.add({\n severity: 'warn',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('auth.login.requires.selection'),\n });\n return;\n }\n\n if (!this.sessionId) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.error'),\n detail: this.translate('auth.session.expired'),\n });\n this.goBackToCredentials();\n return;\n }\n\n this.isLoading.set(true);\n\n const formData = this.selectionFormModel();\n const selectData: ISelectRequest = {\n sessionId: this.sessionId,\n companyId: formData.companyId!,\n branchId: formData.branchId!,\n rememberMe: this.loginFormModel().rememberMe,\n };\n\n this.authApi\n .select(selectData)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n if (!response.data) return;\n this.authState.setLoginState(response.data);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n\n goBackToCredentials(): void {\n this.sessionId = null;\n this.companies.set([]);\n this.unverifiedEmail.set('');\n this.selectionFormModel.set({\n companyId: '',\n branchId: '',\n rememberSelection: true,\n });\n this.authState.resetState();\n this.currentStep.set('credentials');\n }\n\n onResendVerification(): void {\n const email = this.unverifiedEmail();\n if (!email) return;\n\n this.isLoading.set(true);\n\n this.authApi\n .resendVerification(email)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n });\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n\n private autoSelectIfSingle(): void {\n if (this.companies().length === 1) {\n this.selectionFormModel.update((model) => ({\n ...model,\n companyId: this.companies()[0].id,\n }));\n this.onCompanyChange();\n }\n\n const storedCompanyId = this.authState.getStoredCompanyId();\n const storedBranchId = this.authState.getStoredBranchId();\n\n if (storedCompanyId) {\n const company = this.companies().find((c) => c.id === storedCompanyId);\n if (company) {\n this.selectionFormModel.update((model) => ({\n ...model,\n companyId: storedCompanyId,\n }));\n if (storedBranchId) {\n const branch = company.branches.find((b) => b.id === storedBranchId);\n if (branch) {\n this.selectionFormModel.update((model) => ({\n ...model,\n branchId: storedBranchId,\n }));\n }\n }\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -339,7 +339,7 @@ var ProfilePageComponent = class ProfilePageComponent {
339
339
  }
340
340
  static ɵfac = i0.ɵɵngDeclareFactory({
341
341
  minVersion: "12.0.0",
342
- version: "22.2.2",
342
+ version: "22.2.3",
343
343
  ngImport: i0,
344
344
  type: ProfilePageComponent,
345
345
  deps: [],
@@ -347,7 +347,7 @@ var ProfilePageComponent = class ProfilePageComponent {
347
347
  });
348
348
  static ɵcmp = i0.ɵɵngDeclareComponent({
349
349
  minVersion: "17.0.0",
350
- version: "22.2.2",
350
+ version: "22.2.3",
351
351
  type: ProfilePageComponent,
352
352
  isStandalone: true,
353
353
  selector: "lib-profile-page",
@@ -1218,7 +1218,7 @@ var ProfilePageComponent = class ProfilePageComponent {
1218
1218
  };
1219
1219
  i0.ɵɵngDeclareClassMetadata({
1220
1220
  minVersion: "12.0.0",
1221
- version: "22.2.2",
1221
+ version: "22.2.3",
1222
1222
  ngImport: i0,
1223
1223
  type: ProfilePageComponent,
1224
1224
  decorators: [{
@@ -1789,4 +1789,4 @@ i0.ɵɵngDeclareClassMetadata({
1789
1789
  });
1790
1790
  export { ProfilePageComponent };
1791
1791
 
1792
- //# sourceMappingURL=flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs.map
1792
+ //# sourceMappingURL=flusys-ng-auth-profile-page.component-Dg25DA0i.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs","names":[],"sources":["../../../projects/ng-auth/pages/profile/profile-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport {\n APP_CONFIG,\n getPermissionMode,\n isCompanyFeatureEnabled,\n isServiceEnabled,\n} from '@flusys/ng-core';\nimport {\n FILE_PROVIDER,\n FileUploaderComponent,\n FileUrlService,\n HasPermissionDirective,\n IProfileActionInfo,\n IProfileRoleInfo,\n PROFILE_PERMISSION_PROVIDER,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n AvatarComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n SelectComponent,\n SkeletonComponent,\n TagComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { catchError, finalize, forkJoin, of } from 'rxjs';\nimport { IUpdateUserRequest } from '../../interfaces/user.interface';\nimport {\n AUTH_PROFILE_EXTENSION,\n AUTH_USER_FORM_EXTENSION,\n IProfileExtraField,\n IProfileExtraSection,\n IProfileFieldTemplateContext,\n IUserFormExtraField,\n PROFILE_FIELD_CONTEXT,\n} from '../../providers/auth-extension.providers';\nimport { sortByOrder } from '../../providers/extension-order.util';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service';\nimport { UserApiService } from '../../services/user-api.service';\n\ninterface IProfileFormModel {\n name: string;\n phone: string;\n}\n\ninterface IPasswordFormModel {\n currentPassword: string;\n newPassword: string;\n confirmPassword: string;\n}\n\n@Component({\n selector: 'lib-profile-page',\n imports: [\n AvatarComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n SelectComponent,\n SkeletonComponent,\n TagComponent,\n TextareaDirective,\n UiIconComponent,\n FormsModule,\n NgComponentOutlet,\n NgTemplateOutlet,\n FormField,\n FileUploaderComponent,\n HasPermissionDirective,\n TranslatePipe,\n ],\n template: `\n <div class=\"mb-4 md:mb-6\">\n <h1 class=\"text-2xl font-bold text-color mb-2\">\n {{ 'profile.title' | translate }}\n </h1>\n <p class=\"text-muted-color\">{{ 'profile.subtitle' | translate }}</p>\n </div>\n\n <div class=\"card mb-2 md:mb-4\">\n <div class=\"flex flex-col md:flex-row gap-4 md:gap-6\">\n <div\n class=\"flex flex-col items-center gap-4 md:w-72 lg:w-80 md:border-r md:border-surface md:pr-6\"\n >\n @if (profilePictureUrl()) {\n <f-avatar\n [image]=\"profilePictureUrl()!\"\n size=\"xlarge\"\n shape=\"circle\"\n styleClass=\"w-28 h-28\"\n />\n } @else {\n <f-avatar\n [label]=\"userInitials()\"\n size=\"xlarge\"\n shape=\"circle\"\n styleClass=\"w-28 h-28 text-3xl bg-primary text-primary-contrast\"\n />\n }\n <div class=\"text-center\">\n <div class=\"font-semibold text-color\">{{ userName() }}</div>\n <div class=\"text-muted-color text-sm\">{{ userEmail() }}</div>\n </div>\n @if (showUploadSection()) {\n <lib-file-uploader\n [acceptTypes]=\"['image/*']\"\n [multiple]=\"false\"\n [maxSizeMb]=\"5\"\n [showPreview]=\"false\"\n [uploadOptions]=\"profileUploadOptions\"\n (fileUploaded)=\"onProfilePictureUploaded($event)\"\n class=\"w-full\"\n />\n } @else {\n <div class=\"w-full p-3 bg-emphasis rounded-lg text-center\">\n <ui-icon\n name=\"info-circle\"\n class=\"text-muted-color mr-2\"\n ></ui-icon>\n <span class=\"text-sm text-muted-color\">{{\n 'profile.storage.not.enabled' | translate\n }}</span>\n </div>\n }\n </div>\n\n <div class=\"flex-1 min-w-0\">\n <form (ngSubmit)=\"onSubmit()\" class=\"flex flex-col gap-4\">\n <div class=\"flex flex-col gap-2\">\n <label class=\"font-medium text-color\">{{\n 'auth.email.label' | translate\n }}</label>\n <input\n fInputText\n [value]=\"userEmail()\"\n disabled\n class=\"bg-(--f-form-field-filled-background)\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"name\" class=\"font-medium text-color\"\n >{{ 'profile.name.label' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"formTree.name\"\n [placeholder]=\"'profile.name.placeholder' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"phone\" class=\"font-medium text-color\">{{\n 'profile.phone.label' | translate\n }}</label>\n <input\n fInputText\n id=\"phone\"\n [formField]=\"formTree.phone\"\n [placeholder]=\"'profile.phone.placeholder' | translate\"\n />\n </div>\n\n @if (editableFields().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-2\">\n <div class=\"text-sm font-medium text-muted-color mb-4\">\n <ui-icon name=\"pencil\" class=\"mr-2\"></ui-icon\n >{{ 'profile.additional.info' | translate }}\n </div>\n @if (isLoadingExtraFields()) {\n <f-skeleton height=\"2rem\" class=\"mb-2\" />\n <f-skeleton height=\"2rem\" />\n } @else {\n <div class=\"flex flex-col gap-4\">\n @for (field of editableFields(); track field.key) {\n <div class=\"flex flex-col gap-2\">\n <label [for]=\"field.key\" class=\"font-medium text-color\">\n {{ field.labelKey | translate: null : field.label\n }}{{ field.required ? ' *' : '' }}\n </label>\n @if (field.component) {\n <ng-container\n [ngComponentOutlet]=\"field.component\"\n [ngComponentOutletInjector]=\"getFieldInjector(field)\"\n />\n } @else if (field.template) {\n <ng-container\n [ngTemplateOutlet]=\"field.template\"\n [ngTemplateOutletContext]=\"\n getFieldTemplateContext(field)\n \"\n />\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"fieldTemplate\"\n [ngTemplateOutletContext]=\"{ field: field }\"\n />\n }\n </div>\n }\n </div>\n @if (extraFieldsValidationError()) {\n <small class=\"text-danger block mt-2\">{{\n extraFieldsValidationError()\n }}</small>\n }\n }\n </div>\n }\n\n @if (viewOnlyFields().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-2\">\n <div class=\"flex items-center justify-between mb-4\">\n <div class=\"text-sm font-medium text-muted-color\">\n <ui-icon name=\"eye\" class=\"mr-2\"></ui-icon\n >{{ 'profile.employment.info' | translate }}\n </div>\n <f-tag\n [value]=\"'profile.managed.by.admin' | translate\"\n severity=\"secondary\"\n />\n </div>\n @if (isLoadingExtraFields()) {\n <f-skeleton height=\"2rem\" class=\"mb-2\" />\n <f-skeleton height=\"2rem\" />\n } @else {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n @for (field of viewOnlyFields(); track field.key) {\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm text-muted-color\">{{\n field.labelKey | translate: null : field.label\n }}</label>\n <span class=\"text-color font-medium\">\n @if (field.type === 'select') {\n {{\n getSelectLabel(\n field,\n getAdminFieldValue(field.key)\n )\n }}\n } @else {\n {{ getAdminFieldValue(field.key) || '-' }}\n }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <ng-template #fieldTemplate let-field=\"field\">\n @switch (field.type) {\n @case ('text') {\n <input\n fInputText\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(field.key, $any($event.target).value)\n \"\n class=\"w-full\"\n />\n }\n @case ('number') {\n <input\n fInputText\n type=\"number\"\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).valueAsNumber\n )\n \"\n class=\"w-full\"\n />\n }\n @case ('textarea') {\n <textarea\n fTextarea\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(field.key, $any($event.target).value)\n \"\n class=\"w-full\"\n rows=\"3\"\n ></textarea>\n }\n @case ('select') {\n <f-select\n [id]=\"field.key\"\n class=\"w-full\"\n [options]=\"field.options ?? []\"\n optionValue=\"value\"\n [disabled]=\"field.editable === false\"\n [ngModel]=\"getExtraFieldValue(field.key) ?? ''\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"updateExtraField(field.key, $event)\"\n [placeholder]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ?? ('shared.select' | translate)\n \"\n >\n <ng-template #item let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n <ng-template #selectedItem let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n </f-select>\n }\n @case ('checkbox') {\n <f-checkbox\n [inputId]=\"field.key\"\n [checked]=\"$any(getExtraFieldValue(field.key) ?? false)\"\n [disabled]=\"field.editable === false\"\n (onChange)=\"updateExtraField(field.key, $event.checked)\"\n [label]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ??\n (field.labelKey | translate: null : field.label)\n \"\n />\n }\n @case ('date') {\n <input\n fInputText\n type=\"date\"\n [id]=\"field.key\"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(field.key, $any($event.target).value)\n \"\n class=\"w-full\"\n />\n }\n }\n </ng-template>\n\n <div class=\"flex justify-end pt-4\">\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isFormValid() || !isFormDirty() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"check\"></ui-icon>\n }\n <span pButtonLabel>{{\n 'shared.save.changes' | translate\n }}</span>\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n\n <div class=\"card mb-2 md:mb-4\">\n <div class=\"flex items-center gap-2 mb-4\">\n <ui-icon name=\"lock\" class=\"text-primary\"></ui-icon>\n <span class=\"font-semibold text-color\">{{\n 'profile.security' | translate\n }}</span>\n </div>\n <form (ngSubmit)=\"onChangePassword()\" class=\"flex flex-col gap-4\">\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div class=\"flex flex-col gap-2\">\n <label for=\"currentPassword\" class=\"font-medium text-color\"\n >{{ 'profile.current.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'currentPassword'\"\n [formField]=\"passwordForm.currentPassword\"\n [placeholder]=\"'profile.current.password.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"newPassword\" class=\"font-medium text-color\"\n >{{ 'profile.new.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'newPassword'\"\n [formField]=\"passwordForm.newPassword\"\n [placeholder]=\"'shared.min.characters' | translate: { count: passwordPolicy.minLength }\"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (newPasswordError()) {\n <small class=\"text-danger\">{{ newPasswordError() }}</small>\n }\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"confirmPassword\" class=\"font-medium text-color\"\n >{{ 'profile.confirm.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'confirmPassword'\"\n [formField]=\"passwordForm.confirmPassword\"\n [placeholder]=\"'profile.confirm.password.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (!passwordsMatch()) {\n <small class=\"text-danger\">{{\n 'auth.register.passwords.do.not.match' | translate\n }}</small>\n }\n </div>\n </div>\n\n <div class=\"flex justify-end\">\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isPasswordFormValid() || isPasswordLoading()\"\n >\n @if (isPasswordLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"key\"></ui-icon>\n }\n <span pButtonLabel>{{\n 'profile.change.password' | translate\n }}</span>\n </button>\n </div>\n </form>\n </div>\n\n @for (section of extraSections(); track section.key) {\n @if (section.editPermission) {\n <div *hasPermission=\"section.editPermission\" class=\"card mb-2 md:mb-4\">\n <div class=\"flex items-center gap-2 mb-4\">\n @if (section.icon) {\n <ui-icon [name]=\"section.icon\" class=\"text-primary\"></ui-icon>\n }\n <span class=\"font-semibold text-color\">{{\n section.titleKey | translate: null : section.title\n }}</span>\n </div>\n <div class=\"section-content\">\n @if (section.component) {\n <ng-container [ngComponentOutlet]=\"section.component\" />\n }\n </div>\n </div>\n } @else {\n <div class=\"card mb-2 md:mb-4\">\n <div class=\"flex items-center gap-2 mb-4\">\n @if (section.icon) {\n <ui-icon [name]=\"section.icon\" class=\"text-primary\"></ui-icon>\n }\n <span class=\"font-semibold text-color\">{{\n section.titleKey | translate: null : section.title\n }}</span>\n </div>\n <div class=\"section-content\">\n @if (section.component) {\n <ng-container [ngComponentOutlet]=\"section.component\" />\n }\n </div>\n </div>\n }\n }\n\n @if (showBottomRow()) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4 flex-1\">\n @if (showCompanySection()) {\n <div class=\"card h-48 md:h-56 flex flex-col\">\n <div class=\"flex items-center gap-2 mb-4\">\n <ui-icon name=\"building\" class=\"text-primary\"></ui-icon>\n <span class=\"font-semibold text-color\">{{\n 'profile.company.branch' | translate\n }}</span>\n </div>\n <div class=\"flex flex-col gap-4 flex-1 overflow-auto\">\n <div class=\"flex items-center gap-3\">\n <div\n class=\"w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0\"\n >\n <ui-icon name=\"briefcase\" class=\"text-primary\"></ui-icon>\n </div>\n <div>\n <div class=\"text-sm text-muted-color\">\n {{ 'shared.company' | translate }}\n </div>\n <div class=\"font-medium text-color\">\n {{ companyName() || ('shared.not.assigned' | translate) }}\n </div>\n </div>\n </div>\n <div class=\"flex items-center gap-3\">\n <div\n class=\"w-10 h-10 rounded-lg bg-success/10 flex items-center justify-center flex-shrink-0\"\n >\n <ui-icon name=\"map-marker\" class=\"text-success\"></ui-icon>\n </div>\n <div>\n <div class=\"text-sm text-muted-color\">\n {{ 'profile.branch.label' | translate }}\n </div>\n <div class=\"font-medium text-color\">\n {{ branchName() || ('shared.not.assigned' | translate) }}\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n @if (showPermissionsSection()) {\n <div class=\"card h-48 md:h-56 flex flex-col\">\n <div class=\"flex items-center justify-between mb-4\">\n <div class=\"flex items-center gap-2\">\n <ui-icon name=\"shield\" class=\"text-primary\"></ui-icon>\n <span class=\"font-semibold text-color\">{{\n 'profile.permissions.label' | translate\n }}</span>\n </div>\n <f-tag\n [value]=\"'shared.read.only' | translate\"\n severity=\"secondary\"\n />\n </div>\n <div class=\"flex flex-col gap-4 flex-1 overflow-auto\">\n @if (showRoles()) {\n <div>\n <div\n class=\"text-sm text-muted-color mb-2 flex items-center gap-2\"\n >\n <ui-icon name=\"users\"></ui-icon>\n {{ 'profile.roles.label' | translate }}\n </div>\n @if (isLoadingPermissions()) {\n <f-skeleton height=\"1.5rem\" class=\"mb-2\" />\n } @else if (userRoles().length === 0) {\n <span class=\"text-muted-color text-sm\">{{\n 'profile.roles.none.assigned' | translate\n }}</span>\n } @else {\n <div class=\"flex flex-wrap gap-2\">\n @for (role of userRoles(); track role.id) {\n <f-tag [value]=\"role.name\" severity=\"info\" />\n }\n </div>\n }\n </div>\n }\n\n @if (showActions()) {\n <div>\n <div\n class=\"text-sm text-muted-color mb-2 flex items-center gap-2\"\n >\n <ui-icon name=\"bolt\"></ui-icon>\n {{ 'profile.actions.label' | translate }}\n </div>\n @if (isLoadingPermissions()) {\n <f-skeleton height=\"1.5rem\" class=\"mb-2\" />\n } @else if (userActions().length === 0) {\n <span class=\"text-muted-color text-sm\">{{\n 'profile.actions.none.assigned' | translate\n }}</span>\n } @else {\n <div class=\"flex flex-wrap gap-2\">\n @for (action of userActions(); track action.id) {\n <f-tag [value]=\"action.name\" severity=\"success\" />\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n `,\n})\nexport class ProfilePageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly messageService = inject(MessageService);\n private readonly authState = inject(AuthStateService);\n private readonly userService = inject(UserApiService);\n private readonly authApiService = inject(AuthApiService);\n protected readonly passwordPolicy = inject(PasswordPolicyService);\n private readonly fileUrlService = inject(FileUrlService);\n private readonly fileProvider = inject(FILE_PROVIDER, { optional: true });\n private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, {\n optional: true,\n });\n private readonly profileExtension = inject(AUTH_PROFILE_EXTENSION, {\n optional: true,\n });\n private readonly userFormExtension = inject(AUTH_USER_FORM_EXTENSION, {\n optional: true,\n });\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly isLoading = signal(false);\n readonly isLoadingPermissions = signal(false);\n readonly isLoadingExtraFields = signal(false);\n private readonly _profilePictureUrl = signal<string | null>(null);\n readonly profilePictureUrl = this._profilePictureUrl.asReadonly();\n\n private readonly _userRoles = signal<IProfileRoleInfo[]>([]);\n readonly userRoles = this._userRoles.asReadonly();\n private readonly _userActions = signal<IProfileActionInfo[]>([]);\n readonly userActions = this._userActions.asReadonly();\n\n readonly extraSections = computed<IProfileExtraSection[]>(() => {\n if (!this.profileExtension?.getExtraSections) return [];\n return sortByOrder(this.profileExtension.getExtraSections());\n });\n\n readonly editableFields = computed<IProfileExtraField[]>(() => {\n if (!this.profileExtension?.getExtraFields) return [];\n return sortByOrder(this.profileExtension.getExtraFields());\n });\n\n readonly viewOnlyFields = computed<IUserFormExtraField[]>(() => {\n if (!this.userFormExtension?.getExtraFields) return [];\n return sortByOrder(this.userFormExtension.getExtraFields());\n });\n\n readonly hasExtraContent = computed(\n () =>\n this.extraSections().length > 0 ||\n this.editableFields().length > 0 ||\n this.viewOnlyFields().length > 0,\n );\n\n readonly extraFieldsModel = signal<Record<string, unknown>>({});\n readonly originalExtraFieldsModel = signal<Record<string, unknown>>({});\n readonly adminFieldsModel = signal<Record<string, unknown>>({});\n\n readonly isExtraFieldsDirty = computed(() => {\n const current = this.extraFieldsModel();\n const original = this.originalExtraFieldsModel();\n return JSON.stringify(current) !== JSON.stringify(original);\n });\n\n readonly extraFieldsValidationError = computed(() => {\n if (!this.profileExtension?.validateExtraFields) return null;\n return this.profileExtension.validateExtraFields(this.extraFieldsModel());\n });\n\n readonly userEmail = computed(() => this.authState.user()?.email ?? '');\n readonly userName = computed(() => this.authState.userName());\n readonly userInitials = computed(() => {\n const name = this.authState.user()?.name ?? '';\n return name\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n });\n readonly companyName = computed(() => this.authState.companyName());\n readonly branchName = computed(() => this.authState.branchName());\n\n readonly showUploadSection = computed(\n () =>\n isServiceEnabled(this.appConfig, 'storage') && this.fileProvider !== null,\n );\n readonly showCompanySection = computed(() =>\n isCompanyFeatureEnabled(this.appConfig),\n );\n readonly showPermissionsSection = computed(\n () =>\n isServiceEnabled(this.appConfig, 'iam') &&\n this.permissionProvider !== null,\n );\n readonly permissionMode = computed(() => getPermissionMode(this.appConfig));\n readonly showRoles = computed(() => {\n const mode = this.permissionMode();\n return mode === 'rbac' || mode === 'full';\n });\n readonly showActions = computed(() => {\n const mode = this.permissionMode();\n return mode === 'direct' || mode === 'full';\n });\n readonly showBottomRow = computed(\n () => this.showCompanySection() || this.showPermissionsSection(),\n );\n\n private readonly originalFormModel = signal<IProfileFormModel>({\n name: '',\n phone: '',\n });\n readonly formModel = signal<IProfileFormModel>({ name: '', phone: '' });\n\n readonly formTree = form(this.formModel, (f) => {\n required(f.name, {\n message: this.translate('shared.name.required'),\n });\n });\n\n readonly isFormValid = computed(\n () => this.formModel().name.trim().length > 0,\n );\n\n readonly isFormDirty = computed(() => {\n const current = this.formModel();\n const original = this.originalFormModel();\n const basicDirty =\n current.name !== original.name || current.phone !== original.phone;\n return basicDirty || this.isExtraFieldsDirty();\n });\n\n updateExtraField(key: string, value: unknown): void {\n this.extraFieldsModel.update((model) => ({ ...model, [key]: value }));\n }\n\n getExtraFieldValue(key: string): unknown {\n return this.extraFieldsModel()[key];\n }\n\n getAdminFieldValue(key: string): unknown {\n return this.adminFieldsModel()[key];\n }\n\n getSelectLabel(\n field: IProfileExtraField | IUserFormExtraField,\n value: unknown,\n ): string {\n if (!value || !field.options) return '-';\n const option = field.options.find((opt) => opt.value === value);\n return option?.label ?? String(value);\n }\n\n getFieldTemplateContext(\n field: IProfileExtraField,\n ): IProfileFieldTemplateContext {\n return {\n field,\n value: this.extraFieldsModel()[field.key],\n updateValue: (value: unknown) => this.updateExtraField(field.key, value),\n };\n }\n\n private readonly parentInjector = inject(Injector);\n\n private readonly fieldInjectors = new Map<\n string,\n { injector: Injector; setField: (field: IProfileExtraField) => void }\n >();\n\n getFieldInjector(field: IProfileExtraField): Injector {\n const cached = this.fieldInjectors.get(field.key);\n if (cached) {\n cached.setField(field);\n return cached.injector;\n }\n\n let currentField = field;\n const extraFieldsModel = this.extraFieldsModel;\n const context: IProfileFieldTemplateContext = {\n get field() {\n return currentField;\n },\n get value() {\n return extraFieldsModel()[currentField.key];\n },\n updateValue: (value: unknown) =>\n this.updateExtraField(currentField.key, value),\n };\n\n const injector = Injector.create({\n providers: [{ provide: PROFILE_FIELD_CONTEXT, useValue: context }],\n parent: field.injector ?? this.parentInjector,\n });\n this.fieldInjectors.set(field.key, {\n injector,\n setField: (next) => (currentField = next),\n });\n return injector;\n }\n\n readonly passwordModel = signal<IPasswordFormModel>({\n currentPassword: '',\n newPassword: '',\n confirmPassword: '',\n });\n\n readonly passwordForm = form(this.passwordModel, (f) => {\n required(f.currentPassword, {\n message: this.translate('auth.password.change.current.required'),\n });\n required(f.newPassword, {\n message: this.translate('auth.validation.password.required'),\n });\n });\n\n readonly isPasswordLoading = signal(false);\n\n readonly newPasswordError = computed(() =>\n this.passwordPolicy.validate(this.passwordModel().newPassword),\n );\n\n readonly isPasswordFormValid = computed(() => {\n const model = this.passwordModel();\n return (\n model.currentPassword.length > 0 &&\n model.newPassword.length > 0 &&\n !this.newPasswordError() &&\n model.newPassword === model.confirmPassword\n );\n });\n\n readonly passwordsMatch = computed(() => {\n const model = this.passwordModel();\n return (\n model.confirmPassword.length === 0 ||\n model.newPassword === model.confirmPassword\n );\n });\n\n readonly profileUploadOptions = {\n folderPath: 'profile-pictures',\n compress: true,\n maxWidth: 400,\n maxHeight: 400,\n isPrivate: true,\n };\n\n constructor() {\n this.loadUserData();\n\n effect(() => {\n if (this.showPermissionsSection()) this.loadPermissions();\n });\n\n effect(() => {\n const user = this.authState.user();\n if (user && this.hasExtraContent()) this.loadExtraFields();\n });\n }\n\n private loadUserData(): void {\n const user = this.authState.user();\n if (user) {\n const initialValues: IProfileFormModel = {\n name: user.name ?? '',\n phone: user.phone ?? '',\n };\n this.originalFormModel.set(initialValues);\n this.formModel.set(initialValues);\n\n if (\n user.profilePictureId &&\n isServiceEnabled(this.appConfig, 'storage')\n ) {\n this.fileUrlService\n .fetchSingleFileUrl(user.profilePictureId)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((file) => this._profilePictureUrl.set(file?.url ?? null));\n }\n }\n }\n\n private loadPermissions(): void {\n const user = this.authState.user();\n const branch = this.authState.branch();\n\n if (!user || !this.permissionProvider) return;\n\n const loadRoles = this.showRoles();\n const loadActions = this.showActions();\n\n if (!loadRoles && !loadActions) return;\n\n this.isLoadingPermissions.set(true);\n\n const roles$ = loadRoles\n ? this.permissionProvider\n .getUserRoles(user.id, branch?.id)\n .pipe(catchError(() => of({ data: [] as IProfileRoleInfo[] })))\n : of({ data: [] as IProfileRoleInfo[] });\n\n const actions$ = loadActions\n ? this.permissionProvider\n .getUserActions(user.id, branch?.id)\n .pipe(catchError(() => of({ data: [] as IProfileActionInfo[] })))\n : of({ data: [] as IProfileActionInfo[] });\n\n forkJoin([roles$, actions$])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoadingPermissions.set(false)),\n )\n .subscribe(([rolesResponse, actionsResponse]) => {\n this._userRoles.set(rolesResponse.data ?? []);\n this._userActions.set(actionsResponse.data ?? []);\n });\n }\n\n private loadExtraFields(): void {\n const user = this.authState.user();\n if (!user) return;\n\n const hasProfileFields = !!this.profileExtension?.getExtraFieldValues;\n const hasAdminFields = !!this.userFormExtension?.getExtraFieldValues;\n\n if (!hasProfileFields && !hasAdminFields) return;\n\n this.isLoadingExtraFields.set(true);\n\n const profileFields$ = hasProfileFields\n ? this.profileExtension!.getExtraFieldValues!(user.id).pipe(\n catchError(() => {\n const defaults: Record<string, unknown> = {};\n for (const field of this.editableFields()) {\n if (field.key) defaults[field.key] = undefined;\n }\n return of(defaults);\n }),\n )\n : of({} as Record<string, unknown>);\n\n const adminFields$ = hasAdminFields\n ? this.userFormExtension!.getExtraFieldValues!(user.id).pipe(\n catchError(() => {\n const defaults: Record<string, unknown> = {};\n for (const field of this.viewOnlyFields()) {\n if (field.key) defaults[field.key] = undefined;\n }\n return of(defaults);\n }),\n )\n : of({} as Record<string, unknown>);\n\n forkJoin([profileFields$, adminFields$])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoadingExtraFields.set(false)),\n )\n .subscribe(([profileValues, adminValues]) => {\n this.extraFieldsModel.set(profileValues);\n this.originalExtraFieldsModel.set(profileValues);\n this.adminFieldsModel.set(adminValues);\n });\n }\n\n onProfilePictureUploaded(file: {\n id?: string;\n name: string;\n key: string;\n size: number;\n contentType: string;\n }): void {\n const user = this.authState.user();\n if (!user || !file.id) return;\n\n const fileManagerId = file.id;\n\n this.userService\n .updateProfile({ id: user.id, profilePictureId: fileManagerId })\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success && response.data) {\n this.authState.setUser({\n ...user,\n profilePictureId: fileManagerId,\n });\n this.fileUrlService\n .fetchSingleFileUrl(fileManagerId, true)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((fileInfo) =>\n this._profilePictureUrl.set(fileInfo?.url ?? null),\n );\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<\n string,\n string | number\n >,\n )\n : response.message,\n });\n }\n },\n error: () => {},\n });\n }\n\n onSubmit(): void {\n if (!this.isFormValid()) return;\n\n const extraFieldsError = this.extraFieldsValidationError();\n if (extraFieldsError) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: extraFieldsError,\n });\n return;\n }\n\n const user = this.authState.user();\n if (!user) return;\n\n this.isLoading.set(true);\n const model = this.formModel();\n\n const updateData: IUpdateUserRequest = {\n id: user.id,\n name: model.name,\n phone: model.phone || undefined,\n };\n\n const profileUpdate$ = this.userService.updateProfile(updateData);\n const extraFieldsUpdate$ =\n this.isExtraFieldsDirty() && this.profileExtension?.saveExtraFieldValues\n ? this.profileExtension.saveExtraFieldValues(\n user.id,\n this.extraFieldsModel(),\n )\n : of(undefined);\n\n forkJoin([profileUpdate$, extraFieldsUpdate$])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoading.set(false)),\n )\n .subscribe({\n next: ([response]) => {\n if (response.success && response.data) {\n this.authState.setUser({\n ...user,\n name: response.data.name,\n phone: response.data.phone ?? null,\n });\n this.originalFormModel.set({\n name: response.data.name,\n phone: response.data.phone ?? '',\n });\n this.originalExtraFieldsModel.set({ ...this.extraFieldsModel() });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<\n string,\n string | number\n >,\n )\n : response.message,\n });\n }\n },\n error: () => {},\n });\n }\n\n updatePasswordField(field: keyof IPasswordFormModel, value: string): void {\n this.passwordModel.update((model) => ({ ...model, [field]: value }));\n }\n\n onChangePassword(): void {\n if (!this.isPasswordFormValid()) return;\n\n this.isPasswordLoading.set(true);\n const model = this.passwordModel();\n\n this.authApiService\n .changePassword({\n currentPassword: model.currentPassword,\n newPassword: model.newPassword,\n })\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isPasswordLoading.set(false)),\n )\n .subscribe({\n next: (response) => {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response?.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response?.message,\n });\n this.passwordModel.set({\n currentPassword: '',\n newPassword: '',\n confirmPassword: '',\n });\n },\n error: () => {},\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"flusys-ng-auth-profile-page.component-Dg25DA0i.mjs","names":[],"sources":["../../../projects/ng-auth/pages/profile/profile-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport {\n APP_CONFIG,\n getPermissionMode,\n isCompanyFeatureEnabled,\n isServiceEnabled,\n} from '@flusys/ng-core';\nimport {\n FILE_PROVIDER,\n FileUploaderComponent,\n FileUrlService,\n HasPermissionDirective,\n IProfileActionInfo,\n IProfileRoleInfo,\n PROFILE_PERMISSION_PROVIDER,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n AvatarComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n SelectComponent,\n SkeletonComponent,\n TagComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { catchError, finalize, forkJoin, of } from 'rxjs';\nimport { IUpdateUserRequest } from '../../interfaces/user.interface';\nimport {\n AUTH_PROFILE_EXTENSION,\n AUTH_USER_FORM_EXTENSION,\n IProfileExtraField,\n IProfileExtraSection,\n IProfileFieldTemplateContext,\n IUserFormExtraField,\n PROFILE_FIELD_CONTEXT,\n} from '../../providers/auth-extension.providers';\nimport { sortByOrder } from '../../providers/extension-order.util';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service';\nimport { UserApiService } from '../../services/user-api.service';\n\ninterface IProfileFormModel {\n name: string;\n phone: string;\n}\n\ninterface IPasswordFormModel {\n currentPassword: string;\n newPassword: string;\n confirmPassword: string;\n}\n\n@Component({\n selector: 'lib-profile-page',\n imports: [\n AvatarComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n SelectComponent,\n SkeletonComponent,\n TagComponent,\n TextareaDirective,\n UiIconComponent,\n FormsModule,\n NgComponentOutlet,\n NgTemplateOutlet,\n FormField,\n FileUploaderComponent,\n HasPermissionDirective,\n TranslatePipe,\n ],\n template: `\n <div class=\"mb-4 md:mb-6\">\n <h1 class=\"text-2xl font-bold text-color mb-2\">\n {{ 'profile.title' | translate }}\n </h1>\n <p class=\"text-muted-color\">{{ 'profile.subtitle' | translate }}</p>\n </div>\n\n <div class=\"card mb-2 md:mb-4\">\n <div class=\"flex flex-col md:flex-row gap-4 md:gap-6\">\n <div\n class=\"flex flex-col items-center gap-4 md:w-72 lg:w-80 md:border-r md:border-surface md:pr-6\"\n >\n @if (profilePictureUrl()) {\n <f-avatar\n [image]=\"profilePictureUrl()!\"\n size=\"xlarge\"\n shape=\"circle\"\n styleClass=\"w-28 h-28\"\n />\n } @else {\n <f-avatar\n [label]=\"userInitials()\"\n size=\"xlarge\"\n shape=\"circle\"\n styleClass=\"w-28 h-28 text-3xl bg-primary text-primary-contrast\"\n />\n }\n <div class=\"text-center\">\n <div class=\"font-semibold text-color\">{{ userName() }}</div>\n <div class=\"text-muted-color text-sm\">{{ userEmail() }}</div>\n </div>\n @if (showUploadSection()) {\n <lib-file-uploader\n [acceptTypes]=\"['image/*']\"\n [multiple]=\"false\"\n [maxSizeMb]=\"5\"\n [showPreview]=\"false\"\n [uploadOptions]=\"profileUploadOptions\"\n (fileUploaded)=\"onProfilePictureUploaded($event)\"\n class=\"w-full\"\n />\n } @else {\n <div class=\"w-full p-3 bg-emphasis rounded-lg text-center\">\n <ui-icon\n name=\"info-circle\"\n class=\"text-muted-color mr-2\"\n ></ui-icon>\n <span class=\"text-sm text-muted-color\">{{\n 'profile.storage.not.enabled' | translate\n }}</span>\n </div>\n }\n </div>\n\n <div class=\"flex-1 min-w-0\">\n <form (ngSubmit)=\"onSubmit()\" class=\"flex flex-col gap-4\">\n <div class=\"flex flex-col gap-2\">\n <label class=\"font-medium text-color\">{{\n 'auth.email.label' | translate\n }}</label>\n <input\n fInputText\n [value]=\"userEmail()\"\n disabled\n class=\"bg-(--f-form-field-filled-background)\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"name\" class=\"font-medium text-color\"\n >{{ 'profile.name.label' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"formTree.name\"\n [placeholder]=\"'profile.name.placeholder' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"phone\" class=\"font-medium text-color\">{{\n 'profile.phone.label' | translate\n }}</label>\n <input\n fInputText\n id=\"phone\"\n [formField]=\"formTree.phone\"\n [placeholder]=\"'profile.phone.placeholder' | translate\"\n />\n </div>\n\n @if (editableFields().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-2\">\n <div class=\"text-sm font-medium text-muted-color mb-4\">\n <ui-icon name=\"pencil\" class=\"mr-2\"></ui-icon\n >{{ 'profile.additional.info' | translate }}\n </div>\n @if (isLoadingExtraFields()) {\n <f-skeleton height=\"2rem\" class=\"mb-2\" />\n <f-skeleton height=\"2rem\" />\n } @else {\n <div class=\"flex flex-col gap-4\">\n @for (field of editableFields(); track field.key) {\n <div class=\"flex flex-col gap-2\">\n <label [for]=\"field.key\" class=\"font-medium text-color\">\n {{ field.labelKey | translate: null : field.label\n }}{{ field.required ? ' *' : '' }}\n </label>\n @if (field.component) {\n <ng-container\n [ngComponentOutlet]=\"field.component\"\n [ngComponentOutletInjector]=\"getFieldInjector(field)\"\n />\n } @else if (field.template) {\n <ng-container\n [ngTemplateOutlet]=\"field.template\"\n [ngTemplateOutletContext]=\"\n getFieldTemplateContext(field)\n \"\n />\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"fieldTemplate\"\n [ngTemplateOutletContext]=\"{ field: field }\"\n />\n }\n </div>\n }\n </div>\n @if (extraFieldsValidationError()) {\n <small class=\"text-danger block mt-2\">{{\n extraFieldsValidationError()\n }}</small>\n }\n }\n </div>\n }\n\n @if (viewOnlyFields().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-2\">\n <div class=\"flex items-center justify-between mb-4\">\n <div class=\"text-sm font-medium text-muted-color\">\n <ui-icon name=\"eye\" class=\"mr-2\"></ui-icon\n >{{ 'profile.employment.info' | translate }}\n </div>\n <f-tag\n [value]=\"'profile.managed.by.admin' | translate\"\n severity=\"secondary\"\n />\n </div>\n @if (isLoadingExtraFields()) {\n <f-skeleton height=\"2rem\" class=\"mb-2\" />\n <f-skeleton height=\"2rem\" />\n } @else {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n @for (field of viewOnlyFields(); track field.key) {\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm text-muted-color\">{{\n field.labelKey | translate: null : field.label\n }}</label>\n <span class=\"text-color font-medium\">\n @if (field.type === 'select') {\n {{\n getSelectLabel(\n field,\n getAdminFieldValue(field.key)\n )\n }}\n } @else {\n {{ getAdminFieldValue(field.key) || '-' }}\n }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <ng-template #fieldTemplate let-field=\"field\">\n @switch (field.type) {\n @case ('text') {\n <input\n fInputText\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(field.key, $any($event.target).value)\n \"\n class=\"w-full\"\n />\n }\n @case ('number') {\n <input\n fInputText\n type=\"number\"\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).valueAsNumber\n )\n \"\n class=\"w-full\"\n />\n }\n @case ('textarea') {\n <textarea\n fTextarea\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(field.key, $any($event.target).value)\n \"\n class=\"w-full\"\n rows=\"3\"\n ></textarea>\n }\n @case ('select') {\n <f-select\n [id]=\"field.key\"\n class=\"w-full\"\n [options]=\"field.options ?? []\"\n optionValue=\"value\"\n [disabled]=\"field.editable === false\"\n [ngModel]=\"getExtraFieldValue(field.key) ?? ''\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"updateExtraField(field.key, $event)\"\n [placeholder]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ?? ('shared.select' | translate)\n \"\n >\n <ng-template #item let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n <ng-template #selectedItem let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n </f-select>\n }\n @case ('checkbox') {\n <f-checkbox\n [inputId]=\"field.key\"\n [checked]=\"$any(getExtraFieldValue(field.key) ?? false)\"\n [disabled]=\"field.editable === false\"\n (onChange)=\"updateExtraField(field.key, $event.checked)\"\n [label]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ??\n (field.labelKey | translate: null : field.label)\n \"\n />\n }\n @case ('date') {\n <input\n fInputText\n type=\"date\"\n [id]=\"field.key\"\n [value]=\"getExtraFieldValue(field.key) ?? ''\"\n [disabled]=\"field.editable === false\"\n (input)=\"\n updateExtraField(field.key, $any($event.target).value)\n \"\n class=\"w-full\"\n />\n }\n }\n </ng-template>\n\n <div class=\"flex justify-end pt-4\">\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isFormValid() || !isFormDirty() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"check\"></ui-icon>\n }\n <span pButtonLabel>{{\n 'shared.save.changes' | translate\n }}</span>\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n\n <div class=\"card mb-2 md:mb-4\">\n <div class=\"flex items-center gap-2 mb-4\">\n <ui-icon name=\"lock\" class=\"text-primary\"></ui-icon>\n <span class=\"font-semibold text-color\">{{\n 'profile.security' | translate\n }}</span>\n </div>\n <form (ngSubmit)=\"onChangePassword()\" class=\"flex flex-col gap-4\">\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div class=\"flex flex-col gap-2\">\n <label for=\"currentPassword\" class=\"font-medium text-color\"\n >{{ 'profile.current.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'currentPassword'\"\n [formField]=\"passwordForm.currentPassword\"\n [placeholder]=\"'profile.current.password.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"current-password\"\n />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"newPassword\" class=\"font-medium text-color\"\n >{{ 'profile.new.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'newPassword'\"\n [formField]=\"passwordForm.newPassword\"\n [placeholder]=\"'shared.min.characters' | translate: { count: passwordPolicy.minLength }\"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (newPasswordError()) {\n <small class=\"text-danger\">{{ newPasswordError() }}</small>\n }\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"confirmPassword\" class=\"font-medium text-color\"\n >{{ 'profile.confirm.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'confirmPassword'\"\n [formField]=\"passwordForm.confirmPassword\"\n [placeholder]=\"'profile.confirm.password.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (!passwordsMatch()) {\n <small class=\"text-danger\">{{\n 'auth.register.passwords.do.not.match' | translate\n }}</small>\n }\n </div>\n </div>\n\n <div class=\"flex justify-end\">\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isPasswordFormValid() || isPasswordLoading()\"\n >\n @if (isPasswordLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"key\"></ui-icon>\n }\n <span pButtonLabel>{{\n 'profile.change.password' | translate\n }}</span>\n </button>\n </div>\n </form>\n </div>\n\n @for (section of extraSections(); track section.key) {\n @if (section.editPermission) {\n <div *hasPermission=\"section.editPermission\" class=\"card mb-2 md:mb-4\">\n <div class=\"flex items-center gap-2 mb-4\">\n @if (section.icon) {\n <ui-icon [name]=\"section.icon\" class=\"text-primary\"></ui-icon>\n }\n <span class=\"font-semibold text-color\">{{\n section.titleKey | translate: null : section.title\n }}</span>\n </div>\n <div class=\"section-content\">\n @if (section.component) {\n <ng-container [ngComponentOutlet]=\"section.component\" />\n }\n </div>\n </div>\n } @else {\n <div class=\"card mb-2 md:mb-4\">\n <div class=\"flex items-center gap-2 mb-4\">\n @if (section.icon) {\n <ui-icon [name]=\"section.icon\" class=\"text-primary\"></ui-icon>\n }\n <span class=\"font-semibold text-color\">{{\n section.titleKey | translate: null : section.title\n }}</span>\n </div>\n <div class=\"section-content\">\n @if (section.component) {\n <ng-container [ngComponentOutlet]=\"section.component\" />\n }\n </div>\n </div>\n }\n }\n\n @if (showBottomRow()) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4 flex-1\">\n @if (showCompanySection()) {\n <div class=\"card h-48 md:h-56 flex flex-col\">\n <div class=\"flex items-center gap-2 mb-4\">\n <ui-icon name=\"building\" class=\"text-primary\"></ui-icon>\n <span class=\"font-semibold text-color\">{{\n 'profile.company.branch' | translate\n }}</span>\n </div>\n <div class=\"flex flex-col gap-4 flex-1 overflow-auto\">\n <div class=\"flex items-center gap-3\">\n <div\n class=\"w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0\"\n >\n <ui-icon name=\"briefcase\" class=\"text-primary\"></ui-icon>\n </div>\n <div>\n <div class=\"text-sm text-muted-color\">\n {{ 'shared.company' | translate }}\n </div>\n <div class=\"font-medium text-color\">\n {{ companyName() || ('shared.not.assigned' | translate) }}\n </div>\n </div>\n </div>\n <div class=\"flex items-center gap-3\">\n <div\n class=\"w-10 h-10 rounded-lg bg-success/10 flex items-center justify-center flex-shrink-0\"\n >\n <ui-icon name=\"map-marker\" class=\"text-success\"></ui-icon>\n </div>\n <div>\n <div class=\"text-sm text-muted-color\">\n {{ 'profile.branch.label' | translate }}\n </div>\n <div class=\"font-medium text-color\">\n {{ branchName() || ('shared.not.assigned' | translate) }}\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n @if (showPermissionsSection()) {\n <div class=\"card h-48 md:h-56 flex flex-col\">\n <div class=\"flex items-center justify-between mb-4\">\n <div class=\"flex items-center gap-2\">\n <ui-icon name=\"shield\" class=\"text-primary\"></ui-icon>\n <span class=\"font-semibold text-color\">{{\n 'profile.permissions.label' | translate\n }}</span>\n </div>\n <f-tag\n [value]=\"'shared.read.only' | translate\"\n severity=\"secondary\"\n />\n </div>\n <div class=\"flex flex-col gap-4 flex-1 overflow-auto\">\n @if (showRoles()) {\n <div>\n <div\n class=\"text-sm text-muted-color mb-2 flex items-center gap-2\"\n >\n <ui-icon name=\"users\"></ui-icon>\n {{ 'profile.roles.label' | translate }}\n </div>\n @if (isLoadingPermissions()) {\n <f-skeleton height=\"1.5rem\" class=\"mb-2\" />\n } @else if (userRoles().length === 0) {\n <span class=\"text-muted-color text-sm\">{{\n 'profile.roles.none.assigned' | translate\n }}</span>\n } @else {\n <div class=\"flex flex-wrap gap-2\">\n @for (role of userRoles(); track role.id) {\n <f-tag [value]=\"role.name\" severity=\"info\" />\n }\n </div>\n }\n </div>\n }\n\n @if (showActions()) {\n <div>\n <div\n class=\"text-sm text-muted-color mb-2 flex items-center gap-2\"\n >\n <ui-icon name=\"bolt\"></ui-icon>\n {{ 'profile.actions.label' | translate }}\n </div>\n @if (isLoadingPermissions()) {\n <f-skeleton height=\"1.5rem\" class=\"mb-2\" />\n } @else if (userActions().length === 0) {\n <span class=\"text-muted-color text-sm\">{{\n 'profile.actions.none.assigned' | translate\n }}</span>\n } @else {\n <div class=\"flex flex-wrap gap-2\">\n @for (action of userActions(); track action.id) {\n <f-tag [value]=\"action.name\" severity=\"success\" />\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n `,\n})\nexport class ProfilePageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly messageService = inject(MessageService);\n private readonly authState = inject(AuthStateService);\n private readonly userService = inject(UserApiService);\n private readonly authApiService = inject(AuthApiService);\n protected readonly passwordPolicy = inject(PasswordPolicyService);\n private readonly fileUrlService = inject(FileUrlService);\n private readonly fileProvider = inject(FILE_PROVIDER, { optional: true });\n private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, {\n optional: true,\n });\n private readonly profileExtension = inject(AUTH_PROFILE_EXTENSION, {\n optional: true,\n });\n private readonly userFormExtension = inject(AUTH_USER_FORM_EXTENSION, {\n optional: true,\n });\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly isLoading = signal(false);\n readonly isLoadingPermissions = signal(false);\n readonly isLoadingExtraFields = signal(false);\n private readonly _profilePictureUrl = signal<string | null>(null);\n readonly profilePictureUrl = this._profilePictureUrl.asReadonly();\n\n private readonly _userRoles = signal<IProfileRoleInfo[]>([]);\n readonly userRoles = this._userRoles.asReadonly();\n private readonly _userActions = signal<IProfileActionInfo[]>([]);\n readonly userActions = this._userActions.asReadonly();\n\n readonly extraSections = computed<IProfileExtraSection[]>(() => {\n if (!this.profileExtension?.getExtraSections) return [];\n return sortByOrder(this.profileExtension.getExtraSections());\n });\n\n readonly editableFields = computed<IProfileExtraField[]>(() => {\n if (!this.profileExtension?.getExtraFields) return [];\n return sortByOrder(this.profileExtension.getExtraFields());\n });\n\n readonly viewOnlyFields = computed<IUserFormExtraField[]>(() => {\n if (!this.userFormExtension?.getExtraFields) return [];\n return sortByOrder(this.userFormExtension.getExtraFields());\n });\n\n readonly hasExtraContent = computed(\n () =>\n this.extraSections().length > 0 ||\n this.editableFields().length > 0 ||\n this.viewOnlyFields().length > 0,\n );\n\n readonly extraFieldsModel = signal<Record<string, unknown>>({});\n readonly originalExtraFieldsModel = signal<Record<string, unknown>>({});\n readonly adminFieldsModel = signal<Record<string, unknown>>({});\n\n readonly isExtraFieldsDirty = computed(() => {\n const current = this.extraFieldsModel();\n const original = this.originalExtraFieldsModel();\n return JSON.stringify(current) !== JSON.stringify(original);\n });\n\n readonly extraFieldsValidationError = computed(() => {\n if (!this.profileExtension?.validateExtraFields) return null;\n return this.profileExtension.validateExtraFields(this.extraFieldsModel());\n });\n\n readonly userEmail = computed(() => this.authState.user()?.email ?? '');\n readonly userName = computed(() => this.authState.userName());\n readonly userInitials = computed(() => {\n const name = this.authState.user()?.name ?? '';\n return name\n .split(' ')\n .map((n) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n });\n readonly companyName = computed(() => this.authState.companyName());\n readonly branchName = computed(() => this.authState.branchName());\n\n readonly showUploadSection = computed(\n () =>\n isServiceEnabled(this.appConfig, 'storage') && this.fileProvider !== null,\n );\n readonly showCompanySection = computed(() =>\n isCompanyFeatureEnabled(this.appConfig),\n );\n readonly showPermissionsSection = computed(\n () =>\n isServiceEnabled(this.appConfig, 'iam') &&\n this.permissionProvider !== null,\n );\n readonly permissionMode = computed(() => getPermissionMode(this.appConfig));\n readonly showRoles = computed(() => {\n const mode = this.permissionMode();\n return mode === 'rbac' || mode === 'full';\n });\n readonly showActions = computed(() => {\n const mode = this.permissionMode();\n return mode === 'direct' || mode === 'full';\n });\n readonly showBottomRow = computed(\n () => this.showCompanySection() || this.showPermissionsSection(),\n );\n\n private readonly originalFormModel = signal<IProfileFormModel>({\n name: '',\n phone: '',\n });\n readonly formModel = signal<IProfileFormModel>({ name: '', phone: '' });\n\n readonly formTree = form(this.formModel, (f) => {\n required(f.name, {\n message: this.translate('shared.name.required'),\n });\n });\n\n readonly isFormValid = computed(\n () => this.formModel().name.trim().length > 0,\n );\n\n readonly isFormDirty = computed(() => {\n const current = this.formModel();\n const original = this.originalFormModel();\n const basicDirty =\n current.name !== original.name || current.phone !== original.phone;\n return basicDirty || this.isExtraFieldsDirty();\n });\n\n updateExtraField(key: string, value: unknown): void {\n this.extraFieldsModel.update((model) => ({ ...model, [key]: value }));\n }\n\n getExtraFieldValue(key: string): unknown {\n return this.extraFieldsModel()[key];\n }\n\n getAdminFieldValue(key: string): unknown {\n return this.adminFieldsModel()[key];\n }\n\n getSelectLabel(\n field: IProfileExtraField | IUserFormExtraField,\n value: unknown,\n ): string {\n if (!value || !field.options) return '-';\n const option = field.options.find((opt) => opt.value === value);\n return option?.label ?? String(value);\n }\n\n getFieldTemplateContext(\n field: IProfileExtraField,\n ): IProfileFieldTemplateContext {\n return {\n field,\n value: this.extraFieldsModel()[field.key],\n updateValue: (value: unknown) => this.updateExtraField(field.key, value),\n };\n }\n\n private readonly parentInjector = inject(Injector);\n\n private readonly fieldInjectors = new Map<\n string,\n { injector: Injector; setField: (field: IProfileExtraField) => void }\n >();\n\n getFieldInjector(field: IProfileExtraField): Injector {\n const cached = this.fieldInjectors.get(field.key);\n if (cached) {\n cached.setField(field);\n return cached.injector;\n }\n\n let currentField = field;\n const extraFieldsModel = this.extraFieldsModel;\n const context: IProfileFieldTemplateContext = {\n get field() {\n return currentField;\n },\n get value() {\n return extraFieldsModel()[currentField.key];\n },\n updateValue: (value: unknown) =>\n this.updateExtraField(currentField.key, value),\n };\n\n const injector = Injector.create({\n providers: [{ provide: PROFILE_FIELD_CONTEXT, useValue: context }],\n parent: field.injector ?? this.parentInjector,\n });\n this.fieldInjectors.set(field.key, {\n injector,\n setField: (next) => (currentField = next),\n });\n return injector;\n }\n\n readonly passwordModel = signal<IPasswordFormModel>({\n currentPassword: '',\n newPassword: '',\n confirmPassword: '',\n });\n\n readonly passwordForm = form(this.passwordModel, (f) => {\n required(f.currentPassword, {\n message: this.translate('auth.password.change.current.required'),\n });\n required(f.newPassword, {\n message: this.translate('auth.validation.password.required'),\n });\n });\n\n readonly isPasswordLoading = signal(false);\n\n readonly newPasswordError = computed(() =>\n this.passwordPolicy.validate(this.passwordModel().newPassword),\n );\n\n readonly isPasswordFormValid = computed(() => {\n const model = this.passwordModel();\n return (\n model.currentPassword.length > 0 &&\n model.newPassword.length > 0 &&\n !this.newPasswordError() &&\n model.newPassword === model.confirmPassword\n );\n });\n\n readonly passwordsMatch = computed(() => {\n const model = this.passwordModel();\n return (\n model.confirmPassword.length === 0 ||\n model.newPassword === model.confirmPassword\n );\n });\n\n readonly profileUploadOptions = {\n folderPath: 'profile-pictures',\n compress: true,\n maxWidth: 400,\n maxHeight: 400,\n isPrivate: true,\n };\n\n constructor() {\n this.loadUserData();\n\n effect(() => {\n if (this.showPermissionsSection()) this.loadPermissions();\n });\n\n effect(() => {\n const user = this.authState.user();\n if (user && this.hasExtraContent()) this.loadExtraFields();\n });\n }\n\n private loadUserData(): void {\n const user = this.authState.user();\n if (user) {\n const initialValues: IProfileFormModel = {\n name: user.name ?? '',\n phone: user.phone ?? '',\n };\n this.originalFormModel.set(initialValues);\n this.formModel.set(initialValues);\n\n if (\n user.profilePictureId &&\n isServiceEnabled(this.appConfig, 'storage')\n ) {\n this.fileUrlService\n .fetchSingleFileUrl(user.profilePictureId)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((file) => this._profilePictureUrl.set(file?.url ?? null));\n }\n }\n }\n\n private loadPermissions(): void {\n const user = this.authState.user();\n const branch = this.authState.branch();\n\n if (!user || !this.permissionProvider) return;\n\n const loadRoles = this.showRoles();\n const loadActions = this.showActions();\n\n if (!loadRoles && !loadActions) return;\n\n this.isLoadingPermissions.set(true);\n\n const roles$ = loadRoles\n ? this.permissionProvider\n .getUserRoles(user.id, branch?.id)\n .pipe(catchError(() => of({ data: [] as IProfileRoleInfo[] })))\n : of({ data: [] as IProfileRoleInfo[] });\n\n const actions$ = loadActions\n ? this.permissionProvider\n .getUserActions(user.id, branch?.id)\n .pipe(catchError(() => of({ data: [] as IProfileActionInfo[] })))\n : of({ data: [] as IProfileActionInfo[] });\n\n forkJoin([roles$, actions$])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoadingPermissions.set(false)),\n )\n .subscribe(([rolesResponse, actionsResponse]) => {\n this._userRoles.set(rolesResponse.data ?? []);\n this._userActions.set(actionsResponse.data ?? []);\n });\n }\n\n private loadExtraFields(): void {\n const user = this.authState.user();\n if (!user) return;\n\n const hasProfileFields = !!this.profileExtension?.getExtraFieldValues;\n const hasAdminFields = !!this.userFormExtension?.getExtraFieldValues;\n\n if (!hasProfileFields && !hasAdminFields) return;\n\n this.isLoadingExtraFields.set(true);\n\n const profileFields$ = hasProfileFields\n ? this.profileExtension!.getExtraFieldValues!(user.id).pipe(\n catchError(() => {\n const defaults: Record<string, unknown> = {};\n for (const field of this.editableFields()) {\n if (field.key) defaults[field.key] = undefined;\n }\n return of(defaults);\n }),\n )\n : of({} as Record<string, unknown>);\n\n const adminFields$ = hasAdminFields\n ? this.userFormExtension!.getExtraFieldValues!(user.id).pipe(\n catchError(() => {\n const defaults: Record<string, unknown> = {};\n for (const field of this.viewOnlyFields()) {\n if (field.key) defaults[field.key] = undefined;\n }\n return of(defaults);\n }),\n )\n : of({} as Record<string, unknown>);\n\n forkJoin([profileFields$, adminFields$])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoadingExtraFields.set(false)),\n )\n .subscribe(([profileValues, adminValues]) => {\n this.extraFieldsModel.set(profileValues);\n this.originalExtraFieldsModel.set(profileValues);\n this.adminFieldsModel.set(adminValues);\n });\n }\n\n onProfilePictureUploaded(file: {\n id?: string;\n name: string;\n key: string;\n size: number;\n contentType: string;\n }): void {\n const user = this.authState.user();\n if (!user || !file.id) return;\n\n const fileManagerId = file.id;\n\n this.userService\n .updateProfile({ id: user.id, profilePictureId: fileManagerId })\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success && response.data) {\n this.authState.setUser({\n ...user,\n profilePictureId: fileManagerId,\n });\n this.fileUrlService\n .fetchSingleFileUrl(fileManagerId, true)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((fileInfo) =>\n this._profilePictureUrl.set(fileInfo?.url ?? null),\n );\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<\n string,\n string | number\n >,\n )\n : response.message,\n });\n }\n },\n error: () => {},\n });\n }\n\n onSubmit(): void {\n if (!this.isFormValid()) return;\n\n const extraFieldsError = this.extraFieldsValidationError();\n if (extraFieldsError) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: extraFieldsError,\n });\n return;\n }\n\n const user = this.authState.user();\n if (!user) return;\n\n this.isLoading.set(true);\n const model = this.formModel();\n\n const updateData: IUpdateUserRequest = {\n id: user.id,\n name: model.name,\n phone: model.phone || undefined,\n };\n\n const profileUpdate$ = this.userService.updateProfile(updateData);\n const extraFieldsUpdate$ =\n this.isExtraFieldsDirty() && this.profileExtension?.saveExtraFieldValues\n ? this.profileExtension.saveExtraFieldValues(\n user.id,\n this.extraFieldsModel(),\n )\n : of(undefined);\n\n forkJoin([profileUpdate$, extraFieldsUpdate$])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoading.set(false)),\n )\n .subscribe({\n next: ([response]) => {\n if (response.success && response.data) {\n this.authState.setUser({\n ...user,\n name: response.data.name,\n phone: response.data.phone ?? null,\n });\n this.originalFormModel.set({\n name: response.data.name,\n phone: response.data.phone ?? '',\n });\n this.originalExtraFieldsModel.set({ ...this.extraFieldsModel() });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<\n string,\n string | number\n >,\n )\n : response.message,\n });\n }\n },\n error: () => {},\n });\n }\n\n updatePasswordField(field: keyof IPasswordFormModel, value: string): void {\n this.passwordModel.update((model) => ({ ...model, [field]: value }));\n }\n\n onChangePassword(): void {\n if (!this.isPasswordFormValid()) return;\n\n this.isPasswordLoading.set(true);\n const model = this.passwordModel();\n\n this.authApiService\n .changePassword({\n currentPassword: model.currentPassword,\n newPassword: model.newPassword,\n })\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isPasswordLoading.set(false)),\n )\n .subscribe({\n next: (response) => {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response?.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response?.message,\n });\n this.passwordModel.set({\n currentPassword: '',\n newPassword: '',\n confirmPassword: '',\n });\n },\n error: () => {},\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAwnBA,IAAa,uBAAb,MAAa,qBAAoB;CACd,aAAa,OAAO,UAAU;CAC9B,YAAY,OAAO,UAAU;CAC7B,iBAAiB,OAAO,cAAc;CACtC,YAAY,OAAO,gBAAgB;CACnC,cAAc,OAAO,cAAc;CACnC,iBAAiB,OAAO,cAAc;CACpC,iBAAiB,OAAO,qBAAqB;CAC/C,iBAAiB,OAAO,cAAc;CACtC,eAAe,OAAO,eAAe,EAAE,UAAU,KAAI,CAAE;CACvD,qBAAqB,OAAO,6BAA6B,EACxE,UAAU,KACX,CAAA;CACgB,mBAAmB,OAAO,wBAAwB,EACjE,UAAU,KACX,CAAA;CACgB,oBAAoB,OAAO,0BAA0B,EACpE,UAAU,KACX,CAAA;CACgB,mBAAmB,OAAO,kBAAkB,EAC3D,UAAU,KACX,CAAA;CAEO,UACN,KACA,MAA8B;EAE9B,OAAO,KAAK,kBAAkB,UAAU,KAAK,IAAI,KAAK;CACxD;CAES,YAAY,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACzB,uBAAuB,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,uBAAA,CAAA,+BAAA,CAAA,CAAA;CACpC,uBAAuB,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,uBAAA,CAAA,+BAAA,CAAA,CAAA;CAC5B,qBAAqB,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CACxD,oBAAoB,KAAK,mBAAmB,WAAU;CAE9C,aAAa,OAA2B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CACnD,YAAY,KAAK,WAAW,WAAU;CAC9B,eAAe,OAA6B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CACvD,cAAc,KAAK,aAAa,WAAU;CAE1C,gBAAgB,eAAsC;EAC7D,IAAI,CAAC,KAAK,kBAAkB,kBAAkB,OAAO,CAAA;EACrD,OAAO,YAAY,KAAK,iBAAiB,iBAAgB,CAAE;CAC7D,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,iBAAiB,eAAoC;EAC5D,IAAI,CAAC,KAAK,kBAAkB,gBAAgB,OAAO,CAAA;EACnD,OAAO,YAAY,KAAK,iBAAiB,eAAc,CAAE;CAC3D,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,iBAAiB,eAAqC;EAC7D,IAAI,CAAC,KAAK,mBAAmB,gBAAgB,OAAO,CAAA;EACpD,OAAO,YAAY,KAAK,kBAAkB,eAAc,CAAE;CAC5D,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,kBAAkB,eAEvB,KAAK,cAAa,CAAE,CAAC,SAAS,KAC9B,KAAK,eAAc,CAAE,CAAC,SAAS,KAC/B,KAAK,eAAc,CAAE,CAAC,SAAS,GAClC,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAEQ,mBAAmB,OAAgC,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CACtD,2BAA2B,OAAgC,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,2BAAA,CAAA,+BAAA,CAAA,CAAA;CAC9D,mBAAmB,OAAgC,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAEtD,qBAAqB,eAAc;EAC1C,MAAM,UAAU,KAAK,iBAAgB;EACrC,MAAM,WAAW,KAAK,yBAAwB;EAC9C,OAAO,KAAK,UAAU,OAAO,MAAM,KAAK,UAAU,QAAQ;CAC5D,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,6BAA6B,eAAc;EAClD,IAAI,CAAC,KAAK,kBAAkB,qBAAqB,OAAO;EACxD,OAAO,KAAK,iBAAiB,oBAAoB,KAAK,iBAAgB,CAAE;CAC1E,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,6BAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,YAAY,eAAe,KAAK,UAAU,KAAI,CAAE,EAAE,SAAS,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAC9D,WAAW,eAAe,KAAK,UAAU,SAAQ,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CACpD,eAAe,eAAc;EAEpC,QADa,KAAK,UAAU,KAAI,CAAE,EAAE,QAAQ,GACrC,CACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,EAAE,CAAC,CAChB,KAAK,EAAE,CAAC,CACR,YAAW,CAAE,CACb,MAAM,GAAG,CAAC;CACf,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CACO,cAAc,eAAe,KAAK,UAAU,YAAW,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAC1D,aAAa,eAAe,KAAK,UAAU,WAAU,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAExD,oBAAoB,eAEzB,iBAAiB,KAAK,WAAW,SAAS,KAAK,KAAK,iBAAiB,MACxE,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CACQ,qBAAqB,eAC5B,wBAAwB,KAAK,SAAS,GACvC,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CACQ,yBAAyB,eAE9B,iBAAiB,KAAK,WAAW,KAAK,KACtC,KAAK,uBAAuB,MAC/B,GAAA,YAAA,CAAA,EAAA,WAAA,yBAAA,CAAA,+BAAA,CAAA,CAAA;CACQ,iBAAiB,eAAe,kBAAkB,KAAK,SAAS,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAClE,YAAY,eAAc;EACjC,MAAM,OAAO,KAAK,eAAc;EAChC,OAAO,SAAS,UAAU,SAAS;CACrC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACO,cAAc,eAAc;EACnC,MAAM,OAAO,KAAK,eAAc;EAChC,OAAO,SAAS,YAAY,SAAS;CACvC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CACO,gBAAgB,eACjB,KAAK,mBAAkB,KAAM,KAAK,uBAAsB,GAC/D,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAEgB,oBAAoB,OAA0B;EAC7D,MAAM;EACN,OAAO;CACR,GAAC,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CACO,YAAY,OAA0B;EAAE,MAAM;EAAI,OAAO;CAAE,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAE9D,WAAW,KAAK,KAAK,YAAY,MAAK;EAC7C,SAAS,EAAE,MAAM,EACf,SAAS,KAAK,UAAU,sBAAsB,EAC/C,CAAA;CACH,CAAC;CAEQ,cAAc,eACf,KAAK,UAAS,CAAE,CAAC,KAAK,KAAI,CAAE,CAAC,SAAS,GAC7C,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEQ,cAAc,eAAc;EACnC,MAAM,UAAU,KAAK,UAAS;EAC9B,MAAM,WAAW,KAAK,kBAAiB;EAGvC,OADE,QAAQ,SAAS,SAAS,QAAQ,QAAQ,UAAU,SAAS,SAC1C,KAAK,mBAAkB;CAC9C,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,iBAAiB,KAAa,OAAc;EAC1C,KAAK,iBAAiB,QAAQ,WAAW;GAAE,GAAG;IAAQ,MAAM;EAAK,EAAG;CACtE;CAEA,mBAAmB,KAAW;EAC5B,OAAO,KAAK,iBAAgB,CAAE,CAAC;CACjC;CAEA,mBAAmB,KAAW;EAC5B,OAAO,KAAK,iBAAgB,CAAE,CAAC;CACjC;CAEA,eACE,OACA,OAAc;EAEd,IAAI,CAAC,SAAS,CAAC,MAAM,SAAS,OAAO;EAErC,OADe,MAAM,QAAQ,MAAM,QAAQ,IAAI,UAAU,KAClD,CAAA,EAAQ,SAAS,OAAO,KAAK;CACtC;CAEA,wBACE,OAAyB;EAEzB,OAAO;GACL;GACA,OAAO,KAAK,iBAAgB,CAAE,CAAC,MAAM;GACrC,cAAc,UAAmB,KAAK,iBAAiB,MAAM,KAAK,KAAK;EACxE;CACH;CAEiB,iBAAiB,OAAO,QAAQ;CAEhC,iCAAiB,IAAI,IAAG;CAKzC,iBAAiB,OAAyB;EACxC,MAAM,SAAS,KAAK,eAAe,IAAI,MAAM,GAAG;EAChD,IAAI,QAAQ;GACV,OAAO,SAAS,KAAK;GACrB,OAAO,OAAO;EAChB;EAEA,IAAI,eAAe;EACnB,MAAM,mBAAmB,KAAK;EAY9B,MAAM,WAAW,SAAS,OAAO;GAC/B,WAAW,CAAC;IAAE,SAAS;IAAuB,UAAU;KAXxD,IAAI,QAAK;MACP,OAAO;KACT;KACA,IAAI,QAAK;MACP,OAAO,iBAAgB,CAAE,CAAC,aAAa;KACzC;KACA,cAAc,UACZ,KAAK,iBAAiB,aAAa,KAAK,KAAK;IAIS;GAAO,CAAE;GACjE,QAAQ,MAAM,YAAY,KAAK;EAChC,CAAA;EACD,KAAK,eAAe,IAAI,MAAM,KAAK;GACjC;GACA,WAAW,SAAU,eAAe;EACrC,CAAA;EACD,OAAO;CACT;CAES,gBAAgB,OAA2B;EAClD,iBAAiB;EACjB,aAAa;EACb,iBAAiB;CAClB,GAAC,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,eAAe,KAAK,KAAK,gBAAgB,MAAK;EACrD,SAAS,EAAE,iBAAiB,EAC1B,SAAS,KAAK,UAAU,uCAAuC,EAChE,CAAA;EACD,SAAS,EAAE,aAAa,EACtB,SAAS,KAAK,UAAU,mCAAmC,EAC5D,CAAA;CACH,CAAC;CAEQ,oBAAoB,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAEjC,mBAAmB,eAC1B,KAAK,eAAe,SAAS,KAAK,cAAa,CAAE,CAAC,WAAW,GAC9D,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAEQ,sBAAsB,eAAc;EAC3C,MAAM,QAAQ,KAAK,cAAa;EAChC,OACE,MAAM,gBAAgB,SAAS,KAC/B,MAAM,YAAY,SAAS,KAC3B,CAAC,KAAK,iBAAgB,KACtB,MAAM,gBAAgB,MAAM;CAEhC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,sBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,iBAAiB,eAAc;EACtC,MAAM,QAAQ,KAAK,cAAa;EAChC,OACE,MAAM,gBAAgB,WAAW,KACjC,MAAM,gBAAgB,MAAM;CAEhC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,uBAAuB;EAC9B,YAAY;EACZ,UAAU;EACV,UAAU;EACV,WAAW;EACX,WAAW;CACZ;CAED,cAAA;EACE,KAAK,aAAY;EAEjB,aAAY;GACV,IAAI,KAAK,uBAAsB,GAAI,KAAK,gBAAe;EACzD,CAAC;EAED,aAAY;GAEV,IADa,KAAK,UAAU,KACxB,KAAQ,KAAK,gBAAe,GAAI,KAAK,gBAAe;EAC1D,CAAC;CACH;CAEQ,eAAY;EAClB,MAAM,OAAO,KAAK,UAAU,KAAI;EAChC,IAAI,MAAM;GACR,MAAM,gBAAmC;IACvC,MAAM,KAAK,QAAQ;IACnB,OAAO,KAAK,SAAS;GACtB;GACD,KAAK,kBAAkB,IAAI,aAAa;GACxC,KAAK,UAAU,IAAI,aAAa;GAEhC,IACE,KAAK,oBACL,iBAAiB,KAAK,WAAW,SAAS,GAE1C,KAAK,eACF,mBAAmB,KAAK,gBAAgB,CAAC,CACzC,KAAK,mBAAmB,KAAK,UAAU,CAAC,CAAC,CACzC,WAAW,SAAS,KAAK,mBAAmB,IAAI,MAAM,OAAO,IAAI,CAAC;EAEzE;CACF;CAEQ,kBAAe;EACrB,MAAM,OAAO,KAAK,UAAU,KAAI;EAChC,MAAM,SAAS,KAAK,UAAU,OAAM;EAEpC,IAAI,CAAC,QAAQ,CAAC,KAAK,oBAAoB;EAEvC,MAAM,YAAY,KAAK,UAAS;EAChC,MAAM,cAAc,KAAK,YAAW;EAEpC,IAAI,CAAC,aAAa,CAAC,aAAa;EAEhC,KAAK,qBAAqB,IAAI,IAAI;EAElC,MAAM,SAAS,YACX,KAAK,mBACF,aAAa,KAAK,IAAI,QAAQ,EAAE,CAAC,CACjC,KAAK,iBAAiB,GAAG,EAAE,MAAM,CAAA,EAAwB,CAAE,CAAC,CAAC,IAChE,GAAG,EAAE,MAAM,CAAA,EAAwB,CAAE;EAEzC,MAAM,WAAW,cACb,KAAK,mBACF,eAAe,KAAK,IAAI,QAAQ,EAAE,CAAC,CACnC,KAAK,iBAAiB,GAAG,EAAE,MAAM,CAAA,EAA0B,CAAE,CAAC,CAAC,IAClE,GAAG,EAAE,MAAM,CAAA,EAA0B,CAAE;EAE3C,SAAS,CAAC,QAAQ,QAAQ,CAAC,CAAC,CACzB,KACC,mBAAmB,KAAK,UAAU,GAClC,eAAe,KAAK,qBAAqB,IAAI,KAAK,CAAC,CAAC,CACrD,CACA,WAAW,CAAC,eAAe,qBAAoB;GAC9C,KAAK,WAAW,IAAI,cAAc,QAAQ,CAAA,CAAE;GAC5C,KAAK,aAAa,IAAI,gBAAgB,QAAQ,CAAA,CAAE;EAClD,CAAC;CACL;CAEQ,kBAAe;EACrB,MAAM,OAAO,KAAK,UAAU,KAAI;EAChC,IAAI,CAAC,MAAM;EAEX,MAAM,mBAAmB,CAAC,CAAC,KAAK,kBAAkB;EAClD,MAAM,iBAAiB,CAAC,CAAC,KAAK,mBAAmB;EAEjD,IAAI,CAAC,oBAAoB,CAAC,gBAAgB;EAE1C,KAAK,qBAAqB,IAAI,IAAI;EAElC,MAAM,iBAAiB,mBACnB,KAAK,iBAAkB,oBAAqB,KAAK,EAAE,CAAC,CAAC,KACnD,iBAAgB;GACd,MAAM,WAAoC,CAAA;GAC1C,KAAK,MAAM,SAAS,KAAK,eAAc,GACrC,IAAI,MAAM,KAAK,SAAS,MAAM,OAAO;GAEvC,OAAO,GAAG,QAAQ;EACpB,CAAC,CAAC,IAEJ,GAAG,CAAA,CAA6B;EAEpC,MAAM,eAAe,iBACjB,KAAK,kBAAmB,oBAAqB,KAAK,EAAE,CAAC,CAAC,KACpD,iBAAgB;GACd,MAAM,WAAoC,CAAA;GAC1C,KAAK,MAAM,SAAS,KAAK,eAAc,GACrC,IAAI,MAAM,KAAK,SAAS,MAAM,OAAO;GAEvC,OAAO,GAAG,QAAQ;EACpB,CAAC,CAAC,IAEJ,GAAG,CAAA,CAA6B;EAEpC,SAAS,CAAC,gBAAgB,YAAY,CAAC,CAAC,CACrC,KACC,mBAAmB,KAAK,UAAU,GAClC,eAAe,KAAK,qBAAqB,IAAI,KAAK,CAAC,CAAC,CACrD,CACA,WAAW,CAAC,eAAe,iBAAgB;GAC1C,KAAK,iBAAiB,IAAI,aAAa;GACvC,KAAK,yBAAyB,IAAI,aAAa;GAC/C,KAAK,iBAAiB,IAAI,WAAW;EACvC,CAAC;CACL;CAEA,yBAAyB,MAMxB;EACC,MAAM,OAAO,KAAK,UAAU,KAAI;EAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI;EAEvB,MAAM,gBAAgB,KAAK;EAE3B,KAAK,YACF,cAAc;GAAE,IAAI,KAAK;GAAI,kBAAkB;EAAa,CAAE,CAAC,CAC/D,KAAK,mBAAmB,KAAK,UAAU,CAAC,CAAC,CACzC,UAAU;GACT,OAAO,aAAY;IACjB,IAAI,SAAS,WAAW,SAAS,MAAM;KACrC,KAAK,UAAU,QAAQ;MACrB,GAAG;MACH,kBAAkB;KACnB,CAAA;KACD,KAAK,eACF,mBAAmB,eAAe,IAAI,CAAC,CACvC,KAAK,mBAAmB,KAAK,UAAU,CAAC,CAAC,CACzC,WAAW,aACV,KAAK,mBAAmB,IAAI,UAAU,OAAO,IAAI,CAAC;KAEtD,KAAK,eAAe,IAAI;MACtB,UAAU;MACV,SAAS,KAAK,UAAU,gBAAgB;MACxC,QAAQ,SAAS,aACb,KAAK,UACH,SAAS,YACT,SAAS,gBAGR,IAEH,SAAS;KACd,CAAA;IACH;GACF;GACA,aAAY,CAAE;EACf,CAAA;CACL;CAEA,WAAQ;EACN,IAAI,CAAC,KAAK,YAAW,GAAI;EAEzB,MAAM,mBAAmB,KAAK,2BAA0B;EACxD,IAAI,kBAAkB;GACpB,KAAK,eAAe,IAAI;IACtB,UAAU;IACV,SAAS,KAAK,UAAU,yBAAyB;IACjD,QAAQ;GACT,CAAA;GACD;EACF;EAEA,MAAM,OAAO,KAAK,UAAU,KAAI;EAChC,IAAI,CAAC,MAAM;EAEX,KAAK,UAAU,IAAI,IAAI;EACvB,MAAM,QAAQ,KAAK,UAAS;EAE5B,MAAM,aAAiC;GACrC,IAAI,KAAK;GACT,MAAM,MAAM;GACZ,OAAO,MAAM,SAAS;EACvB;EAED,MAAM,iBAAiB,KAAK,YAAY,cAAc,UAAU;EAChE,MAAM,qBACJ,KAAK,mBAAkB,KAAM,KAAK,kBAAkB,uBAChD,KAAK,iBAAiB,qBACpB,KAAK,IACL,KAAK,iBAAgB,CAAE,IAEzB,GAAG,MAAS;EAElB,SAAS,CAAC,gBAAgB,kBAAkB,CAAC,CAAC,CAC3C,KACC,mBAAmB,KAAK,UAAU,GAClC,eAAe,KAAK,UAAU,IAAI,KAAK,CAAC,CAAC,CAC1C,CACA,UAAU;GACT,OAAO,CAAC,cAAa;IACnB,IAAI,SAAS,WAAW,SAAS,MAAM;KACrC,KAAK,UAAU,QAAQ;MACrB,GAAG;MACH,MAAM,SAAS,KAAK;MACpB,OAAO,SAAS,KAAK,SAAS;KAC/B,CAAA;KACD,KAAK,kBAAkB,IAAI;MACzB,MAAM,SAAS,KAAK;MACpB,OAAO,SAAS,KAAK,SAAS;KAC/B,CAAA;KACD,KAAK,yBAAyB,IAAI,EAAE,GAAG,KAAK,iBAAgB,EAAE,CAAE;KAChE,KAAK,eAAe,IAAI;MACtB,UAAU;MACV,SAAS,KAAK,UAAU,gBAAgB;MACxC,QAAQ,SAAS,aACb,KAAK,UACH,SAAS,YACT,SAAS,gBAGR,IAEH,SAAS;KACd,CAAA;IACH;GACF;GACA,aAAY,CAAE;EACf,CAAA;CACL;CAEA,oBAAoB,OAAiC,OAAa;EAChE,KAAK,cAAc,QAAQ,WAAW;GAAE,GAAG;IAAQ,QAAQ;EAAK,EAAG;CACrE;CAEA,mBAAgB;EACd,IAAI,CAAC,KAAK,oBAAmB,GAAI;EAEjC,KAAK,kBAAkB,IAAI,IAAI;EAC/B,MAAM,QAAQ,KAAK,cAAa;EAEhC,KAAK,eACF,eAAe;GACd,iBAAiB,MAAM;GACvB,aAAa,MAAM;EACpB,CAAA,CAAC,CACD,KACC,mBAAmB,KAAK,UAAU,GAClC,eAAe,KAAK,kBAAkB,IAAI,KAAK,CAAC,CAAC,CAClD,CACA,UAAU;GACT,OAAO,aAAY;IACjB,KAAK,eAAe,IAAI;KACtB,UAAU;KACV,SAAS,KAAK,UAAU,gBAAgB;KACxC,QAAQ,UAAU,aACd,KAAK,UAAU,SAAS,YAAY,SAAS,gBAAgB,IAC7D,UAAU;IACf,CAAA;IACD,KAAK,cAAc,IAAI;KACrB,iBAAiB;KACjB,aAAa;KACb,iBAAiB;IAClB,CAAA;GACH;GACA,aAAY,CAAE;EACf,CAAA;CACL;CAjhBW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAApB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAoB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UA5hBrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0hBT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MA5iBC;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,cAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAChB;IAAkB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAClB;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,UAAA,SAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAY,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACZ;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;GAAW;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,eAAA;IAAA,UAAA,CAAA,SAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;IAAA,QAAA,CAAA,eAAA;IAAA,SAAA,CAAA,UAAA;IAAA,UAAA,CAAA,QAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACX;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,UAAA,CAAA,mBAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAChB;IAAS,UAAA;IAAA,QAAA,CAAA,WAAA;IAAA,UAAA,CAAA,WAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACT;IAAqB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACrB;IAAsB,UAAA;IAAA,QAAA,CAAA,eAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACtB;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AA8hBJ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAoB,YAAA,CAAA;EAjjBhC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD;GACD,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2hBX,CAAA"}
@@ -242,7 +242,7 @@ var RegisterPageComponent = class RegisterPageComponent {
242
242
  }
243
243
  static ɵfac = i0.ɵɵngDeclareFactory({
244
244
  minVersion: "12.0.0",
245
- version: "22.2.2",
245
+ version: "22.2.3",
246
246
  ngImport: i0,
247
247
  type: RegisterPageComponent,
248
248
  deps: [],
@@ -250,7 +250,7 @@ var RegisterPageComponent = class RegisterPageComponent {
250
250
  });
251
251
  static ɵcmp = i0.ɵɵngDeclareComponent({
252
252
  minVersion: "17.0.0",
253
- version: "22.2.2",
253
+ version: "22.2.3",
254
254
  type: RegisterPageComponent,
255
255
  isStandalone: true,
256
256
  selector: "lib-register-page",
@@ -1006,7 +1006,7 @@ var RegisterPageComponent = class RegisterPageComponent {
1006
1006
  };
1007
1007
  i0.ɵɵngDeclareClassMetadata({
1008
1008
  minVersion: "12.0.0",
1009
- version: "22.2.2",
1009
+ version: "22.2.3",
1010
1010
  ngImport: i0,
1011
1011
  type: RegisterPageComponent,
1012
1012
  decorators: [{
@@ -1510,4 +1510,4 @@ i0.ɵɵngDeclareClassMetadata({
1510
1510
  });
1511
1511
  export { RegisterPageComponent };
1512
1512
 
1513
- //# sourceMappingURL=flusys-ng-auth-register-page.component-B0me9tCm.mjs.map
1513
+ //# sourceMappingURL=flusys-ng-auth-register-page.component-Cb-ycJHR.mjs.map