@keycloakify/angular 0.0.3 → 0.0.5

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 (182) hide show
  1. package/README.md +2 -5
  2. package/account/DefaultPage/DefaultPage.d.ts +2 -30
  3. package/esm2022/account/containers/template/template.component.mjs +6 -6
  4. package/esm2022/account/directives/kc-class/kc-class.directive.mjs +3 -3
  5. package/esm2022/account/pages/account/account.component.mjs +3 -3
  6. package/esm2022/account/pages/applications/applications.component.mjs +3 -3
  7. package/esm2022/account/pages/federatedIdentity/federatedIdentity.component.mjs +3 -3
  8. package/esm2022/account/pages/log/log.component.mjs +3 -3
  9. package/esm2022/account/pages/password/password.component.mjs +3 -3
  10. package/esm2022/account/pages/sessions/sessions.component.mjs +3 -3
  11. package/esm2022/account/pages/totp/totp.component.mjs +3 -3
  12. package/esm2022/account/services/account-resource-injector/account-resource-injector.service.mjs +3 -3
  13. package/esm2022/account/services/i18n/i18n.service.mjs +3 -3
  14. package/esm2022/lib/directives/attributes/attributes.directive.mjs +3 -3
  15. package/esm2022/lib/pipes/input-type/input-type.pipe.mjs +3 -3
  16. package/esm2022/lib/pipes/is-array-with-empty-object/is-array-with-empty-object.pipe.mjs +3 -3
  17. package/esm2022/lib/pipes/kc-sanitize/kc-sanitize.pipe.mjs +3 -3
  18. package/esm2022/lib/pipes/to-array/to-array.pipe.mjs +3 -3
  19. package/esm2022/lib/pipes/to-number/to-number.pipe.mjs +3 -3
  20. package/esm2022/lib/services/resource-injector/resource-injector.service.mjs +6 -5
  21. package/esm2022/login/components/add-remove-buttons-multi-valued-attribute/add-remove-buttons-multi-valued-attribute.component.mjs +7 -53
  22. package/esm2022/login/components/field-errors/field-errors.component.mjs +3 -3
  23. package/esm2022/login/components/group-label/group-label.component.mjs +3 -3
  24. package/esm2022/login/components/input-field-by-type/input-field-by-type.component.mjs +3 -3
  25. package/esm2022/login/components/input-tag/input-tag.component.mjs +3 -3
  26. package/esm2022/login/components/input-tag-selects/input-tag-selects.component.mjs +3 -3
  27. package/esm2022/login/components/logout-other-sessions/logout-other-sessions.component.mjs +3 -3
  28. package/esm2022/login/components/password-wrapper/password-wrapper.component.mjs +3 -3
  29. package/esm2022/login/components/select-tag/select-tag.component.mjs +3 -3
  30. package/esm2022/login/components/textarea-tag/textarea-tag.component.mjs +3 -3
  31. package/esm2022/login/components/user-profile-form-fields/user-profile-form-fields.component.mjs +15 -22
  32. package/esm2022/login/containers/template/template.component.mjs +6 -6
  33. package/esm2022/login/directives/kc-class/kc-class.directive.mjs +3 -3
  34. package/esm2022/login/pages/code/code.component.mjs +3 -3
  35. package/esm2022/login/pages/delete-account-confirm/delete-account-confirm.component.mjs +3 -3
  36. package/esm2022/login/pages/delete-credential/delete-credential.component.mjs +3 -3
  37. package/esm2022/login/pages/error/error.component.mjs +3 -3
  38. package/esm2022/login/pages/frontchannel-logout/frontchannel-logout.component.mjs +3 -3
  39. package/esm2022/login/pages/idp-review-user-profile/idp-review-user-profile.component.mjs +13 -15
  40. package/esm2022/login/pages/info/info.component.mjs +3 -3
  41. package/esm2022/login/pages/login/login.component.mjs +3 -3
  42. package/esm2022/login/pages/login-config-totp/login-config-totp.component.mjs +3 -3
  43. package/esm2022/login/pages/login-idp-link-confirm/login-idp-link-confirm.component.mjs +3 -3
  44. package/esm2022/login/pages/login-idp-link-confirm-override/login-idp-link-confirm-override.component.mjs +3 -3
  45. package/esm2022/login/pages/login-idp-link-email/login-idp-link-email.component.mjs +3 -3
  46. package/esm2022/login/pages/login-oauth-grant/login-oauth-grant.component.mjs +3 -3
  47. package/esm2022/login/pages/login-oauth2-device-verify-user-code/login-oauth2-device-verify-user-code.component.mjs +3 -3
  48. package/esm2022/login/pages/login-otp/login-otp.component.mjs +3 -3
  49. package/esm2022/login/pages/login-page-expired/login-page-expired.component.mjs +3 -3
  50. package/esm2022/login/pages/login-passkeys-conditional-authenticate/login-passkeys-conditional-authenticate.component.mjs +3 -3
  51. package/esm2022/login/pages/login-password/login-password.component.mjs +3 -3
  52. package/esm2022/login/pages/login-recovery-authn-code-config/login-recovery-authn-code-config.component.mjs +3 -3
  53. package/esm2022/login/pages/login-recovery-authn-code-input/login-recovery-authn-code-input.component.mjs +3 -3
  54. package/esm2022/login/pages/login-reset-otp/login-reset-otp.component.mjs +3 -3
  55. package/esm2022/login/pages/login-reset-password/login-reset-password.component.mjs +3 -3
  56. package/esm2022/login/pages/login-update-password/login-update-password.component.mjs +3 -3
  57. package/esm2022/login/pages/login-update-profile/login-update-profile.component.mjs +13 -15
  58. package/esm2022/login/pages/login-username/login-username.component.mjs +6 -6
  59. package/esm2022/login/pages/login-verify-email/login-verify-email.component.mjs +3 -3
  60. package/esm2022/login/pages/login-x509-info/login-x509-info.component.mjs +3 -3
  61. package/esm2022/login/pages/logout-confirm/logout-confirm.component.mjs +3 -3
  62. package/esm2022/login/pages/register/register.component.mjs +14 -16
  63. package/esm2022/login/pages/saml-post-form/saml-post-form.component.mjs +3 -3
  64. package/esm2022/login/pages/select-authenticator/select-authenticator.component.mjs +3 -3
  65. package/esm2022/login/pages/terms/terms.component.mjs +3 -3
  66. package/esm2022/login/pages/update-email/update-email.component.mjs +13 -15
  67. package/esm2022/login/pages/webauthn-authenticate/webauthn-authenticate.component.mjs +3 -3
  68. package/esm2022/login/pages/webauthn-error/webauthn-error.component.mjs +3 -3
  69. package/esm2022/login/pages/webauthn-register/webauthn-register.component.mjs +3 -3
  70. package/esm2022/login/services/i18n/i18n.service.mjs +3 -3
  71. package/esm2022/login/services/login-resource-injector/login-resource-injector.service.mjs +9 -8
  72. package/esm2022/login/services/user-profile-form/user-profile-form.service.mjs +56 -1004
  73. package/fesm2022/keycloakify-angular-account-containers-template.mjs +6 -6
  74. package/fesm2022/keycloakify-angular-account-directives-kc-class.mjs +3 -3
  75. package/fesm2022/keycloakify-angular-account-pages-account.mjs +3 -3
  76. package/fesm2022/keycloakify-angular-account-pages-applications.mjs +3 -3
  77. package/fesm2022/keycloakify-angular-account-pages-federatedIdentity.mjs +3 -3
  78. package/fesm2022/keycloakify-angular-account-pages-log.mjs +3 -3
  79. package/fesm2022/keycloakify-angular-account-pages-password.mjs +3 -3
  80. package/fesm2022/keycloakify-angular-account-pages-sessions.mjs +3 -3
  81. package/fesm2022/keycloakify-angular-account-pages-totp.mjs +3 -3
  82. package/fesm2022/keycloakify-angular-account-services-account-resource-injector.mjs +3 -3
  83. package/fesm2022/keycloakify-angular-account-services-i18n.mjs +3 -3
  84. package/fesm2022/keycloakify-angular-lib-directives-attributes.mjs +3 -3
  85. package/fesm2022/keycloakify-angular-lib-pipes-input-type.mjs +3 -3
  86. package/fesm2022/keycloakify-angular-lib-pipes-is-array-with-empty-object.mjs +3 -3
  87. package/fesm2022/keycloakify-angular-lib-pipes-kc-sanitize.mjs +3 -3
  88. package/fesm2022/keycloakify-angular-lib-pipes-to-array.mjs +3 -3
  89. package/fesm2022/keycloakify-angular-lib-pipes-to-number.mjs +3 -3
  90. package/fesm2022/keycloakify-angular-lib-services-resource-injector.mjs +5 -4
  91. package/fesm2022/keycloakify-angular-lib-services-resource-injector.mjs.map +1 -1
  92. package/fesm2022/keycloakify-angular-login-components-add-remove-buttons-multi-valued-attribute.mjs +6 -52
  93. package/fesm2022/keycloakify-angular-login-components-add-remove-buttons-multi-valued-attribute.mjs.map +1 -1
  94. package/fesm2022/keycloakify-angular-login-components-field-errors.mjs +3 -3
  95. package/fesm2022/keycloakify-angular-login-components-group-label.mjs +3 -3
  96. package/fesm2022/keycloakify-angular-login-components-input-field-by-type.mjs +3 -3
  97. package/fesm2022/keycloakify-angular-login-components-input-tag-selects.mjs +3 -3
  98. package/fesm2022/keycloakify-angular-login-components-input-tag.mjs +3 -3
  99. package/fesm2022/keycloakify-angular-login-components-logout-other-sessions.mjs +3 -3
  100. package/fesm2022/keycloakify-angular-login-components-password-wrapper.mjs +3 -3
  101. package/fesm2022/keycloakify-angular-login-components-select-tag.mjs +3 -3
  102. package/fesm2022/keycloakify-angular-login-components-textarea-tag.mjs +3 -3
  103. package/fesm2022/keycloakify-angular-login-components-user-profile-form-fields.mjs +14 -21
  104. package/fesm2022/keycloakify-angular-login-components-user-profile-form-fields.mjs.map +1 -1
  105. package/fesm2022/keycloakify-angular-login-containers-template.mjs +6 -6
  106. package/fesm2022/keycloakify-angular-login-directives-kc-class.mjs +3 -3
  107. package/fesm2022/keycloakify-angular-login-pages-code.mjs +3 -3
  108. package/fesm2022/keycloakify-angular-login-pages-delete-account-confirm.mjs +3 -3
  109. package/fesm2022/keycloakify-angular-login-pages-delete-credential.mjs +3 -3
  110. package/fesm2022/keycloakify-angular-login-pages-error.mjs +3 -3
  111. package/fesm2022/keycloakify-angular-login-pages-frontchannel-logout.mjs +3 -3
  112. package/fesm2022/keycloakify-angular-login-pages-idp-review-user-profile.mjs +12 -14
  113. package/fesm2022/keycloakify-angular-login-pages-idp-review-user-profile.mjs.map +1 -1
  114. package/fesm2022/keycloakify-angular-login-pages-info.mjs +3 -3
  115. package/fesm2022/keycloakify-angular-login-pages-login-config-totp.mjs +3 -3
  116. package/fesm2022/keycloakify-angular-login-pages-login-idp-link-confirm-override.mjs +3 -3
  117. package/fesm2022/keycloakify-angular-login-pages-login-idp-link-confirm.mjs +3 -3
  118. package/fesm2022/keycloakify-angular-login-pages-login-idp-link-email.mjs +3 -3
  119. package/fesm2022/keycloakify-angular-login-pages-login-oauth-grant.mjs +3 -3
  120. package/fesm2022/keycloakify-angular-login-pages-login-oauth2-device-verify-user-code.mjs +3 -3
  121. package/fesm2022/keycloakify-angular-login-pages-login-otp.mjs +3 -3
  122. package/fesm2022/keycloakify-angular-login-pages-login-page-expired.mjs +3 -3
  123. package/fesm2022/keycloakify-angular-login-pages-login-passkeys-conditional-authenticate.mjs +3 -3
  124. package/fesm2022/keycloakify-angular-login-pages-login-password.mjs +3 -3
  125. package/fesm2022/keycloakify-angular-login-pages-login-recovery-authn-code-config.mjs +3 -3
  126. package/fesm2022/keycloakify-angular-login-pages-login-recovery-authn-code-input.mjs +3 -3
  127. package/fesm2022/keycloakify-angular-login-pages-login-reset-otp.mjs +3 -3
  128. package/fesm2022/keycloakify-angular-login-pages-login-reset-password.mjs +3 -3
  129. package/fesm2022/keycloakify-angular-login-pages-login-update-password.mjs +3 -3
  130. package/fesm2022/keycloakify-angular-login-pages-login-update-profile.mjs +12 -14
  131. package/fesm2022/keycloakify-angular-login-pages-login-update-profile.mjs.map +1 -1
  132. package/fesm2022/keycloakify-angular-login-pages-login-username.mjs +5 -5
  133. package/fesm2022/keycloakify-angular-login-pages-login-username.mjs.map +1 -1
  134. package/fesm2022/keycloakify-angular-login-pages-login-verify-email.mjs +3 -3
  135. package/fesm2022/keycloakify-angular-login-pages-login-x509-info.mjs +3 -3
  136. package/fesm2022/keycloakify-angular-login-pages-login.mjs +3 -3
  137. package/fesm2022/keycloakify-angular-login-pages-logout-confirm.mjs +3 -3
  138. package/fesm2022/keycloakify-angular-login-pages-register.mjs +13 -15
  139. package/fesm2022/keycloakify-angular-login-pages-register.mjs.map +1 -1
  140. package/fesm2022/keycloakify-angular-login-pages-saml-post-form.mjs +3 -3
  141. package/fesm2022/keycloakify-angular-login-pages-select-authenticator.mjs +3 -3
  142. package/fesm2022/keycloakify-angular-login-pages-terms.mjs +3 -3
  143. package/fesm2022/keycloakify-angular-login-pages-update-email.mjs +12 -14
  144. package/fesm2022/keycloakify-angular-login-pages-update-email.mjs.map +1 -1
  145. package/fesm2022/keycloakify-angular-login-pages-webauthn-authenticate.mjs +3 -3
  146. package/fesm2022/keycloakify-angular-login-pages-webauthn-error.mjs +3 -3
  147. package/fesm2022/keycloakify-angular-login-pages-webauthn-register.mjs +3 -3
  148. package/fesm2022/keycloakify-angular-login-services-i18n.mjs +3 -3
  149. package/fesm2022/keycloakify-angular-login-services-login-resource-injector.mjs +8 -7
  150. package/fesm2022/keycloakify-angular-login-services-login-resource-injector.mjs.map +1 -1
  151. package/fesm2022/keycloakify-angular-login-services-user-profile-form.mjs +55 -1003
  152. package/fesm2022/keycloakify-angular-login-services-user-profile-form.mjs.map +1 -1
  153. package/login/components/add-remove-buttons-multi-valued-attribute/add-remove-buttons-multi-valued-attribute.component.d.ts +0 -1
  154. package/login/components/user-profile-form-fields/user-profile-form-fields.component.d.ts +3 -13
  155. package/login/pages/idp-review-user-profile/idp-review-user-profile.component.d.ts +1 -2
  156. package/login/pages/login-update-profile/login-update-profile.component.d.ts +1 -2
  157. package/login/pages/register/register.component.d.ts +1 -2
  158. package/login/pages/update-email/update-email.component.d.ts +1 -2
  159. package/login/services/user-profile-form/user-profile-form.service.d.ts +20 -41
  160. package/package.json +2 -8
  161. package/src/lib/services/resource-injector/resource-injector.service.ts +2 -1
  162. package/src/login/components/add-remove-buttons-multi-valued-attribute/add-remove-buttons-multi-valued-attribute.component.ts +3 -69
  163. package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.html +71 -68
  164. package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.ts +6 -21
  165. package/src/login/pages/idp-review-user-profile/idp-review-user-profile.component.ts +6 -13
  166. package/src/login/pages/login-update-profile/login-update-profile.component.ts +6 -12
  167. package/src/login/pages/login-username/login-username.component.html +0 -1
  168. package/src/login/pages/register/register.component.html +1 -4
  169. package/src/login/pages/register/register.component.ts +5 -10
  170. package/src/login/pages/update-email/update-email.component.ts +6 -12
  171. package/src/login/services/login-resource-injector/login-resource-injector.service.ts +5 -4
  172. package/src/login/services/user-profile-form/user-profile-form.service.ts +103 -1433
  173. package/esm2022/login/services/submit/keycloakify-angular-login-services-submit.mjs +0 -5
  174. package/esm2022/login/services/submit/public-api.mjs +0 -2
  175. package/esm2022/login/services/submit/submit.service.mjs +0 -20
  176. package/fesm2022/keycloakify-angular-login-services-submit.mjs +0 -27
  177. package/fesm2022/keycloakify-angular-login-services-submit.mjs.map +0 -1
  178. package/login/services/submit/index.d.ts +0 -5
  179. package/login/services/submit/public-api.d.ts +0 -1
  180. package/login/services/submit/submit.service.d.ts +0 -9
  181. package/src/login/services/submit/index.ts +0 -1
  182. package/src/login/services/submit/submit.service.ts +0 -12
