@keycloakify/angular 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/account/DefaultPage/DefaultPage.d.ts +2 -30
- package/esm2022/account/containers/template/template.component.mjs +6 -6
- package/esm2022/account/directives/kc-class/kc-class.directive.mjs +3 -3
- package/esm2022/account/pages/account/account.component.mjs +3 -3
- package/esm2022/account/pages/applications/applications.component.mjs +3 -3
- package/esm2022/account/pages/federatedIdentity/federatedIdentity.component.mjs +3 -3
- package/esm2022/account/pages/log/log.component.mjs +3 -3
- package/esm2022/account/pages/password/password.component.mjs +3 -3
- package/esm2022/account/pages/sessions/sessions.component.mjs +3 -3
- package/esm2022/account/pages/totp/totp.component.mjs +3 -3
- package/esm2022/account/services/account-resource-injector/account-resource-injector.service.mjs +3 -3
- package/esm2022/account/services/i18n/i18n.service.mjs +3 -3
- package/esm2022/lib/directives/attributes/attributes.directive.mjs +3 -3
- package/esm2022/lib/pipes/input-type/input-type.pipe.mjs +3 -3
- package/esm2022/lib/pipes/is-array-with-empty-object/is-array-with-empty-object.pipe.mjs +3 -3
- package/esm2022/lib/pipes/kc-sanitize/kc-sanitize.pipe.mjs +3 -3
- package/esm2022/lib/pipes/to-array/to-array.pipe.mjs +3 -3
- package/esm2022/lib/pipes/to-number/to-number.pipe.mjs +3 -3
- package/esm2022/lib/services/resource-injector/resource-injector.service.mjs +3 -3
- package/esm2022/login/components/add-remove-buttons-multi-valued-attribute/add-remove-buttons-multi-valued-attribute.component.mjs +7 -53
- package/esm2022/login/components/field-errors/field-errors.component.mjs +3 -3
- package/esm2022/login/components/group-label/group-label.component.mjs +3 -3
- package/esm2022/login/components/input-field-by-type/input-field-by-type.component.mjs +3 -3
- package/esm2022/login/components/input-tag/input-tag.component.mjs +3 -3
- package/esm2022/login/components/input-tag-selects/input-tag-selects.component.mjs +3 -3
- package/esm2022/login/components/logout-other-sessions/logout-other-sessions.component.mjs +3 -3
- package/esm2022/login/components/password-wrapper/password-wrapper.component.mjs +3 -3
- package/esm2022/login/components/select-tag/select-tag.component.mjs +3 -3
- package/esm2022/login/components/textarea-tag/textarea-tag.component.mjs +3 -3
- package/esm2022/login/components/user-profile-form-fields/user-profile-form-fields.component.mjs +15 -22
- package/esm2022/login/containers/template/template.component.mjs +6 -6
- package/esm2022/login/directives/kc-class/kc-class.directive.mjs +3 -3
- package/esm2022/login/pages/code/code.component.mjs +3 -3
- package/esm2022/login/pages/delete-account-confirm/delete-account-confirm.component.mjs +3 -3
- package/esm2022/login/pages/delete-credential/delete-credential.component.mjs +3 -3
- package/esm2022/login/pages/error/error.component.mjs +3 -3
- package/esm2022/login/pages/frontchannel-logout/frontchannel-logout.component.mjs +3 -3
- package/esm2022/login/pages/idp-review-user-profile/idp-review-user-profile.component.mjs +13 -15
- package/esm2022/login/pages/info/info.component.mjs +3 -3
- package/esm2022/login/pages/login/login.component.mjs +3 -3
- package/esm2022/login/pages/login-config-totp/login-config-totp.component.mjs +3 -3
- package/esm2022/login/pages/login-idp-link-confirm/login-idp-link-confirm.component.mjs +3 -3
- package/esm2022/login/pages/login-idp-link-confirm-override/login-idp-link-confirm-override.component.mjs +3 -3
- package/esm2022/login/pages/login-idp-link-email/login-idp-link-email.component.mjs +3 -3
- package/esm2022/login/pages/login-oauth-grant/login-oauth-grant.component.mjs +3 -3
- package/esm2022/login/pages/login-oauth2-device-verify-user-code/login-oauth2-device-verify-user-code.component.mjs +3 -3
- package/esm2022/login/pages/login-otp/login-otp.component.mjs +3 -3
- package/esm2022/login/pages/login-page-expired/login-page-expired.component.mjs +3 -3
- package/esm2022/login/pages/login-passkeys-conditional-authenticate/login-passkeys-conditional-authenticate.component.mjs +3 -3
- package/esm2022/login/pages/login-password/login-password.component.mjs +3 -3
- package/esm2022/login/pages/login-recovery-authn-code-config/login-recovery-authn-code-config.component.mjs +125 -6
- package/esm2022/login/pages/login-recovery-authn-code-input/login-recovery-authn-code-input.component.mjs +3 -3
- package/esm2022/login/pages/login-reset-otp/login-reset-otp.component.mjs +3 -3
- package/esm2022/login/pages/login-reset-password/login-reset-password.component.mjs +3 -3
- package/esm2022/login/pages/login-update-password/login-update-password.component.mjs +3 -3
- package/esm2022/login/pages/login-update-profile/login-update-profile.component.mjs +13 -15
- package/esm2022/login/pages/login-username/login-username.component.mjs +3 -3
- package/esm2022/login/pages/login-verify-email/login-verify-email.component.mjs +3 -3
- package/esm2022/login/pages/login-x509-info/login-x509-info.component.mjs +3 -3
- package/esm2022/login/pages/logout-confirm/logout-confirm.component.mjs +3 -3
- package/esm2022/login/pages/register/register.component.mjs +12 -14
- package/esm2022/login/pages/saml-post-form/saml-post-form.component.mjs +3 -3
- package/esm2022/login/pages/select-authenticator/select-authenticator.component.mjs +3 -3
- package/esm2022/login/pages/terms/terms.component.mjs +3 -3
- package/esm2022/login/pages/update-email/update-email.component.mjs +13 -15
- package/esm2022/login/pages/webauthn-authenticate/webauthn-authenticate.component.mjs +3 -3
- package/esm2022/login/pages/webauthn-error/webauthn-error.component.mjs +3 -3
- package/esm2022/login/pages/webauthn-register/webauthn-register.component.mjs +3 -3
- package/esm2022/login/services/i18n/i18n.service.mjs +3 -3
- package/esm2022/login/services/login-resource-injector/login-resource-injector.service.mjs +3 -3
- package/esm2022/login/services/user-profile-form/user-profile-form.service.mjs +56 -1004
- package/fesm2022/keycloakify-angular-account-containers-template.mjs +6 -6
- package/fesm2022/keycloakify-angular-account-directives-kc-class.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-account.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-applications.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-federatedIdentity.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-log.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-password.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-sessions.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-pages-totp.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-services-account-resource-injector.mjs +3 -3
- package/fesm2022/keycloakify-angular-account-services-i18n.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-directives-attributes.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-pipes-input-type.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-pipes-is-array-with-empty-object.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-pipes-kc-sanitize.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-pipes-to-array.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-pipes-to-number.mjs +3 -3
- package/fesm2022/keycloakify-angular-lib-services-resource-injector.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-add-remove-buttons-multi-valued-attribute.mjs +6 -52
- package/fesm2022/keycloakify-angular-login-components-add-remove-buttons-multi-valued-attribute.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-components-field-errors.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-group-label.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-input-field-by-type.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-input-tag-selects.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-input-tag.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-logout-other-sessions.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-password-wrapper.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-select-tag.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-textarea-tag.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-components-user-profile-form-fields.mjs +14 -21
- package/fesm2022/keycloakify-angular-login-components-user-profile-form-fields.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-containers-template.mjs +6 -6
- package/fesm2022/keycloakify-angular-login-directives-kc-class.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-code.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-delete-account-confirm.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-delete-credential.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-error.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-frontchannel-logout.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-idp-review-user-profile.mjs +12 -14
- package/fesm2022/keycloakify-angular-login-pages-idp-review-user-profile.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-pages-info.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-config-totp.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-idp-link-confirm-override.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-idp-link-confirm.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-idp-link-email.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-oauth-grant.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-oauth2-device-verify-user-code.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-otp.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-page-expired.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-passkeys-conditional-authenticate.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-password.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-recovery-authn-code-config.mjs +124 -5
- package/fesm2022/keycloakify-angular-login-pages-login-recovery-authn-code-config.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-pages-login-recovery-authn-code-input.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-reset-otp.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-reset-password.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-update-password.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-update-profile.mjs +12 -14
- package/fesm2022/keycloakify-angular-login-pages-login-update-profile.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-pages-login-username.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-verify-email.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login-x509-info.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-login.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-logout-confirm.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-register.mjs +11 -13
- package/fesm2022/keycloakify-angular-login-pages-register.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-pages-saml-post-form.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-select-authenticator.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-terms.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-update-email.mjs +12 -14
- package/fesm2022/keycloakify-angular-login-pages-update-email.mjs.map +1 -1
- package/fesm2022/keycloakify-angular-login-pages-webauthn-authenticate.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-webauthn-error.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-pages-webauthn-register.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-services-i18n.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-services-login-resource-injector.mjs +3 -3
- package/fesm2022/keycloakify-angular-login-services-user-profile-form.mjs +55 -1003
- package/fesm2022/keycloakify-angular-login-services-user-profile-form.mjs.map +1 -1
- package/login/components/add-remove-buttons-multi-valued-attribute/add-remove-buttons-multi-valued-attribute.component.d.ts +0 -1
- package/login/components/user-profile-form-fields/user-profile-form-fields.component.d.ts +3 -13
- package/login/pages/idp-review-user-profile/idp-review-user-profile.component.d.ts +1 -2
- package/login/pages/login-recovery-authn-code-config/login-recovery-authn-code-config.component.d.ts +3 -0
- package/login/pages/login-update-profile/login-update-profile.component.d.ts +1 -2
- package/login/pages/register/register.component.d.ts +1 -2
- package/login/pages/update-email/update-email.component.d.ts +1 -2
- package/login/services/user-profile-form/user-profile-form.service.d.ts +20 -41
- package/package.json +8 -14
- package/src/login/components/add-remove-buttons-multi-valued-attribute/add-remove-buttons-multi-valued-attribute.component.ts +3 -69
- package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.html +71 -68
- package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.ts +6 -21
- package/src/login/pages/idp-review-user-profile/idp-review-user-profile.component.ts +6 -13
- package/src/login/pages/login-recovery-authn-code-config/login-recovery-authn-code-config.component.ts +123 -0
- package/src/login/pages/login-update-profile/login-update-profile.component.ts +6 -12
- package/src/login/pages/register/register.component.ts +5 -10
- package/src/login/pages/update-email/update-email.component.ts +6 -12
- package/src/login/services/user-profile-form/user-profile-form.service.ts +103 -1433
- package/esm2022/login/services/submit/keycloakify-angular-login-services-submit.mjs +0 -5
- package/esm2022/login/services/submit/public-api.mjs +0 -2
- package/esm2022/login/services/submit/submit.service.mjs +0 -20
- package/fesm2022/keycloakify-angular-login-services-submit.mjs +0 -27
- package/fesm2022/keycloakify-angular-login-services-submit.mjs.map +0 -1
- package/login/services/submit/index.d.ts +0 -5
- package/login/services/submit/public-api.d.ts +0 -1
- package/login/services/submit/submit.service.d.ts +0 -9
- package/src/login/services/submit/index.ts +0 -1
- package/src/login/services/submit/submit.service.ts +0 -12
package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.html
CHANGED
|
@@ -1,78 +1,81 @@
|
|
|
1
|
-
@let
|
|
1
|
+
@let formState = formState$ | async;
|
|
2
|
+
@if (formState) {
|
|
3
|
+
@let formFieldStates = formState.formFieldStates;
|
|
2
4
|
|
|
3
|
-
@for (fieldState of formFieldStates; track fieldState.attribute) {
|
|
4
|
-
|
|
5
|
+
@for (fieldState of formFieldStates; track fieldState.attribute) {
|
|
6
|
+
<kc-group-label [attribute]="fieldState.attribute" />
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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.
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
{{ i18n.advancedMsgStr(fieldState.attribute.displayName ?? '') }}
|
|
29
|
+
@if (fieldState.attribute.required) {
|
|
30
|
+
*
|
|
31
|
+
}
|
|
32
|
+
</label>
|
|
33
|
+
</div>
|
|
43
34
|
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
[
|
|
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
|
-
|
|
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
|
-
|
|
80
|
+
}
|
|
78
81
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
-
import { ChangeDetectionStrategy, Component, ContentChild,
|
|
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
|
-
|
|
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
|
|
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,
|
|
3
|
-
import {
|
|
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 {
|
|
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 =
|
|
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();
|
|
@@ -5,6 +5,7 @@ import { LogoutOtherSessionsComponent } from '@keycloakify/angular/login/compone
|
|
|
5
5
|
import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class';
|
|
6
6
|
import type { I18n } from '@keycloakify/angular/login/i18n';
|
|
7
7
|
import type { KcContext } from '@keycloakify/angular/login/KcContext';
|
|
8
|
+
import { LoginResourceInjectorService } from '@keycloakify/angular/login/services/login-resource-injector';
|
|
8
9
|
import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes';
|
|
9
10
|
import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n';
|
|
10
11
|
import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context';
|
|
@@ -26,6 +27,7 @@ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
|
|
|
26
27
|
export class LoginRecoveryAuthnCodeConfigComponent extends ComponentReference {
|
|
27
28
|
kcContext = inject<Extract<KcContext, { pageId: 'login-recovery-authn-code-config.ftl' }>>(KC_LOGIN_CONTEXT);
|
|
28
29
|
i18n = inject<I18n>(LOGIN_I18N);
|
|
30
|
+
loginResourceInjectorService = inject(LoginResourceInjectorService);
|
|
29
31
|
|
|
30
32
|
override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
|
|
31
33
|
override classes = inject<Partial<Record<ClassKey, string>>>(LOGIN_CLASSES);
|
|
@@ -44,4 +46,125 @@ export class LoginRecoveryAuthnCodeConfigComponent extends ComponentReference {
|
|
|
44
46
|
toggleRecoveryCodesConfirmation = signal(false);
|
|
45
47
|
|
|
46
48
|
olRecoveryCodesListId = 'kc-recovery-codes-list';
|
|
49
|
+
|
|
50
|
+
constructor() {
|
|
51
|
+
super();
|
|
52
|
+
this.loginResourceInjectorService.insertAdditionalScripts([
|
|
53
|
+
{
|
|
54
|
+
type: 'text/javascript',
|
|
55
|
+
id: `${this.olRecoveryCodesListId}-script`,
|
|
56
|
+
textContent: `
|
|
57
|
+
/* copy recovery codes */
|
|
58
|
+
function copyRecoveryCodes() {
|
|
59
|
+
var tmpTextarea = document.createElement("textarea");
|
|
60
|
+
var codes = document.querySelectorAll("#${this.olRecoveryCodesListId} li");
|
|
61
|
+
for (i = 0; i < codes.length; i++) {
|
|
62
|
+
tmpTextarea.value = tmpTextarea.value + codes[i].innerText + "\\n";
|
|
63
|
+
}
|
|
64
|
+
document.body.appendChild(tmpTextarea);
|
|
65
|
+
tmpTextarea.select();
|
|
66
|
+
document.execCommand("copy");
|
|
67
|
+
document.body.removeChild(tmpTextarea);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var copyButton = document.getElementById("copyRecoveryCodes");
|
|
71
|
+
copyButton && copyButton.addEventListener("click", function () {
|
|
72
|
+
copyRecoveryCodes();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
/* download recovery codes */
|
|
76
|
+
function formatCurrentDateTime() {
|
|
77
|
+
var dt = new Date();
|
|
78
|
+
var options = {
|
|
79
|
+
month: 'long',
|
|
80
|
+
day: 'numeric',
|
|
81
|
+
year: 'numeric',
|
|
82
|
+
hour: 'numeric',
|
|
83
|
+
minute: 'numeric',
|
|
84
|
+
timeZoneName: 'short'
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return dt.toLocaleString('en-US', options);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function parseRecoveryCodeList() {
|
|
91
|
+
var recoveryCodes = document.querySelectorAll("#${this.olRecoveryCodesListId} li");
|
|
92
|
+
var recoveryCodeList = "";
|
|
93
|
+
|
|
94
|
+
for (var i = 0; i < recoveryCodes.length; i++) {
|
|
95
|
+
var recoveryCodeLiElement = recoveryCodes[i].innerText;
|
|
96
|
+
recoveryCodeList += recoveryCodeLiElement + "\\r\\n";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return recoveryCodeList;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function buildDownloadContent() {
|
|
103
|
+
var recoveryCodeList = parseRecoveryCodeList();
|
|
104
|
+
var dt = new Date();
|
|
105
|
+
var options = {
|
|
106
|
+
month: 'long',
|
|
107
|
+
day: 'numeric',
|
|
108
|
+
year: 'numeric',
|
|
109
|
+
hour: 'numeric',
|
|
110
|
+
minute: 'numeric',
|
|
111
|
+
timeZoneName: 'short'
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
return fileBodyContent =
|
|
115
|
+
${JSON.stringify(this.i18n.msgStr('recovery-codes-download-file-header'))} + "\\n\\n" +
|
|
116
|
+
recoveryCodeList + "\\n" +
|
|
117
|
+
${JSON.stringify(this.i18n.msgStr('recovery-codes-download-file-description'))} + "\\n\\n" +
|
|
118
|
+
${JSON.stringify(this.i18n.msgStr('recovery-codes-download-file-date'))} + " " + formatCurrentDateTime();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function setUpDownloadLinkAndDownload(filename, text) {
|
|
122
|
+
var el = document.createElement('a');
|
|
123
|
+
el.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
|
124
|
+
el.setAttribute('download', filename);
|
|
125
|
+
el.style.display = 'none';
|
|
126
|
+
document.body.appendChild(el);
|
|
127
|
+
el.click();
|
|
128
|
+
document.body.removeChild(el);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function downloadRecoveryCodes() {
|
|
132
|
+
setUpDownloadLinkAndDownload('kc-download-recovery-codes.txt', buildDownloadContent());
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var downloadButton = document.getElementById("downloadRecoveryCodes");
|
|
136
|
+
downloadButton && downloadButton.addEventListener("click", downloadRecoveryCodes);
|
|
137
|
+
|
|
138
|
+
/* print recovery codes */
|
|
139
|
+
function buildPrintContent() {
|
|
140
|
+
var recoveryCodeListHTML = document.getElementById('${this.olRecoveryCodesListId}').innerHTML;
|
|
141
|
+
var styles =
|
|
142
|
+
\`@page { size: auto; margin-top: 0; }
|
|
143
|
+
body { width: 480px; }
|
|
144
|
+
div { list-style-type: none; font-family: monospace }
|
|
145
|
+
p:first-of-type { margin-top: 48px }\`;
|
|
146
|
+
|
|
147
|
+
return printFileContent =
|
|
148
|
+
"<html><style>" + styles + "</style><body>" +
|
|
149
|
+
"<title>kc-download-recovery-codes</title>" +
|
|
150
|
+
"<p>" + ${JSON.stringify(this.i18n.msgStr('recovery-codes-download-file-header'))} + "</p>" +
|
|
151
|
+
"<div>" + recoveryCodeListHTML + "</div>" +
|
|
152
|
+
"<p>" + ${JSON.stringify(this.i18n.msgStr('recovery-codes-download-file-description'))} + "</p>" +
|
|
153
|
+
"<p>" + ${JSON.stringify(this.i18n.msgStr('recovery-codes-download-file-date'))} + " " + formatCurrentDateTime() + "</p>" +
|
|
154
|
+
"</body></html>";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function printRecoveryCodes() {
|
|
158
|
+
var w = window.open();
|
|
159
|
+
w.document.write(buildPrintContent());
|
|
160
|
+
w.print();
|
|
161
|
+
w.close();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var printButton = document.getElementById("printRecoveryCodes");
|
|
165
|
+
printButton && printButton.addEventListener("click", printRecoveryCodes);
|
|
166
|
+
`
|
|
167
|
+
}
|
|
168
|
+
]);
|
|
169
|
+
}
|
|
47
170
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { NgComponentOutlet } from '@angular/common';
|
|
2
|
-
import { ChangeDetectionStrategy, Component, forwardRef, inject, input,
|
|
3
|
-
import {
|
|
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 {
|
|
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
|
-
#
|
|
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 =
|
|
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
|
}
|
|
@@ -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 {
|
|
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 {
|
|
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
|
-
#
|
|
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 =
|
|
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,
|
|
3
|
-
import {
|
|
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 {
|
|
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
|
-
#
|
|
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 =
|
|
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
|
}
|