@acontplus/ng-auth 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -135
- package/fesm2022/acontplus-ng-auth.mjs +21 -8
- package/fesm2022/acontplus-ng-auth.mjs.map +1 -1
- package/package.json +4 -3
- package/types/acontplus-ng-auth.d.ts +3 -0
|
@@ -14,11 +14,13 @@ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
|
14
14
|
import { MatCard, MatCardHeader, MatCardTitle, MatCardContent, MatCardFooter } from '@angular/material/card';
|
|
15
15
|
import { MatLabel, MatFormField } from '@angular/material/form-field';
|
|
16
16
|
import { MatInput } from '@angular/material/input';
|
|
17
|
-
import { MatIcon } from '@angular/material/icon';
|
|
17
|
+
import { MatIconRegistry, MatIcon } from '@angular/material/icon';
|
|
18
18
|
import { MatButton, MatAnchor } from '@angular/material/button';
|
|
19
19
|
import { MatCheckbox } from '@angular/material/checkbox';
|
|
20
20
|
import { MatDivider } from '@angular/material/divider';
|
|
21
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
21
22
|
import { LoggingService } from '@acontplus/ng-infrastructure';
|
|
23
|
+
import { DEFAULT_ICONS } from '@acontplus/ui-kit';
|
|
22
24
|
import * as i1$1 from '@angular/material/progress-spinner';
|
|
23
25
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
24
26
|
|
|
@@ -97,9 +99,7 @@ class AuthHttpRepository extends AuthRepository {
|
|
|
97
99
|
params['domain'] = config.domain;
|
|
98
100
|
if (config?.redirectUri)
|
|
99
101
|
params['redirectUri'] = config.redirectUri;
|
|
100
|
-
const queryString = Object.keys(params).length > 0
|
|
101
|
-
? '?' + new URLSearchParams(params).toString()
|
|
102
|
-
: '';
|
|
102
|
+
const queryString = Object.keys(params).length > 0 ? '?' + new URLSearchParams(params).toString() : '';
|
|
103
103
|
return this.http.get(`${this.URL}social/${provider}/url${queryString}`);
|
|
104
104
|
}
|
|
105
105
|
socialLogin(request) {
|
|
@@ -1055,6 +1055,8 @@ class Login {
|
|
|
1055
1055
|
fb = inject(FormBuilder);
|
|
1056
1056
|
authState = inject(AuthState);
|
|
1057
1057
|
loggingService = inject(LoggingService);
|
|
1058
|
+
iconRegistry = inject(MatIconRegistry);
|
|
1059
|
+
sanitizer = inject(DomSanitizer);
|
|
1058
1060
|
// Angular 20+ signals
|
|
1059
1061
|
isLoginMode = signal(true, ...(ngDevMode ? [{ debugName: "isLoginMode" }] : []));
|
|
1060
1062
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
@@ -1064,6 +1066,8 @@ class Login {
|
|
|
1064
1066
|
signinForm;
|
|
1065
1067
|
signupForm;
|
|
1066
1068
|
constructor() {
|
|
1069
|
+
// Register social login icons
|
|
1070
|
+
this.registerSocialIcons();
|
|
1067
1071
|
this.signinForm = this.fb.group({
|
|
1068
1072
|
email: ['', [Validators.required, Validators.email]],
|
|
1069
1073
|
password: ['', Validators.required],
|
|
@@ -1075,6 +1079,15 @@ class Login {
|
|
|
1075
1079
|
password: ['', [Validators.required, Validators.minLength(6)]],
|
|
1076
1080
|
});
|
|
1077
1081
|
}
|
|
1082
|
+
registerSocialIcons() {
|
|
1083
|
+
const socialIconNames = ['google', 'microsoft', 'github', 'facebook', 'apple', 'linkedin'];
|
|
1084
|
+
socialIconNames.forEach((name) => {
|
|
1085
|
+
const icon = DEFAULT_ICONS.find((i) => i.name === name);
|
|
1086
|
+
if (icon) {
|
|
1087
|
+
this.iconRegistry.addSvgIconLiteral(name, this.sanitizer.bypassSecurityTrustHtml(icon.data));
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1078
1091
|
ngOnInit() {
|
|
1079
1092
|
// Handle rememberMe control based on showRememberMe input
|
|
1080
1093
|
if (!this.showRememberMe()) {
|
|
@@ -1192,7 +1205,7 @@ class Login {
|
|
|
1192
1205
|
this.loginWithProvider(provider);
|
|
1193
1206
|
}
|
|
1194
1207
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: Login, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1195
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: Login, isStandalone: true, selector: "acp-login", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showRegisterButton: { classPropertyName: "showRegisterButton", publicName: "showRegisterButton", isSignal: true, isRequired: false, transformFunction: null }, showRememberMe: { classPropertyName: "showRememberMe", publicName: "showRememberMe", isSignal: true, isRequired: false, transformFunction: null }, enableDomainDiscovery: { classPropertyName: "enableDomainDiscovery", publicName: "enableDomainDiscovery", isSignal: true, isRequired: false, transformFunction: null }, showSocialLogin: { classPropertyName: "showSocialLogin", publicName: "showSocialLogin", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninControls: { classPropertyName: "additionalSigninControls", publicName: "additionalSigninControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupControls: { classPropertyName: "additionalSignupControls", publicName: "additionalSignupControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninFields: { classPropertyName: "additionalSigninFields", publicName: "additionalSigninFields", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupFields: { classPropertyName: "additionalSignupFields", publicName: "additionalSignupFields", isSignal: true, isRequired: false, transformFunction: null }, footerContent: { classPropertyName: "footerContent", publicName: "footerContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth && discoveryResult()!.provider) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatCardFooter, selector: "mat-card-footer" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1208
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: Login, isStandalone: true, selector: "acp-login", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showRegisterButton: { classPropertyName: "showRegisterButton", publicName: "showRegisterButton", isSignal: true, isRequired: false, transformFunction: null }, showRememberMe: { classPropertyName: "showRememberMe", publicName: "showRememberMe", isSignal: true, isRequired: false, transformFunction: null }, enableDomainDiscovery: { classPropertyName: "enableDomainDiscovery", publicName: "enableDomainDiscovery", isSignal: true, isRequired: false, transformFunction: null }, showSocialLogin: { classPropertyName: "showSocialLogin", publicName: "showSocialLogin", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninControls: { classPropertyName: "additionalSigninControls", publicName: "additionalSigninControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupControls: { classPropertyName: "additionalSignupControls", publicName: "additionalSignupControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninFields: { classPropertyName: "additionalSigninFields", publicName: "additionalSigninFields", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupFields: { classPropertyName: "additionalSignupFields", publicName: "additionalSignupFields", isSignal: true, isRequired: false, transformFunction: null }, footerContent: { classPropertyName: "footerContent", publicName: "footerContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (\n enableDomainDiscovery() &&\n discoveryResult() &&\n discoveryResult()!.requiresOAuth &&\n discoveryResult()!.provider\n ) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatCardFooter, selector: "mat-card-footer" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1196
1209
|
}
|
|
1197
1210
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: Login, decorators: [{
|
|
1198
1211
|
type: Component,
|
|
@@ -1212,7 +1225,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
1212
1225
|
MatAnchor,
|
|
1213
1226
|
MatCheckbox,
|
|
1214
1227
|
MatDivider,
|
|
1215
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (enableDomainDiscovery()
|
|
1228
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (\n enableDomainDiscovery() &&\n discoveryResult() &&\n discoveryResult()!.requiresOAuth &&\n discoveryResult()!.provider\n ) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"] }]
|
|
1216
1229
|
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showRegisterButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRegisterButton", required: false }] }], showRememberMe: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRememberMe", required: false }] }], enableDomainDiscovery: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDomainDiscovery", required: false }] }], showSocialLogin: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSocialLogin", required: false }] }], additionalSigninControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSigninControls", required: false }] }], additionalSignupControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSignupControls", required: false }] }], additionalSigninFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSigninFields", required: false }] }], additionalSignupFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSignupFields", required: false }] }], footerContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerContent", required: false }] }] } });
|
|
1217
1230
|
|
|
1218
1231
|
// src/lib/presentation/components/index.ts
|
|
@@ -1317,11 +1330,11 @@ class OAuthCallbackComponent {
|
|
|
1317
1330
|
</div>
|
|
1318
1331
|
}
|
|
1319
1332
|
</div>
|
|
1320
|
-
`, isInline: true, styles: [".oauth-callback-container{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;padding:2rem;text-align:center}mat-spinner{margin-bottom:1.5rem}p{font-size:1rem;color:#666;margin:0}.error-message{max-width:400px}.error-message h2{color:#d32f2f;margin-bottom:1rem}.error-message p{color:#666;margin-bottom:2rem}.error-message button{padding:.75rem 2rem;background-color:#1976d2;color:#fff;border:none;border-radius:4px;font-size:1rem;cursor:pointer;transition:background-color .2s}.error-message button:hover{background-color:#1565c0}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
1333
|
+
`, isInline: true, styles: [".oauth-callback-container{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;padding:2rem;text-align:center}mat-spinner{margin-bottom:1.5rem}p{font-size:1rem;color:#666;margin:0}.error-message{max-width:400px}.error-message h2{color:#d32f2f;margin-bottom:1rem}.error-message p{color:#666;margin-bottom:2rem}.error-message button{padding:.75rem 2rem;background-color:#1976d2;color:#fff;border:none;border-radius:4px;font-size:1rem;cursor:pointer;transition:background-color .2s}.error-message button:hover{background-color:#1565c0}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] });
|
|
1321
1334
|
}
|
|
1322
1335
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: OAuthCallbackComponent, decorators: [{
|
|
1323
1336
|
type: Component,
|
|
1324
|
-
args: [{ selector: 'acp-oauth-callback', standalone: true, imports: [
|
|
1337
|
+
args: [{ selector: 'acp-oauth-callback', standalone: true, imports: [MatProgressSpinnerModule], template: `
|
|
1325
1338
|
<div class="oauth-callback-container">
|
|
1326
1339
|
@if (loading) {
|
|
1327
1340
|
<mat-spinner diameter="48"></mat-spinner>
|