@@ -1,78 +1,81 @@
1
- @let formFieldStates = formState().formFieldStates;
1
+ @let formState = formState$ | async;
2
+ @if (formState) {
3
+ @let formFieldStates = formState.formFieldStates;
2
4
 
3
- @for (fieldState of formFieldStates; track fieldState.attribute) {
4
- <kc-group-label [attribute]="fieldState.attribute" />
5
+ @for (fieldState of formFieldStates; track fieldState.attribute) {
6
+ <kc-group-label [attribute]="fieldState.attribute" />
5
7
 
6
- @if (beforeField) {
7
- <ng-container
8
- [ngTemplateOutlet]="beforeField"
9
- [ngTemplateOutletContext]="{
10
- attribute: fieldState.attribute,
11
- valueOrValues: fieldState.valueOrValues,
12
- displayableErrors: fieldState.displayableErrors
13
- }"
14
- />
15
- }
16
-
17
- <div
18
- [kcClass]="'kcFormGroupClass'"
19
- [style.display]="fieldState.attribute.name === 'password-confirm' && !doMakeUserConfirmPassword ? 'none' : 'block'"
20
- >
21
- <div [kcClass]="'kcLabelWrapperClass'">
22
- <label
23
- [for]="fieldState.attribute.name"
24
- [kcClass]="'kcLabelClass'"
25
- >
26
- {{ i18n.advancedMsgStr(fieldState.attribute.displayName ?? '') }}
27
- @if (fieldState.attribute.required) {
28
- *
29
- }
30
- </label>
31
- </div>
8
+ @if (beforeField) {
9
+ <ng-container
10
+ [ngTemplateOutlet]="beforeField"
11
+ [ngTemplateOutletContext]="{
12
+ attribute: fieldState.attribute,
13
+ valueOrValues: fieldState.valueOrValues,
14
+ displayableErrors: fieldState.displayableErrors
15
+ }"
16
+ />
17
+ }
32
18
 
33
- <div [kcClass]="'kcInputWrapperClass'">
34
- @if (fieldState.attribute.annotations.inputHelperTextBefore) {
35
- <div
36
- aria-live="polite"
37
- [kcClass]="'kcInputHelperTextBeforeClass'"
38
- [id]="'form-help-text-before-' + fieldState.attribute.name"
19
+ <div
20
+ [kcClass]="'kcFormGroupClass'"
21
+ [style.display]="fieldState.attribute.name === 'password-confirm' && !doMakeUserConfirmPassword ? 'none' : 'block'"
22
+ >
23
+ <div [kcClass]="'kcLabelWrapperClass'">
24
+ <label
25
+ [for]="fieldState.attribute.name"
26
+ [kcClass]="'kcLabelClass'"
39
27
  >
40
- {{ i18n.advancedMsgStr(fieldState.attribute.annotations.inputHelperTextBefore) }}
41
- </div>
42
- }
28
+ {{ i18n.advancedMsgStr(fieldState.attribute.displayName ?? '') }}
29
+ @if (fieldState.attribute.required) {
30
+ *
31
+ }
32
+ </label>
33
+ </div>
43
34
 
44
- <kc-input-field-by-type
45
- [attribute]="fieldState.attribute"
46
- [valueOrValues]="fieldState.valueOrValues"
47
- [displayableErrors]="fieldState.displayableErrors"
48
- (dispatchFormAction)="onDispatch($event)"
49
- />
35
+ <div [kcClass]="'kcInputWrapperClass'">
36
+ @if (fieldState.attribute.annotations.inputHelperTextBefore) {
37
+ <div
38
+ aria-live="polite"
39
+ [kcClass]="'kcInputHelperTextBeforeClass'"
40
+ [id]="'form-help-text-before-' + fieldState.attribute.name"
41
+ >
42
+ {{ i18n.advancedMsgStr(fieldState.attribute.annotations.inputHelperTextBefore) }}
43
+ </div>
44
+ }
50
45
 
51
- <kc-field-errors
52
- [attribute]="fieldState.attribute"
53
- [displayableErrors]="fieldState.displayableErrors"
54
- />
55
- @if (fieldState.attribute.annotations.inputHelperTextAfter) {
56
- <div
57
- aria-live="polite"
58
- [kcClass]="'kcInputHelperTextAfterClass'"
59
- [id]="'form-help-text-after-' + fieldState.attribute.name"
60
- >
61
- {{ i18n.advancedMsgStr(fieldState.attribute.annotations.inputHelperTextAfter) }}
62
- </div>
63
- }
46
+ <kc-input-field-by-type
47
+ [attribute]="fieldState.attribute"
48
+ [valueOrValues]="fieldState.valueOrValues"
49
+ [displayableErrors]="fieldState.displayableErrors"
50
+ (dispatchFormAction)="onDispatch($event)"
51
+ />
64
52
 
65
- @if (afterField) {
66
- <ng-container
67
- [ngTemplateOutlet]="afterField"
68
- [ngTemplateOutletContext]="{
69
- attribute: fieldState.attribute,
70
- valueOrValues: fieldState.valueOrValues,
71
- displayableErrors: fieldState.displayableErrors
72
- }"
53
+ <kc-field-errors
54
+ [attribute]="fieldState.attribute"
55
+ [displayableErrors]="fieldState.displayableErrors"
73
56
  />
74
- }
75
- <!-- NOTE: Downloading of html5DataAnnotations scripts is done in the useUserProfileForm hook -->
57
+ @if (fieldState.attribute.annotations.inputHelperTextAfter) {
58
+ <div
59
+ aria-live="polite"
60
+ [kcClass]="'kcInputHelperTextAfterClass'"
61
+ [id]="'form-help-text-after-' + fieldState.attribute.name"
62
+ >
63
+ {{ i18n.advancedMsgStr(fieldState.attribute.annotations.inputHelperTextAfter) }}
64
+ </div>
65
+ }
66
+
67
+ @if (afterField) {
68
+ <ng-container
69
+ [ngTemplateOutlet]="afterField"
70
+ [ngTemplateOutletContext]="{
71
+ attribute: fieldState.attribute,
72
+ valueOrValues: fieldState.valueOrValues,
73
+ displayableErrors: fieldState.displayableErrors
74
+ }"
75
+ />
76
+ }
77
+ <!-- NOTE: Downloading of html5DataAnnotations scripts is done in the useUserProfileForm hook -->
78
+ </div>
76
79
  </div>
