@keycloakify/angular 0.0.1-rc.7 → 0.0.1-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/login/components/user-profile-form-fields/user-profile-form-fields.component.d.ts +1 -0
  2. package/login/components/user-profile-form-fields/user-profile-form-fields.component.js +8 -5
  3. package/login/pages/idp-review-user-profile/idp-review-user-profile.component.d.ts +5 -8
  4. package/login/pages/idp-review-user-profile/idp-review-user-profile.component.js +16 -20
  5. package/login/pages/login-update-profile/login-update-profile.component.d.ts +6 -1
  6. package/login/pages/login-update-profile/login-update-profile.component.js +17 -9
  7. package/login/pages/register/register.component.d.ts +6 -1
  8. package/login/pages/register/register.component.js +17 -10
  9. package/login/pages/update-email/update-email.component.d.ts +6 -1
  10. package/login/pages/update-email/update-email.component.js +17 -9
  11. package/login/providers/keycloakify-angular.providers.d.ts +0 -1
  12. package/login/providers/keycloakify-angular.providers.js +2 -7
  13. package/login/services/submit.service.d.ts +9 -0
  14. package/login/services/submit.service.js +20 -0
  15. package/package.json +4 -4
  16. package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.html +0 -3
  17. package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.ts +9 -4
  18. package/src/login/pages/idp-review-user-profile/idp-review-user-profile.component.html +2 -2
  19. package/src/login/pages/idp-review-user-profile/idp-review-user-profile.component.ts +12 -19
  20. package/src/login/pages/login-update-profile/login-update-profile.component.html +2 -3
  21. package/src/login/pages/login-update-profile/login-update-profile.component.ts +14 -2
  22. package/src/login/pages/register/register.component.html +2 -2
  23. package/src/login/pages/register/register.component.ts +14 -3
  24. package/src/login/pages/update-email/update-email.component.html +2 -2
  25. package/src/login/pages/update-email/update-email.component.ts +15 -2
  26. package/src/login/providers/keycloakify-angular.providers.ts +1 -7
  27. package/src/login/services/submit.service.ts +12 -0
  28. package/login/tokens/user-profile-form-fields-ejected-path.token.d.ts +0 -2
  29. package/login/tokens/user-profile-form-fields-ejected-path.token.js +0 -3
  30. package/src/login/tokens/user-profile-form-fields-ejected-path.token.ts +0 -3
@@ -1,5 +1,6 @@
1
- import { AsyncPipe, NgComponentOutlet } from '@angular/common';
2
- import { AfterContentInit, ChangeDetectionStrategy, Component, ContentChild, forwardRef, inject, input, signal, Type } from '@angular/core';
1
+ import { NgComponentOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
4
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
4
5
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
5
6
  import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields/user-profile-form-fields.component';
@@ -8,15 +9,14 @@ import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class
8
9
  import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes.token';
9
10
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n.token';
10
11
  import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.token';
11
- import { USER_PROFILE_FORM_FIELDS_EJECTED_PATH } from '@keycloakify/angular/login/tokens/user-profile-form-fields-ejected-path.token';
12
12
  import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
13
- import { from, Observable, tap } from 'rxjs';
14
13
  import { type I18n } from '../../i18n';
15
14
  import { type KcContext } from '../../KcContext';
15
+ import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
16
16
 
17
17
  @Component({
18
18
  standalone: true,
19
- imports: [TemplateComponent, KcClassDirective, NgComponentOutlet, AsyncPipe],
19
+ imports: [TemplateComponent, KcClassDirective, NgComponentOutlet],
20
20
  selector: 'kc-root',
21
21
  templateUrl: 'idp-review-user-profile.component.html',
22
22
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -27,8 +27,8 @@ import { type KcContext } from '../../KcContext';
27
27
  }
28
28
  ]
29
29
  })
