@sinequa/atomic-angular 1.0.11 → 1.0.13
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/fesm2022/sinequa-atomic-angular.mjs +156 -115
- package/fesm2022/sinequa-atomic-angular.mjs.map +1 -1
- package/index.d.ts +106 -99
- package/package.json +1 -1
|
@@ -3415,14 +3415,10 @@ function AuthGuard() {
|
|
|
3415
3415
|
const { loginPath, useCredentials, useSSO } = globalConfig;
|
|
3416
3416
|
if (state.url.startsWith("/login"))
|
|
3417
3417
|
return true;
|
|
3418
|
-
// If the user is not authenticated, navigate to the login page
|
|
3418
|
+
// If the user is not authenticated, navigate to the login page.
|
|
3419
|
+
// The login page handles every authentication method (credentials, OAuth, SAML).
|
|
3419
3420
|
if (!isAuthenticated() && !useSSO) {
|
|
3420
|
-
|
|
3421
|
-
router.navigate([loginPath], { queryParams: { returnUrl: state.url } });
|
|
3422
|
-
}
|
|
3423
|
-
else {
|
|
3424
|
-
router.navigate(["loading"], { queryParams: { returnUrl: state.url } });
|
|
3425
|
-
}
|
|
3421
|
+
router.navigate([loginPath], { queryParams: { returnUrl: state.url } });
|
|
3426
3422
|
return false;
|
|
3427
3423
|
}
|
|
3428
3424
|
// If the user is authenticated, initialize the principal store if it's in the initial state
|
|
@@ -4031,7 +4027,7 @@ class NavigationService {
|
|
|
4031
4027
|
* - Maps all router events to `RouterEvent`.
|
|
4032
4028
|
* - Filters the events to only include instances of `NavigationEnd`.
|
|
4033
4029
|
* - Taps into the event stream to extract the route name from the URL and notify the audit service of route changes,
|
|
4034
|
-
* excluding
|
|
4030
|
+
* excluding duplicate navigations.
|
|
4035
4031
|
* - Updates the `urlAfterNavigation` property with the current URL after navigation.
|
|
4036
4032
|
* - Shares the replayed value with a buffer size of 1 to ensure subscribers receive the latest emitted value.
|
|
4037
4033
|
*
|
|
@@ -4039,8 +4035,7 @@ class NavigationService {
|
|
|
4039
4035
|
*/
|
|
4040
4036
|
navigationEnd$ = this.router.events.pipe(map((event) => event), filter((event) => event instanceof NavigationEnd), tap((event) => {
|
|
4041
4037
|
const url = event.url.slice(1).split("?")[0]; // Extract route name
|
|
4042
|
-
|
|
4043
|
-
if (url && url !== "loading" && url !== this.urlAfterNavigation) {
|
|
4038
|
+
if (url && url !== this.urlAfterNavigation) {
|
|
4044
4039
|
this.auditService.notifyRouteChange(url);
|
|
4045
4040
|
}
|
|
4046
4041
|
}), tap((event) => {
|
|
@@ -5372,6 +5367,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
5372
5367
|
}]
|
|
5373
5368
|
}] });
|
|
5374
5369
|
|
|
5370
|
+
/**
|
|
5371
|
+
* @deprecated This component and its `/loading` route are no longer used.
|
|
5372
|
+
* Authentication is handled at bootstrap by `withBootstrapApp`/`signIn`, and the
|
|
5373
|
+
* `AuthGuard` now redirects unauthenticated users to the login page directly.
|
|
5374
|
+
* Will be removed in a future major release. Do not use in new code.
|
|
5375
|
+
*/
|
|
5375
5376
|
class LoadingComponent {
|
|
5376
5377
|
state = computed(() => getState(this.application), ...(ngDevMode ? [{ debugName: "state" }] : []));
|
|
5377
5378
|
application = inject(ApplicationStore);
|
|
@@ -8989,6 +8990,24 @@ class AggregationListComponent {
|
|
|
8989
8990
|
}
|
|
8990
8991
|
});
|
|
8991
8992
|
}
|
|
8993
|
+
else if (Array.isArray(activeFilters.values) && activeFilters.values.length) {
|
|
8994
|
+
// multiple values stored as a string array, e.g. { values: ["alice_martin", "caroline_dubois"] }
|
|
8995
|
+
// (no `filters` sub-array and no single `value`) — mark each matching item as selected
|
|
8996
|
+
activeFilters.values.forEach((value) => {
|
|
8997
|
+
const found = aggItems.find(item => item.value?.toString().toLocaleLowerCase() === value?.toLocaleLowerCase());
|
|
8998
|
+
if (!found) {
|
|
8999
|
+
// value not in the loaded items — add it so it shows up as selected
|
|
9000
|
+
aggItems.unshift({
|
|
9001
|
+
value,
|
|
9002
|
+
display: value,
|
|
9003
|
+
$selected: true
|
|
9004
|
+
});
|
|
9005
|
+
}
|
|
9006
|
+
else {
|
|
9007
|
+
found.$selected = true;
|
|
9008
|
+
}
|
|
9009
|
+
});
|
|
9010
|
+
}
|
|
8992
9011
|
else {
|
|
8993
9012
|
// single filter
|
|
8994
9013
|
const found = aggItems.find(item => item.value?.toString().toLocaleLowerCase() === activeFilters.value?.toLocaleLowerCase());
|
|
@@ -10740,6 +10759,15 @@ class SignInComponent {
|
|
|
10740
10759
|
destroyRef;
|
|
10741
10760
|
cn = cn;
|
|
10742
10761
|
config = globalConfig;
|
|
10762
|
+
/**
|
|
10763
|
+
* True when authentication is handled outside the credentials form — i.e. by the
|
|
10764
|
+
* browser/proxy (`useSSO`) or by an auto-configured OAuth/SAML provider. In those
|
|
10765
|
+
* modes this screen shows a loader instead of a login form and initiates the
|
|
10766
|
+
* handshake automatically by calling `handleLogin()`.
|
|
10767
|
+
*/
|
|
10768
|
+
externalAuth = !!(globalConfig.useSSO ||
|
|
10769
|
+
globalConfig.autoOAuthProvider ||
|
|
10770
|
+
globalConfig.autoSAMLProvider);
|
|
10743
10771
|
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : []));
|
|
10744
10772
|
forgotPassword = output();
|
|
10745
10773
|
username = model("", ...(ngDevMode ? [{ debugName: "username" }] : []));
|
|
@@ -10761,6 +10789,30 @@ class SignInComponent {
|
|
|
10761
10789
|
expiresSoonNotified = signal(false, ...(ngDevMode ? [{ debugName: "expiresSoonNotified" }] : []));
|
|
10762
10790
|
constructor(destroyRef) {
|
|
10763
10791
|
this.destroyRef = destroyRef;
|
|
10792
|
+
// If the user is already authenticated when landing here (e.g. page refresh on
|
|
10793
|
+
// /login, or an external handshake completed before this screen was created),
|
|
10794
|
+
// don't sit on the loader: go straight to the returnUrl.
|
|
10795
|
+
if (this.authenticated()) {
|
|
10796
|
+
const url = this.route.snapshot.queryParams["returnUrl"] || "/";
|
|
10797
|
+
this.router.navigateByUrl(url);
|
|
10798
|
+
}
|
|
10799
|
+
// When authentication is delegated to the browser/proxy (SSO) or an OAuth/SAML
|
|
10800
|
+
// provider, no credentials form is shown: this screen shows a loader and initiates
|
|
10801
|
+
// the handshake automatically by calling `handleLogin()`. If the handshake never
|
|
10802
|
+
// completes, fall back to /error after 5s; the fallback is cancelled as soon as
|
|
10803
|
+
// the login succeeds (the `authenticated` event then drives navigation).
|
|
10804
|
+
if (this.externalAuth && !this.authenticated()) {
|
|
10805
|
+
const timeout = setTimeout(() => {
|
|
10806
|
+
this.router.navigate(["/error"], {
|
|
10807
|
+
queryParams: { returnUrl: this.route.snapshot.queryParams["returnUrl"] }
|
|
10808
|
+
});
|
|
10809
|
+
}, 5000);
|
|
10810
|
+
destroyRef.onDestroy(() => clearTimeout(timeout));
|
|
10811
|
+
this.handleLogin().then(result => {
|
|
10812
|
+
if (result)
|
|
10813
|
+
clearTimeout(timeout);
|
|
10814
|
+
});
|
|
10815
|
+
}
|
|
10764
10816
|
effect(() => {
|
|
10765
10817
|
const principal = getState(this.principalStore);
|
|
10766
10818
|
if (this.authenticated() && principal && !this.expiresSoonNotified()) {
|
|
@@ -10806,14 +10858,16 @@ class SignInComponent {
|
|
|
10806
10858
|
this.router.navigate(["/login"]);
|
|
10807
10859
|
}
|
|
10808
10860
|
async handleLogin() {
|
|
10809
|
-
login().then((result) => {
|
|
10861
|
+
return login().then((result) => {
|
|
10810
10862
|
if (result) {
|
|
10811
10863
|
this.auditService.notifyLogin();
|
|
10812
10864
|
}
|
|
10865
|
+
return result;
|
|
10813
10866
|
}).catch(error => {
|
|
10814
10867
|
warn("An error occurred while logging in", error);
|
|
10815
10868
|
this.auditService.notify({ type: 'Login_Denied' });
|
|
10816
10869
|
this.router.navigate(["error"]);
|
|
10870
|
+
return false;
|
|
10817
10871
|
});
|
|
10818
10872
|
}
|
|
10819
10873
|
async handleLoginWithCredentials() {
|
|
@@ -10856,7 +10910,7 @@ class SignInComponent {
|
|
|
10856
10910
|
}
|
|
10857
10911
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SignInComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
10858
10912
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SignInComponent, isStandalone: true, selector: "signIn, signin, sign-in", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, username: { classPropertyName: "username", publicName: "username", isSignal: true, isRequired: false, transformFunction: null }, password: { classPropertyName: "password", publicName: "password", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { forgotPassword: "forgotPassword", username: "usernameChange", password: "passwordChange" }, host: { properties: { "class": "cn('grid h-dvh w-full place-content-center', class())" } }, providers: [provideTranslocoScope("login")], ngImport: i0, template: `
|
|
10859
|
-
@if (!authenticated()) {
|
|
10913
|
+
@if (!authenticated() && !externalAuth) {
|
|
10860
10914
|
<Card
|
|
10861
10915
|
hover="no"
|
|
10862
10916
|
cdkTrapFocus
|
|
@@ -10867,60 +10921,54 @@ class SignInComponent {
|
|
|
10867
10921
|
</CardHeader>
|
|
10868
10922
|
|
|
10869
10923
|
<CardContent class="grid gap-4">
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
|
|
10875
|
-
|
|
10876
|
-
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
(click)="handleLoginWithCredentials()">
|
|
10909
|
-
{{ "login.connect" | transloco }}
|
|
10910
|
-
</button>
|
|
10911
|
-
}
|
|
10912
|
-
@else {
|
|
10913
|
-
<!-- authentication using OAuth or SAML provider -->
|
|
10914
|
-
<button (click)="handleLogin()">
|
|
10915
|
-
{{ "login.SignInWith" | transloco : { provider: config.autoOAuthProvider ? "OAuth" : "SAML" } }}
|
|
10916
|
-
</button>
|
|
10917
|
-
}
|
|
10924
|
+
<!-- authentication using credentials -->
|
|
10925
|
+
<div class="grid gap-2">
|
|
10926
|
+
<label class="text-sm font-medium" for="username">{{
|
|
10927
|
+
"login.username" | transloco
|
|
10928
|
+
}}</label>
|
|
10929
|
+
<input
|
|
10930
|
+
id="username"
|
|
10931
|
+
type="text"
|
|
10932
|
+
required
|
|
10933
|
+
[(ngModel)]="username"
|
|
10934
|
+
(keydown.enter)="handleLoginWithCredentials()" />
|
|
10935
|
+
</div>
|
|
10936
|
+
|
|
10937
|
+
<div class="grid gap-2">
|
|
10938
|
+
<label class="text-sm font-medium" for="password">{{
|
|
10939
|
+
"login.password" | transloco
|
|
10940
|
+
}}</label>
|
|
10941
|
+
<input
|
|
10942
|
+
id="password"
|
|
10943
|
+
type="password"
|
|
10944
|
+
required
|
|
10945
|
+
[(ngModel)]="password"
|
|
10946
|
+
(keydown.enter)="handleLoginWithCredentials()" />
|
|
10947
|
+
</div>
|
|
10948
|
+
|
|
10949
|
+
<span
|
|
10950
|
+
class="text-muted-foreground cursor-pointer justify-self-start text-xs hover:underline"
|
|
10951
|
+
role="button"
|
|
10952
|
+
tabindex="0"
|
|
10953
|
+
(click)="forgotPassword.emit()"
|
|
10954
|
+
(keydown.enter)="forgotPassword.emit()">
|
|
10955
|
+
{{ "login.forgotPassword" | transloco }}
|
|
10956
|
+
</span>
|
|
10957
|
+
<button variant="primary"
|
|
10958
|
+
[disabled]="!isValid()"
|
|
10959
|
+
(click)="handleLoginWithCredentials()">
|
|
10960
|
+
{{ "login.connect" | transloco }}
|
|
10961
|
+
</button>
|
|
10918
10962
|
</CardContent>
|
|
10919
10963
|
</Card>
|
|
10920
10964
|
} @else {
|
|
10921
|
-
<
|
|
10965
|
+
<div class="flex h-dvh w-full items-center justify-center">
|
|
10966
|
+
<div class="flex flex-col items-center space-y-4">
|
|
10967
|
+
<span class="loader"></span>
|
|
10968
|
+
</div>
|
|
10969
|
+
</div>
|
|
10922
10970
|
}
|
|
10923
|
-
`, isInline: true, styles: ["input{background-color:var(--background)}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i2.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: CardComponent, selector: ".card, card, Card", inputs: ["class", "variant", "hover"] }, { kind: "directive", type: CardHeaderComponent, selector: ".card-header, card-header, CardHeader, cardheader", inputs: ["class"] }, { kind: "directive", type: CardContentComponent, selector: ".card-content, card-content, CardContent, cardcontent", inputs: ["class"] }, { kind: "
|
|
10971
|
+
`, isInline: true, styles: ["input{background-color:var(--background)}.loader{--w: 96px;--h: 96px;transform:rotate(45deg);perspective:1000px;border-radius:50%;width:var(--w);height:var(--h);color:#0040bf}.loader:before,.loader:after{content:\"\";display:block;position:absolute;top:0;left:0;width:inherit;height:inherit;border-radius:50%;transform:rotateX(70deg);animation:1s spin linear infinite}.loader:after{color:#ff854a;transform:rotateY(70deg);animation-delay:.4s}@keyframes spin{0%,to{box-shadow:.4em 0 0 0 currentcolor}12%{box-shadow:.4em .4em 0 0 currentcolor}25%{box-shadow:0 .4em 0 0 currentcolor}37%{box-shadow:-.4em .4em 0 0 currentcolor}50%{box-shadow:-.4em 0 0 0 currentcolor}62%{box-shadow:-.4em -.4em 0 0 currentcolor}75%{box-shadow:0 -.4em 0 0 currentcolor}87%{box-shadow:.4em -.4em 0 0 currentcolor}}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i2.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: CardComponent, selector: ".card, card, Card", inputs: ["class", "variant", "hover"] }, { kind: "directive", type: CardHeaderComponent, selector: ".card-header, card-header, CardHeader, cardheader", inputs: ["class"] }, { kind: "directive", type: CardContentComponent, selector: ".card-content, card-content, CardContent, cardcontent", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
10924
10972
|
}
|
|
10925
10973
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SignInComponent, decorators: [{
|
|
10926
10974
|
type: Component,
|
|
@@ -10933,10 +10981,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
10933
10981
|
ButtonComponent,
|
|
10934
10982
|
CardComponent,
|
|
10935
10983
|
CardHeaderComponent,
|
|
10936
|
-
CardContentComponent
|
|
10937
|
-
LoadingComponent
|
|
10984
|
+
CardContentComponent
|
|
10938
10985
|
], providers: [provideTranslocoScope("login")], template: `
|
|
10939
|
-
@if (!authenticated()) {
|
|
10986
|
+
@if (!authenticated() && !externalAuth) {
|
|
10940
10987
|
<Card
|
|
10941
10988
|
hover="no"
|
|
10942
10989
|
cdkTrapFocus
|
|
@@ -10947,62 +10994,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
10947
10994
|
</CardHeader>
|
|
10948
10995
|
|
|
10949
10996
|
<CardContent class="grid gap-4">
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
(click)="handleLoginWithCredentials()">
|
|
10989
|
-
{{ "login.connect" | transloco }}
|
|
10990
|
-
</button>
|
|
10991
|
-
}
|
|
10992
|
-
@else {
|
|
10993
|
-
<!-- authentication using OAuth or SAML provider -->
|
|
10994
|
-
<button (click)="handleLogin()">
|
|
10995
|
-
{{ "login.SignInWith" | transloco : { provider: config.autoOAuthProvider ? "OAuth" : "SAML" } }}
|
|
10996
|
-
</button>
|
|
10997
|
-
}
|
|
10997
|
+
<!-- authentication using credentials -->
|
|
10998
|
+
<div class="grid gap-2">
|
|
10999
|
+
<label class="text-sm font-medium" for="username">{{
|
|
11000
|
+
"login.username" | transloco
|
|
11001
|
+
}}</label>
|
|
11002
|
+
<input
|
|
11003
|
+
id="username"
|
|
11004
|
+
type="text"
|
|
11005
|
+
required
|
|
11006
|
+
[(ngModel)]="username"
|
|
11007
|
+
(keydown.enter)="handleLoginWithCredentials()" />
|
|
11008
|
+
</div>
|
|
11009
|
+
|
|
11010
|
+
<div class="grid gap-2">
|
|
11011
|
+
<label class="text-sm font-medium" for="password">{{
|
|
11012
|
+
"login.password" | transloco
|
|
11013
|
+
}}</label>
|
|
11014
|
+
<input
|
|
11015
|
+
id="password"
|
|
11016
|
+
type="password"
|
|
11017
|
+
required
|
|
11018
|
+
[(ngModel)]="password"
|
|
11019
|
+
(keydown.enter)="handleLoginWithCredentials()" />
|
|
11020
|
+
</div>
|
|
11021
|
+
|
|
11022
|
+
<span
|
|
11023
|
+
class="text-muted-foreground cursor-pointer justify-self-start text-xs hover:underline"
|
|
11024
|
+
role="button"
|
|
11025
|
+
tabindex="0"
|
|
11026
|
+
(click)="forgotPassword.emit()"
|
|
11027
|
+
(keydown.enter)="forgotPassword.emit()">
|
|
11028
|
+
{{ "login.forgotPassword" | transloco }}
|
|
11029
|
+
</span>
|
|
11030
|
+
<button variant="primary"
|
|
11031
|
+
[disabled]="!isValid()"
|
|
11032
|
+
(click)="handleLoginWithCredentials()">
|
|
11033
|
+
{{ "login.connect" | transloco }}
|
|
11034
|
+
</button>
|
|
10998
11035
|
</CardContent>
|
|
10999
11036
|
</Card>
|
|
11000
11037
|
} @else {
|
|
11001
|
-
<
|
|
11038
|
+
<div class="flex h-dvh w-full items-center justify-center">
|
|
11039
|
+
<div class="flex flex-col items-center space-y-4">
|
|
11040
|
+
<span class="loader"></span>
|
|
11041
|
+
</div>
|
|
11042
|
+
</div>
|
|
11002
11043
|
}
|
|
11003
11044
|
`, host: {
|
|
11004
11045
|
"[class]": "cn('grid h-dvh w-full place-content-center', class())"
|
|
11005
|
-
}, styles: ["input{background-color:var(--background)}\n"] }]
|
|
11046
|
+
}, styles: ["input{background-color:var(--background)}.loader{--w: 96px;--h: 96px;transform:rotate(45deg);perspective:1000px;border-radius:50%;width:var(--w);height:var(--h);color:#0040bf}.loader:before,.loader:after{content:\"\";display:block;position:absolute;top:0;left:0;width:inherit;height:inherit;border-radius:50%;transform:rotateX(70deg);animation:1s spin linear infinite}.loader:after{color:#ff854a;transform:rotateY(70deg);animation-delay:.4s}@keyframes spin{0%,to{box-shadow:.4em 0 0 0 currentcolor}12%{box-shadow:.4em .4em 0 0 currentcolor}25%{box-shadow:0 .4em 0 0 currentcolor}37%{box-shadow:-.4em .4em 0 0 currentcolor}50%{box-shadow:-.4em 0 0 0 currentcolor}62%{box-shadow:-.4em -.4em 0 0 currentcolor}75%{box-shadow:0 -.4em 0 0 currentcolor}87%{box-shadow:.4em -.4em 0 0 currentcolor}}\n"] }]
|
|
11006
11047
|
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], forgotPassword: [{ type: i0.Output, args: ["forgotPassword"] }], username: [{ type: i0.Input, args: [{ isSignal: true, alias: "username", required: false }] }, { type: i0.Output, args: ["usernameChange"] }], password: [{ type: i0.Input, args: [{ isSignal: true, alias: "password", required: false }] }, { type: i0.Output, args: ["passwordChange"] }] } });
|
|
11007
11048
|
|
|
11008
11049
|
class AuthPageComponent {
|