77
- </div>
80
+ }
78
81
  }
@@ -1,5 +1,5 @@
1
- import { NgTemplateOutlet } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, ContentChild, effect, forwardRef, inject, output, TemplateRef } from '@angular/core';
1
+ import { AsyncPipe, NgTemplateOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, ContentChild, forwardRef, inject, TemplateRef } from '@angular/core';
3
3
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css';
4
4
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference';
5
5
  import { FieldErrorsComponent } from '@keycloakify/angular/login/components/field-errors';
@@ -8,7 +8,6 @@ import { InputFieldByTypeComponent } from '@keycloakify/angular/login/components
8
8
  import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class';
9
9
  import type { I18n } from '@keycloakify/angular/login/i18n';
10
10
  import type { KcContext } from '@keycloakify/angular/login/KcContext';
11
- import { SubmitService } from '@keycloakify/angular/login/services/submit';
12
11
  import { type FormAction, UserProfileFormService } from '@keycloakify/angular/login/services/user-profile-form';
13
12
  import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes';
14
13
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n';
@@ -25,7 +24,7 @@ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
25
24
  }
26
25
  `
27
26
  ],
28
- imports: [KcClassDirective, FieldErrorsComponent, InputFieldByTypeComponent, GroupLabelComponent, NgTemplateOutlet],
27
+ imports: [KcClassDirective, FieldErrorsComponent, InputFieldByTypeComponent, GroupLabelComponent, NgTemplateOutlet, AsyncPipe],
29
28
  selector: 'kc-user-profile-form-fields',
30
29
  templateUrl: 'user-profile-form-fields.component.html',
31
30
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -40,31 +39,17 @@ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
40
39
  export class UserProfileFormFieldsComponent extends ComponentReference {
41
40
  i18n = inject<I18n>(LOGIN_I18N);
42
41
  kcContext = inject<KcContext>(KC_LOGIN_CONTEXT);
43
- userProfileFormService = inject(UserProfileFormService);
44
- #submitService = inject(SubmitService);
42
+ #userProfileFormService = inject(UserProfileFormService);
45
43
  doMakeUserConfirmPassword = inject(DO_MAKE_USER_CONFIRM_PASSWORD);
46
44
  override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
47
45
  override classes = inject<Partial<Record<ClassKey, string>>>(LOGIN_CLASSES);
48
46
 
49
- onIsFormSubmittable = output<boolean>();
50
-
51
- formState = this.userProfileFormService.formState;
47
+ formState$ = this.#userProfileFormService.formState$;
52
48
 
53
49
  @ContentChild('beforField') beforeField: TemplateRef<unknown> | undefined;
54
50
  @ContentChild('afterField') afterField: TemplateRef<unknown> | undefined;
55
51
 
56
- constructor() {
57
- super();
58
- effect(
59
- () => {
60
- const isFormSubmittable = this.formState().isFormSubmittable;
61
- this.#submitService.setIsSubmittable(isFormSubmittable);
62
- },
63
- { allowSignalWrites: true }
64
- );
65
- }
66
-
67
52
  onDispatch(formAction: FormAction) {
68
- this.userProfileFormService.dispatchFormAction(formAction);
53
+ this.#userProfileFormService.dispatchFormAction(formAction);
69
54
  }
70
55
  }
@@ -1,17 +1,18 @@
1
1
  import { NgComponentOutlet } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, type TemplateRef, Type, viewChild } from '@angular/core';
3
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, type TemplateRef, Type, viewChild } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
4
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css';
5
5
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference';
6
6
  import type { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields';
7
7
  import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class';
8
8
  import type { I18n } from '@keycloakify/angular/login/i18n';
9
9
  import type { KcContext } from '@keycloakify/angular/login/KcContext';
10
- import { SubmitService } from '@keycloakify/angular/login/services/submit';
10
+ import { UserProfileFormService } from '@keycloakify/angular/login/services/user-profile-form';
11
11
  import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes';
12
12
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n';
13
13
  import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context';
14
14
  import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
15
+ import { map } from 'rxjs';
15
16
 
16
17
  @Component({
17
18
  standalone: true,
@@ -27,10 +28,9 @@ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
27
28
  ]
28
29
  })
29
30
  export class IdpReviewUserProfileComponent extends ComponentReference {
30
- #submitService = inject(SubmitService);
31
31
  kcContext = inject<Extract<KcContext, { pageId: 'idp-review-user-profile.ftl' }>>(KC_LOGIN_CONTEXT);
32
32
  i18n = inject<I18n>(LOGIN_I18N);
33
-
33
+ #userProfileFormService = inject(UserProfileFormService);
34
34
  override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
35
35
  override classes = inject<Partial<Record<ClassKey, string>>>(LOGIN_CLASSES);
36
36
 
@@ -46,14 +46,7 @@ export class IdpReviewUserProfileComponent extends ComponentReference {
46
46
  socialProvidersNode = viewChild<TemplateRef<HTMLElement>>('socialProvidersNode');
47
47
 
48
48
  userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
49
- isFormSubmittable = signal(false);
50
-
51
- constructor() {
52
- super();
53
- this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
54
- this.isFormSubmittable.set(submittable);
55
- });
56
- }
49
+ isFormSubmittable = toSignal(this.#userProfileFormService.formState$.pipe(map(s => s.isFormSubmittable)), { initialValue: false });
57
50
 
58
51
  onCallback() {
59
52
  (document.getElementById('kc-register-form') as HTMLFormElement).submit();
@@ -1,17 +1,18 @@
1
1
  import { NgComponentOutlet } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, type TemplateRef, Type, viewChild } from '@angular/core';
3
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, type TemplateRef, Type, viewChild } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
4
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css';
5
5
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference';
6
6
  import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields';
7
7
  import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class';
8
8
  import type { I18n } from '@keycloakify/angular/login/i18n';
9
9
  import type { KcContext } from '@keycloakify/angular/login/KcContext';
10
- import { SubmitService } from '@keycloakify/angular/login/services/submit';
10
+ import { UserProfileFormService } from '@keycloakify/angular/login/services/user-profile-form';
11
11
  import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes';
12
12
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n';
13
13
  import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context';
14
14
  import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
15
+ import { map } from 'rxjs';
15
16
 
16
17
  @Component({
17
18
  standalone: true,
@@ -27,7 +28,7 @@ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
27
28
  ]
28
29
  })
29
30
  export class LoginUpdateProfileComponent extends ComponentReference {
30
- #submitService = inject(SubmitService);
31
+ #userProfileFormService = inject(UserProfileFormService);
31
32
  kcContext = inject<Extract<KcContext, { pageId: 'login-update-profile.ftl' }>>(KC_LOGIN_CONTEXT);
32
33
  i18n = inject<I18n>(LOGIN_I18N);
33
34
 
@@ -45,13 +46,6 @@ export class LoginUpdateProfileComponent extends ComponentReference {
45
46
  infoNode = viewChild<TemplateRef<HTMLElement>>('infoNode');
46
47
  socialProvidersNode = viewChild<TemplateRef<HTMLElement>>('socialProvidersNode');
47
48
 
48
- isFormSubmittable = signal(false);
49
+ isFormSubmittable = toSignal(this.#userProfileFormService.formState$.pipe(map(s => s.isFormSubmittable)), { initialValue: false });
49
50
  userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
50
-
51
- constructor() {
52
- super();
53
- this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
54
- this.isFormSubmittable.set(submittable);
55
- });
56
- }
57
51
  }
@@ -76,10 +76,7 @@
76
76
  >
77
77
  <div [kcClass]="'kcFormOptionsWrapperClass'">
78
78
  <span>
79
- <a
80
- [href]="url.loginUrl"
81
- [innerHTML]="i18n.msgStr('backToLogin') | kcSanitize: 'html'"
82
- ></a>
79
+ <a [href]="url.loginUrl">{{ i18n.msgStr('backToLogin') }}</a>
83
80
  </span>
84
81
  </div>
85
82
  </div>
@@ -1,6 +1,6 @@
1
1
  import { AsyncPipe, NgClass, NgComponentOutlet } from '@angular/common';
2
2
  import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, type TemplateRef, Type, viewChild } from '@angular/core';
3
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
4
  import { KcSanitizePipe } from '@keycloakify/angular/lib/pipes/kc-sanitize';
5
5
  import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css';
6
6
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference';
@@ -8,11 +8,12 @@ import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/compo
8
8
  import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class';
9
9
  import type { I18n } from '@keycloakify/angular/login/i18n';
10
10
  import type { KcContext } from '@keycloakify/angular/login/KcContext';
11
- import { SubmitService } from '@keycloakify/angular/login/services/submit';
11
+ import { UserProfileFormService } from '@keycloakify/angular/login/services/user-profile-form';
12
12
  import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes';
13
13
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n';
14
14
  import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context';
15
15
  import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
16
+ import { map } from 'rxjs';
16
17
 
17
18
  @Component({
18
19
  selector: 'kc-register',
@@ -28,7 +29,7 @@ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
28
29
  ]
29
30
  })
30
31
  export class RegisterComponent extends ComponentReference {
31
- #submitService = inject(SubmitService);
32
+ #userProfileFormService = inject(UserProfileFormService);
32
33
  kcContext = inject<Extract<KcContext, { pageId: 'register.ftl' }>>(KC_LOGIN_CONTEXT);
33
34
  i18n = inject<I18n>(LOGIN_I18N);
34
35
 
@@ -46,16 +47,10 @@ export class RegisterComponent extends ComponentReference {
46
47
  infoNode = viewChild<TemplateRef<HTMLElement>>('infoNode');
47
48
  socialProvidersNode = viewChild<TemplateRef<HTMLElement>>('socialProvidersNode');
48
49
 
49
- isFormSubmittable = signal(false);
50
+ isFormSubmittable = toSignal(this.#userProfileFormService.formState$.pipe(map(s => s.isFormSubmittable)), { initialValue: false });
50
51
  areTermsAccepted = signal(false);
51
52
  userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
52
53
 
53
- constructor() {
54
- super();
55
- this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
56
- this.isFormSubmittable.set(submittable);
57
- });
58
- }
59
54
  onCallback() {
60
55
  (document.getElementById('kc-register-form') as HTMLFormElement).submit();
61
56
  }
@@ -1,15 +1,16 @@
1
1
  import { NgComponentOutlet } from '@angular/common';
2
- import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, type TemplateRef, Type, viewChild } from '@angular/core';
3
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
+ import { ChangeDetectionStrategy, Component, forwardRef, inject, input, type TemplateRef, Type, viewChild } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
4
  import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference';
5
5
  import { LogoutOtherSessionsComponent } from '@keycloakify/angular/login/components/logout-other-sessions';
6
6
  import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields';
7
7
  import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class';
8
8
  import type { I18n } from '@keycloakify/angular/login/i18n';
9
9
  import type { KcContext } from '@keycloakify/angular/login/KcContext';
10
- import { SubmitService } from '@keycloakify/angular/login/services/submit';
10
+ import { UserProfileFormService } from '@keycloakify/angular/login/services/user-profile-form';
11
11
  import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n';
12
12
  import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context';
13
+ import { map } from 'rxjs';
13
14
 
14
15
  @Component({
15
16
  standalone: true,
@@ -25,7 +26,7 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context';
25
26
  ]
26
27
  })
27
28
  export class UpdateEmailComponent extends ComponentReference {
28
- #submitService = inject(SubmitService);
29
+ #userProfileFormService = inject(UserProfileFormService);
29
30
  kcContext = inject<Extract<KcContext, { pageId: 'update-email.ftl' }>>(KC_LOGIN_CONTEXT);
30
31
  i18n = inject<I18n>(LOGIN_I18N);
31
32
 
@@ -41,12 +42,5 @@ export class UpdateEmailComponent extends ComponentReference {
41
42
  socialProvidersNode = viewChild<TemplateRef<HTMLElement>>('socialProvidersNode');
42
43
 
43
44
  userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
44
- isFormSubmittable = signal(false);
45
-
46
- constructor() {
47
- super();
48
- this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
49
- this.isFormSubmittable.set(submittable);
50
- });
51
- }
45
+ isFormSubmittable = toSignal(this.#userProfileFormService.formState$.pipe(map(s => s.isFormSubmittable)), { initialValue: false });
52
46
  }
@@ -19,12 +19,13 @@ export class LoginResourceInjectorService {
19
19
  this.injectScripts();
20
20
  return of(true);
21
21
  }
22
+ //reversed order of stylesheets to accomodate prepending to head
22
23
  const stylesheets = [
23
- `${this.kcContext.url.resourcesCommonPath}/node_modules/@patternfly/patternfly/patternfly.min.css`,
24
- `${this.kcContext.url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`,
25
- `${this.kcContext.url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`,
24
+ `${this.kcContext.url.resourcesPath}/css/login.css`,
26
25
  `${this.kcContext.url.resourcesCommonPath}/lib/pficon/pficon.css`,
27
- `${this.kcContext.url.resourcesPath}/css/login.css`
26
+ `${this.kcContext.url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`,
27
+ `${this.kcContext.url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`,
28
+ `${this.kcContext.url.resourcesCommonPath}/node_modules/@patternfly/patternfly/patternfly.min.css`
28
29
  ];
29
30
 
30
31
  return forkJoin(