30
- export class IdpReviewUserProfileComponent extends ComponentReference implements AfterContentInit {
31
- @ContentChild(UserProfileFormFieldsComponent, { descendants: true }) userProfileFormFields: UserProfileFormFieldsComponent | undefined;
30
+ export class IdpReviewUserProfileComponent extends ComponentReference {
31
+ #submitService = inject(SubmitService);
32
32
 
33
33
  kcContext = inject<Extract<KcContext, { pageId: 'idp-review-user-profile.ftl' }>>(KC_LOGIN_CONTEXT);
34
34
  displayRequiredFields = input(true);
@@ -41,20 +41,13 @@ export class IdpReviewUserProfileComponent extends ComponentReference implements
41
41
  displayInfo: boolean = false;
42
42
  displayMessage: boolean = !this.kcContext?.messagesPerField?.existsError('global');
43
43
 
44
- userProfileFormFieldsComponent: Observable<Type<UserProfileFormFieldsComponent> | null>;
45
- userProfileFormFieldsEjectedPath = inject<string | undefined>(USER_PROFILE_FORM_FIELDS_EJECTED_PATH);
44
+ userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
45
+
46
46
  constructor() {
47
47
  super();
48
- this.userProfileFormFieldsComponent = from(
49
- import(/* @vite-ignore */
50
- this.userProfileFormFieldsEjectedPath ??
51
- '../../components/user-profile-form-fields/user-profile-form-fields.component'
52
- ).then(c => c.UserProfileFormFieldsComponent)
53
- );
54
- }
55
-
56
- ngAfterContentInit(): void {
57
- this.userProfileFormFields?.onIsFormSubmittable?.subscribe(submittable => this.isFormSubmittable.set(submittable));
48
+ this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
49
+ this.isFormSubmittable.set(submittable);
50
+ });
58
51
  }
59
52
 
60
53
  onCallback() {
@@ -17,8 +17,7 @@
17
17
  [action]="url.loginAction"
18
18
  method="post"
19
19
  >
20
- <kc-user-profile-form-fields (onIsFormSubmittable)="isFormSubmittable.set($event)"></kc-user-profile-form-fields>
21
-
20
+ <ng-container [ngComponentOutlet]="userProfileFormFields() ?? null"></ng-container>
22
21
  <div [kcClass]="'kcFormGroupClass'">
23
22
  <div
24
23
  id="kc-form-options"
@@ -31,7 +30,7 @@
31
30
  [kcClass]="'kcFormButtonsClass'"
32
31
  >
33
32
  <input
34
- [disabled]="!isFormSubmittable"
33
+ [disabled]="!isFormSubmittable()"
35
34
  [kcClass]="{
36
35
  kcButtonClass: true,
37
36
  kcButtonPrimaryClass: true,
@@ -1,4 +1,6 @@
1
- import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal } from '@angular/core';
1
+ import { NgComponentOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
4
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
3
5
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
4
6
  import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields/user-profile-form-fields.component';
@@ -10,10 +12,11 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.t
10
12
  import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
11
13
  import { type I18n } from '../../i18n';
12
14
  import { type KcContext } from '../../KcContext';
15
+ import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
13
16
 
14
17
  @Component({
15
18
  standalone: true,
16
- imports: [TemplateComponent, KcClassDirective, UserProfileFormFieldsComponent],
19
+ imports: [TemplateComponent, KcClassDirective, NgComponentOutlet],
17
20
  selector: 'kc-root',
18
21
  templateUrl: 'login-update-profile.component.html',
19
22
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -25,6 +28,7 @@ import { type KcContext } from '../../KcContext';
25
28
  ]
26
29
  })
27
30
  export class LoginUpdateProfileComponent extends ComponentReference {
31
+ #submitService = inject(SubmitService);
28
32
  kcContext = inject<Extract<KcContext, { pageId: 'login-update-profile.ftl' }>>(KC_LOGIN_CONTEXT);
29
33
  i18n = inject<I18n>(LOGIN_I18N);
30
34
  override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
@@ -36,4 +40,12 @@ export class LoginUpdateProfileComponent extends ComponentReference {
36
40
  displayMessage: boolean = this.kcContext.messagesPerField.exists('global');
37
41
 
38
42
  isFormSubmittable = signal(false);
43
+
44
+ userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
45
+ constructor() {
46
+ super();
47
+ this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
48
+ this.isFormSubmittable.set(submittable);
49
+ });
50
+ }
39
51
  }
@@ -24,7 +24,7 @@
24
24
  [action]="url.registrationAction"
25
25
  method="post"
26
26
  >
27
- <kc-user-profile-form-fields (onIsFormSubmittable)="isFormSubmittable.set($event)"></kc-user-profile-form-fields>
27
+ <ng-container [ngComponentOutlet]="userProfileFormFields() ?? null"></ng-container>
28
28
  @if (termsAcceptanceRequired) {
29
29
  <div className="form-group">
30
30
  <div [kcClass]="'kcInputWrapperClass'">
@@ -113,7 +113,7 @@
113
113
  [kcClass]="'kcFormButtonsClass'"
114
114
  >
115
115
  <input
116
- [disabled]="!isFormSubmittable || (termsAcceptanceRequired && !areTermsAccepted)"
116
+ [disabled]="!isFormSubmittable() || (termsAcceptanceRequired && !areTermsAccepted())"
117
117
  [kcClass]="['kcButtonClass', 'kcButtonPrimaryClass', 'kcButtonBlockClass', 'kcButtonLargeClass']"
118
118
  type="submit"
119
119
  [value]="i18n.msgStr('doRegister')"
@@ -1,5 +1,6 @@
1
- import { AsyncPipe, NgClass } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal } from '@angular/core';
1
+ import { AsyncPipe, NgClass, NgComponentOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
4
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
4
5
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
5
6
  import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields/user-profile-form-fields.component';
@@ -12,13 +13,14 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.t
12
13
  import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
13
14
  import { type I18n } from '../../i18n';
14
15
  import { type KcContext } from '../../KcContext';
16
+ import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
15
17
 
16
18
  @Component({
17
19
  selector: 'kc-root',
18
20
  templateUrl: './register.component.html',
19
21
  standalone: true,
20
22
  changeDetection: ChangeDetectionStrategy.OnPush,
21
- imports: [KcClassDirective, AsyncPipe, KcSanitizePipe, NgClass, TemplateComponent, UserProfileFormFieldsComponent],
23
+ imports: [KcClassDirective, AsyncPipe, KcSanitizePipe, NgClass, TemplateComponent, NgComponentOutlet],
22
24
  providers: [
23
25
  {
24
26
  provide: ComponentReference,
@@ -27,6 +29,7 @@ import { type KcContext } from '../../KcContext';
27
29
  ]
28
30
  })
29
31
  export class RegisterComponent extends ComponentReference {
32
+ #submitService = inject(SubmitService);
30
33
  kcContext = inject<Extract<KcContext, { pageId: 'register.ftl' }>>(KC_LOGIN_CONTEXT);
31
34
  displayRequiredFields = input(false);
32
35
  documentTitle = input<string>();
@@ -39,6 +42,14 @@ export class RegisterComponent extends ComponentReference {
39
42
  displayInfo: boolean = false;
40
43
  displayMessage: boolean = !this.kcContext?.messagesPerField?.existsError('global');
41
44
 
45
+ userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
46
+
47
+ constructor() {
48
+ super();
49
+ this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
50
+ this.isFormSubmittable.set(submittable);
51
+ });
52
+ }
42
53
  onCallback() {
43
54
  (document.getElementById('kc-register-form') as HTMLFormElement).submit();
44
55
  }
@@ -17,7 +17,7 @@
17
17
  [action]="url.loginAction"
18
18
  method="post"
19
19
  >
20
- <kc-user-profile-form-fields (onIsFormSubmittable)="isFormSubmittable.set($event)"></kc-user-profile-form-fields>
20
+ <ng-container [ngComponentOutlet]="userProfileFormFields() ?? null"></ng-container>
21
21
  <div [kcClass]="'kcFormGroupClass'">
22
22
  <div
23
23
  id="kc-form-options"
@@ -31,7 +31,7 @@
31
31
  [kcClass]="'kcFormButtonsClass'"
32
32
  >
33
33
  <input
34
- [disabled]="!isFormSubmittable"
34
+ [disabled]="!isFormSubmittable()"
35
35
  [kcClass]="{
36
36
  kcButtonClass: true,
37
37
  kcButtonPrimaryClass: true,
@@ -1,4 +1,6 @@
1
- import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal } from '@angular/core';
1
+ import { NgComponentOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
4
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
3
5
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
4
6
  import { LogoutOtherSessionsComponent } from '@keycloakify/angular/login/components/logout-other-sessions/logout-other-sessions.component';
@@ -11,10 +13,11 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.t
11
13
  import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
12
14
  import { type I18n } from '../../i18n';
13
15
  import { type KcContext } from '../../KcContext';
16
+ import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
14
17
 
15
18
  @Component({
16
19
  standalone: true,
17
- imports: [TemplateComponent, KcClassDirective, UserProfileFormFieldsComponent, LogoutOtherSessionsComponent],
20
+ imports: [TemplateComponent, KcClassDirective, NgComponentOutlet, LogoutOtherSessionsComponent],
18
21
  selector: 'kc-root',
19
22
  templateUrl: 'update-email.component.html',
20
23
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -26,6 +29,7 @@ import { type KcContext } from '../../KcContext';
26
29
  ]
27
30
  })
28
31
  export class UpdateEmailComponent extends ComponentReference {
32
+ #submitService = inject(SubmitService);
29
33
  kcContext = inject<Extract<KcContext, { pageId: 'update-email.ftl' }>>(KC_LOGIN_CONTEXT);
30
34
  i18n = inject<I18n>(LOGIN_I18N);
31
35
  override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
@@ -36,4 +40,13 @@ export class UpdateEmailComponent extends ComponentReference {
36
40
  displayInfo: boolean = false;
37
41
  displayMessage: boolean = this.kcContext.messagesPerField.exists('global');
38
42
  isFormSubmittable = signal(false);
43
+
44
+ userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
45
+
46
+ constructor() {
47
+ super();
48
+ this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
49
+ this.isFormSubmittable.set(submittable);
50
+ });
51
+ }
39
52
  }
@@ -5,7 +5,6 @@ import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes.token';
5
5
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n.token';
6
6
  import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.token';
7
7
  import { DO_MAKE_USER_CONFIRM_PASSWORD } from '@keycloakify/angular/login/tokens/make-user-confirm-password.token';
8
- import { USER_PROFILE_FORM_FIELDS_EJECTED_PATH } from '@keycloakify/angular/login/tokens/user-profile-form-fields-ejected-path.token';
9
8
  import { type KcContextLike } from 'keycloakify/login/i18n/noJsx';
10
9
  import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
11
10
  import { type KcContext } from '../KcContext';
@@ -15,7 +14,6 @@ export type KeycloakifyAngularLoginConfig = {
15
14
  doMakeUserConfirmPassword?: boolean;
16
15
  doUseDefaultCss?: boolean;
17
16
  classes?: { [key in ClassKey]?: string };
18
- userProfileFormFieldsEjectedPath?: string;
19
17
  getI18n: (params: { kcContext: KcContextLike }) => {
20
18
  i18n: unknown;
21
19
  prI18n_currentLanguage: Promise<unknown> | undefined;
@@ -66,9 +64,5 @@ export const provideKeycloakifyAngularLogin = (config: KeycloakifyAngularLoginCo
66
64
  deps: [I18nService]
67
65
  },
68
66
  { provide: USE_DEFAULT_CSS, useValue: config?.doUseDefaultCss ?? true },
69
- { provide: LOGIN_CLASSES, useValue: config?.classes ?? {} },
70
- {
71
- provide: USER_PROFILE_FORM_FIELDS_EJECTED_PATH,
72
- useValue: config.userProfileFormFieldsEjectedPath
73
- }
67
+ { provide: LOGIN_CLASSES, useValue: config?.classes ?? {} }
74
68
  ]);
@@ -0,0 +1,12 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Observable, BehaviorSubject } from 'rxjs';
3
+
4
+ @Injectable({ providedIn: 'root' })
5
+ export class SubmitService {
6
+ #submittableSubj: BehaviorSubject<boolean> = new BehaviorSubject(false);
7
+ isSubmittable: Observable<boolean> = this.#submittableSubj.asObservable();
8
+
9
+ setIsSubmittable(submittable: boolean) {
10
+ this.#submittableSubj.next(submittable);
11
+ }
12
+ }
@@ -1,2 +0,0 @@
1
- import { InjectionToken } from "@angular/core";
2
- export declare const USER_PROFILE_FORM_FIELDS_EJECTED_PATH: InjectionToken<string>;
@@ -1,3 +0,0 @@
1
- import { InjectionToken } from "@angular/core";
2
- export const USER_PROFILE_FORM_FIELDS_EJECTED_PATH = new InjectionToken('profile form fields ejected path');
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wcm9maWxlLWZvcm0tZmllbGRzLWVqZWN0ZWQtcGF0aC50b2tlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tleWNsb2FraWZ5LWFuZ3VsYXIvc3JjL2xvZ2luL3Rva2Vucy91c2VyLXByb2ZpbGUtZm9ybS1maWVsZHMtZWplY3RlZC1wYXRoLnRva2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFL0MsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUcsSUFBSSxjQUFjLENBQVMsa0NBQWtDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuZXhwb3J0IGNvbnN0IFVTRVJfUFJPRklMRV9GT1JNX0ZJRUxEU19FSkVDVEVEX1BBVEggPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPigncHJvZmlsZSBmb3JtIGZpZWxkcyBlamVjdGVkIHBhdGgnKSJdfQ==
@@ -1,3 +0,0 @@
1
- import { InjectionToken } from "@angular/core";
2
-
3
- export const USER_PROFILE_FORM_FIELDS_EJECTED_PATH = new InjectionToken<string>('profile form fields ejected path')